aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorIlija Hadzic <ihadzic@research.bell-labs.com>2011-10-28 17:43:28 -0400
committerDave Airlie <airlied@redhat.com>2012-01-05 09:43:02 -0500
commit09b4ea47d1041612b101c369969db123ac2c1511 (patch)
tree177a2cf53107d2451f47cf2680ce20db8af5f623
parent53fead966a584cd2130e0c5565726dd56ccf7924 (diff)
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>
-rw-r--r--drivers/gpu/drm/drm_context.c5
-rw-r--r--drivers/gpu/drm/drm_drv.c6
-rw-r--r--drivers/gpu/drm/drm_ioctl.c15
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,
154 return -EINVAL; 154 return -EINVAL;
155 } 155 }
156 156
157 mutex_unlock(&dev->struct_mutex);
158
159 request->handle = NULL; 157 request->handle = NULL;
160 list_for_each_entry(_entry, &dev->maplist, head) { 158 list_for_each_entry(_entry, &dev->maplist, head) {
161 if (_entry->map == map) { 159 if (_entry->map == map) {
@@ -164,6 +162,9 @@ int drm_getsareactx(struct drm_device *dev, void *data,
164 break; 162 break;
165 } 163 }
166 } 164 }
165
166 mutex_unlock(&dev->struct_mutex);
167
167 if (request->handle == NULL) 168 if (request->handle == NULL)
168 return -EINVAL; 169 return -EINVAL;
169 170
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[] = {
65 DRM_IOCTL_DEF(DRM_IOCTL_GET_UNIQUE, drm_getunique, 0), 65 DRM_IOCTL_DEF(DRM_IOCTL_GET_UNIQUE, drm_getunique, 0),
66 DRM_IOCTL_DEF(DRM_IOCTL_GET_MAGIC, drm_getmagic, 0), 66 DRM_IOCTL_DEF(DRM_IOCTL_GET_MAGIC, drm_getmagic, 0),
67 DRM_IOCTL_DEF(DRM_IOCTL_IRQ_BUSID, drm_irq_by_busid, DRM_MASTER|DRM_ROOT_ONLY), 67 DRM_IOCTL_DEF(DRM_IOCTL_IRQ_BUSID, drm_irq_by_busid, DRM_MASTER|DRM_ROOT_ONLY),
68 DRM_IOCTL_DEF(DRM_IOCTL_GET_MAP, drm_getmap, 0), 68 DRM_IOCTL_DEF(DRM_IOCTL_GET_MAP, drm_getmap, DRM_UNLOCKED),
69 DRM_IOCTL_DEF(DRM_IOCTL_GET_CLIENT, drm_getclient, 0), 69 DRM_IOCTL_DEF(DRM_IOCTL_GET_CLIENT, drm_getclient, DRM_UNLOCKED),
70 DRM_IOCTL_DEF(DRM_IOCTL_GET_STATS, drm_getstats, 0), 70 DRM_IOCTL_DEF(DRM_IOCTL_GET_STATS, drm_getstats, DRM_UNLOCKED),
71 DRM_IOCTL_DEF(DRM_IOCTL_GET_CAP, drm_getcap, DRM_UNLOCKED), 71 DRM_IOCTL_DEF(DRM_IOCTL_GET_CAP, drm_getcap, DRM_UNLOCKED),
72 DRM_IOCTL_DEF(DRM_IOCTL_SET_VERSION, drm_setversion, DRM_MASTER), 72 DRM_IOCTL_DEF(DRM_IOCTL_SET_VERSION, drm_setversion, DRM_MASTER),
73 73
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,
158 int i; 158 int i;
159 159
160 idx = map->offset; 160 idx = map->offset;
161 161 if (idx < 0)
162 mutex_lock(&dev->struct_mutex);
163 if (idx < 0) {
164 mutex_unlock(&dev->struct_mutex);
165 return -EINVAL; 162 return -EINVAL;
166 }
167 163
168 i = 0; 164 i = 0;
165 mutex_lock(&dev->struct_mutex);
169 list_for_each(list, &dev->maplist) { 166 list_for_each(list, &dev->maplist) {
170 if (i == idx) { 167 if (i == idx) {
171 r_list = list_entry(list, struct drm_map_list, head); 168 r_list = list_entry(list, struct drm_map_list, head);
@@ -211,9 +208,9 @@ int drm_getclient(struct drm_device *dev, void *data,
211 int i; 208 int i;
212 209
213 idx = client->idx; 210 idx = client->idx;
214 mutex_lock(&dev->struct_mutex);
215
216 i = 0; 211 i = 0;
212
213 mutex_lock(&dev->struct_mutex);
217 list_for_each_entry(pt, &dev->filelist, lhead) { 214 list_for_each_entry(pt, &dev->filelist, lhead) {
218 if (i++ >= idx) { 215 if (i++ >= idx) {
219 client->auth = pt->authenticated; 216 client->auth = pt->authenticated;
@@ -249,8 +246,6 @@ int drm_getstats(struct drm_device *dev, void *data,
249 246
250 memset(stats, 0, sizeof(*stats)); 247 memset(stats, 0, sizeof(*stats));
251 248
252 mutex_lock(&dev->struct_mutex);
253
254 for (i = 0; i < dev->counters; i++) { 249 for (i = 0; i < dev->counters; i++) {
255 if (dev->types[i] == _DRM_STAT_LOCK) 250 if (dev->types[i] == _DRM_STAT_LOCK)
256 stats->data[i].value = 251 stats->data[i].value =
@@ -262,8 +257,6 @@ int drm_getstats(struct drm_device *dev, void *data,
262 257
263 stats->count = dev->counters; 258 stats->count = dev->counters;
264 259
265 mutex_unlock(&dev->struct_mutex);
266
267 return 0; 260 return 0;
268} 261}
269 262