aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLaurent Pinchart <laurent.pinchart@ideasonboard.com>2015-02-16 12:38:28 -0500
committerMauro Carvalho Chehab <mchehab@osg.samsung.com>2015-04-02 16:29:28 -0400
commit9e68c53910721ffc55c05ee9bbc08129c796b470 (patch)
treeb46ceedf3b73da8a2c9405ab6afb22e4bef4ed1a
parentcfa967224382f8ac3adbb40117be776838b91ebc (diff)
[media] uvcvideo: Don't call vb2 mmap and get_unmapped_area with queue lock held
videobuf2 has long been subject to AB-BA style deadlocks due to the queue lock and mmap_sem being taken in different orders for the mmap and get_unmapped_area operations. The problem has been fixed by making those two operations callable without taking the queue lock, using an mmap_lock internal to videobuf2. The uvcvideo driver still calls the mmap and get_unmapped_area operations with the queue lock held, resulting in a potential deadlock. As the operations can now be called without locking the queue, fix it. Reported-by: Bjørn Mork <bjorn@mork.no> Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Signed-off-by: Mauro Carvalho Chehab <mchehab@osg.samsung.com>
-rw-r--r--drivers/media/usb/uvc/uvc_queue.c15
1 files changed, 2 insertions, 13 deletions
diff --git a/drivers/media/usb/uvc/uvc_queue.c b/drivers/media/usb/uvc/uvc_queue.c
index 10c554e7655c..87a19f33e460 100644
--- a/drivers/media/usb/uvc/uvc_queue.c
+++ b/drivers/media/usb/uvc/uvc_queue.c
@@ -306,25 +306,14 @@ int uvc_queue_streamoff(struct uvc_video_queue *queue, enum v4l2_buf_type type)
306 306
307int uvc_queue_mmap(struct uvc_video_queue *queue, struct vm_area_struct *vma) 307int uvc_queue_mmap(struct uvc_video_queue *queue, struct vm_area_struct *vma)
308{ 308{
309 int ret; 309 return vb2_mmap(&queue->queue, vma);
310
311 mutex_lock(&queue->mutex);
312 ret = vb2_mmap(&queue->queue, vma);
313 mutex_unlock(&queue->mutex);
314
315 return ret;
316} 310}
317 311
318#ifndef CONFIG_MMU 312#ifndef CONFIG_MMU
319unsigned long uvc_queue_get_unmapped_area(struct uvc_video_queue *queue, 313unsigned long uvc_queue_get_unmapped_area(struct uvc_video_queue *queue,
320 unsigned long pgoff) 314 unsigned long pgoff)
321{ 315{
322 unsigned long ret; 316 return vb2_get_unmapped_area(&queue->queue, 0, 0, pgoff, 0);
323
324 mutex_lock(&queue->mutex);
325 ret = vb2_get_unmapped_area(&queue->queue, 0, 0, pgoff, 0);
326 mutex_unlock(&queue->mutex);
327 return ret;
328} 317}
329#endif 318#endif
330 319