aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBen Skeggs <[email protected]>2022-06-01 20:46:51 +1000
committerBen Skeggs <[email protected]>2022-11-09 10:44:35 +1000
commitab4f75eb1cc261263ac51814fed14fde08b6716f (patch)
tree84385f50a58509a96c276fc622a4292280cd1e58
parent4a16dd9d18a04742292cc7bfdbb79aedfe24e2c8 (diff)
drm/nouveau/nvkm: give each nvkm_event its own lockdep class
The vblank and nonstall events have some annoying interactions with DRM locking, and aren't able to do certain things as a result. However, other uses of event notifications don't have such requirements, and upcoming patches take advantage of this for various improvements. Having separate classes for each nvkm_event's spinlocks allows lockdep to distinguish between them and avoid false-positives. v2: __always_inline + comment Signed-off-by: Ben Skeggs <[email protected]> Reviewed-by: Lyude Paul <[email protected]>
-rw-r--r--drivers/gpu/drm/nouveau/include/nvkm/core/event.h19
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/core/event.c6
2 files changed, 19 insertions, 6 deletions
diff --git a/drivers/gpu/drm/nouveau/include/nvkm/core/event.h b/drivers/gpu/drm/nouveau/include/nvkm/core/event.h
index 8e8fb4b6bca4..82b267c11147 100644
--- a/drivers/gpu/drm/nouveau/include/nvkm/core/event.h
+++ b/drivers/gpu/drm/nouveau/include/nvkm/core/event.h
@@ -25,8 +25,23 @@ struct nvkm_event_func {
void (*fini)(struct nvkm_event *, int type, int index);
};
-int nvkm_event_init(const struct nvkm_event_func *func, struct nvkm_subdev *, int types_nr,
- int index_nr, struct nvkm_event *);
+int __nvkm_event_init(const struct nvkm_event_func *func, struct nvkm_subdev *, int types_nr,
+ int index_nr, struct nvkm_event *);
+
+/* Each nvkm_event needs its own lockdep class due to inter-dependencies, to
+ * prevent lockdep false-positives.
+ *
+ * Inlining the spinlock initialisation ensures each is unique.
+ */
+static __always_inline int
+nvkm_event_init(const struct nvkm_event_func *func, struct nvkm_subdev *subdev,
+ int types_nr, int index_nr, struct nvkm_event *event)
+{
+ spin_lock_init(&event->refs_lock);
+ spin_lock_init(&event->list_lock);
+ return __nvkm_event_init(func, subdev, types_nr, index_nr, event);
+}
+
void nvkm_event_fini(struct nvkm_event *);
#define NVKM_EVENT_KEEP 0
diff --git a/drivers/gpu/drm/nouveau/nvkm/core/event.c b/drivers/gpu/drm/nouveau/nvkm/core/event.c
index 622df36391be..a6c877135598 100644
--- a/drivers/gpu/drm/nouveau/nvkm/core/event.c
+++ b/drivers/gpu/drm/nouveau/nvkm/core/event.c
@@ -198,8 +198,8 @@ nvkm_event_fini(struct nvkm_event *event)
}
int
-nvkm_event_init(const struct nvkm_event_func *func, struct nvkm_subdev *subdev,
- int types_nr, int index_nr, struct nvkm_event *event)
+__nvkm_event_init(const struct nvkm_event_func *func, struct nvkm_subdev *subdev,
+ int types_nr, int index_nr, struct nvkm_event *event)
{
event->refs = kzalloc(array3_size(index_nr, types_nr, sizeof(*event->refs)), GFP_KERNEL);
if (!event->refs)
@@ -209,8 +209,6 @@ nvkm_event_init(const struct nvkm_event_func *func, struct nvkm_subdev *subdev,
event->subdev = subdev;
event->types_nr = types_nr;
event->index_nr = index_nr;
- spin_lock_init(&event->refs_lock);
- spin_lock_init(&event->list_lock);
INIT_LIST_HEAD(&event->ntfy);
return 0;
}