Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

authored by

Krzysztof Helt and committed by
Linus Torvalds
3e680aae e5367711

+21 -19
+20 -19
drivers/video/fbmem.c
··· 1018 1018 void __user *argp = (void __user *)arg; 1019 1019 long ret = 0; 1020 1020 1021 - lock_kernel(); 1022 1021 info = registered_fb[fbidx]; 1022 + mutex_lock(&info->lock); 1023 1023 fb = info->fbops; 1024 1024 1025 1025 if (!fb) { 1026 - unlock_kernel(); 1026 + mutex_unlock(&info->lock); 1027 1027 return -ENODEV; 1028 1028 } 1029 1029 switch (cmd) { ··· 1126 1126 else 1127 1127 ret = fb->fb_ioctl(info, cmd, arg); 1128 1128 } 1129 - unlock_kernel(); 1129 + mutex_unlock(&info->lock); 1130 1130 return ret; 1131 1131 } 1132 1132 ··· 1253 1253 struct fb_ops *fb = info->fbops; 1254 1254 long ret = -ENOIOCTLCMD; 1255 1255 1256 - lock_kernel(); 1256 + mutex_lock(&info->lock); 1257 1257 switch(cmd) { 1258 1258 case FBIOGET_VSCREENINFO: 1259 1259 case FBIOPUT_VSCREENINFO: ··· 1279 1279 ret = fb->fb_compat_ioctl(info, cmd, arg); 1280 1280 break; 1281 1281 } 1282 - unlock_kernel(); 1282 + mutex_unlock(&info->lock); 1283 1283 return ret; 1284 1284 } 1285 1285 #endif ··· 1301 1301 return -ENODEV; 1302 1302 if (fb->fb_mmap) { 1303 1303 int res; 1304 - lock_kernel(); 1304 + mutex_lock(&info->lock); 1305 1305 res = fb->fb_mmap(info, vma); 1306 - unlock_kernel(); 1306 + mutex_unlock(&info->lock); 1307 1307 return res; 1308 1308 } 1309 1309 1310 - lock_kernel(); 1310 + mutex_lock(&info->lock); 1311 1311 1312 1312 /* frame buffer memory */ 1313 1313 start = info->fix.smem_start; ··· 1316 1316 /* memory mapped io */ 1317 1317 off -= len; 1318 1318 if (info->var.accel_flags) { 1319 - unlock_kernel(); 1319 + mutex_unlock(&info->lock); 1320 1320 return -EINVAL; 1321 1321 } 1322 1322 start = info->fix.mmio_start; 1323 1323 len = PAGE_ALIGN((start & ~PAGE_MASK) + info->fix.mmio_len); 1324 1324 } 1325 - unlock_kernel(); 1325 + mutex_unlock(&info->lock); 1326 1326 start &= PAGE_MASK; 1327 1327 if ((vma->vm_end - vma->vm_start + off) > len) 1328 1328 return -EINVAL; ··· 1346 1346 1347 1347 if (fbidx >= FB_MAX) 1348 1348 return -ENODEV; 1349 - lock_kernel(); 1350 - if (!(info = registered_fb[fbidx])) 1349 + info = registered_fb[fbidx]; 1350 + if (!info) 1351 1351 request_module("fb%d", fbidx); 1352 - if (!(info = registered_fb[fbidx])) { 1353 - res = -ENODEV; 1354 - goto out; 1355 - } 1352 + info = registered_fb[fbidx]; 1353 + if (!info) 1354 + return -ENODEV; 1355 + mutex_lock(&info->lock); 1356 1356 if (!try_module_get(info->fbops->owner)) { 1357 1357 res = -ENODEV; 1358 1358 goto out; ··· 1368 1368 fb_deferred_io_open(info, inode, file); 1369 1369 #endif 1370 1370 out: 1371 - unlock_kernel(); 1371 + mutex_unlock(&info->lock); 1372 1372 return res; 1373 1373 } 1374 1374 ··· 1377 1377 { 1378 1378 struct fb_info * const info = file->private_data; 1379 1379 1380 - lock_kernel(); 1380 + mutex_lock(&info->lock); 1381 1381 if (info->fbops->fb_release) 1382 1382 info->fbops->fb_release(info,1); 1383 1383 module_put(info->fbops->owner); 1384 - unlock_kernel(); 1384 + mutex_unlock(&info->lock); 1385 1385 return 0; 1386 1386 } 1387 1387 ··· 1460 1460 if (!registered_fb[i]) 1461 1461 break; 1462 1462 fb_info->node = i; 1463 + mutex_init(&fb_info->lock); 1463 1464 1464 1465 fb_info->dev = device_create(fb_class, fb_info->device, 1465 1466 MKDEV(FB_MAJOR, i), NULL, "fb%d", i);
+1
include/linux/fb.h
··· 808 808 struct fb_info { 809 809 int node; 810 810 int flags; 811 + struct mutex lock; /* Lock for open/release/ioctl funcs */ 811 812 struct fb_var_screeninfo var; /* Current var */ 812 813 struct fb_fix_screeninfo fix; /* Current fix */ 813 814 struct fb_monspecs monspecs; /* Current Monitor specs */