linux/drivers/media/common
Hans Verkuil 6093d3002e media: vb2: keep a reference to the request until dqbuf
When vb2_buffer_done is called the buffer is unbound from the
request and put. The media_request_object_put also 'put's the
request reference. If the application has already closed the
request fd, then that means that the request reference at that
point goes to 0 and the whole request is released.

This means that the control handler associated with the request is
also freed and that causes this kernel oops:

[174705.995401] BUG: sleeping function called from invalid context at kernel/locking/mutex.c:908
[174705.995411] in_atomic(): 1, irqs_disabled(): 1, pid: 28071, name: vivid-000-vid-o
[174705.995416] 2 locks held by vivid-000-vid-o/28071:
[174705.995420]  #0: 000000001ea3a232 (&dev->mutex#3){....}, at: vivid_thread_vid_out+0x3f5/0x550 [vivid]
[174705.995447]  #1: 00000000e30a0d1e (&(&q->done_lock)->rlock){....}, at: vb2_buffer_done+0x92/0x1d0 [videobuf2_common]
[174705.995460] Preemption disabled at:
[174705.995461] [<0000000000000000>]           (null)
[174705.995472] CPU: 11 PID: 28071 Comm: vivid-000-vid-o Tainted: G        W         4.20.0-rc1-test-no #88
[174705.995476] Hardware name: VMware, Inc. VMware Virtual Platform/440BX Desktop Reference Platform, BIOS 6.00 05/19/2017
[174705.995481] Call Trace:
[174705.995500]  dump_stack+0x46/0x60
[174705.995512]  ___might_sleep.cold.79+0xe1/0xf1
[174705.995523]  __mutex_lock+0x50/0x8f0
[174705.995531]  ? find_held_lock+0x2d/0x90
[174705.995536]  ? find_held_lock+0x2d/0x90
[174705.995542]  ? find_held_lock+0x2d/0x90
[174705.995564]  ? v4l2_ctrl_handler_free.part.13+0x44/0x1d0 [videodev]
[174705.995576]  v4l2_ctrl_handler_free.part.13+0x44/0x1d0 [videodev]
[174705.995590]  v4l2_ctrl_request_release+0x1c/0x30 [videodev]
[174705.995600]  media_request_clean+0x64/0xe0 [media]
[174705.995609]  media_request_release+0x19/0x40 [media]
[174705.995617]  vb2_buffer_done+0xef/0x1d0 [videobuf2_common]
[174705.995630]  vivid_thread_vid_out+0x2c1/0x550 [vivid]
[174705.995645]  ? vivid_stop_generating_vid_cap+0x1c0/0x1c0 [vivid]
[174705.995653]  kthread+0x113/0x130
[174705.995659]  ? kthread_park+0x80/0x80
[174705.995667]  ret_from_fork+0x35/0x40

The vb2_buffer_done function can be called from interrupt context, so
anything that sleeps is not allowed.

The solution is to increment the request refcount when the buffer is
queued and decrement it when the buffer is dequeued. Releasing the
request is fine if that happens from VIDIOC_DQBUF.

Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
Acked-by: Sakari Ailus <sakari.ailus@linux.intel.com>
Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
Signed-off-by: Mauro Carvalho Chehab <mchehab+samsung@kernel.org>
2018-12-03 15:02:22 -05:00
..
b2c2 media: use strscpy() instead of strlcpy() 2018-09-11 13:32:17 -04:00
saa7146 media: replace strcpy() by strscpy() 2018-09-11 13:32:17 -04:00
siano media: rc: Remove init_ir_raw_event and DEFINE_IR_RAW_EVENT macros 2018-10-04 14:22:27 -04:00
v4l2-tpg media: v4l2-tpg: fix kernel oops when enabling HFLIP and OSD 2018-10-09 08:10:38 -04:00
videobuf2 media: vb2: keep a reference to the request until dqbuf 2018-12-03 15:02:22 -05:00
btcx-risc.h License cleanup: add SPDX GPL-2.0 license identifier to files with no license 2017-11-02 11:10:55 +01:00
cx2341x.c media: use strscpy() instead of strlcpy() 2018-09-11 13:32:17 -04:00
cypress_firmware.c media: drivers: improve a size determination 2017-09-23 08:20:57 -04:00
cypress_firmware.h License cleanup: add SPDX GPL-2.0 license identifier to files with no license 2017-11-02 11:10:55 +01:00
Kconfig media: drivers/media/common/videobuf2: rename from videobuf 2018-01-23 08:05:02 -05:00
Makefile media: drivers/media/common/videobuf2: rename from videobuf 2018-01-23 08:05:02 -05:00
tveeprom.c [media] tveeprom: get rid of unused arg on tveeprom_hauppauge_analog() 2017-03-03 07:35:02 -03:00