All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v2] drm: make DRM_UNLOCKED ioctls with their own mutex
@ 2011-10-28 21:43 Ilija Hadzic
  2011-10-29  1:15 ` Daniel Vetter
  0 siblings, 1 reply; 2+ messages in thread
From: Ilija Hadzic @ 2011-10-28 21:43 UTC (permalink / raw)
  To: airlied, dri-devel

drm_getclient, drm_getstats and drm_getmap (with a few minor
adjustments) do not need global mutex, so fix that and
make the said ioctls DRM_UNLOCKED. Details:

  drm_getclient: the only thing that should be protected here
  is dev->filelist and that is already protected everywhere with
  dev->struct_mutex.

  drm_getstats: there is no need for any mutex here because the
  loop runs through quasi-static (set at load time only)
  data, and the actual count access is done with atomic_read()

  drm_getmap already uses dev->struct_mutex to protect
  dev->maplist, which also used to protect the same structure
  everywhere else except at three places:
  * drm_getsarea, which doesn't grab *any* mutex before
    touching dev->maplist (so no drm_global_mutex doesn't help
    here either; different issue for a different patch).
    However, drivers seem to call it only at
    initialization time so it probably doesn't matter
  * drm_master_destroy, which is called from drm_master_put,
    which in turn is protected with dev->struct_mutex
    everywhere else in drm module, so we are good here too.
  * drm_getsareactx, which releases the dev->struct_mutex
    too early, but this patch includes the fix for that.

v2: * incorporate comments received from Daniel Vetter
    * include the (long) explanation above to make it clear what
      we are doing (and why), also at Daniel Vetter's request
    * tighten up mutex grab/release locations to only
      encompass real critical sections, rather than some
      random code around them

Signed-off-by: Ilija Hadzic <ihadzic@research.bell-labs.com>
---
 drivers/gpu/drm/drm_context.c |    5 +++--
 drivers/gpu/drm/drm_drv.c     |    6 +++---
 drivers/gpu/drm/drm_ioctl.c   |   15 ++++-----------
 3 files changed, 10 insertions(+), 16 deletions(-)

diff --git a/drivers/gpu/drm/drm_context.c b/drivers/gpu/drm/drm_context.c
index 6d440fb..325365f 100644
--- a/drivers/gpu/drm/drm_context.c
+++ b/drivers/gpu/drm/drm_context.c
@@ -154,8 +154,6 @@ int drm_getsareactx(struct drm_device *dev, void *data,
 		return -EINVAL;
 	}
 
-	mutex_unlock(&dev->struct_mutex);
-
 	request->handle = NULL;
 	list_for_each_entry(_entry, &dev->maplist, head) {
 		if (_entry->map == map) {
@@ -164,6 +162,9 @@ int drm_getsareactx(struct drm_device *dev, void *data,
 			break;
 		}
 	}
+
+	mutex_unlock(&dev->struct_mutex);
+
 	if (request->handle == NULL)
 		return -EINVAL;
 
diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c
index c990dab..dc0eb0b 100644
--- a/drivers/gpu/drm/drm_drv.c
+++ b/drivers/gpu/drm/drm_drv.c
@@ -64,9 +64,9 @@ static struct drm_ioctl_desc drm_ioctls[] = {
 	DRM_IOCTL_DEF(DRM_IOCTL_GET_UNIQUE, drm_getunique, 0),
 	DRM_IOCTL_DEF(DRM_IOCTL_GET_MAGIC, drm_getmagic, 0),
 	DRM_IOCTL_DEF(DRM_IOCTL_IRQ_BUSID, drm_irq_by_busid, DRM_MASTER|DRM_ROOT_ONLY),
-	DRM_IOCTL_DEF(DRM_IOCTL_GET_MAP, drm_getmap, 0),
-	DRM_IOCTL_DEF(DRM_IOCTL_GET_CLIENT, drm_getclient, 0),
-	DRM_IOCTL_DEF(DRM_IOCTL_GET_STATS, drm_getstats, 0),
+	DRM_IOCTL_DEF(DRM_IOCTL_GET_MAP, drm_getmap, DRM_UNLOCKED),
+	DRM_IOCTL_DEF(DRM_IOCTL_GET_CLIENT, drm_getclient, DRM_UNLOCKED),
+	DRM_IOCTL_DEF(DRM_IOCTL_GET_STATS, drm_getstats, DRM_UNLOCKED),
 	DRM_IOCTL_DEF(DRM_IOCTL_GET_CAP, drm_getcap, DRM_UNLOCKED),
 	DRM_IOCTL_DEF(DRM_IOCTL_SET_VERSION, drm_setversion, DRM_MASTER),
 
diff --git a/drivers/gpu/drm/drm_ioctl.c b/drivers/gpu/drm/drm_ioctl.c
index 904d7e9..956fd38 100644
--- a/drivers/gpu/drm/drm_ioctl.c
+++ b/drivers/gpu/drm/drm_ioctl.c
@@ -158,14 +158,11 @@ int drm_getmap(struct drm_device *dev, void *data,
 	int i;
 
 	idx = map->offset;
-
-	mutex_lock(&dev->struct_mutex);
-	if (idx < 0) {
-		mutex_unlock(&dev->struct_mutex);
+	if (idx < 0)
 		return -EINVAL;
-	}
 
 	i = 0;
+	mutex_lock(&dev->struct_mutex);
 	list_for_each(list, &dev->maplist) {
 		if (i == idx) {
 			r_list = list_entry(list, struct drm_map_list, head);
@@ -211,9 +208,9 @@ int drm_getclient(struct drm_device *dev, void *data,
 	int i;
 
 	idx = client->idx;
-	mutex_lock(&dev->struct_mutex);
-
 	i = 0;
+
+	mutex_lock(&dev->struct_mutex);
 	list_for_each_entry(pt, &dev->filelist, lhead) {
 		if (i++ >= idx) {
 			client->auth = pt->authenticated;
@@ -249,8 +246,6 @@ int drm_getstats(struct drm_device *dev, void *data,
 
 	memset(stats, 0, sizeof(*stats));
 
-	mutex_lock(&dev->struct_mutex);
-
 	for (i = 0; i < dev->counters; i++) {
 		if (dev->types[i] == _DRM_STAT_LOCK)
 			stats->data[i].value =
@@ -262,8 +257,6 @@ int drm_getstats(struct drm_device *dev, void *data,
 
 	stats->count = dev->counters;
 
-	mutex_unlock(&dev->struct_mutex);
-
 	return 0;
 }
 
-- 
1.7.7

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

* Re: [PATCH v2] drm: make DRM_UNLOCKED ioctls with their own mutex
  2011-10-28 21:43 [PATCH v2] drm: make DRM_UNLOCKED ioctls with their own mutex Ilija Hadzic
@ 2011-10-29  1:15 ` Daniel Vetter
  0 siblings, 0 replies; 2+ messages in thread
From: Daniel Vetter @ 2011-10-29  1:15 UTC (permalink / raw)
  To: Ilija Hadzic; +Cc: dri-devel

On Fri, Oct 28, 2011 at 05:43:28PM -0400, Ilija Hadzic wrote:
> drm_getclient, drm_getstats and drm_getmap (with a few minor
> adjustments) do not need global mutex, so fix that and
> make the said ioctls DRM_UNLOCKED. Details:
> 
>   drm_getclient: the only thing that should be protected here
>   is dev->filelist and that is already protected everywhere with
>   dev->struct_mutex.
> 
>   drm_getstats: there is no need for any mutex here because the
>   loop runs through quasi-static (set at load time only)
>   data, and the actual count access is done with atomic_read()
> 
>   drm_getmap already uses dev->struct_mutex to protect
>   dev->maplist, which also used to protect the same structure
>   everywhere else except at three places:
>   * drm_getsarea, which doesn't grab *any* mutex before
>     touching dev->maplist (so no drm_global_mutex doesn't help
>     here either; different issue for a different patch).
>     However, drivers seem to call it only at
>     initialization time so it probably doesn't matter
>   * drm_master_destroy, which is called from drm_master_put,
>     which in turn is protected with dev->struct_mutex
>     everywhere else in drm module, so we are good here too.
>   * drm_getsareactx, which releases the dev->struct_mutex
>     too early, but this patch includes the fix for that.
> 
> v2: * incorporate comments received from Daniel Vetter
>     * include the (long) explanation above to make it clear what
>       we are doing (and why), also at Daniel Vetter's request
>     * tighten up mutex grab/release locations to only
>       encompass real critical sections, rather than some
>       random code around them
> 
> Signed-off-by: Ilija Hadzic <ihadzic@research.bell-labs.com>

Quite a load of stuff to check for this, i.e. next time around maybe split
it up into one patch for each of the three functions changed (and move the
locking bugfix in drm_getsareactx into its own patch).

Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch>
-- 
Daniel Vetter
Mail: daniel@ffwll.ch
Mobile: +41 (0)79 365 57 48

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

end of thread, other threads:[~2011-10-29  1:14 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-10-28 21:43 [PATCH v2] drm: make DRM_UNLOCKED ioctls with their own mutex Ilija Hadzic
2011-10-29  1:15 ` 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.