diff options
author | Laurent Pinchart <laurent.pinchart@ideasonboard.com> | 2015-02-16 12:38:28 -0500 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@osg.samsung.com> | 2015-04-02 16:29:28 -0400 |
commit | 9e68c53910721ffc55c05ee9bbc08129c796b470 (patch) | |
tree | b46ceedf3b73da8a2c9405ab6afb22e4bef4ed1a | |
parent | cfa967224382f8ac3adbb40117be776838b91ebc (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.c | 15 |
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 | ||
307 | int uvc_queue_mmap(struct uvc_video_queue *queue, struct vm_area_struct *vma) | 307 | int 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 |
319 | unsigned long uvc_queue_get_unmapped_area(struct uvc_video_queue *queue, | 313 | unsigned 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 | ||