diff options
author | Krzysztof Helt <krzysztof.h1@wp.pl> | 2008-10-18 23:27:51 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2008-10-20 11:52:36 -0400 |
commit | 3e680aae4e53ab54cdbb0c29257dae0cbb158e1c (patch) | |
tree | 389c2a60625b2f9dbd9555378a9d4917730f335e /drivers/video/fbmem.c | |
parent | e53677113e32e6f118e31b8391a2eab7ee52c0a7 (diff) |
fb: convert lock/unlock_kernel() into local fb mutex
Change lock_kernel()/unlock_kernel() to local fb mutex. Each frame buffer
instance has its own mutex.
The one line try_to_load() function is unrolled to request_module() in two
places for readability.
[righi.andrea@gmail.com: fb: fix NULL pointer BUG dereference in fb_open()]
Signed-off-by: Krzysztof Helt <krzysztof.h1@wp.pl>
Signed-off-by: Andrea Righi <righi.andrea@gmail.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'drivers/video/fbmem.c')
-rw-r--r-- | drivers/video/fbmem.c | 39 |
1 files changed, 20 insertions, 19 deletions
diff --git a/drivers/video/fbmem.c b/drivers/video/fbmem.c index 2a0f013dc37b..cd5f20da738a 100644 --- a/drivers/video/fbmem.c +++ b/drivers/video/fbmem.c | |||
@@ -1018,12 +1018,12 @@ fb_ioctl(struct file *file, unsigned int cmd, | |||
1018 | void __user *argp = (void __user *)arg; | 1018 | void __user *argp = (void __user *)arg; |
1019 | long ret = 0; | 1019 | long ret = 0; |
1020 | 1020 | ||
1021 | lock_kernel(); | ||
1022 | info = registered_fb[fbidx]; | 1021 | info = registered_fb[fbidx]; |
1022 | mutex_lock(&info->lock); | ||
1023 | fb = info->fbops; | 1023 | fb = info->fbops; |
1024 | 1024 | ||
1025 | if (!fb) { | 1025 | if (!fb) { |
1026 | unlock_kernel(); | 1026 | mutex_unlock(&info->lock); |
1027 | return -ENODEV; | 1027 | return -ENODEV; |
1028 | } | 1028 | } |
1029 | switch (cmd) { | 1029 | switch (cmd) { |
@@ -1126,7 +1126,7 @@ fb_ioctl(struct file *file, unsigned int cmd, | |||
1126 | else | 1126 | else |
1127 | ret = fb->fb_ioctl(info, cmd, arg); | 1127 | ret = fb->fb_ioctl(info, cmd, arg); |
1128 | } | 1128 | } |
1129 | unlock_kernel(); | 1129 | mutex_unlock(&info->lock); |
1130 | return ret; | 1130 | return ret; |
1131 | } | 1131 | } |
1132 | 1132 | ||
@@ -1253,7 +1253,7 @@ fb_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg) | |||
1253 | struct fb_ops *fb = info->fbops; | 1253 | struct fb_ops *fb = info->fbops; |
1254 | long ret = -ENOIOCTLCMD; | 1254 | long ret = -ENOIOCTLCMD; |
1255 | 1255 | ||
1256 | lock_kernel(); | 1256 | mutex_lock(&info->lock); |
1257 | switch(cmd) { | 1257 | switch(cmd) { |
1258 | case FBIOGET_VSCREENINFO: | 1258 | case FBIOGET_VSCREENINFO: |
1259 | case FBIOPUT_VSCREENINFO: | 1259 | case FBIOPUT_VSCREENINFO: |
@@ -1279,7 +1279,7 @@ fb_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg) | |||
1279 | ret = fb->fb_compat_ioctl(info, cmd, arg); | 1279 | ret = fb->fb_compat_ioctl(info, cmd, arg); |
1280 | break; | 1280 | break; |
1281 | } | 1281 | } |
1282 | unlock_kernel(); | 1282 | mutex_unlock(&info->lock); |
1283 | return ret; | 1283 | return ret; |
1284 | } | 1284 | } |
1285 | #endif | 1285 | #endif |
@@ -1301,13 +1301,13 @@ fb_mmap(struct file *file, struct vm_area_struct * vma) | |||
1301 | return -ENODEV; | 1301 | return -ENODEV; |
1302 | if (fb->fb_mmap) { | 1302 | if (fb->fb_mmap) { |
1303 | int res; | 1303 | int res; |
1304 | lock_kernel(); | 1304 | mutex_lock(&info->lock); |
1305 | res = fb->fb_mmap(info, vma); | 1305 | res = fb->fb_mmap(info, vma); |
1306 | unlock_kernel(); | 1306 | mutex_unlock(&info->lock); |
1307 | return res; | 1307 | return res; |
1308 | } | 1308 | } |
1309 | 1309 | ||
1310 | lock_kernel(); | 1310 | mutex_lock(&info->lock); |
1311 | 1311 | ||
1312 | /* frame buffer memory */ | 1312 | /* frame buffer memory */ |
1313 | start = info->fix.smem_start; | 1313 | start = info->fix.smem_start; |
@@ -1316,13 +1316,13 @@ fb_mmap(struct file *file, struct vm_area_struct * vma) | |||
1316 | /* memory mapped io */ | 1316 | /* memory mapped io */ |
1317 | off -= len; | 1317 | off -= len; |
1318 | if (info->var.accel_flags) { | 1318 | if (info->var.accel_flags) { |
1319 | unlock_kernel(); | 1319 | mutex_unlock(&info->lock); |
1320 | return -EINVAL; | 1320 | return -EINVAL; |
1321 | } | 1321 | } |
1322 | start = info->fix.mmio_start; | 1322 | start = info->fix.mmio_start; |
1323 | len = PAGE_ALIGN((start & ~PAGE_MASK) + info->fix.mmio_len); | 1323 | len = PAGE_ALIGN((start & ~PAGE_MASK) + info->fix.mmio_len); |
1324 | } | 1324 | } |
1325 | unlock_kernel(); | 1325 | mutex_unlock(&info->lock); |
1326 | start &= PAGE_MASK; | 1326 | start &= PAGE_MASK; |
1327 | if ((vma->vm_end - vma->vm_start + off) > len) | 1327 | if ((vma->vm_end - vma->vm_start + off) > len) |
1328 | return -EINVAL; | 1328 | return -EINVAL; |
@@ -1346,13 +1346,13 @@ fb_open(struct inode *inode, struct file *file) | |||
1346 | 1346 | ||
1347 | if (fbidx >= FB_MAX) | 1347 | if (fbidx >= FB_MAX) |
1348 | return -ENODEV; | 1348 | return -ENODEV; |
1349 | lock_kernel(); | 1349 | info = registered_fb[fbidx]; |
1350 | if (!(info = registered_fb[fbidx])) | 1350 | if (!info) |
1351 | request_module("fb%d", fbidx); | 1351 | request_module("fb%d", fbidx); |
1352 | if (!(info = registered_fb[fbidx])) { | 1352 | info = registered_fb[fbidx]; |
1353 | res = -ENODEV; | 1353 | if (!info) |
1354 | goto out; | 1354 | return -ENODEV; |
1355 | } | 1355 | mutex_lock(&info->lock); |
1356 | if (!try_module_get(info->fbops->owner)) { | 1356 | if (!try_module_get(info->fbops->owner)) { |
1357 | res = -ENODEV; | 1357 | res = -ENODEV; |
1358 | goto out; | 1358 | goto out; |
@@ -1368,7 +1368,7 @@ fb_open(struct inode *inode, struct file *file) | |||
1368 | fb_deferred_io_open(info, inode, file); | 1368 | fb_deferred_io_open(info, inode, file); |
1369 | #endif | 1369 | #endif |
1370 | out: | 1370 | out: |
1371 | unlock_kernel(); | 1371 | mutex_unlock(&info->lock); |
1372 | return res; | 1372 | return res; |
1373 | } | 1373 | } |
1374 | 1374 | ||
@@ -1377,11 +1377,11 @@ fb_release(struct inode *inode, struct file *file) | |||
1377 | { | 1377 | { |
1378 | struct fb_info * const info = file->private_data; | 1378 | struct fb_info * const info = file->private_data; |
1379 | 1379 | ||
1380 | lock_kernel(); | 1380 | mutex_lock(&info->lock); |
1381 | if (info->fbops->fb_release) | 1381 | if (info->fbops->fb_release) |
1382 | info->fbops->fb_release(info,1); | 1382 | info->fbops->fb_release(info,1); |
1383 | module_put(info->fbops->owner); | 1383 | module_put(info->fbops->owner); |
1384 | unlock_kernel(); | 1384 | mutex_unlock(&info->lock); |
1385 | return 0; | 1385 | return 0; |
1386 | } | 1386 | } |
1387 | 1387 | ||
@@ -1460,6 +1460,7 @@ register_framebuffer(struct fb_info *fb_info) | |||
1460 | if (!registered_fb[i]) | 1460 | if (!registered_fb[i]) |
1461 | break; | 1461 | break; |
1462 | fb_info->node = i; | 1462 | fb_info->node = i; |
1463 | mutex_init(&fb_info->lock); | ||
1463 | 1464 | ||
1464 | fb_info->dev = device_create(fb_class, fb_info->device, | 1465 | fb_info->dev = device_create(fb_class, fb_info->device, |
1465 | MKDEV(FB_MAJOR, i), NULL, "fb%d", i); | 1466 | MKDEV(FB_MAJOR, i), NULL, "fb%d", i); |