diff options
author | Hans Verkuil <hverkuil@xs4all.nl> | 2008-07-26 14:01:24 +0200 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@infradead.org> | 2008-07-27 16:06:23 +0200 |
commit | 1052efe0fc69130d9d6a44bc9ceecd229221d9a1 (patch) | |
tree | 7e7f19cbbd3ff023e80eb7da5b68469085bdfe59 /drivers/media/video/saa7134/saa7134-empress.c | |
parent | V4L/DVB (8504): s2255drv: add missing header (diff) | |
download | linux-1052efe0fc69130d9d6a44bc9ceecd229221d9a1.tar.xz linux-1052efe0fc69130d9d6a44bc9ceecd229221d9a1.zip |
V4L/DVB (8505): saa7134-empress.c: fix deadlock
ts_release() locked a mutex that videobuf_stop() also tried to obtain.
But ts_release() shouldn't hold that mutex at all.
Make empress_users atomic as well to prevent possible race condition.
Signed-off-by: Hans Verkuil <hverkuil@xs4all.nl>
Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
Diffstat (limited to 'drivers/media/video/saa7134/saa7134-empress.c')
-rw-r--r-- | drivers/media/video/saa7134/saa7134-empress.c | 12 |
1 files changed, 4 insertions, 8 deletions
diff --git a/drivers/media/video/saa7134/saa7134-empress.c b/drivers/media/video/saa7134/saa7134-empress.c index 8b3f95167781..2ecfbd1b41fc 100644 --- a/drivers/media/video/saa7134/saa7134-empress.c +++ b/drivers/media/video/saa7134/saa7134-empress.c @@ -89,14 +89,14 @@ static int ts_open(struct inode *inode, struct file *file) err = -EBUSY; if (!mutex_trylock(&dev->empress_tsq.vb_lock)) goto done; - if (dev->empress_users) + if (atomic_read(&dev->empress_users)) goto done_up; /* Unmute audio */ saa_writeb(SAA7134_AUDIO_MUTE_CTRL, saa_readb(SAA7134_AUDIO_MUTE_CTRL) & ~(1 << 6)); - dev->empress_users++; + atomic_inc(&dev->empress_users); file->private_data = dev; err = 0; @@ -110,8 +110,6 @@ static int ts_release(struct inode *inode, struct file *file) { struct saa7134_dev *dev = file->private_data; - mutex_lock(&dev->empress_tsq.vb_lock); - videobuf_stop(&dev->empress_tsq); videobuf_mmap_free(&dev->empress_tsq); @@ -122,9 +120,7 @@ static int ts_release(struct inode *inode, struct file *file) saa_writeb(SAA7134_AUDIO_MUTE_CTRL, saa_readb(SAA7134_AUDIO_MUTE_CTRL) | (1 << 6)); - dev->empress_users--; - - mutex_unlock(&dev->empress_tsq.vb_lock); + atomic_dec(&dev->empress_users); return 0; } @@ -447,7 +443,7 @@ static void empress_signal_update(struct work_struct *work) ts_reset_encoder(dev); } else { dprintk("video signal acquired\n"); - if (dev->empress_users) + if (atomic_read(&dev->empress_users)) ts_init_encoder(dev); } } |