[media] v4l: kill the BKL

All of the hard problems for BKL removal appear to be solved in the
v4l-dvb/master tree. This removes the BKL from the various open
functions that do not need it, or only use it to protect an
open count.

The zoran driver is nontrivial in this regard, so I introduce
a new mutex that locks both the open/release and the ioctl
functions. Someone with access to the hardware can probably
improve that by using the existing lock in all cases.

Finally, all drivers that still use the locked version of the
ioctl function now get called under a new mutex instead of
the BKL.

Signed-off-by: Arnd Bergmann <arnd@arndb.de>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>

authored by Arnd Bergmann and committed by Mauro Carvalho Chehab 0edf2e5e 2c2742da

+51 -59
-1
drivers/media/Kconfig
··· 19 20 config VIDEO_DEV 21 tristate "Video For Linux" 22 - depends on BKL # used in many drivers for ioctl handling, need to kill 23 ---help--- 24 V4L core support for video capture and overlay devices, webcams and 25 AM/FM radio cards.
··· 19 20 config VIDEO_DEV 21 tristate "Video For Linux" 22 ---help--- 23 V4L core support for video capture and overlay devices, webcams and 24 AM/FM radio cards.
+2 -4
drivers/media/video/cx231xx/cx231xx-417.c
··· 31 #include <linux/delay.h> 32 #include <linux/device.h> 33 #include <linux/firmware.h> 34 - #include <linux/smp_lock.h> 35 #include <linux/vmalloc.h> 36 #include <media/v4l2-common.h> 37 #include <media/v4l2-ioctl.h> ··· 1926 dev = h; 1927 } 1928 1929 - if (dev == NULL) { 1930 - unlock_kernel(); 1931 return -ENODEV; 1932 - } 1933 mutex_lock(&dev->lock); 1934 1935 /* allocate + initialize per filehandle data */
··· 31 #include <linux/delay.h> 32 #include <linux/device.h> 33 #include <linux/firmware.h> 34 #include <linux/vmalloc.h> 35 #include <media/v4l2-common.h> 36 #include <media/v4l2-ioctl.h> ··· 1927 dev = h; 1928 } 1929 1930 + if (dev == NULL) 1931 return -ENODEV; 1932 + 1933 mutex_lock(&dev->lock); 1934 1935 /* allocate + initialize per filehandle data */
+1 -8
drivers/media/video/cx23885/cx23885-417.c
··· 31 #include <linux/delay.h> 32 #include <linux/device.h> 33 #include <linux/firmware.h> 34 - #include <linux/smp_lock.h> 35 #include <linux/slab.h> 36 #include <media/v4l2-common.h> 37 #include <media/v4l2-ioctl.h> ··· 1575 1576 /* allocate + initialize per filehandle data */ 1577 fh = kzalloc(sizeof(*fh), GFP_KERNEL); 1578 - if (NULL == fh) { 1579 - unlock_kernel(); 1580 return -ENOMEM; 1581 - } 1582 - 1583 - lock_kernel(); 1584 1585 file->private_data = fh; 1586 fh->dev = dev; ··· 1587 V4L2_FIELD_INTERLACED, 1588 sizeof(struct cx23885_buffer), 1589 fh, NULL); 1590 - unlock_kernel(); 1591 - 1592 return 0; 1593 } 1594
··· 31 #include <linux/delay.h> 32 #include <linux/device.h> 33 #include <linux/firmware.h> 34 #include <linux/slab.h> 35 #include <media/v4l2-common.h> 36 #include <media/v4l2-ioctl.h> ··· 1576 1577 /* allocate + initialize per filehandle data */ 1578 fh = kzalloc(sizeof(*fh), GFP_KERNEL); 1579 + if (!fh) 1580 return -ENOMEM; 1581 1582 file->private_data = fh; 1583 fh->dev = dev; ··· 1592 V4L2_FIELD_INTERLACED, 1593 sizeof(struct cx23885_buffer), 1594 fh, NULL); 1595 return 0; 1596 } 1597
-5
drivers/media/video/cx23885/cx23885-video.c
··· 26 #include <linux/kmod.h> 27 #include <linux/kernel.h> 28 #include <linux/slab.h> 29 - #include <linux/smp_lock.h> 30 #include <linux/interrupt.h> 31 #include <linux/delay.h> 32 #include <linux/kthread.h> ··· 742 if (NULL == fh) 743 return -ENOMEM; 744 745 - lock_kernel(); 746 - 747 file->private_data = fh; 748 fh->dev = dev; 749 fh->radio = radio; ··· 758 fh, NULL); 759 760 dprintk(1, "post videobuf_queue_init()\n"); 761 - 762 - unlock_kernel(); 763 764 return 0; 765 }
··· 26 #include <linux/kmod.h> 27 #include <linux/kernel.h> 28 #include <linux/slab.h> 29 #include <linux/interrupt.h> 30 #include <linux/delay.h> 31 #include <linux/kthread.h> ··· 743 if (NULL == fh) 744 return -ENOMEM; 745 746 file->private_data = fh; 747 fh->dev = dev; 748 fh->radio = radio; ··· 761 fh, NULL); 762 763 dprintk(1, "post videobuf_queue_init()\n"); 764 765 return 0; 766 }
+3 -4
drivers/media/video/se401.c
··· 31 #include <linux/init.h> 32 #include <linux/vmalloc.h> 33 #include <linux/slab.h> 34 - #include <linux/smp_lock.h> 35 #include <linux/pagemap.h> 36 #include <linux/usb.h> 37 #include "se401.h" ··· 950 struct usb_se401 *se401 = (struct usb_se401 *)dev; 951 int err = 0; 952 953 - lock_kernel(); 954 if (se401->user) { 955 - unlock_kernel(); 956 return -EBUSY; 957 } 958 se401->fbuf = rvmalloc(se401->maxframesize * SE401_NUMFRAMES); ··· 961 else 962 err = -ENOMEM; 963 se401->user = !err; 964 - unlock_kernel(); 965 966 return err; 967 }
··· 31 #include <linux/init.h> 32 #include <linux/vmalloc.h> 33 #include <linux/slab.h> 34 #include <linux/pagemap.h> 35 #include <linux/usb.h> 36 #include "se401.h" ··· 951 struct usb_se401 *se401 = (struct usb_se401 *)dev; 952 int err = 0; 953 954 + mutex_lock(&se401->lock); 955 if (se401->user) { 956 + mutex_unlock(&se401->lock); 957 return -EBUSY; 958 } 959 se401->fbuf = rvmalloc(se401->maxframesize * SE401_NUMFRAMES); ··· 962 else 963 err = -ENOMEM; 964 se401->user = !err; 965 + mutex_unlock(&se401->lock); 966 967 return err; 968 }
-4
drivers/media/video/stk-webcam.c
··· 27 #include <linux/kernel.h> 28 #include <linux/errno.h> 29 #include <linux/slab.h> 30 - #include <linux/smp_lock.h> 31 32 #include <linux/usb.h> 33 #include <linux/mm.h> ··· 672 vdev = video_devdata(fp); 673 dev = vdev_to_camera(vdev); 674 675 - lock_kernel(); 676 if (dev == NULL || !is_present(dev)) { 677 - unlock_kernel(); 678 return -ENXIO; 679 } 680 fp->private_data = dev; 681 usb_autopm_get_interface(dev->interface); 682 - unlock_kernel(); 683 684 return 0; 685 }
··· 27 #include <linux/kernel.h> 28 #include <linux/errno.h> 29 #include <linux/slab.h> 30 31 #include <linux/usb.h> 32 #include <linux/mm.h> ··· 673 vdev = video_devdata(fp); 674 dev = vdev_to_camera(vdev); 675 676 if (dev == NULL || !is_present(dev)) { 677 return -ENXIO; 678 } 679 fp->private_data = dev; 680 usb_autopm_get_interface(dev->interface); 681 682 return 0; 683 }
+4 -9
drivers/media/video/tlg2300/pd-main.c
··· 36 #include <linux/string.h> 37 #include <linux/types.h> 38 #include <linux/firmware.h> 39 - #include <linux/smp_lock.h> 40 41 #include "vendorcmds.h" 42 #include "pd-common.h" ··· 484 /*unregister v4l2 device */ 485 v4l2_device_unregister(&pd->v4l2_dev); 486 487 - lock_kernel(); 488 - { 489 - pd_dvb_usb_device_exit(pd); 490 - poseidon_fm_exit(pd); 491 492 - poseidon_audio_free(pd); 493 - pd_video_exit(pd); 494 - } 495 - unlock_kernel(); 496 497 usb_set_intfdata(interface, NULL); 498 kref_put(&pd->kref, poseidon_delete);
··· 36 #include <linux/string.h> 37 #include <linux/types.h> 38 #include <linux/firmware.h> 39 40 #include "vendorcmds.h" 41 #include "pd-common.h" ··· 485 /*unregister v4l2 device */ 486 v4l2_device_unregister(&pd->v4l2_dev); 487 488 + pd_dvb_usb_device_exit(pd); 489 + poseidon_fm_exit(pd); 490 491 + poseidon_audio_free(pd); 492 + pd_video_exit(pd); 493 494 usb_set_intfdata(interface, NULL); 495 kref_put(&pd->kref, poseidon_delete);
+14 -15
drivers/media/video/usbvideo/vicam.c
··· 43 #include <linux/vmalloc.h> 44 #include <linux/mm.h> 45 #include <linux/slab.h> 46 - #include <linux/smp_lock.h> 47 #include <linux/mutex.h> 48 #include <linux/firmware.h> 49 #include <linux/ihex.h> ··· 482 return -EINVAL; 483 } 484 485 - /* the videodev_lock held above us protects us from 486 - * simultaneous opens...for now. we probably shouldn't 487 - * rely on this fact forever. 488 */ 489 490 - lock_kernel(); 491 if (cam->open_count > 0) { 492 printk(KERN_INFO 493 "vicam_open called on already opened camera"); 494 - unlock_kernel(); 495 return -EBUSY; 496 } 497 498 cam->raw_image = kmalloc(VICAM_MAX_READ_SIZE, GFP_KERNEL); 499 if (!cam->raw_image) { 500 - unlock_kernel(); 501 return -ENOMEM; 502 } 503 504 cam->framebuf = rvmalloc(VICAM_MAX_FRAME_SIZE * VICAM_FRAMES); 505 if (!cam->framebuf) { 506 kfree(cam->raw_image); 507 - unlock_kernel(); 508 return -ENOMEM; 509 } 510 ··· 511 if (!cam->cntrlbuf) { 512 kfree(cam->raw_image); 513 rvfree(cam->framebuf, VICAM_MAX_FRAME_SIZE * VICAM_FRAMES); 514 - unlock_kernel(); 515 return -ENOMEM; 516 } 517 518 // First upload firmware, then turn the camera on 519 ··· 531 } 532 533 set_camera_power(cam, 1); 534 - 535 - cam->needsDummyRead = 1; 536 - cam->open_count++; 537 - 538 - file->private_data = cam; 539 - unlock_kernel(); 540 541 return 0; 542 }
··· 43 #include <linux/vmalloc.h> 44 #include <linux/mm.h> 45 #include <linux/slab.h> 46 #include <linux/mutex.h> 47 #include <linux/firmware.h> 48 #include <linux/ihex.h> ··· 483 return -EINVAL; 484 } 485 486 + /* cam_lock/open_count protects us from simultaneous opens 487 + * ... for now. we probably shouldn't rely on this fact forever. 488 */ 489 490 + mutex_lock(&cam->cam_lock); 491 if (cam->open_count > 0) { 492 printk(KERN_INFO 493 "vicam_open called on already opened camera"); 494 + mutex_unlock(&cam->cam_lock); 495 return -EBUSY; 496 } 497 498 cam->raw_image = kmalloc(VICAM_MAX_READ_SIZE, GFP_KERNEL); 499 if (!cam->raw_image) { 500 + mutex_unlock(&cam->cam_lock); 501 return -ENOMEM; 502 } 503 504 cam->framebuf = rvmalloc(VICAM_MAX_FRAME_SIZE * VICAM_FRAMES); 505 if (!cam->framebuf) { 506 kfree(cam->raw_image); 507 + mutex_unlock(&cam->cam_lock); 508 return -ENOMEM; 509 } 510 ··· 513 if (!cam->cntrlbuf) { 514 kfree(cam->raw_image); 515 rvfree(cam->framebuf, VICAM_MAX_FRAME_SIZE * VICAM_FRAMES); 516 + mutex_unlock(&cam->cam_lock); 517 return -ENOMEM; 518 } 519 + 520 + cam->needsDummyRead = 1; 521 + cam->open_count++; 522 + 523 + file->private_data = cam; 524 + mutex_unlock(&cam->cam_lock); 525 + 526 527 // First upload firmware, then turn the camera on 528 ··· 526 } 527 528 set_camera_power(cam, 1); 529 530 return 0; 531 }
+4 -3
drivers/media/video/v4l2-dev.c
··· 25 #include <linux/init.h> 26 #include <linux/kmod.h> 27 #include <linux/slab.h> 28 - #include <linux/smp_lock.h> 29 #include <asm/uaccess.h> 30 #include <asm/system.h> 31 ··· 246 mutex_unlock(vdev->lock); 247 } else if (vdev->fops->ioctl) { 248 /* TODO: convert all drivers to unlocked_ioctl */ 249 - lock_kernel(); 250 if (video_is_registered(vdev)) 251 ret = vdev->fops->ioctl(filp, cmd, arg); 252 - unlock_kernel(); 253 } else 254 ret = -ENOTTY; 255
··· 25 #include <linux/init.h> 26 #include <linux/kmod.h> 27 #include <linux/slab.h> 28 #include <asm/uaccess.h> 29 #include <asm/system.h> 30 ··· 247 mutex_unlock(vdev->lock); 248 } else if (vdev->fops->ioctl) { 249 /* TODO: convert all drivers to unlocked_ioctl */ 250 + static DEFINE_MUTEX(v4l2_ioctl_mutex); 251 + 252 + mutex_lock(&v4l2_ioctl_mutex); 253 if (video_is_registered(vdev)) 254 ret = vdev->fops->ioctl(filp, cmd, arg); 255 + mutex_unlock(&v4l2_ioctl_mutex); 256 } else 257 ret = -ENOTTY; 258
+1
drivers/media/video/zoran/zoran.h
··· 388 struct videocodec *vfe; /* video front end */ 389 390 struct mutex resource_lock; /* prevent evil stuff */ 391 392 u8 initialized; /* flag if zoran has been correctly initialized */ 393 int user; /* number of current users */
··· 388 struct videocodec *vfe; /* video front end */ 389 390 struct mutex resource_lock; /* prevent evil stuff */ 391 + struct mutex other_lock; /* please merge with above */ 392 393 u8 initialized; /* flag if zoran has been correctly initialized */ 394 int user; /* number of current users */
+1
drivers/media/video/zoran/zoran_card.c
··· 1227 snprintf(ZR_DEVNAME(zr), sizeof(ZR_DEVNAME(zr)), "MJPEG[%u]", zr->id); 1228 spin_lock_init(&zr->spinlock); 1229 mutex_init(&zr->resource_lock); 1230 if (pci_enable_device(pdev)) 1231 goto zr_unreg; 1232 pci_read_config_byte(zr->pci_dev, PCI_CLASS_REVISION, &zr->revision);
··· 1227 snprintf(ZR_DEVNAME(zr), sizeof(ZR_DEVNAME(zr)), "MJPEG[%u]", zr->id); 1228 spin_lock_init(&zr->spinlock); 1229 mutex_init(&zr->resource_lock); 1230 + mutex_init(&zr->other_lock); 1231 if (pci_enable_device(pdev)) 1232 goto zr_unreg; 1233 pci_read_config_byte(zr->pci_dev, PCI_CLASS_REVISION, &zr->revision);
+21 -6
drivers/media/video/zoran/zoran_driver.c
··· 49 #include <linux/module.h> 50 #include <linux/delay.h> 51 #include <linux/slab.h> 52 - #include <linux/smp_lock.h> 53 #include <linux/pci.h> 54 #include <linux/vmalloc.h> 55 #include <linux/wait.h> ··· 912 dprintk(2, KERN_INFO "%s: %s(%s, pid=[%d]), users(-)=%d\n", 913 ZR_DEVNAME(zr), __func__, current->comm, task_pid_nr(current), zr->user + 1); 914 915 - lock_kernel(); 916 917 if (zr->user >= 2048) { 918 dprintk(1, KERN_ERR "%s: too many users (%d) on device\n", ··· 962 file->private_data = fh; 963 fh->zr = zr; 964 zoran_open_init_session(fh); 965 - unlock_kernel(); 966 967 return 0; 968 969 fail_fh: 970 kfree(fh); 971 fail_unlock: 972 - unlock_kernel(); 973 974 dprintk(2, KERN_INFO "%s: open failed (%d), users(-)=%d\n", 975 ZR_DEVNAME(zr), res, zr->user); ··· 988 989 /* kernel locks (fs/device.c), so don't do that ourselves 990 * (prevents deadlocks) */ 991 - /*mutex_lock(&zr->resource_lock);*/ 992 993 zoran_close_end_session(fh); 994 ··· 1022 encoder_call(zr, video, s_routing, 2, 0, 0); 1023 } 1024 } 1025 1026 file->private_data = NULL; 1027 kfree(fh->overlay_mask); ··· 3370 #endif 3371 }; 3372 3373 static const struct v4l2_file_operations zoran_fops = { 3374 .owner = THIS_MODULE, 3375 .open = zoran_open, 3376 .release = zoran_close, 3377 - .ioctl = video_ioctl2, 3378 .read = zoran_read, 3379 .write = zoran_write, 3380 .mmap = zoran_mmap,
··· 49 #include <linux/module.h> 50 #include <linux/delay.h> 51 #include <linux/slab.h> 52 #include <linux/pci.h> 53 #include <linux/vmalloc.h> 54 #include <linux/wait.h> ··· 913 dprintk(2, KERN_INFO "%s: %s(%s, pid=[%d]), users(-)=%d\n", 914 ZR_DEVNAME(zr), __func__, current->comm, task_pid_nr(current), zr->user + 1); 915 916 + mutex_lock(&zr->other_lock); 917 918 if (zr->user >= 2048) { 919 dprintk(1, KERN_ERR "%s: too many users (%d) on device\n", ··· 963 file->private_data = fh; 964 fh->zr = zr; 965 zoran_open_init_session(fh); 966 + mutex_unlock(&zr->other_lock); 967 968 return 0; 969 970 fail_fh: 971 kfree(fh); 972 fail_unlock: 973 + mutex_unlock(&zr->other_lock); 974 975 dprintk(2, KERN_INFO "%s: open failed (%d), users(-)=%d\n", 976 ZR_DEVNAME(zr), res, zr->user); ··· 989 990 /* kernel locks (fs/device.c), so don't do that ourselves 991 * (prevents deadlocks) */ 992 + mutex_lock(&zr->other_lock); 993 994 zoran_close_end_session(fh); 995 ··· 1023 encoder_call(zr, video, s_routing, 2, 0, 0); 1024 } 1025 } 1026 + mutex_unlock(&zr->other_lock); 1027 1028 file->private_data = NULL; 1029 kfree(fh->overlay_mask); ··· 3370 #endif 3371 }; 3372 3373 + /* please use zr->resource_lock consistently and kill this wrapper */ 3374 + static long zoran_ioctl(struct file *file, unsigned int cmd, 3375 + unsigned long arg) 3376 + { 3377 + struct zoran_fh *fh = file->private_data; 3378 + struct zoran *zr = fh->zr; 3379 + int ret; 3380 + 3381 + mutex_lock(&zr->other_lock); 3382 + ret = video_ioctl2(file, cmd, arg); 3383 + mutex_unlock(&zr->other_lock); 3384 + 3385 + return ret; 3386 + } 3387 + 3388 static const struct v4l2_file_operations zoran_fops = { 3389 .owner = THIS_MODULE, 3390 .open = zoran_open, 3391 .release = zoran_close, 3392 + .unlocked_ioctl = zoran_ioctl, 3393 .read = zoran_read, 3394 .write = zoran_write, 3395 .mmap = zoran_mmap,