[PATCH] drm: Make each driver's struct_mutex its own subclass

Chris Wilson chris at chris-wilson.co.uk
Fri Dec 9 16:52:32 UTC 2016


With prime, we are running into false circular dependencies based on the
order in which two drivers may lock their own struct_mutex wrt to a
common lock (like the reservation->lock). Work around this by adding the
lock_class_key to the struct drm_driver such that each driver can have
its own subclass of struct_mutex. Circular dependencies between drivers
will now be ignored, but real circular dependencies on any one mutex
will still be caught. A driver creating more than one device will still
need to be careful!

Reported-by: Tobias Klausmann <tobias.johannes.klausmann at mni.thm.de>
Reported-by: Hans de Goede <hdegoede at redhat.com>
Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>
---
 drivers/gpu/drm/drm_drv.c | 4 +++-
 include/drm/drm_drv.h     | 6 ++++++
 2 files changed, 9 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c
index 2fa4e4fa7c33..82b521146e71 100644
--- a/drivers/gpu/drm/drm_drv.c
+++ b/drivers/gpu/drm/drm_drv.c
@@ -488,7 +488,9 @@ int drm_dev_init(struct drm_device *dev,
 
 	spin_lock_init(&dev->buf_lock);
 	spin_lock_init(&dev->event_lock);
-	mutex_init(&dev->struct_mutex);
+	__mutex_init(&dev->struct_mutex,
+		     "&dev->struct_mutex",
+		     &driver->class.struct_mutex_key);
 	mutex_init(&dev->filelist_mutex);
 	mutex_init(&dev->ctxlist_mutex);
 	mutex_init(&dev->master_mutex);
diff --git a/include/drm/drm_drv.h b/include/drm/drm_drv.h
index 554104ccb939..5d521923404a 100644
--- a/include/drm/drm_drv.h
+++ b/include/drm/drm_drv.h
@@ -39,6 +39,10 @@ struct dma_buf_attachment;
 struct drm_display_mode;
 struct drm_mode_create_dumb;
 
+struct drm_driver_class {
+	struct lock_class_key struct_mutex_key;
+};
+
 /* driver capabilities and requirements mask */
 #define DRIVER_USE_AGP			0x1
 #define DRIVER_LEGACY			0x2
@@ -64,6 +68,8 @@ struct drm_mode_create_dumb;
  * structure for GEM drivers.
  */
 struct drm_driver {
+	struct drm_driver_class class;
+
 	int (*load) (struct drm_device *, unsigned long flags);
 	int (*firstopen) (struct drm_device *);
 	int (*open) (struct drm_device *, struct drm_file *);
-- 
2.11.0



More information about the dri-devel mailing list