All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH RESEND 00/20] dev->struct_mutex locking crusade
@ 2015-11-19 16:46 Daniel Vetter
  2015-11-19 16:46 ` [PATCH RESEND 01/20] drm/armada: Plug leak in dumb_map_offset Daniel Vetter
                   ` (20 more replies)
  0 siblings, 21 replies; 30+ messages in thread
From: Daniel Vetter @ 2015-11-19 16:46 UTC (permalink / raw)
  To: DRI Development; +Cc: Daniel Vetter, Intel Graphics Development

Hi all,

Here's my resend of the dev->struct_mutex locking removal patches. I'd like to
get them all into 4.5, so please pick them either up into your tree or ack them.
I'll send a pull request for the remaining in a few weeks.

Thanks, Daniel

Daniel Vetter (20):
  drm/armada: Plug leak in dumb_map_offset
  drm/armada: Don't grab dev->struct_mutex for in mmap offset ioctl
  drm/armada: Drop struct_mutex from cursor paths
  drm/armada: Use a private mutex to protect priv->linear
  drm/tegra: don't take dev->struct_mutex in mmap offset ioctl
  drm/tegra: Use drm_gem_object_unreference_unlocked
  drm/gma500: Use correct unref in the gem bo create function
  drm/gma500: Drop dev->struct_mutex from modeset code
  drm/gma500: Drop dev->struct_mutex from fbdev init/teardown code
  drm/gma500: Drop dev->struct_mutex from mmap offset function
  drm/gma500: Add driver private mutex for the fault handler
  drm/nouveau: Drop dev->struct_mutex from fbdev init
  drm/exynos: Drop dev->struct_mutex from mmap offset function
  drm/exynos: drop struct_mutex from exynos_gem_map_sgt_with_dma
  drm/exynos: drop struct_mutex from exynos_drm_gem_get_ioctl
  drm/exynos: drop struct_mutex from fbdev setup
  drm/vgem: Simplify dum_map
  drm/vgem: Move get_pages to gem_create
  drm/vgem: Drop dev->struct_mutex
  drm/vma_manage: Drop has_offset

 drivers/gpu/drm/armada/armada_crtc.c      |  6 +-----
 drivers/gpu/drm/armada/armada_debugfs.c   |  4 ++--
 drivers/gpu/drm/armada/armada_drm.h       |  3 ++-
 drivers/gpu/drm/armada/armada_drv.c       |  1 +
 drivers/gpu/drm/armada/armada_gem.c       | 21 ++++++++-----------
 drivers/gpu/drm/drm_gem.c                 | 17 ++++++++++++++++
 drivers/gpu/drm/exynos/exynos_drm_fbdev.c | 22 ++++++++------------
 drivers/gpu/drm/exynos/exynos_drm_gem.c   | 15 +-------------
 drivers/gpu/drm/gma500/framebuffer.c      | 12 ++---------
 drivers/gpu/drm/gma500/gem.c              | 19 ++++++-----------
 drivers/gpu/drm/gma500/gma_display.c      | 13 +++---------
 drivers/gpu/drm/gma500/gtt.c              |  1 +
 drivers/gpu/drm/gma500/psb_drv.h          |  2 ++
 drivers/gpu/drm/i915/i915_gem.c           |  3 ---
 drivers/gpu/drm/nouveau/nouveau_fbcon.c   |  5 -----
 drivers/gpu/drm/tegra/drm.c               |  4 +---
 drivers/gpu/drm/tegra/gem.c               | 13 ++----------
 drivers/gpu/drm/vgem/vgem_drv.c           | 34 +++++++++----------------------
 include/drm/drm_vma_manager.h             | 15 +-------------
 19 files changed, 69 insertions(+), 141 deletions(-)

-- 
2.5.1

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 30+ messages in thread

* [PATCH RESEND 01/20] drm/armada: Plug leak in dumb_map_offset
  2015-11-19 16:46 [PATCH RESEND 00/20] dev->struct_mutex locking crusade Daniel Vetter
@ 2015-11-19 16:46 ` Daniel Vetter
  2015-11-19 16:46 ` [PATCH RESEND 02/20] drm/armada: Don't grab dev->struct_mutex for in mmap offset ioctl Daniel Vetter
                   ` (19 subsequent siblings)
  20 siblings, 0 replies; 30+ messages in thread
From: Daniel Vetter @ 2015-11-19 16:46 UTC (permalink / raw)
  To: DRI Development
  Cc: Daniel Vetter, Daniel Vetter, Intel Graphics Development, Russell King

We need to drop the gem bo reference if it's an imported one.

Cc: Russell King <rmk+kernel@arm.linux.org.uk>
Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
---
 drivers/gpu/drm/armada/armada_gem.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/armada/armada_gem.c b/drivers/gpu/drm/armada/armada_gem.c
index 60a688ef81c7..323da46c7ca8 100644
--- a/drivers/gpu/drm/armada/armada_gem.c
+++ b/drivers/gpu/drm/armada/armada_gem.c
@@ -285,7 +285,7 @@ int armada_gem_dumb_map_offset(struct drm_file *file, struct drm_device *dev,
 	/* Don't allow imported objects to be mapped */
 	if (obj->obj.import_attach) {
 		ret = -EINVAL;
-		goto err_unlock;
+		goto err_unref;
 	}
 
 	ret = drm_gem_create_mmap_offset(&obj->obj);
@@ -294,6 +294,7 @@ int armada_gem_dumb_map_offset(struct drm_file *file, struct drm_device *dev,
 		DRM_DEBUG_DRIVER("handle %#x offset %llx\n", handle, *offset);
 	}
 
+ err_unref:
 	drm_gem_object_unreference(&obj->obj);
  err_unlock:
 	mutex_unlock(&dev->struct_mutex);
-- 
2.5.1

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [PATCH RESEND 02/20] drm/armada: Don't grab dev->struct_mutex for in mmap offset ioctl
  2015-11-19 16:46 [PATCH RESEND 00/20] dev->struct_mutex locking crusade Daniel Vetter
  2015-11-19 16:46 ` [PATCH RESEND 01/20] drm/armada: Plug leak in dumb_map_offset Daniel Vetter
@ 2015-11-19 16:46 ` Daniel Vetter
  2015-11-19 16:46 ` [PATCH RESEND 03/20] drm/armada: Drop struct_mutex from cursor paths Daniel Vetter
                   ` (18 subsequent siblings)
  20 siblings, 0 replies; 30+ messages in thread
From: Daniel Vetter @ 2015-11-19 16:46 UTC (permalink / raw)
  To: DRI Development
  Cc: Daniel Vetter, Daniel Vetter, Intel Graphics Development, Russell King

Since David Herrmann's mmap vma manager rework we don't need to grab
dev->struct_mutex any more to prevent races when looking up the mmap
offset. Drop it and instead don't forget to use the unref_unlocked
variant (since the drm core still cares).

v2: Split out the leak fix in dump_map_offset into a separate patch as
requested by Russell. Also align labels the same way as before to
stick with local coding style.

Cc: Russell King <rmk+kernel@arm.linux.org.uk>
Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
---
 drivers/gpu/drm/armada/armada_gem.c | 8 ++------
 1 file changed, 2 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/armada/armada_gem.c b/drivers/gpu/drm/armada/armada_gem.c
index 323da46c7ca8..59fafa468347 100644
--- a/drivers/gpu/drm/armada/armada_gem.c
+++ b/drivers/gpu/drm/armada/armada_gem.c
@@ -274,12 +274,10 @@ int armada_gem_dumb_map_offset(struct drm_file *file, struct drm_device *dev,
 	struct armada_gem_object *obj;
 	int ret = 0;
 
-	mutex_lock(&dev->struct_mutex);
 	obj = armada_gem_object_lookup(dev, file, handle);
 	if (!obj) {
 		DRM_ERROR("failed to lookup gem object\n");
-		ret = -EINVAL;
-		goto err_unlock;
+		return -EINVAL;
 	}
 
 	/* Don't allow imported objects to be mapped */
@@ -295,9 +293,7 @@ int armada_gem_dumb_map_offset(struct drm_file *file, struct drm_device *dev,
 	}
 
  err_unref:
-	drm_gem_object_unreference(&obj->obj);
- err_unlock:
-	mutex_unlock(&dev->struct_mutex);
+	drm_gem_object_unreference_unlocked(&obj->obj);
 
 	return ret;
 }
-- 
2.5.1

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [PATCH RESEND 03/20] drm/armada: Drop struct_mutex from cursor paths
  2015-11-19 16:46 [PATCH RESEND 00/20] dev->struct_mutex locking crusade Daniel Vetter
  2015-11-19 16:46 ` [PATCH RESEND 01/20] drm/armada: Plug leak in dumb_map_offset Daniel Vetter
  2015-11-19 16:46 ` [PATCH RESEND 02/20] drm/armada: Don't grab dev->struct_mutex for in mmap offset ioctl Daniel Vetter
@ 2015-11-19 16:46 ` Daniel Vetter
  2015-11-19 16:46 ` [PATCH RESEND 04/20] drm/armada: Use a private mutex to protect priv->linear Daniel Vetter
                   ` (17 subsequent siblings)
  20 siblings, 0 replies; 30+ messages in thread
From: Daniel Vetter @ 2015-11-19 16:46 UTC (permalink / raw)
  To: DRI Development
  Cc: Daniel Vetter, Daniel Vetter, Intel Graphics Development, Russell King

The kms state itself is already protected by the modeset locks
acquired by the drm core. The only thing left is gem bo state, and
since the cursor code expects small objects which are statically
mapped at create time and then invariant over the lifetime of the gem
bo there's nothing to protect.

See armada_gem_dumb_create -> armada_gem_linear_back which assigns
obj->addr which is the only thing used by the cursor code.

Only tricky bit is to switch to the _unlocked unreference function.

Cc: Russell King <rmk+kernel@arm.linux.org.uk>
Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
---
 drivers/gpu/drm/armada/armada_crtc.c | 6 +-----
 1 file changed, 1 insertion(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/armada/armada_crtc.c b/drivers/gpu/drm/armada/armada_crtc.c
index cebcab560626..67fed0bbe53a 100644
--- a/drivers/gpu/drm/armada/armada_crtc.c
+++ b/drivers/gpu/drm/armada/armada_crtc.c
@@ -928,11 +928,10 @@ static int armada_drm_crtc_cursor_set(struct drm_crtc *crtc,
 		}
 	}
 
-	mutex_lock(&dev->struct_mutex);
 	if (dcrtc->cursor_obj) {
 		dcrtc->cursor_obj->update = NULL;
 		dcrtc->cursor_obj->update_data = NULL;
-		drm_gem_object_unreference(&dcrtc->cursor_obj->obj);
+		drm_gem_object_unreference_unlocked(&dcrtc->cursor_obj->obj);
 	}
 	dcrtc->cursor_obj = obj;
 	dcrtc->cursor_w = w;
@@ -942,7 +941,6 @@ static int armada_drm_crtc_cursor_set(struct drm_crtc *crtc,
 		obj->update_data = dcrtc;
 		obj->update = cursor_update;
 	}
-	mutex_unlock(&dev->struct_mutex);
 
 	return ret;
 }
@@ -957,11 +955,9 @@ static int armada_drm_crtc_cursor_move(struct drm_crtc *crtc, int x, int y)
 	if (!dcrtc->variant->has_spu_adv_reg)
 		return -EFAULT;
 
-	mutex_lock(&dev->struct_mutex);
 	dcrtc->cursor_x = x;
 	dcrtc->cursor_y = y;
 	ret = armada_drm_crtc_cursor_update(dcrtc, false);
-	mutex_unlock(&dev->struct_mutex);
 
 	return ret;
 }
-- 
2.5.1

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [PATCH RESEND 04/20] drm/armada: Use a private mutex to protect priv->linear
  2015-11-19 16:46 [PATCH RESEND 00/20] dev->struct_mutex locking crusade Daniel Vetter
                   ` (2 preceding siblings ...)
  2015-11-19 16:46 ` [PATCH RESEND 03/20] drm/armada: Drop struct_mutex from cursor paths Daniel Vetter
@ 2015-11-19 16:46 ` Daniel Vetter
  2015-11-19 16:46 ` [PATCH RESEND 05/20] drm/tegra: don't take dev->struct_mutex in mmap offset ioctl Daniel Vetter
                   ` (16 subsequent siblings)
  20 siblings, 0 replies; 30+ messages in thread
From: Daniel Vetter @ 2015-11-19 16:46 UTC (permalink / raw)
  To: DRI Development
  Cc: Daniel Vetter, Daniel Vetter, Intel Graphics Development, Russell King

Reusing the Big DRM Lock just leaks, and the few things left that
dev->struct_mutex protected are very well contained - it's just the
linear drm_mm manager.

With this armada is completely struct_mutex free!

Cc: Russell King <rmk+kernel@arm.linux.org.uk>
Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
---
 drivers/gpu/drm/armada/armada_debugfs.c |  4 ++--
 drivers/gpu/drm/armada/armada_drm.h     |  3 ++-
 drivers/gpu/drm/armada/armada_drv.c     |  1 +
 drivers/gpu/drm/armada/armada_gem.c     | 10 +++++-----
 4 files changed, 10 insertions(+), 8 deletions(-)

diff --git a/drivers/gpu/drm/armada/armada_debugfs.c b/drivers/gpu/drm/armada/armada_debugfs.c
index 471e45627f1e..d4f7ab0a30d4 100644
--- a/drivers/gpu/drm/armada/armada_debugfs.c
+++ b/drivers/gpu/drm/armada/armada_debugfs.c
@@ -21,9 +21,9 @@ static int armada_debugfs_gem_linear_show(struct seq_file *m, void *data)
 	struct armada_private *priv = dev->dev_private;
 	int ret;
 
-	mutex_lock(&dev->struct_mutex);
+	mutex_lock(&priv->linear_lock);
 	ret = drm_mm_dump_table(m, &priv->linear);
-	mutex_unlock(&dev->struct_mutex);
+	mutex_unlock(&priv->linear_lock);
 
 	return ret;
 }
diff --git a/drivers/gpu/drm/armada/armada_drm.h b/drivers/gpu/drm/armada/armada_drm.h
index 4df6f2af2b21..6d2d8be38297 100644
--- a/drivers/gpu/drm/armada/armada_drm.h
+++ b/drivers/gpu/drm/armada/armada_drm.h
@@ -57,7 +57,8 @@ struct armada_private {
 	DECLARE_KFIFO(fb_unref, struct drm_framebuffer *, 8);
 	struct drm_fb_helper	*fbdev;
 	struct armada_crtc	*dcrtc[2];
-	struct drm_mm		linear;
+	struct drm_mm		linear; /* protectec by linear_lock */
+	struct mutex		linear_lock;
 	struct drm_property	*csc_yuv_prop;
 	struct drm_property	*csc_rgb_prop;
 	struct drm_property	*colorkey_prop;
diff --git a/drivers/gpu/drm/armada/armada_drv.c b/drivers/gpu/drm/armada/armada_drv.c
index 77ab93d60125..3bd7e1cde99e 100644
--- a/drivers/gpu/drm/armada/armada_drv.c
+++ b/drivers/gpu/drm/armada/armada_drv.c
@@ -102,6 +102,7 @@ static int armada_drm_load(struct drm_device *dev, unsigned long flags)
 	dev->mode_config.preferred_depth = 24;
 	dev->mode_config.funcs = &armada_drm_mode_config_funcs;
 	drm_mm_init(&priv->linear, mem->start, resource_size(mem));
+	mutex_init(&priv->linear_lock);
 
 	ret = component_bind_all(dev->dev, dev);
 	if (ret)
diff --git a/drivers/gpu/drm/armada/armada_gem.c b/drivers/gpu/drm/armada/armada_gem.c
index 59fafa468347..45e12d4c1722 100644
--- a/drivers/gpu/drm/armada/armada_gem.c
+++ b/drivers/gpu/drm/armada/armada_gem.c
@@ -46,7 +46,7 @@ static size_t roundup_gem_size(size_t size)
 	return roundup(size, PAGE_SIZE);
 }
 
-/* dev->struct_mutex is held here */
+/* dev_priv->linear_lock is held here */
 void armada_gem_free_object(struct drm_gem_object *obj)
 {
 	struct armada_gem_object *dobj = drm_to_armada_gem(obj);
@@ -144,10 +144,10 @@ armada_gem_linear_back(struct drm_device *dev, struct armada_gem_object *obj)
 		if (!node)
 			return -ENOSPC;
 
-		mutex_lock(&dev->struct_mutex);
+		mutex_lock(&priv->linear_lock);
 		ret = drm_mm_insert_node(&priv->linear, node, size, align,
 					 DRM_MM_SEARCH_DEFAULT);
-		mutex_unlock(&dev->struct_mutex);
+		mutex_unlock(&priv->linear_lock);
 		if (ret) {
 			kfree(node);
 			return ret;
@@ -158,9 +158,9 @@ armada_gem_linear_back(struct drm_device *dev, struct armada_gem_object *obj)
 		/* Ensure that the memory we're returning is cleared. */
 		ptr = ioremap_wc(obj->linear->start, size);
 		if (!ptr) {
-			mutex_lock(&dev->struct_mutex);
+			mutex_lock(&priv->linear_lock);
 			drm_mm_remove_node(obj->linear);
-			mutex_unlock(&dev->struct_mutex);
+			mutex_unlock(&priv->linear_lock);
 			kfree(obj->linear);
 			obj->linear = NULL;
 			return -ENOMEM;
-- 
2.5.1

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [PATCH RESEND 05/20] drm/tegra: don't take dev->struct_mutex in mmap offset ioctl
  2015-11-19 16:46 [PATCH RESEND 00/20] dev->struct_mutex locking crusade Daniel Vetter
                   ` (3 preceding siblings ...)
  2015-11-19 16:46 ` [PATCH RESEND 04/20] drm/armada: Use a private mutex to protect priv->linear Daniel Vetter
@ 2015-11-19 16:46 ` Daniel Vetter
  2015-11-19 16:46 ` [PATCH RESEND 06/20] drm/tegra: Use drm_gem_object_unreference_unlocked Daniel Vetter
                   ` (15 subsequent siblings)
  20 siblings, 0 replies; 30+ messages in thread
From: Daniel Vetter @ 2015-11-19 16:46 UTC (permalink / raw)
  To: DRI Development
  Cc: Daniel Vetter, Intel Graphics Development, Thierry Reding, Daniel Vetter

Since David Herrmann's mmap vma manager rework we don't need to grab
dev->struct_mutex any more to prevent races when looking up the mmap
offset. Drop it and instead don't forget to use the unref_unlocked
variant (since the drm core still cares).

v2: Finally get rid of the copypasta from another commit in this
commit message. And convert to _unlocked like we need to (Patrik).

Cc: Patrik Jakobsson <patrik.r.jakobsson@gmail.com>
Cc: Thierry Reding <thierry.reding@gmail.com>
Acked-by: Thierry Reding <thierry.reding@gmail.com>
Reviewed-by: Patrik Jakobsson <patrik.r.jakobsson@gmail.com>
Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
---
 drivers/gpu/drm/tegra/gem.c | 7 +------
 1 file changed, 1 insertion(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/tegra/gem.c b/drivers/gpu/drm/tegra/gem.c
index 01e16e146bfe..fb712316c522 100644
--- a/drivers/gpu/drm/tegra/gem.c
+++ b/drivers/gpu/drm/tegra/gem.c
@@ -408,12 +408,9 @@ int tegra_bo_dumb_map_offset(struct drm_file *file, struct drm_device *drm,
 	struct drm_gem_object *gem;
 	struct tegra_bo *bo;
 
-	mutex_lock(&drm->struct_mutex);
-
 	gem = drm_gem_object_lookup(drm, file, handle);
 	if (!gem) {
 		dev_err(drm->dev, "failed to lookup GEM object\n");
-		mutex_unlock(&drm->struct_mutex);
 		return -EINVAL;
 	}
 
@@ -421,9 +418,7 @@ int tegra_bo_dumb_map_offset(struct drm_file *file, struct drm_device *drm,
 
 	*offset = drm_vma_node_offset_addr(&bo->gem.vma_node);
 
-	drm_gem_object_unreference(gem);
-
-	mutex_unlock(&drm->struct_mutex);
+	drm_gem_object_unreference_unlocked(gem);
 
 	return 0;
 }
-- 
2.5.1

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [PATCH RESEND 06/20] drm/tegra: Use drm_gem_object_unreference_unlocked
  2015-11-19 16:46 [PATCH RESEND 00/20] dev->struct_mutex locking crusade Daniel Vetter
                   ` (4 preceding siblings ...)
  2015-11-19 16:46 ` [PATCH RESEND 05/20] drm/tegra: don't take dev->struct_mutex in mmap offset ioctl Daniel Vetter
@ 2015-11-19 16:46 ` Daniel Vetter
  2015-11-19 16:46 ` [PATCH RESEND 07/20] drm/gma500: Use correct unref in the gem bo create function Daniel Vetter
                   ` (14 subsequent siblings)
  20 siblings, 0 replies; 30+ messages in thread
From: Daniel Vetter @ 2015-11-19 16:46 UTC (permalink / raw)
  To: DRI Development; +Cc: Daniel Vetter, Intel Graphics Development, Daniel Vetter

This only grabs the mutex when really needed, but still has a
might-acquire lockdep check to make sure that's always possible.
With this patch tegra is officially struct_mutex free, yay!

v2: refernce_unlocked doesn't exist as kbuild spotted.

Cc: Thierry Reding <thierry.reding@gmail.com>
Acked-by: Thierry Reding <thierry.reding@gmail.com>
Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
---
 drivers/gpu/drm/tegra/drm.c | 4 +---
 drivers/gpu/drm/tegra/gem.c | 6 +-----
 2 files changed, 2 insertions(+), 8 deletions(-)

diff --git a/drivers/gpu/drm/tegra/drm.c b/drivers/gpu/drm/tegra/drm.c
index e0f827790a5e..41f4efef777b 100644
--- a/drivers/gpu/drm/tegra/drm.c
+++ b/drivers/gpu/drm/tegra/drm.c
@@ -277,9 +277,7 @@ host1x_bo_lookup(struct drm_device *drm, struct drm_file *file, u32 handle)
 	if (!gem)
 		return NULL;
 
-	mutex_lock(&drm->struct_mutex);
-	drm_gem_object_unreference(gem);
-	mutex_unlock(&drm->struct_mutex);
+	drm_gem_object_unreference_unlocked(gem);
 
 	bo = to_tegra_bo(gem);
 	return &bo->base;
diff --git a/drivers/gpu/drm/tegra/gem.c b/drivers/gpu/drm/tegra/gem.c
index fb712316c522..fbec29516bcb 100644
--- a/drivers/gpu/drm/tegra/gem.c
+++ b/drivers/gpu/drm/tegra/gem.c
@@ -30,9 +30,7 @@ static void tegra_bo_put(struct host1x_bo *bo)
 	struct tegra_bo *obj = host1x_to_tegra_bo(bo);
 	struct drm_device *drm = obj->gem.dev;
 
-	mutex_lock(&drm->struct_mutex);
-	drm_gem_object_unreference(&obj->gem);
-	mutex_unlock(&drm->struct_mutex);
+	drm_gem_object_unreference_unlocked(&obj->gem);
 }
 
 static dma_addr_t tegra_bo_pin(struct host1x_bo *bo, struct sg_table **sgt)
@@ -74,9 +72,7 @@ static struct host1x_bo *tegra_bo_get(struct host1x_bo *bo)
 	struct tegra_bo *obj = host1x_to_tegra_bo(bo);
 	struct drm_device *drm = obj->gem.dev;
 
-	mutex_lock(&drm->struct_mutex);
 	drm_gem_object_reference(&obj->gem);
-	mutex_unlock(&drm->struct_mutex);
 
 	return bo;
 }
-- 
2.5.1

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [PATCH RESEND 07/20] drm/gma500: Use correct unref in the gem bo create function
  2015-11-19 16:46 [PATCH RESEND 00/20] dev->struct_mutex locking crusade Daniel Vetter
                   ` (5 preceding siblings ...)
  2015-11-19 16:46 ` [PATCH RESEND 06/20] drm/tegra: Use drm_gem_object_unreference_unlocked Daniel Vetter
@ 2015-11-19 16:46 ` Daniel Vetter
  2015-11-19 16:46 ` [PATCH RESEND 08/20] drm/gma500: Drop dev->struct_mutex from modeset code Daniel Vetter
                   ` (13 subsequent siblings)
  20 siblings, 0 replies; 30+ messages in thread
From: Daniel Vetter @ 2015-11-19 16:46 UTC (permalink / raw)
  To: DRI Development; +Cc: Daniel Vetter, Intel Graphics Development

This is called without dev->struct_mutex held, we need to use the
_unlocked variant.

Never caught in the wild since you'd need an evil userspace which
races a gem_close ioctl call with the in-progress open.

Cc: Patrik Jakobsson <patrik.r.jakobsson@gmail.com>
Acked-by: Patrik Jakobsson <patrik.r.jakobsson@gmail.com>
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
---
 drivers/gpu/drm/gma500/gem.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/gma500/gem.c b/drivers/gpu/drm/gma500/gem.c
index c707fa6fca85..e3bdc8b1c32c 100644
--- a/drivers/gpu/drm/gma500/gem.c
+++ b/drivers/gpu/drm/gma500/gem.c
@@ -130,7 +130,7 @@ int psb_gem_create(struct drm_file *file, struct drm_device *dev, u64 size,
 		return ret;
 	}
 	/* We have the initial and handle reference but need only one now */
-	drm_gem_object_unreference(&r->gem);
+	drm_gem_object_unreference_unlocked(&r->gem);
 	*handlep = handle;
 	return 0;
 }
-- 
2.5.1

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [PATCH RESEND 08/20] drm/gma500: Drop dev->struct_mutex from modeset code
  2015-11-19 16:46 [PATCH RESEND 00/20] dev->struct_mutex locking crusade Daniel Vetter
                   ` (6 preceding siblings ...)
  2015-11-19 16:46 ` [PATCH RESEND 07/20] drm/gma500: Use correct unref in the gem bo create function Daniel Vetter
@ 2015-11-19 16:46 ` Daniel Vetter
  2015-11-19 16:46 ` [PATCH RESEND 09/20] drm/gma500: Drop dev->struct_mutex from fbdev init/teardown code Daniel Vetter
                   ` (12 subsequent siblings)
  20 siblings, 0 replies; 30+ messages in thread
From: Daniel Vetter @ 2015-11-19 16:46 UTC (permalink / raw)
  To: DRI Development; +Cc: Daniel Vetter, Intel Graphics Development

It's either init code or already protected by other means. Note
that psb_gtt_pin/unpin has it's own lock, and that's really the
only piece of driver private state - all the modeset state is
protected with modeset locks already.

The only important bit is to switch all gem_obj_unref calls to the
_unlocked variant.

Cc: Patrik Jakobsson <patrik.r.jakobsson@gmail.com>
Acked-by: Patrik Jakobsson <patrik.r.jakobsson@gmail.com>
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
---
 drivers/gpu/drm/gma500/gma_display.c | 13 +++----------
 1 file changed, 3 insertions(+), 10 deletions(-)

diff --git a/drivers/gpu/drm/gma500/gma_display.c b/drivers/gpu/drm/gma500/gma_display.c
index 001b450b27b3..ff17af4cfc64 100644
--- a/drivers/gpu/drm/gma500/gma_display.c
+++ b/drivers/gpu/drm/gma500/gma_display.c
@@ -349,8 +349,6 @@ int gma_crtc_cursor_set(struct drm_crtc *crtc,
 	/* If we didn't get a handle then turn the cursor off */
 	if (!handle) {
 		temp = CURSOR_MODE_DISABLE;
-		mutex_lock(&dev->struct_mutex);
-
 		if (gma_power_begin(dev, false)) {
 			REG_WRITE(control, temp);
 			REG_WRITE(base, 0);
@@ -362,11 +360,9 @@ int gma_crtc_cursor_set(struct drm_crtc *crtc,
 			gt = container_of(gma_crtc->cursor_obj,
 					  struct gtt_range, gem);
 			psb_gtt_unpin(gt);
-			drm_gem_object_unreference(gma_crtc->cursor_obj);
+			drm_gem_object_unreference_unlocked(gma_crtc->cursor_obj);
 			gma_crtc->cursor_obj = NULL;
 		}
-
-		mutex_unlock(&dev->struct_mutex);
 		return 0;
 	}
 
@@ -376,7 +372,6 @@ int gma_crtc_cursor_set(struct drm_crtc *crtc,
 		return -EINVAL;
 	}
 
-	mutex_lock(&dev->struct_mutex);
 	obj = drm_gem_object_lookup(dev, file_priv, handle);
 	if (!obj) {
 		ret = -ENOENT;
@@ -441,17 +436,15 @@ int gma_crtc_cursor_set(struct drm_crtc *crtc,
 	if (gma_crtc->cursor_obj) {
 		gt = container_of(gma_crtc->cursor_obj, struct gtt_range, gem);
 		psb_gtt_unpin(gt);
-		drm_gem_object_unreference(gma_crtc->cursor_obj);
+		drm_gem_object_unreference_unlocked(gma_crtc->cursor_obj);
 	}
 
 	gma_crtc->cursor_obj = obj;
 unlock:
-	mutex_unlock(&dev->struct_mutex);
 	return ret;
 
 unref_cursor:
-	drm_gem_object_unreference(obj);
-	mutex_unlock(&dev->struct_mutex);
+	drm_gem_object_unreference_unlocked(obj);
 	return ret;
 }
 
-- 
2.5.1

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [PATCH RESEND 09/20] drm/gma500: Drop dev->struct_mutex from fbdev init/teardown code
  2015-11-19 16:46 [PATCH RESEND 00/20] dev->struct_mutex locking crusade Daniel Vetter
                   ` (7 preceding siblings ...)
  2015-11-19 16:46 ` [PATCH RESEND 08/20] drm/gma500: Drop dev->struct_mutex from modeset code Daniel Vetter
@ 2015-11-19 16:46 ` Daniel Vetter
  2015-11-19 16:46 ` [PATCH RESEND 10/20] drm/gma500: Drop dev->struct_mutex from mmap offset function Daniel Vetter
                   ` (11 subsequent siblings)
  20 siblings, 0 replies; 30+ messages in thread
From: Daniel Vetter @ 2015-11-19 16:46 UTC (permalink / raw)
  To: DRI Development; +Cc: Daniel Vetter, Intel Graphics Development

This is init/teardown code, locking is just to appease locking checks.
And since gem create/free doesn't need this any more there's really no
reason for grabbing dev->struct_mutex.

Again important to switch obj_unref to _unlocked variants.

Cc: Patrik Jakobsson <patrik.r.jakobsson@gmail.com>
Acked-by: Patrik Jakobsson <patrik.r.jakobsson@gmail.com>
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
---
 drivers/gpu/drm/gma500/framebuffer.c | 12 ++----------
 1 file changed, 2 insertions(+), 10 deletions(-)

diff --git a/drivers/gpu/drm/gma500/framebuffer.c b/drivers/gpu/drm/gma500/framebuffer.c
index dc0508dca1d4..ee95c03a8c54 100644
--- a/drivers/gpu/drm/gma500/framebuffer.c
+++ b/drivers/gpu/drm/gma500/framebuffer.c
@@ -406,8 +406,6 @@ static int psbfb_create(struct psb_fbdev *fbdev,
 
 	memset(dev_priv->vram_addr + backing->offset, 0, size);
 
-	mutex_lock(&dev->struct_mutex);
-
 	info = drm_fb_helper_alloc_fbi(&fbdev->psb_fb_helper);
 	if (IS_ERR(info)) {
 		ret = PTR_ERR(info);
@@ -463,17 +461,15 @@ static int psbfb_create(struct psb_fbdev *fbdev,
 	dev_dbg(dev->dev, "allocated %dx%d fb\n",
 					psbfb->base.width, psbfb->base.height);
 
-	mutex_unlock(&dev->struct_mutex);
 	return 0;
 out_unref:
 	if (backing->stolen)
 		psb_gtt_free_range(dev, backing);
 	else
-		drm_gem_object_unreference(&backing->gem);
+		drm_gem_object_unreference_unlocked(&backing->gem);
 
 	drm_fb_helper_release_fbi(&fbdev->psb_fb_helper);
 out_err1:
-	mutex_unlock(&dev->struct_mutex);
 	psb_gtt_free_range(dev, backing);
 	return ret;
 }
@@ -569,7 +565,7 @@ static int psb_fbdev_destroy(struct drm_device *dev, struct psb_fbdev *fbdev)
 	drm_framebuffer_cleanup(&psbfb->base);
 
 	if (psbfb->gtt)
-		drm_gem_object_unreference(&psbfb->gtt->gem);
+		drm_gem_object_unreference_unlocked(&psbfb->gtt->gem);
 	return 0;
 }
 
@@ -784,12 +780,8 @@ void psb_modeset_cleanup(struct drm_device *dev)
 {
 	struct drm_psb_private *dev_priv = dev->dev_private;
 	if (dev_priv->modeset) {
-		mutex_lock(&dev->struct_mutex);
-
 		drm_kms_helper_poll_fini(dev);
 		psb_fbdev_fini(dev);
 		drm_mode_config_cleanup(dev);
-
-		mutex_unlock(&dev->struct_mutex);
 	}
 }
-- 
2.5.1

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [PATCH RESEND 10/20] drm/gma500: Drop dev->struct_mutex from mmap offset function
  2015-11-19 16:46 [PATCH RESEND 00/20] dev->struct_mutex locking crusade Daniel Vetter
                   ` (8 preceding siblings ...)
  2015-11-19 16:46 ` [PATCH RESEND 09/20] drm/gma500: Drop dev->struct_mutex from fbdev init/teardown code Daniel Vetter
@ 2015-11-19 16:46 ` Daniel Vetter
  2015-11-19 16:46 ` [PATCH RESEND 11/20] drm/gma500: Add driver private mutex for the fault handler Daniel Vetter
                   ` (10 subsequent siblings)
  20 siblings, 0 replies; 30+ messages in thread
From: Daniel Vetter @ 2015-11-19 16:46 UTC (permalink / raw)
  To: DRI Development; +Cc: Daniel Vetter, Intel Graphics Development, Daniel Vetter

Simply forgotten about this when I was doing my general cleansing of
simple gem mmap offset functions. There's nothing but core functions
called here, and they all have their own protection already.

Cc: Patrik Jakobsson <patrik.r.jakobsson@gmail.com>
Acked-by: Patrik Jakobsson <patrik.r.jakobsson@gmail.com>
Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
---
 drivers/gpu/drm/gma500/gem.c | 13 +++----------
 1 file changed, 3 insertions(+), 10 deletions(-)

diff --git a/drivers/gpu/drm/gma500/gem.c b/drivers/gpu/drm/gma500/gem.c
index e3bdc8b1c32c..f0357f525f56 100644
--- a/drivers/gpu/drm/gma500/gem.c
+++ b/drivers/gpu/drm/gma500/gem.c
@@ -62,15 +62,10 @@ int psb_gem_dumb_map_gtt(struct drm_file *file, struct drm_device *dev,
 	int ret = 0;
 	struct drm_gem_object *obj;
 
-	mutex_lock(&dev->struct_mutex);
-
 	/* GEM does all our handle to object mapping */
 	obj = drm_gem_object_lookup(dev, file, handle);
-	if (obj == NULL) {
-		ret = -ENOENT;
-		goto unlock;
-	}
-	/* What validation is needed here ? */
+	if (obj == NULL)
+		return -ENOENT;
 
 	/* Make it mmapable */
 	ret = drm_gem_create_mmap_offset(obj);
@@ -78,9 +73,7 @@ int psb_gem_dumb_map_gtt(struct drm_file *file, struct drm_device *dev,
 		goto out;
 	*offset = drm_vma_node_offset_addr(&obj->vma_node);
 out:
-	drm_gem_object_unreference(obj);
-unlock:
-	mutex_unlock(&dev->struct_mutex);
+	drm_gem_object_unreference_unlocked(obj);
 	return ret;
 }
 
-- 
2.5.1

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [PATCH RESEND 11/20] drm/gma500: Add driver private mutex for the fault handler
  2015-11-19 16:46 [PATCH RESEND 00/20] dev->struct_mutex locking crusade Daniel Vetter
                   ` (9 preceding siblings ...)
  2015-11-19 16:46 ` [PATCH RESEND 10/20] drm/gma500: Drop dev->struct_mutex from mmap offset function Daniel Vetter
@ 2015-11-19 16:46 ` Daniel Vetter
  2015-11-19 16:46 ` [PATCH RESEND 12/20] drm/nouveau: Drop dev->struct_mutex from fbdev init Daniel Vetter
                   ` (9 subsequent siblings)
  20 siblings, 0 replies; 30+ messages in thread
From: Daniel Vetter @ 2015-11-19 16:46 UTC (permalink / raw)
  To: DRI Development; +Cc: Daniel Vetter, Intel Graphics Development, Daniel Vetter

There's currently two places where the gma500 fault handler relies
upon dev->struct_mutex:
- To protect r->mappping
- To make sure vm_insert_pfn isn't called concurrently (in which case
  the 2nd thread would get an error code).

Everything else (specifically psb_gtt_pin) is already protected by
some other locks. Hence just create a new driver-private mmap_mutex
just for this function.

With this gma500 is complete dev->struct_mutex free!

Cc: Patrik Jakobsson <patrik.r.jakobsson@gmail.com>
Acked-by: Patrik Jakobsson <patrik.r.jakobsson@gmail.com>
Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
---
 drivers/gpu/drm/gma500/gem.c     | 4 ++--
 drivers/gpu/drm/gma500/gtt.c     | 1 +
 drivers/gpu/drm/gma500/psb_drv.h | 2 ++
 3 files changed, 5 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/gma500/gem.c b/drivers/gpu/drm/gma500/gem.c
index f0357f525f56..506224b3a0ad 100644
--- a/drivers/gpu/drm/gma500/gem.c
+++ b/drivers/gpu/drm/gma500/gem.c
@@ -182,7 +182,7 @@ int psb_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
 
 	/* Make sure we don't parallel update on a fault, nor move or remove
 	   something from beneath our feet */
-	mutex_lock(&dev->struct_mutex);
+	mutex_lock(&dev_priv->mmap_mutex);
 
 	/* For now the mmap pins the object and it stays pinned. As things
 	   stand that will do us no harm */
@@ -208,7 +208,7 @@ int psb_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
 	ret = vm_insert_pfn(vma, (unsigned long)vmf->virtual_address, pfn);
 
 fail:
-	mutex_unlock(&dev->struct_mutex);
+	mutex_unlock(&dev_priv->mmap_mutex);
 	switch (ret) {
 	case 0:
 	case -ERESTARTSYS:
diff --git a/drivers/gpu/drm/gma500/gtt.c b/drivers/gpu/drm/gma500/gtt.c
index ce015db59dc6..8f69225ce2b4 100644
--- a/drivers/gpu/drm/gma500/gtt.c
+++ b/drivers/gpu/drm/gma500/gtt.c
@@ -425,6 +425,7 @@ int psb_gtt_init(struct drm_device *dev, int resume)
 
 	if (!resume) {
 		mutex_init(&dev_priv->gtt_mutex);
+		mutex_init(&dev_priv->mmap_mutex);
 		psb_gtt_alloc(dev);
 	}
 
diff --git a/drivers/gpu/drm/gma500/psb_drv.h b/drivers/gpu/drm/gma500/psb_drv.h
index e21726ecac32..3bd2c726dd61 100644
--- a/drivers/gpu/drm/gma500/psb_drv.h
+++ b/drivers/gpu/drm/gma500/psb_drv.h
@@ -465,6 +465,8 @@ struct drm_psb_private {
 	struct mutex gtt_mutex;
 	struct resource *gtt_mem;	/* Our PCI resource */
 
+	struct mutex mmap_mutex;
+
 	struct psb_mmu_driver *mmu;
 	struct psb_mmu_pd *pf_pd;
 
-- 
2.5.1

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [PATCH RESEND 12/20] drm/nouveau: Drop dev->struct_mutex from fbdev init
  2015-11-19 16:46 [PATCH RESEND 00/20] dev->struct_mutex locking crusade Daniel Vetter
                   ` (10 preceding siblings ...)
  2015-11-19 16:46 ` [PATCH RESEND 11/20] drm/gma500: Add driver private mutex for the fault handler Daniel Vetter
@ 2015-11-19 16:46 ` Daniel Vetter
  2015-11-19 16:46 ` [PATCH RESEND 13/20] drm/exynos: Drop dev->struct_mutex from mmap offset function Daniel Vetter
                   ` (8 subsequent siblings)
  20 siblings, 0 replies; 30+ messages in thread
From: Daniel Vetter @ 2015-11-19 16:46 UTC (permalink / raw)
  To: DRI Development
  Cc: Daniel Vetter, Intel Graphics Development, Ben Skeggs, Daniel Vetter

Doesn't protect anything at all.

With this patch nouveau is completely dev->struct_mutex free!

Cc: Ben Skeggs <bskeggs@redhat.com>
Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
---
 drivers/gpu/drm/nouveau/nouveau_fbcon.c | 5 -----
 1 file changed, 5 deletions(-)

diff --git a/drivers/gpu/drm/nouveau/nouveau_fbcon.c b/drivers/gpu/drm/nouveau/nouveau_fbcon.c
index 59f27e774acb..3bae706126bd 100644
--- a/drivers/gpu/drm/nouveau/nouveau_fbcon.c
+++ b/drivers/gpu/drm/nouveau/nouveau_fbcon.c
@@ -386,8 +386,6 @@ nouveau_fbcon_create(struct drm_fb_helper *helper,
 		}
 	}
 
-	mutex_lock(&dev->struct_mutex);
-
 	info = drm_fb_helper_alloc_fbi(helper);
 	if (IS_ERR(info)) {
 		ret = PTR_ERR(info);
@@ -426,8 +424,6 @@ nouveau_fbcon_create(struct drm_fb_helper *helper,
 
 	/* Use default scratch pixmap (info->pixmap.flags = FB_PIXMAP_SYSTEM) */
 
-	mutex_unlock(&dev->struct_mutex);
-
 	if (chan)
 		nouveau_fbcon_accel_init(dev);
 	nouveau_fbcon_zfill(dev, fbcon);
@@ -441,7 +437,6 @@ nouveau_fbcon_create(struct drm_fb_helper *helper,
 	return 0;
 
 out_unlock:
-	mutex_unlock(&dev->struct_mutex);
 	if (chan)
 		nouveau_bo_vma_del(nvbo, &fbcon->nouveau_fb.vma);
 	nouveau_bo_unmap(nvbo);
-- 
2.5.1

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [PATCH RESEND 13/20] drm/exynos: Drop dev->struct_mutex from mmap offset function
  2015-11-19 16:46 [PATCH RESEND 00/20] dev->struct_mutex locking crusade Daniel Vetter
                   ` (11 preceding siblings ...)
  2015-11-19 16:46 ` [PATCH RESEND 12/20] drm/nouveau: Drop dev->struct_mutex from fbdev init Daniel Vetter
@ 2015-11-19 16:46 ` Daniel Vetter
  2015-11-19 16:46 ` [PATCH RESEND 14/20] drm/exynos: drop struct_mutex from exynos_gem_map_sgt_with_dma Daniel Vetter
                   ` (7 subsequent siblings)
  20 siblings, 0 replies; 30+ messages in thread
From: Daniel Vetter @ 2015-11-19 16:46 UTC (permalink / raw)
  To: DRI Development; +Cc: Daniel Vetter, Intel Graphics Development, Daniel Vetter

Simply forgotten about this when I was doing my general cleansing of
simple gem mmap offset functions. There's nothing but core functions
called here, and they all have their own protection already.

Aside: DRM_ERROR for userspace controlled input isn't great, but
that's for another patch.

Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
---
 drivers/gpu/drm/exynos/exynos_drm_gem.c | 7 +------
 1 file changed, 1 insertion(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/exynos/exynos_drm_gem.c b/drivers/gpu/drm/exynos/exynos_drm_gem.c
index 252eb301470c..91d87e7c2a2f 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_gem.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_gem.c
@@ -448,8 +448,6 @@ int exynos_drm_gem_dumb_map_offset(struct drm_file *file_priv,
 	struct drm_gem_object *obj;
 	int ret = 0;
 
-	mutex_lock(&dev->struct_mutex);
-
 	/*
 	 * get offset of memory allocated for drm framebuffer.
 	 * - this callback would be called by user application
@@ -459,16 +457,13 @@ int exynos_drm_gem_dumb_map_offset(struct drm_file *file_priv,
 	obj = drm_gem_object_lookup(dev, file_priv, handle);
 	if (!obj) {
 		DRM_ERROR("failed to lookup gem object.\n");
-		ret = -EINVAL;
-		goto unlock;
+		return -EINVAL;
 	}
 
 	*offset = drm_vma_node_offset_addr(&obj->vma_node);
 	DRM_DEBUG_KMS("offset = 0x%lx\n", (unsigned long)*offset);
 
 	drm_gem_object_unreference(obj);
-unlock:
-	mutex_unlock(&dev->struct_mutex);
 	return ret;
 }
 
-- 
2.5.1

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [PATCH RESEND 14/20] drm/exynos: drop struct_mutex from exynos_gem_map_sgt_with_dma
  2015-11-19 16:46 [PATCH RESEND 00/20] dev->struct_mutex locking crusade Daniel Vetter
                   ` (12 preceding siblings ...)
  2015-11-19 16:46 ` [PATCH RESEND 13/20] drm/exynos: Drop dev->struct_mutex from mmap offset function Daniel Vetter
@ 2015-11-19 16:46 ` Daniel Vetter
  2015-11-19 16:46 ` [PATCH RESEND 15/20] drm/exynos: drop struct_mutex from exynos_drm_gem_get_ioctl Daniel Vetter
                   ` (6 subsequent siblings)
  20 siblings, 0 replies; 30+ messages in thread
From: Daniel Vetter @ 2015-11-19 16:46 UTC (permalink / raw)
  To: DRI Development; +Cc: Daniel Vetter, Intel Graphics Development, Daniel Vetter

The sg table isn't refcounted, there's no corresponding locking for
unmapping and drm_map_sg is ok with being called concurrently.

So drop the locking since it doesn't protect anything.

Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
---
 drivers/gpu/drm/exynos/exynos_drm_gem.c | 4 ----
 1 file changed, 4 deletions(-)

diff --git a/drivers/gpu/drm/exynos/exynos_drm_gem.c b/drivers/gpu/drm/exynos/exynos_drm_gem.c
index 91d87e7c2a2f..a3286a1ec2b1 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_gem.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_gem.c
@@ -378,16 +378,12 @@ int exynos_gem_map_sgt_with_dma(struct drm_device *drm_dev,
 {
 	int nents;
 
-	mutex_lock(&drm_dev->struct_mutex);
-
 	nents = dma_map_sg(drm_dev->dev, sgt->sgl, sgt->nents, dir);
 	if (!nents) {
 		DRM_ERROR("failed to map sgl with dma.\n");
-		mutex_unlock(&drm_dev->struct_mutex);
 		return nents;
 	}
 
-	mutex_unlock(&drm_dev->struct_mutex);
 	return 0;
 }
 
-- 
2.5.1

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [PATCH RESEND 15/20] drm/exynos: drop struct_mutex from exynos_drm_gem_get_ioctl
  2015-11-19 16:46 [PATCH RESEND 00/20] dev->struct_mutex locking crusade Daniel Vetter
                   ` (13 preceding siblings ...)
  2015-11-19 16:46 ` [PATCH RESEND 14/20] drm/exynos: drop struct_mutex from exynos_gem_map_sgt_with_dma Daniel Vetter
@ 2015-11-19 16:46 ` Daniel Vetter
  2015-11-19 16:50   ` Daniel Stone
  2015-11-19 16:46 ` [PATCH RESEND 16/20] drm/exynos: drop struct_mutex from fbdev setup Daniel Vetter
                   ` (5 subsequent siblings)
  20 siblings, 1 reply; 30+ messages in thread
From: Daniel Vetter @ 2015-11-19 16:46 UTC (permalink / raw)
  To: DRI Development; +Cc: Daniel Vetter, Intel Graphics Development, Daniel Vetter

The only things this protects is reading ->flags and ->size, both of
which are invariant over the lifetime of an exynos gem bo. So no
locking needed at all (besides that, nothing protects the writers
anyway).

Aside: exynos_gem_obj->size is redundant with
exynos_gem_obj->base.size and probably should be removed.

Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
---
 drivers/gpu/drm/exynos/exynos_drm_gem.c | 4 ----
 1 file changed, 4 deletions(-)

diff --git a/drivers/gpu/drm/exynos/exynos_drm_gem.c b/drivers/gpu/drm/exynos/exynos_drm_gem.c
index a3286a1ec2b1..dfb3bfee1b63 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_gem.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_gem.c
@@ -352,12 +352,9 @@ int exynos_drm_gem_get_ioctl(struct drm_device *dev, void *data,
 	struct drm_exynos_gem_info *args = data;
 	struct drm_gem_object *obj;
 
-	mutex_lock(&dev->struct_mutex);
-
 	obj = drm_gem_object_lookup(dev, file_priv, args->handle);
 	if (!obj) {
 		DRM_ERROR("failed to lookup gem object.\n");
-		mutex_unlock(&dev->struct_mutex);
 		return -EINVAL;
 	}
 
@@ -367,7 +364,6 @@ int exynos_drm_gem_get_ioctl(struct drm_device *dev, void *data,
 	args->size = exynos_gem->size;
 
 	drm_gem_object_unreference(obj);
-	mutex_unlock(&dev->struct_mutex);
 
 	return 0;
 }
-- 
2.5.1

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [PATCH RESEND 16/20] drm/exynos: drop struct_mutex from fbdev setup
  2015-11-19 16:46 [PATCH RESEND 00/20] dev->struct_mutex locking crusade Daniel Vetter
                   ` (14 preceding siblings ...)
  2015-11-19 16:46 ` [PATCH RESEND 15/20] drm/exynos: drop struct_mutex from exynos_drm_gem_get_ioctl Daniel Vetter
@ 2015-11-19 16:46 ` Daniel Vetter
  2015-11-19 16:46 ` [PATCH RESEND 17/20] drm/vgem: Simplify dum_map Daniel Vetter
                   ` (4 subsequent siblings)
  20 siblings, 0 replies; 30+ messages in thread
From: Daniel Vetter @ 2015-11-19 16:46 UTC (permalink / raw)
  To: DRI Development; +Cc: Daniel Vetter, Intel Graphics Development, Daniel Vetter

Doesn't protect anything at all, and probably just here because a long
time ago dev->struct_mutex was required to allocate gem objects.

With this patch exynos is completely struct_mutex free!

Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
---
 drivers/gpu/drm/exynos/exynos_drm_fbdev.c | 22 ++++++++--------------
 1 file changed, 8 insertions(+), 14 deletions(-)

diff --git a/drivers/gpu/drm/exynos/exynos_drm_fbdev.c b/drivers/gpu/drm/exynos/exynos_drm_fbdev.c
index f6118baa8e3e..e1f7abaa61df 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_fbdev.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_fbdev.c
@@ -138,8 +138,6 @@ static int exynos_drm_fbdev_create(struct drm_fb_helper *helper,
 	mode_cmd.pixel_format = drm_mode_legacy_fb_format(sizes->surface_bpp,
 							  sizes->surface_depth);
 
-	mutex_lock(&dev->struct_mutex);
-
 	size = mode_cmd.pitches[0] * mode_cmd.height;
 
 	exynos_gem = exynos_drm_gem_create(dev, EXYNOS_BO_CONTIG, size);
@@ -154,10 +152,8 @@ static int exynos_drm_fbdev_create(struct drm_fb_helper *helper,
 						   size);
 	}
 
-	if (IS_ERR(exynos_gem)) {
-		ret = PTR_ERR(exynos_gem);
-		goto out;
-	}
+	if (IS_ERR(exynos_gem))
+		return PTR_ERR(exynos_gem);
 
 	exynos_fbdev->exynos_gem = exynos_gem;
 
@@ -173,7 +169,6 @@ static int exynos_drm_fbdev_create(struct drm_fb_helper *helper,
 	if (ret < 0)
 		goto err_destroy_framebuffer;
 
-	mutex_unlock(&dev->struct_mutex);
 	return ret;
 
 err_destroy_framebuffer:
@@ -181,13 +176,12 @@ err_destroy_framebuffer:
 err_destroy_gem:
 	exynos_drm_gem_destroy(exynos_gem);
 
-/*
- * if failed, all resources allocated above would be released by
- * drm_mode_config_cleanup() when drm_load() had been called prior
- * to any specific driver such as fimd or hdmi driver.
- */
-out:
-	mutex_unlock(&dev->struct_mutex);
+	/*
+	 * if failed, all resources allocated above would be released by
+	 * drm_mode_config_cleanup() when drm_load() had been called prior
+	 * to any specific driver such as fimd or hdmi driver.
+	 */
+
 	return ret;
 }
 
-- 
2.5.1

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [PATCH RESEND 17/20] drm/vgem: Simplify dum_map
  2015-11-19 16:46 [PATCH RESEND 00/20] dev->struct_mutex locking crusade Daniel Vetter
                   ` (15 preceding siblings ...)
  2015-11-19 16:46 ` [PATCH RESEND 16/20] drm/exynos: drop struct_mutex from fbdev setup Daniel Vetter
@ 2015-11-19 16:46 ` Daniel Vetter
  2015-11-19 16:46 ` [PATCH RESEND 18/20] drm/vgem: Move get_pages to gem_create Daniel Vetter
                   ` (3 subsequent siblings)
  20 siblings, 0 replies; 30+ messages in thread
From: Daniel Vetter @ 2015-11-19 16:46 UTC (permalink / raw)
  To: DRI Development; +Cc: Daniel Vetter, Intel Graphics Development, Daniel Vetter

The offset manager already checks for existing offsets internally,
while holding suitable locks. We can drop this check.

Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
---
 drivers/gpu/drm/vgem/vgem_drv.c | 8 +++-----
 1 file changed, 3 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/vgem/vgem_drv.c b/drivers/gpu/drm/vgem/vgem_drv.c
index 02ae60c395b7..63026d4324ad 100644
--- a/drivers/gpu/drm/vgem/vgem_drv.c
+++ b/drivers/gpu/drm/vgem/vgem_drv.c
@@ -208,11 +208,9 @@ int vgem_gem_dumb_map(struct drm_file *file, struct drm_device *dev,
 		goto unlock;
 	}
 
-	if (!drm_vma_node_has_offset(&obj->vma_node)) {
-		ret = drm_gem_create_mmap_offset(obj);
-		if (ret)
-			goto unref;
-	}
+	ret = drm_gem_create_mmap_offset(obj);
+	if (ret)
+		goto unref;
 
 	BUG_ON(!obj->filp);
 
-- 
2.5.1

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [PATCH RESEND 18/20] drm/vgem: Move get_pages to gem_create
  2015-11-19 16:46 [PATCH RESEND 00/20] dev->struct_mutex locking crusade Daniel Vetter
                   ` (16 preceding siblings ...)
  2015-11-19 16:46 ` [PATCH RESEND 17/20] drm/vgem: Simplify dum_map Daniel Vetter
@ 2015-11-19 16:46 ` Daniel Vetter
  2015-11-19 16:46 ` [PATCH RESEND 19/20] drm/vgem: Drop dev->struct_mutex Daniel Vetter
                   ` (2 subsequent siblings)
  20 siblings, 0 replies; 30+ messages in thread
From: Daniel Vetter @ 2015-11-19 16:46 UTC (permalink / raw)
  To: DRI Development; +Cc: Daniel Vetter, Intel Graphics Development, Daniel Vetter

vgem doesn't have a shrinker or anything like that and drops backing
storage only at object_free time. There's no use in trying to be
clever and allocating backing storage delayed, it only causes trouble
by requiring locking.

Instead grab pages when we allocate the object right away.

Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
---
 drivers/gpu/drm/vgem/vgem_drv.c | 12 ++++--------
 1 file changed, 4 insertions(+), 8 deletions(-)

diff --git a/drivers/gpu/drm/vgem/vgem_drv.c b/drivers/gpu/drm/vgem/vgem_drv.c
index 63026d4324ad..1a609347236b 100644
--- a/drivers/gpu/drm/vgem/vgem_drv.c
+++ b/drivers/gpu/drm/vgem/vgem_drv.c
@@ -154,6 +154,10 @@ static struct drm_gem_object *vgem_gem_create(struct drm_device *dev,
 	if (err)
 		goto out;
 
+	ret = vgem_gem_get_pages(to_vgem_bo(obj));
+	if (ret)
+		goto out;
+
 	err = drm_gem_handle_create(file, gem_object, handle);
 	if (err)
 		goto handle_out;
@@ -216,16 +220,8 @@ int vgem_gem_dumb_map(struct drm_file *file, struct drm_device *dev,
 
 	obj->filp->private_data = obj;
 
-	ret = vgem_gem_get_pages(to_vgem_bo(obj));
-	if (ret)
-		goto fail_get_pages;
-
 	*offset = drm_vma_node_offset_addr(&obj->vma_node);
 
-	goto unref;
-
-fail_get_pages:
-	drm_gem_free_mmap_offset(obj);
 unref:
 	drm_gem_object_unreference(obj);
 unlock:
-- 
2.5.1

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [PATCH RESEND 19/20] drm/vgem: Drop dev->struct_mutex
  2015-11-19 16:46 [PATCH RESEND 00/20] dev->struct_mutex locking crusade Daniel Vetter
                   ` (17 preceding siblings ...)
  2015-11-19 16:46 ` [PATCH RESEND 18/20] drm/vgem: Move get_pages to gem_create Daniel Vetter
@ 2015-11-19 16:46 ` Daniel Vetter
  2015-11-19 16:46 ` [PATCH RESEND 20/20] drm/vma_manage: Drop has_offset Daniel Vetter
  2015-11-19 16:46 ` [PATCH] drm/sysfs: Send out uevent when connector->force changes Daniel Vetter
  20 siblings, 0 replies; 30+ messages in thread
From: Daniel Vetter @ 2015-11-19 16:46 UTC (permalink / raw)
  To: DRI Development; +Cc: Daniel Vetter, Intel Graphics Development, Daniel Vetter

With the previous two changes it doesn't protect anything any more.

Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
---
 drivers/gpu/drm/vgem/vgem_drv.c | 14 +++-----------
 1 file changed, 3 insertions(+), 11 deletions(-)

diff --git a/drivers/gpu/drm/vgem/vgem_drv.c b/drivers/gpu/drm/vgem/vgem_drv.c
index 1a609347236b..b525208375aa 100644
--- a/drivers/gpu/drm/vgem/vgem_drv.c
+++ b/drivers/gpu/drm/vgem/vgem_drv.c
@@ -103,12 +103,8 @@ static int vgem_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
 	if (page_offset > num_pages)
 		return VM_FAULT_SIGBUS;
 
-	mutex_lock(&dev->struct_mutex);
-
 	ret = vm_insert_page(vma, (unsigned long)vmf->virtual_address,
 			     obj->pages[page_offset]);
-
-	mutex_unlock(&dev->struct_mutex);
 	switch (ret) {
 	case 0:
 		return VM_FAULT_NOPAGE;
@@ -205,12 +201,9 @@ int vgem_gem_dumb_map(struct drm_file *file, struct drm_device *dev,
 	int ret = 0;
 	struct drm_gem_object *obj;
 
-	mutex_lock(&dev->struct_mutex);
 	obj = drm_gem_object_lookup(dev, file, handle);
-	if (!obj) {
-		ret = -ENOENT;
-		goto unlock;
-	}
+	if (!obj)
+		return -ENOENT;
 
 	ret = drm_gem_create_mmap_offset(obj);
 	if (ret)
@@ -224,8 +217,7 @@ int vgem_gem_dumb_map(struct drm_file *file, struct drm_device *dev,
 
 unref:
 	drm_gem_object_unreference(obj);
-unlock:
-	mutex_unlock(&dev->struct_mutex);
+
 	return ret;
 }
 
-- 
2.5.1

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [PATCH RESEND 20/20] drm/vma_manage: Drop has_offset
  2015-11-19 16:46 [PATCH RESEND 00/20] dev->struct_mutex locking crusade Daniel Vetter
                   ` (18 preceding siblings ...)
  2015-11-19 16:46 ` [PATCH RESEND 19/20] drm/vgem: Drop dev->struct_mutex Daniel Vetter
@ 2015-11-19 16:46 ` Daniel Vetter
  2015-11-19 16:46 ` [PATCH] drm/sysfs: Send out uevent when connector->force changes Daniel Vetter
  20 siblings, 0 replies; 30+ messages in thread
From: Daniel Vetter @ 2015-11-19 16:46 UTC (permalink / raw)
  To: DRI Development; +Cc: Daniel Vetter, Daniel Vetter, Intel Graphics Development

It's racy, creating mmap offsets is a slowpath, so better to remove it
to avoid drivers doing broken things.

The only user is i915, and it's ok there because everything (well
almost) is protected by dev->struct_mutex in i915-gem.

While at it add a note in the create_mmap_offset kerneldoc that
drivers must release it again. And then I also noticed that
drm_gem_object_release entirely lacks kerneldoc.

Cc: David Herrmann <dh.herrmann@gmail.com>
Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
---
 drivers/gpu/drm/drm_gem.c       | 17 +++++++++++++++++
 drivers/gpu/drm/i915/i915_gem.c |  3 ---
 include/drm/drm_vma_manager.h   | 15 +--------------
 3 files changed, 18 insertions(+), 17 deletions(-)

diff --git a/drivers/gpu/drm/drm_gem.c b/drivers/gpu/drm/drm_gem.c
index 2e10bba4468b..5c5001171dd3 100644
--- a/drivers/gpu/drm/drm_gem.c
+++ b/drivers/gpu/drm/drm_gem.c
@@ -392,6 +392,10 @@ EXPORT_SYMBOL(drm_gem_handle_create);
  * @obj: obj in question
  *
  * This routine frees fake offsets allocated by drm_gem_create_mmap_offset().
+ *
+ * Note that drm_gem_object_release() already calls this function, so drivers
+ * don't have to take care of releasing the mmap offset themselves when freeing
+ * the GEM object.
  */
 void
 drm_gem_free_mmap_offset(struct drm_gem_object *obj)
@@ -415,6 +419,9 @@ EXPORT_SYMBOL(drm_gem_free_mmap_offset);
  * This routine allocates and attaches a fake offset for @obj, in cases where
  * the virtual size differs from the physical size (ie. obj->size).  Otherwise
  * just use drm_gem_create_mmap_offset().
+ *
+ * This function is idempotent and handles an already allocated mmap offset
+ * transparently. Drivers do not need to check for this case.
  */
 int
 drm_gem_create_mmap_offset_size(struct drm_gem_object *obj, size_t size)
@@ -436,6 +443,9 @@ EXPORT_SYMBOL(drm_gem_create_mmap_offset_size);
  * structures.
  *
  * This routine allocates and attaches a fake offset for @obj.
+ *
+ * Drivers can call drm_gem_free_mmap_offset() before freeing @obj to release
+ * the fake offset again.
  */
 int drm_gem_create_mmap_offset(struct drm_gem_object *obj)
 {
@@ -754,6 +764,13 @@ drm_gem_release(struct drm_device *dev, struct drm_file *file_private)
 	idr_destroy(&file_private->object_idr);
 }
 
+/**
+ * drm_gem_object_release - release GEM buffer object resources
+ * @obj: GEM buffer object
+ *
+ * This releases any structures and resources used by @obj and is the invers of
+ * drm_gem_object_init().
+ */
 void
 drm_gem_object_release(struct drm_gem_object *obj)
 {
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index 33adc8f8ab20..f10a5d57377e 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -1972,9 +1972,6 @@ static int i915_gem_object_create_mmap_offset(struct drm_i915_gem_object *obj)
 	struct drm_i915_private *dev_priv = obj->base.dev->dev_private;
 	int ret;
 
-	if (drm_vma_node_has_offset(&obj->base.vma_node))
-		return 0;
-
 	dev_priv->mm.shrinker_no_lock_stealing = true;
 
 	ret = drm_gem_create_mmap_offset(&obj->base);
diff --git a/include/drm/drm_vma_manager.h b/include/drm/drm_vma_manager.h
index 2f63dd5e05eb..06ea8e077ec2 100644
--- a/include/drm/drm_vma_manager.h
+++ b/include/drm/drm_vma_manager.h
@@ -176,19 +176,6 @@ static inline unsigned long drm_vma_node_size(struct drm_vma_offset_node *node)
 }
 
 /**
- * drm_vma_node_has_offset() - Check whether node is added to offset manager
- * @node: Node to be checked
- *
- * RETURNS:
- * true iff the node was previously allocated an offset and added to
- * an vma offset manager.
- */
-static inline bool drm_vma_node_has_offset(struct drm_vma_offset_node *node)
-{
-	return drm_mm_node_allocated(&node->vm_node);
-}
-
-/**
  * drm_vma_node_offset_addr() - Return sanitized offset for user-space mmaps
  * @node: Linked offset node
  *
@@ -220,7 +207,7 @@ static inline __u64 drm_vma_node_offset_addr(struct drm_vma_offset_node *node)
 static inline void drm_vma_node_unmap(struct drm_vma_offset_node *node,
 				      struct address_space *file_mapping)
 {
-	if (drm_vma_node_has_offset(node))
+	if (drm_mm_node_allocated(&node->vm_node))
 		unmap_mapping_range(file_mapping,
 				    drm_vma_node_offset_addr(node),
 				    drm_vma_node_size(node) << PAGE_SHIFT, 1);
-- 
2.5.1

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [PATCH] drm/sysfs: Send out uevent when connector->force changes
  2015-11-19 16:46 [PATCH RESEND 00/20] dev->struct_mutex locking crusade Daniel Vetter
                   ` (19 preceding siblings ...)
  2015-11-19 16:46 ` [PATCH RESEND 20/20] drm/vma_manage: Drop has_offset Daniel Vetter
@ 2015-11-19 16:46 ` Daniel Vetter
  2015-11-19 21:06   ` Chris Wilson
  20 siblings, 1 reply; 30+ messages in thread
From: Daniel Vetter @ 2015-11-19 16:46 UTC (permalink / raw)
  To: DRI Development; +Cc: Daniel Vetter, Daniel Vetter, Intel Graphics Development

To avoid even more code duplication punt this all to the probe worker,
which needs some slight adjustment to also generate a uevent when the
status has changed to due connector->force.

v2: Instead of running the output_poll_work (which is kinda the wrong
thing and a layering violation since it's an internal of the probe
helpers), or calling ->detect (which is again a layering violation
since it's used only by probe helpers) just call the official
->fill_modes function, like a GET_CONNECTOR ioctl call.

v3: Restore the accidentally removed forced-probe for echo "detect" >
force.

Cc: Chris Wilson <chris@chris-wilson.co.uk>
Reported-by: Chris Wilson <chris@chris-wilson.co.uk>
Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
---
 drivers/gpu/drm/drm_probe_helper.c | 46 +++++++++++++++++++-------------------
 drivers/gpu/drm/drm_sysfs.c        | 38 +++++++++++--------------------
 2 files changed, 36 insertions(+), 48 deletions(-)

diff --git a/drivers/gpu/drm/drm_probe_helper.c b/drivers/gpu/drm/drm_probe_helper.c
index a214a4a93b03..b7bdf12c54a5 100644
--- a/drivers/gpu/drm/drm_probe_helper.c
+++ b/drivers/gpu/drm/drm_probe_helper.c
@@ -147,6 +147,8 @@ static int drm_helper_probe_single_connector_modes_merge_bits(struct drm_connect
 	list_for_each_entry(mode, &connector->modes, head)
 		mode->status = MODE_UNVERIFIED;
 
+	old_status = connector->status;
+
 	if (connector->force) {
 		if (connector->force == DRM_FORCE_ON ||
 		    connector->force == DRM_FORCE_ON_DIGITAL)
@@ -156,33 +158,31 @@ static int drm_helper_probe_single_connector_modes_merge_bits(struct drm_connect
 		if (connector->funcs->force)
 			connector->funcs->force(connector);
 	} else {
-		old_status = connector->status;
-
 		connector->status = connector->funcs->detect(connector, true);
+	}
+
+	/*
+	 * Normally either the driver's hpd code or the poll loop should
+	 * pick up any changes and fire the hotplug event. But if
+	 * userspace sneaks in a probe, we might miss a change. Hence
+	 * check here, and if anything changed start the hotplug code.
+	 */
+	if (old_status != connector->status) {
+		DRM_DEBUG_KMS("[CONNECTOR:%d:%s] status updated from %d to %d\n",
+			      connector->base.id,
+			      connector->name,
+			      old_status, connector->status);
 
 		/*
-		 * Normally either the driver's hpd code or the poll loop should
-		 * pick up any changes and fire the hotplug event. But if
-		 * userspace sneaks in a probe, we might miss a change. Hence
-		 * check here, and if anything changed start the hotplug code.
+		 * The hotplug event code might call into the fb
+		 * helpers, and so expects that we do not hold any
+		 * locks. Fire up the poll struct instead, it will
+		 * disable itself again.
 		 */
-		if (old_status != connector->status) {
-			DRM_DEBUG_KMS("[CONNECTOR:%d:%s] status updated from %d to %d\n",
-				      connector->base.id,
-				      connector->name,
-				      old_status, connector->status);
-
-			/*
-			 * The hotplug event code might call into the fb
-			 * helpers, and so expects that we do not hold any
-			 * locks. Fire up the poll struct instead, it will
-			 * disable itself again.
-			 */
-			dev->mode_config.delayed_event = true;
-			if (dev->mode_config.poll_enabled)
-				schedule_delayed_work(&dev->mode_config.output_poll_work,
-						      0);
-		}
+		dev->mode_config.delayed_event = true;
+		if (dev->mode_config.poll_enabled)
+			schedule_delayed_work(&dev->mode_config.output_poll_work,
+					      0);
 	}
 
 	/* Re-enable polling in case the global poll config changed. */
diff --git a/drivers/gpu/drm/drm_sysfs.c b/drivers/gpu/drm/drm_sysfs.c
index 9ac4ffa6cce3..df66d9447cb0 100644
--- a/drivers/gpu/drm/drm_sysfs.c
+++ b/drivers/gpu/drm/drm_sysfs.c
@@ -167,47 +167,35 @@ static ssize_t status_store(struct device *device,
 {
 	struct drm_connector *connector = to_drm_connector(device);
 	struct drm_device *dev = connector->dev;
-	enum drm_connector_status old_status;
+	enum drm_connector_force old_force;
 	int ret;
 
 	ret = mutex_lock_interruptible(&dev->mode_config.mutex);
 	if (ret)
 		return ret;
 
-	old_status = connector->status;
+	old_force = connector->force;
 
-	if (sysfs_streq(buf, "detect")) {
+	if (sysfs_streq(buf, "detect"))
 		connector->force = 0;
-		connector->status = connector->funcs->detect(connector, true);
-	} else if (sysfs_streq(buf, "on")) {
+	else if (sysfs_streq(buf, "on"))
 		connector->force = DRM_FORCE_ON;
-	} else if (sysfs_streq(buf, "on-digital")) {
+	else if (sysfs_streq(buf, "on-digital"))
 		connector->force = DRM_FORCE_ON_DIGITAL;
-	} else if (sysfs_streq(buf, "off")) {
+	else if (sysfs_streq(buf, "off"))
 		connector->force = DRM_FORCE_OFF;
-	} else
+	else
 		ret = -EINVAL;
 
-	if (ret == 0 && connector->force) {
-		if (connector->force == DRM_FORCE_ON ||
-		    connector->force == DRM_FORCE_ON_DIGITAL)
-			connector->status = connector_status_connected;
-		else
-			connector->status = connector_status_disconnected;
-		if (connector->funcs->force)
-			connector->funcs->force(connector);
-	}
-
-	if (old_status != connector->status) {
-		DRM_DEBUG_KMS("[CONNECTOR:%d:%s] status updated from %d to %d\n",
+	if (old_force != connector->force || !connector->force) {
+		DRM_DEBUG_KMS("[CONNECTOR:%d:%s] force updated from %d to %d or reprobing\n",
 			      connector->base.id,
 			      connector->name,
-			      old_status, connector->status);
+			      old_force, connector->force);
 
-		dev->mode_config.delayed_event = true;
-		if (dev->mode_config.poll_enabled)
-			schedule_delayed_work(&dev->mode_config.output_poll_work,
-					      0);
+		connector->funcs->fill_modes(connector,
+					     dev->mode_config.max_width,
+					     dev->mode_config.max_height);
 	}
 
 	mutex_unlock(&dev->mode_config.mutex);
-- 
2.5.1

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 30+ messages in thread

* Re: [PATCH RESEND 15/20] drm/exynos: drop struct_mutex from exynos_drm_gem_get_ioctl
  2015-11-19 16:46 ` [PATCH RESEND 15/20] drm/exynos: drop struct_mutex from exynos_drm_gem_get_ioctl Daniel Vetter
@ 2015-11-19 16:50   ` Daniel Stone
  2015-11-19 16:59     ` Daniel Vetter
  0 siblings, 1 reply; 30+ messages in thread
From: Daniel Stone @ 2015-11-19 16:50 UTC (permalink / raw)
  To: Daniel Vetter; +Cc: Daniel Vetter, Intel Graphics Development, DRI Development

Hi,

On 19 November 2015 at 16:46, Daniel Vetter <daniel.vetter@ffwll.ch> wrote:
> @@ -367,7 +364,6 @@ int exynos_drm_gem_get_ioctl(struct drm_device *dev, void *data,
>         args->size = exynos_gem->size;
>
>         drm_gem_object_unreference(obj);
> -       mutex_unlock(&dev->struct_mutex);

drm_gem_object_unreference_unlocked, surely ...

Cheers,
Daniel
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [PATCH RESEND 15/20] drm/exynos: drop struct_mutex from exynos_drm_gem_get_ioctl
  2015-11-19 16:50   ` Daniel Stone
@ 2015-11-19 16:59     ` Daniel Vetter
  0 siblings, 0 replies; 30+ messages in thread
From: Daniel Vetter @ 2015-11-19 16:59 UTC (permalink / raw)
  To: Daniel Stone
  Cc: Daniel Vetter, Intel Graphics Development, DRI Development,
	Daniel Vetter

On Thu, Nov 19, 2015 at 04:50:11PM +0000, Daniel Stone wrote:
> Hi,
> 
> On 19 November 2015 at 16:46, Daniel Vetter <daniel.vetter@ffwll.ch> wrote:
> > @@ -367,7 +364,6 @@ int exynos_drm_gem_get_ioctl(struct drm_device *dev, void *data,
> >         args->size = exynos_gem->size;
> >
> >         drm_gem_object_unreference(obj);
> > -       mutex_unlock(&dev->struct_mutex);
> 
> drm_gem_object_unreference_unlocked, surely ...

Yeah, and then I go and do a grep for this and spot piles more offenders.
-Daniel
-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [PATCH] drm/sysfs: Send out uevent when connector->force changes
  2015-11-19 16:46 ` [PATCH] drm/sysfs: Send out uevent when connector->force changes Daniel Vetter
@ 2015-11-19 21:06   ` Chris Wilson
  2015-11-20  8:11     ` Daniel Vetter
  0 siblings, 1 reply; 30+ messages in thread
From: Chris Wilson @ 2015-11-19 21:06 UTC (permalink / raw)
  To: Daniel Vetter; +Cc: Daniel Vetter, Intel Graphics Development, DRI Development

On Thu, Nov 19, 2015 at 05:46:50PM +0100, Daniel Vetter wrote:
> To avoid even more code duplication punt this all to the probe worker,
> which needs some slight adjustment to also generate a uevent when the
> status has changed to due connector->force.
> 
> v2: Instead of running the output_poll_work (which is kinda the wrong
> thing and a layering violation since it's an internal of the probe
> helpers), or calling ->detect (which is again a layering violation
> since it's used only by probe helpers) just call the official
> ->fill_modes function, like a GET_CONNECTOR ioctl call.
> 
> v3: Restore the accidentally removed forced-probe for echo "detect" >
> force.
> 

> diff --git a/drivers/gpu/drm/drm_sysfs.c b/drivers/gpu/drm/drm_sysfs.c
> index 9ac4ffa6cce3..df66d9447cb0 100644
> --- a/drivers/gpu/drm/drm_sysfs.c
> +++ b/drivers/gpu/drm/drm_sysfs.c
> @@ -167,47 +167,35 @@ static ssize_t status_store(struct device *device,
>  {
>  	struct drm_connector *connector = to_drm_connector(device);
>  	struct drm_device *dev = connector->dev;
> -	enum drm_connector_status old_status;
> +	enum drm_connector_force old_force;
>  	int ret;
>  
>  	ret = mutex_lock_interruptible(&dev->mode_config.mutex);
>  	if (ret)
>  		return ret;
>  
> -	old_status = connector->status;
> +	old_force = connector->force;
>  
> -	if (sysfs_streq(buf, "detect")) {
> +	if (sysfs_streq(buf, "detect"))
>  		connector->force = 0;
> -		connector->status = connector->funcs->detect(connector, true);
> -	} else if (sysfs_streq(buf, "on")) {
> +	else if (sysfs_streq(buf, "on"))
>  		connector->force = DRM_FORCE_ON;
> -	} else if (sysfs_streq(buf, "on-digital")) {
> +	else if (sysfs_streq(buf, "on-digital"))
>  		connector->force = DRM_FORCE_ON_DIGITAL;
> -	} else if (sysfs_streq(buf, "off")) {
> +	else if (sysfs_streq(buf, "off"))
>  		connector->force = DRM_FORCE_OFF;
> -	} else
> +	else
>  		ret = -EINVAL;
>  
> -	if (ret == 0 && connector->force) {
> -		if (connector->force == DRM_FORCE_ON ||
> -		    connector->force == DRM_FORCE_ON_DIGITAL)
> -			connector->status = connector_status_connected;
> -		else
> -			connector->status = connector_status_disconnected;
> -		if (connector->funcs->force)
> -			connector->funcs->force(connector);
> -	}
> -
> -	if (old_status != connector->status) {
> -		DRM_DEBUG_KMS("[CONNECTOR:%d:%s] status updated from %d to %d\n",
> +	if (old_force != connector->force || !connector->force) {
> +		DRM_DEBUG_KMS("[CONNECTOR:%d:%s] force updated from %d to %d or reprobing\n",
>  			      connector->base.id,
>  			      connector->name,
> -			      old_status, connector->status);
> +			      old_force, connector->force);
>  
> -		dev->mode_config.delayed_event = true;
> -		if (dev->mode_config.poll_enabled)
> -			schedule_delayed_work(&dev->mode_config.output_poll_work,
> -					      0);
> +		connector->funcs->fill_modes(connector,
> +					     dev->mode_config.max_width,
> +					     dev->mode_config.max_height);

This now does fill_modes() before we call detect(). We rely on the
ordering of detect() before doing fill_modes() as in many cases we use
the EDID gathered in detect() to generate the modes (if I am not
mistaken, I think we merged those patches to cache the EDID for a
detection cycle).
-Chris

-- 
Chris Wilson, Intel Open Source Technology Centre
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [PATCH] drm/sysfs: Send out uevent when connector->force changes
  2015-11-19 21:06   ` Chris Wilson
@ 2015-11-20  8:11     ` Daniel Vetter
  2015-11-20  9:25       ` Chris Wilson
  0 siblings, 1 reply; 30+ messages in thread
From: Daniel Vetter @ 2015-11-20  8:11 UTC (permalink / raw)
  To: Chris Wilson, Daniel Vetter, DRI Development,
	Intel Graphics Development, Daniel Vetter

On Thu, Nov 19, 2015 at 09:06:04PM +0000, Chris Wilson wrote:
> On Thu, Nov 19, 2015 at 05:46:50PM +0100, Daniel Vetter wrote:
> > To avoid even more code duplication punt this all to the probe worker,
> > which needs some slight adjustment to also generate a uevent when the
> > status has changed to due connector->force.
> > 
> > v2: Instead of running the output_poll_work (which is kinda the wrong
> > thing and a layering violation since it's an internal of the probe
> > helpers), or calling ->detect (which is again a layering violation
> > since it's used only by probe helpers) just call the official
> > ->fill_modes function, like a GET_CONNECTOR ioctl call.
> > 
> > v3: Restore the accidentally removed forced-probe for echo "detect" >
> > force.
> > 
> 
> > diff --git a/drivers/gpu/drm/drm_sysfs.c b/drivers/gpu/drm/drm_sysfs.c
> > index 9ac4ffa6cce3..df66d9447cb0 100644
> > --- a/drivers/gpu/drm/drm_sysfs.c
> > +++ b/drivers/gpu/drm/drm_sysfs.c
> > @@ -167,47 +167,35 @@ static ssize_t status_store(struct device *device,
> >  {
> >  	struct drm_connector *connector = to_drm_connector(device);
> >  	struct drm_device *dev = connector->dev;
> > -	enum drm_connector_status old_status;
> > +	enum drm_connector_force old_force;
> >  	int ret;
> >  
> >  	ret = mutex_lock_interruptible(&dev->mode_config.mutex);
> >  	if (ret)
> >  		return ret;
> >  
> > -	old_status = connector->status;
> > +	old_force = connector->force;
> >  
> > -	if (sysfs_streq(buf, "detect")) {
> > +	if (sysfs_streq(buf, "detect"))
> >  		connector->force = 0;
> > -		connector->status = connector->funcs->detect(connector, true);
> > -	} else if (sysfs_streq(buf, "on")) {
> > +	else if (sysfs_streq(buf, "on"))
> >  		connector->force = DRM_FORCE_ON;
> > -	} else if (sysfs_streq(buf, "on-digital")) {
> > +	else if (sysfs_streq(buf, "on-digital"))
> >  		connector->force = DRM_FORCE_ON_DIGITAL;
> > -	} else if (sysfs_streq(buf, "off")) {
> > +	else if (sysfs_streq(buf, "off"))
> >  		connector->force = DRM_FORCE_OFF;
> > -	} else
> > +	else
> >  		ret = -EINVAL;
> >  
> > -	if (ret == 0 && connector->force) {
> > -		if (connector->force == DRM_FORCE_ON ||
> > -		    connector->force == DRM_FORCE_ON_DIGITAL)
> > -			connector->status = connector_status_connected;
> > -		else
> > -			connector->status = connector_status_disconnected;
> > -		if (connector->funcs->force)
> > -			connector->funcs->force(connector);
> > -	}
> > -
> > -	if (old_status != connector->status) {
> > -		DRM_DEBUG_KMS("[CONNECTOR:%d:%s] status updated from %d to %d\n",
> > +	if (old_force != connector->force || !connector->force) {
> > +		DRM_DEBUG_KMS("[CONNECTOR:%d:%s] force updated from %d to %d or reprobing\n",
> >  			      connector->base.id,
> >  			      connector->name,
> > -			      old_status, connector->status);
> > +			      old_force, connector->force);
> >  
> > -		dev->mode_config.delayed_event = true;
> > -		if (dev->mode_config.poll_enabled)
> > -			schedule_delayed_work(&dev->mode_config.output_poll_work,
> > -					      0);
> > +		connector->funcs->fill_modes(connector,
> > +					     dev->mode_config.max_width,
> > +					     dev->mode_config.max_height);
> 
> This now does fill_modes() before we call detect(). We rely on the
> ordering of detect() before doing fill_modes() as in many cases we use
> the EDID gathered in detect() to generate the modes (if I am not
> mistaken, I think we merged those patches to cache the EDID for a
> detection cycle).

->fill_modes = drm_helper_probe_single_connector_modes which then calls
->detect. By going this way we avoid duplicating the "send uevent if
anything changed" logic all over the place, and ->detect becomes purely a
helper internal callback to get at the mode list for hotpluggeable
outputs.

Yes this means that ->detect should become a helper function, but that's
quite an invasive change.
-Daniel
-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [PATCH] drm/sysfs: Send out uevent when connector->force changes
  2015-11-20  8:11     ` Daniel Vetter
@ 2015-11-20  9:25       ` Chris Wilson
  2015-11-24 10:51         ` Daniel Vetter
  0 siblings, 1 reply; 30+ messages in thread
From: Chris Wilson @ 2015-11-20  9:25 UTC (permalink / raw)
  To: Daniel Vetter
  Cc: Daniel Vetter, Intel Graphics Development, DRI Development,
	Daniel Vetter

On Fri, Nov 20, 2015 at 09:11:00AM +0100, Daniel Vetter wrote:
> On Thu, Nov 19, 2015 at 09:06:04PM +0000, Chris Wilson wrote:
> > On Thu, Nov 19, 2015 at 05:46:50PM +0100, Daniel Vetter wrote:
> > > To avoid even more code duplication punt this all to the probe worker,
> > > which needs some slight adjustment to also generate a uevent when the
> > > status has changed to due connector->force.
> > > 
> > > v2: Instead of running the output_poll_work (which is kinda the wrong
> > > thing and a layering violation since it's an internal of the probe
> > > helpers), or calling ->detect (which is again a layering violation
> > > since it's used only by probe helpers) just call the official
> > > ->fill_modes function, like a GET_CONNECTOR ioctl call.
> > > 
> > > v3: Restore the accidentally removed forced-probe for echo "detect" >
> > > force.
> > > 
> > 
> > > diff --git a/drivers/gpu/drm/drm_sysfs.c b/drivers/gpu/drm/drm_sysfs.c
> > > index 9ac4ffa6cce3..df66d9447cb0 100644
> > > --- a/drivers/gpu/drm/drm_sysfs.c
> > > +++ b/drivers/gpu/drm/drm_sysfs.c
> > > @@ -167,47 +167,35 @@ static ssize_t status_store(struct device *device,
> > >  {
> > >  	struct drm_connector *connector = to_drm_connector(device);
> > >  	struct drm_device *dev = connector->dev;
> > > -	enum drm_connector_status old_status;
> > > +	enum drm_connector_force old_force;
> > >  	int ret;
> > >  
> > >  	ret = mutex_lock_interruptible(&dev->mode_config.mutex);
> > >  	if (ret)
> > >  		return ret;
> > >  
> > > -	old_status = connector->status;
> > > +	old_force = connector->force;
> > >  
> > > -	if (sysfs_streq(buf, "detect")) {
> > > +	if (sysfs_streq(buf, "detect"))
> > >  		connector->force = 0;
> > > -		connector->status = connector->funcs->detect(connector, true);
> > > -	} else if (sysfs_streq(buf, "on")) {
> > > +	else if (sysfs_streq(buf, "on"))
> > >  		connector->force = DRM_FORCE_ON;
> > > -	} else if (sysfs_streq(buf, "on-digital")) {
> > > +	else if (sysfs_streq(buf, "on-digital"))
> > >  		connector->force = DRM_FORCE_ON_DIGITAL;
> > > -	} else if (sysfs_streq(buf, "off")) {
> > > +	else if (sysfs_streq(buf, "off"))
> > >  		connector->force = DRM_FORCE_OFF;
> > > -	} else
> > > +	else
> > >  		ret = -EINVAL;
> > >  
> > > -	if (ret == 0 && connector->force) {
> > > -		if (connector->force == DRM_FORCE_ON ||
> > > -		    connector->force == DRM_FORCE_ON_DIGITAL)
> > > -			connector->status = connector_status_connected;
> > > -		else
> > > -			connector->status = connector_status_disconnected;
> > > -		if (connector->funcs->force)
> > > -			connector->funcs->force(connector);
> > > -	}
> > > -
> > > -	if (old_status != connector->status) {
> > > -		DRM_DEBUG_KMS("[CONNECTOR:%d:%s] status updated from %d to %d\n",
> > > +	if (old_force != connector->force || !connector->force) {
> > > +		DRM_DEBUG_KMS("[CONNECTOR:%d:%s] force updated from %d to %d or reprobing\n",
> > >  			      connector->base.id,
> > >  			      connector->name,
> > > -			      old_status, connector->status);
> > > +			      old_force, connector->force);
> > >  
> > > -		dev->mode_config.delayed_event = true;
> > > -		if (dev->mode_config.poll_enabled)
> > > -			schedule_delayed_work(&dev->mode_config.output_poll_work,
> > > -					      0);
> > > +		connector->funcs->fill_modes(connector,
> > > +					     dev->mode_config.max_width,
> > > +					     dev->mode_config.max_height);
> > 
> > This now does fill_modes() before we call detect(). We rely on the
> > ordering of detect() before doing fill_modes() as in many cases we use
> > the EDID gathered in detect() to generate the modes (if I am not
> > mistaken, I think we merged those patches to cache the EDID for a
> > detection cycle).
> 
> ->fill_modes = drm_helper_probe_single_connector_modes which then calls
> ->detect. By going this way we avoid duplicating the "send uevent if
> anything changed" logic all over the place, and ->detect becomes purely a
> helper internal callback to get at the mode list for hotpluggeable
> outputs.

Ok, that struck me as a little surprising - I was thinking of lower level
get_modes apparently.

With that resolved,
Reviewed-by: Chris Wilson <chris@chris-wilson.co.uk>

> Yes this means that ->detect should become a helper function, but that's
> quite an invasive change.

And something like .fill_modes -> .probe (after removing .detect).
-Chris

-- 
Chris Wilson, Intel Open Source Technology Centre
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [PATCH] drm/sysfs: Send out uevent when connector->force changes
  2015-11-20  9:25       ` Chris Wilson
@ 2015-11-24 10:51         ` Daniel Vetter
  2015-11-24 11:46           ` Chris Wilson
  0 siblings, 1 reply; 30+ messages in thread
From: Daniel Vetter @ 2015-11-24 10:51 UTC (permalink / raw)
  To: Chris Wilson, Daniel Vetter, Daniel Vetter, DRI Development,
	Intel Graphics Development, Daniel Vetter

On Fri, Nov 20, 2015 at 09:25:14AM +0000, Chris Wilson wrote:
> On Fri, Nov 20, 2015 at 09:11:00AM +0100, Daniel Vetter wrote:
> > On Thu, Nov 19, 2015 at 09:06:04PM +0000, Chris Wilson wrote:
> > > On Thu, Nov 19, 2015 at 05:46:50PM +0100, Daniel Vetter wrote:
> > > > To avoid even more code duplication punt this all to the probe worker,
> > > > which needs some slight adjustment to also generate a uevent when the
> > > > status has changed to due connector->force.
> > > > 
> > > > v2: Instead of running the output_poll_work (which is kinda the wrong
> > > > thing and a layering violation since it's an internal of the probe
> > > > helpers), or calling ->detect (which is again a layering violation
> > > > since it's used only by probe helpers) just call the official
> > > > ->fill_modes function, like a GET_CONNECTOR ioctl call.
> > > > 
> > > > v3: Restore the accidentally removed forced-probe for echo "detect" >
> > > > force.
> > > > 
> > > 
> > > > diff --git a/drivers/gpu/drm/drm_sysfs.c b/drivers/gpu/drm/drm_sysfs.c
> > > > index 9ac4ffa6cce3..df66d9447cb0 100644
> > > > --- a/drivers/gpu/drm/drm_sysfs.c
> > > > +++ b/drivers/gpu/drm/drm_sysfs.c
> > > > @@ -167,47 +167,35 @@ static ssize_t status_store(struct device *device,
> > > >  {
> > > >  	struct drm_connector *connector = to_drm_connector(device);
> > > >  	struct drm_device *dev = connector->dev;
> > > > -	enum drm_connector_status old_status;
> > > > +	enum drm_connector_force old_force;
> > > >  	int ret;
> > > >  
> > > >  	ret = mutex_lock_interruptible(&dev->mode_config.mutex);
> > > >  	if (ret)
> > > >  		return ret;
> > > >  
> > > > -	old_status = connector->status;
> > > > +	old_force = connector->force;
> > > >  
> > > > -	if (sysfs_streq(buf, "detect")) {
> > > > +	if (sysfs_streq(buf, "detect"))
> > > >  		connector->force = 0;
> > > > -		connector->status = connector->funcs->detect(connector, true);
> > > > -	} else if (sysfs_streq(buf, "on")) {
> > > > +	else if (sysfs_streq(buf, "on"))
> > > >  		connector->force = DRM_FORCE_ON;
> > > > -	} else if (sysfs_streq(buf, "on-digital")) {
> > > > +	else if (sysfs_streq(buf, "on-digital"))
> > > >  		connector->force = DRM_FORCE_ON_DIGITAL;
> > > > -	} else if (sysfs_streq(buf, "off")) {
> > > > +	else if (sysfs_streq(buf, "off"))
> > > >  		connector->force = DRM_FORCE_OFF;
> > > > -	} else
> > > > +	else
> > > >  		ret = -EINVAL;
> > > >  
> > > > -	if (ret == 0 && connector->force) {
> > > > -		if (connector->force == DRM_FORCE_ON ||
> > > > -		    connector->force == DRM_FORCE_ON_DIGITAL)
> > > > -			connector->status = connector_status_connected;
> > > > -		else
> > > > -			connector->status = connector_status_disconnected;
> > > > -		if (connector->funcs->force)
> > > > -			connector->funcs->force(connector);
> > > > -	}
> > > > -
> > > > -	if (old_status != connector->status) {
> > > > -		DRM_DEBUG_KMS("[CONNECTOR:%d:%s] status updated from %d to %d\n",
> > > > +	if (old_force != connector->force || !connector->force) {
> > > > +		DRM_DEBUG_KMS("[CONNECTOR:%d:%s] force updated from %d to %d or reprobing\n",
> > > >  			      connector->base.id,
> > > >  			      connector->name,
> > > > -			      old_status, connector->status);
> > > > +			      old_force, connector->force);
> > > >  
> > > > -		dev->mode_config.delayed_event = true;
> > > > -		if (dev->mode_config.poll_enabled)
> > > > -			schedule_delayed_work(&dev->mode_config.output_poll_work,
> > > > -					      0);
> > > > +		connector->funcs->fill_modes(connector,
> > > > +					     dev->mode_config.max_width,
> > > > +					     dev->mode_config.max_height);
> > > 
> > > This now does fill_modes() before we call detect(). We rely on the
> > > ordering of detect() before doing fill_modes() as in many cases we use
> > > the EDID gathered in detect() to generate the modes (if I am not
> > > mistaken, I think we merged those patches to cache the EDID for a
> > > detection cycle).
> > 
> > ->fill_modes = drm_helper_probe_single_connector_modes which then calls
> > ->detect. By going this way we avoid duplicating the "send uevent if
> > anything changed" logic all over the place, and ->detect becomes purely a
> > helper internal callback to get at the mode list for hotpluggeable
> > outputs.
> 
> Ok, that struck me as a little surprising - I was thinking of lower level
> get_modes apparently.
> 
> With that resolved,
> Reviewed-by: Chris Wilson <chris@chris-wilson.co.uk>

Applied to drm-misc, thanks for the review.

> > Yes this means that ->detect should become a helper function, but that's
> > quite an invasive change.
> 
> And something like .fill_modes -> .probe (after removing .detect).

Hm, not sure. For panels we never really probe anything, the important bit
is (at least for the caller in drm_crtc.c) that it fills in the
connectore->modes list. Given that I think the current name is okish.
-Daniel
-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [PATCH] drm/sysfs: Send out uevent when connector->force changes
  2015-11-24 10:51         ` Daniel Vetter
@ 2015-11-24 11:46           ` Chris Wilson
  0 siblings, 0 replies; 30+ messages in thread
From: Chris Wilson @ 2015-11-24 11:46 UTC (permalink / raw)
  To: Daniel Vetter
  Cc: Daniel Vetter, Intel Graphics Development, DRI Development,
	Daniel Vetter

On Tue, Nov 24, 2015 at 11:51:09AM +0100, Daniel Vetter wrote:
> On Fri, Nov 20, 2015 at 09:25:14AM +0000, Chris Wilson wrote:
> > And something like .fill_modes -> .probe (after removing .detect).
> 
> Hm, not sure. For panels we never really probe anything, the important bit
> is (at least for the caller in drm_crtc.c) that it fills in the
> connectore->modes list. Given that I think the current name is okish.

imo .fill_modes() does not imply that it communicates with the output,
unlike say .detect(), .probe(), or .get_modes().
-Chris

-- 
Chris Wilson, Intel Open Source Technology Centre
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 30+ messages in thread

* [PATCH] drm/sysfs: Send out uevent when connector->force changes
@ 2015-11-19 14:44 Daniel Vetter
  0 siblings, 0 replies; 30+ messages in thread
From: Daniel Vetter @ 2015-11-19 14:44 UTC (permalink / raw)
  To: Intel Graphics Development; +Cc: Daniel Vetter, Daniel Vetter, DRI Development

To avoid even more code duplication punt this all to the probe worker,
which needs some slight adjustment to also generate a uevent when the
status has changed to due connector->force.

v2: Instead of running the output_poll_work (which is kinda the wrong
thing and a layering violation since it's an internal of the probe
helpers), or calling ->detect (which is again a layering violation
since it's used only by probe helpers) just call the official
->fill_modes function, like a GET_CONNECTOR ioctl call.

v3: Restore the accidentally removed forced-probe for echo "detect" >
force.

Cc: Chris Wilson <chris@chris-wilson.co.uk>
Reported-by: Chris Wilson <chris@chris-wilson.co.uk>
Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
---
 drivers/gpu/drm/drm_probe_helper.c | 46 +++++++++++++++++++-------------------
 drivers/gpu/drm/drm_sysfs.c        | 38 +++++++++++--------------------
 2 files changed, 36 insertions(+), 48 deletions(-)

diff --git a/drivers/gpu/drm/drm_probe_helper.c b/drivers/gpu/drm/drm_probe_helper.c
index a214a4a93b03..b7bdf12c54a5 100644
--- a/drivers/gpu/drm/drm_probe_helper.c
+++ b/drivers/gpu/drm/drm_probe_helper.c
@@ -147,6 +147,8 @@ static int drm_helper_probe_single_connector_modes_merge_bits(struct drm_connect
 	list_for_each_entry(mode, &connector->modes, head)
 		mode->status = MODE_UNVERIFIED;
 
+	old_status = connector->status;
+
 	if (connector->force) {
 		if (connector->force == DRM_FORCE_ON ||
 		    connector->force == DRM_FORCE_ON_DIGITAL)
@@ -156,33 +158,31 @@ static int drm_helper_probe_single_connector_modes_merge_bits(struct drm_connect
 		if (connector->funcs->force)
 			connector->funcs->force(connector);
 	} else {
-		old_status = connector->status;
-
 		connector->status = connector->funcs->detect(connector, true);
+	}
+
+	/*
+	 * Normally either the driver's hpd code or the poll loop should
+	 * pick up any changes and fire the hotplug event. But if
+	 * userspace sneaks in a probe, we might miss a change. Hence
+	 * check here, and if anything changed start the hotplug code.
+	 */
+	if (old_status != connector->status) {
+		DRM_DEBUG_KMS("[CONNECTOR:%d:%s] status updated from %d to %d\n",
+			      connector->base.id,
+			      connector->name,
+			      old_status, connector->status);
 
 		/*
-		 * Normally either the driver's hpd code or the poll loop should
-		 * pick up any changes and fire the hotplug event. But if
-		 * userspace sneaks in a probe, we might miss a change. Hence
-		 * check here, and if anything changed start the hotplug code.
+		 * The hotplug event code might call into the fb
+		 * helpers, and so expects that we do not hold any
+		 * locks. Fire up the poll struct instead, it will
+		 * disable itself again.
 		 */
-		if (old_status != connector->status) {
-			DRM_DEBUG_KMS("[CONNECTOR:%d:%s] status updated from %d to %d\n",
-				      connector->base.id,
-				      connector->name,
-				      old_status, connector->status);
-
-			/*
-			 * The hotplug event code might call into the fb
-			 * helpers, and so expects that we do not hold any
-			 * locks. Fire up the poll struct instead, it will
-			 * disable itself again.
-			 */
-			dev->mode_config.delayed_event = true;
-			if (dev->mode_config.poll_enabled)
-				schedule_delayed_work(&dev->mode_config.output_poll_work,
-						      0);
-		}
+		dev->mode_config.delayed_event = true;
+		if (dev->mode_config.poll_enabled)
+			schedule_delayed_work(&dev->mode_config.output_poll_work,
+					      0);
 	}
 
 	/* Re-enable polling in case the global poll config changed. */
diff --git a/drivers/gpu/drm/drm_sysfs.c b/drivers/gpu/drm/drm_sysfs.c
index 9ac4ffa6cce3..df66d9447cb0 100644
--- a/drivers/gpu/drm/drm_sysfs.c
+++ b/drivers/gpu/drm/drm_sysfs.c
@@ -167,47 +167,35 @@ static ssize_t status_store(struct device *device,
 {
 	struct drm_connector *connector = to_drm_connector(device);
 	struct drm_device *dev = connector->dev;
-	enum drm_connector_status old_status;
+	enum drm_connector_force old_force;
 	int ret;
 
 	ret = mutex_lock_interruptible(&dev->mode_config.mutex);
 	if (ret)
 		return ret;
 
-	old_status = connector->status;
+	old_force = connector->force;
 
-	if (sysfs_streq(buf, "detect")) {
+	if (sysfs_streq(buf, "detect"))
 		connector->force = 0;
-		connector->status = connector->funcs->detect(connector, true);
-	} else if (sysfs_streq(buf, "on")) {
+	else if (sysfs_streq(buf, "on"))
 		connector->force = DRM_FORCE_ON;
-	} else if (sysfs_streq(buf, "on-digital")) {
+	else if (sysfs_streq(buf, "on-digital"))
 		connector->force = DRM_FORCE_ON_DIGITAL;
-	} else if (sysfs_streq(buf, "off")) {
+	else if (sysfs_streq(buf, "off"))
 		connector->force = DRM_FORCE_OFF;
-	} else
+	else
 		ret = -EINVAL;
 
-	if (ret == 0 && connector->force) {
-		if (connector->force == DRM_FORCE_ON ||
-		    connector->force == DRM_FORCE_ON_DIGITAL)
-			connector->status = connector_status_connected;
-		else
-			connector->status = connector_status_disconnected;
-		if (connector->funcs->force)
-			connector->funcs->force(connector);
-	}
-
-	if (old_status != connector->status) {
-		DRM_DEBUG_KMS("[CONNECTOR:%d:%s] status updated from %d to %d\n",
+	if (old_force != connector->force || !connector->force) {
+		DRM_DEBUG_KMS("[CONNECTOR:%d:%s] force updated from %d to %d or reprobing\n",
 			      connector->base.id,
 			      connector->name,
-			      old_status, connector->status);
+			      old_force, connector->force);
 
-		dev->mode_config.delayed_event = true;
-		if (dev->mode_config.poll_enabled)
-			schedule_delayed_work(&dev->mode_config.output_poll_work,
-					      0);
+		connector->funcs->fill_modes(connector,
+					     dev->mode_config.max_width,
+					     dev->mode_config.max_height);
 	}
 
 	mutex_unlock(&dev->mode_config.mutex);
-- 
2.5.1

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 30+ messages in thread

end of thread, other threads:[~2015-11-24 11:46 UTC | newest]

Thread overview: 30+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-11-19 16:46 [PATCH RESEND 00/20] dev->struct_mutex locking crusade Daniel Vetter
2015-11-19 16:46 ` [PATCH RESEND 01/20] drm/armada: Plug leak in dumb_map_offset Daniel Vetter
2015-11-19 16:46 ` [PATCH RESEND 02/20] drm/armada: Don't grab dev->struct_mutex for in mmap offset ioctl Daniel Vetter
2015-11-19 16:46 ` [PATCH RESEND 03/20] drm/armada: Drop struct_mutex from cursor paths Daniel Vetter
2015-11-19 16:46 ` [PATCH RESEND 04/20] drm/armada: Use a private mutex to protect priv->linear Daniel Vetter
2015-11-19 16:46 ` [PATCH RESEND 05/20] drm/tegra: don't take dev->struct_mutex in mmap offset ioctl Daniel Vetter
2015-11-19 16:46 ` [PATCH RESEND 06/20] drm/tegra: Use drm_gem_object_unreference_unlocked Daniel Vetter
2015-11-19 16:46 ` [PATCH RESEND 07/20] drm/gma500: Use correct unref in the gem bo create function Daniel Vetter
2015-11-19 16:46 ` [PATCH RESEND 08/20] drm/gma500: Drop dev->struct_mutex from modeset code Daniel Vetter
2015-11-19 16:46 ` [PATCH RESEND 09/20] drm/gma500: Drop dev->struct_mutex from fbdev init/teardown code Daniel Vetter
2015-11-19 16:46 ` [PATCH RESEND 10/20] drm/gma500: Drop dev->struct_mutex from mmap offset function Daniel Vetter
2015-11-19 16:46 ` [PATCH RESEND 11/20] drm/gma500: Add driver private mutex for the fault handler Daniel Vetter
2015-11-19 16:46 ` [PATCH RESEND 12/20] drm/nouveau: Drop dev->struct_mutex from fbdev init Daniel Vetter
2015-11-19 16:46 ` [PATCH RESEND 13/20] drm/exynos: Drop dev->struct_mutex from mmap offset function Daniel Vetter
2015-11-19 16:46 ` [PATCH RESEND 14/20] drm/exynos: drop struct_mutex from exynos_gem_map_sgt_with_dma Daniel Vetter
2015-11-19 16:46 ` [PATCH RESEND 15/20] drm/exynos: drop struct_mutex from exynos_drm_gem_get_ioctl Daniel Vetter
2015-11-19 16:50   ` Daniel Stone
2015-11-19 16:59     ` Daniel Vetter
2015-11-19 16:46 ` [PATCH RESEND 16/20] drm/exynos: drop struct_mutex from fbdev setup Daniel Vetter
2015-11-19 16:46 ` [PATCH RESEND 17/20] drm/vgem: Simplify dum_map Daniel Vetter
2015-11-19 16:46 ` [PATCH RESEND 18/20] drm/vgem: Move get_pages to gem_create Daniel Vetter
2015-11-19 16:46 ` [PATCH RESEND 19/20] drm/vgem: Drop dev->struct_mutex Daniel Vetter
2015-11-19 16:46 ` [PATCH RESEND 20/20] drm/vma_manage: Drop has_offset Daniel Vetter
2015-11-19 16:46 ` [PATCH] drm/sysfs: Send out uevent when connector->force changes Daniel Vetter
2015-11-19 21:06   ` Chris Wilson
2015-11-20  8:11     ` Daniel Vetter
2015-11-20  9:25       ` Chris Wilson
2015-11-24 10:51         ` Daniel Vetter
2015-11-24 11:46           ` Chris Wilson
  -- strict thread matches above, loose matches on Subject: below --
2015-11-19 14:44 Daniel Vetter

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.