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