summaryrefslogtreecommitdiffstats
path: root/drivers/media/video/pwc/pwc-dec23.c
diff options
context:
space:
mode:
authorHans de Goede <hdegoede@redhat.com>2011-10-09 09:16:46 -0300
committerMauro Carvalho Chehab <mchehab@redhat.com>2012-01-06 10:44:17 -0200
commitc20d78cde37018caa0313469c9320424995cc489 (patch)
tree4b05a8e120a297db144b79bbcda8c409ee0a51bf /drivers/media/video/pwc/pwc-dec23.c
parentf4af65958a6ea987ff61504ad9f053f8ba8da674 (diff)
[media] pwc: Rework locking
While testing gtk-v4l's new ctrl event code, I hit the following deadlock in the pwc driver: Thread 1: -Does a VIDIOC_G_CTRL -video2_ioctl takes the modlock -video2_ioctl calls v4l2_g_ctrl -v4l2_g_ctrl takes the ctrl_handler lock -v4l2_g_ctrl calls pwc_g_volatile_ctrl -pwc_g_volatile_ctrl releases the modlock as the usb transfer can take a significant amount of time and we don't want to block DQBUF / QBUF too long Thread 2: -Does a VIDIOC_FOO_CTRL -video2_ioctl takes the modlock -video2_ioctl calls v4l2_foo_ctrl -v4l2_foo_ctrl blocks while trying to take the ctrl_handler lock Thread 1: -Blocks while trying to re-take the modlock, as its caller will eventually unlock that Now we have thread 1 waiting for the modlock while holding the ctrl_handler lock and thread 2 waiting for the ctrl_handler lock while holding the modlock -> deadlock. Conclusion: 1) We cannot unlock modlock from pwc_s_ctrl / pwc_g_volatile_ctrl, but this can cause QBUF / DQBUF to block for up to a full second 2) After evaluating various option I came to the conclusion that pwc should stop using the v4l2 core locking, and instead do its own locking Thus this patch stops pwc using the v4l2 core locking, and replaces that with it doing its own locking where necessary. Signed-off-by: Hans de Goede <hdegoede@redhat.com> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media/video/pwc/pwc-dec23.c')
-rw-r--r--drivers/media/video/pwc/pwc-dec23.c7
1 files changed, 7 insertions, 0 deletions
diff --git a/drivers/media/video/pwc/pwc-dec23.c b/drivers/media/video/pwc/pwc-dec23.c
index 06a4e877ba4..740bf6b9e8e 100644
--- a/drivers/media/video/pwc/pwc-dec23.c
+++ b/drivers/media/video/pwc/pwc-dec23.c
@@ -315,6 +315,8 @@ int pwc_dec23_init(struct pwc_device *pwc, int type, unsigned char *cmd)
}
pdec = pwc->decompress_data;
+ mutex_init(&pdec->lock);
+
if (DEVICE_USE_CODEC3(type)) {
flags = cmd[2] & 0x18;
if (flags == 8)
@@ -858,6 +860,9 @@ void pwc_dec23_decompress(const struct pwc_device *pwc,
int flags)
{
int bandlines_left, stride, bytes_per_block;
+ struct pwc_dec23_private *pdec = pwc->decompress_data;
+
+ mutex_lock(&pdec->lock);
bandlines_left = pwc->image.y / 4;
bytes_per_block = pwc->view.x * 4;
@@ -917,4 +922,6 @@ void pwc_dec23_decompress(const struct pwc_device *pwc,
}
}
+
+ mutex_unlock(&pdec->lock);
}