diff options
author | Ilija Hadzic <ihadzic@research.bell-labs.com> | 2011-10-29 01:43:28 +0400 |
---|---|---|
committer | Dave Airlie <airlied@redhat.com> | 2012-01-05 18:43:02 +0400 |
commit | 09b4ea47d1041612b101c369969db123ac2c1511 (patch) | |
tree | 177a2cf53107d2451f47cf2680ce20db8af5f623 /drivers | |
parent | 53fead966a584cd2130e0c5565726dd56ccf7924 (diff) | |
download | linux-09b4ea47d1041612b101c369969db123ac2c1511.tar.xz |
drm: make DRM_UNLOCKED ioctls with their own mutex
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>
Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Signed-off-by: Dave Airlie <airlied@redhat.com>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/gpu/drm/drm_context.c | 5 | ||||
-rw-r--r-- | drivers/gpu/drm/drm_drv.c | 6 | ||||
-rw-r--r-- | 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 6d440fb894cf..325365f6d355 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 1919ef05d6d8..ebf7d3f68fc4 100644 --- a/drivers/gpu/drm/drm_drv.c +++ b/drivers/gpu/drm/drm_drv.c @@ -65,9 +65,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 904d7e9c8e47..956fd38d7c9e 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; } |