diff options
author | Hans Verkuil <hverkuil@xs4all.nl> | 2008-07-26 14:01:24 +0200 |
---|---|---|
committer | Hans Verkuil <hverkuil@xs4all.nl> | 2008-07-26 14:01:24 +0200 |
commit | e791213b73718f65586a29d8cf7945fefd188429 (patch) | |
tree | a8d4c436f67b18c3e05ca65ceae8989a76c30cab | |
parent | ddb6d77848776ec7f6b3135f2dfa5fbc1544b003 (diff) | |
download | mediapointer-dvb-s2-e791213b73718f65586a29d8cf7945fefd188429.tar.gz mediapointer-dvb-s2-e791213b73718f65586a29d8cf7945fefd188429.tar.bz2 |
saa7134-empress.c: fix deadlock
From: Hans Verkuil <hverkuil@xs4all.nl>
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>
-rw-r--r-- | linux/drivers/media/video/saa7134/saa7134-empress.c | 12 | ||||
-rw-r--r-- | linux/drivers/media/video/saa7134/saa7134.h | 2 |
2 files changed, 5 insertions, 9 deletions
diff --git a/linux/drivers/media/video/saa7134/saa7134-empress.c b/linux/drivers/media/video/saa7134/saa7134-empress.c index 1d1c19680..d8f26ac84 100644 --- a/linux/drivers/media/video/saa7134/saa7134-empress.c +++ b/linux/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; } @@ -455,7 +451,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); } } diff --git a/linux/drivers/media/video/saa7134/saa7134.h b/linux/drivers/media/video/saa7134/saa7134.h index 053c358ff..9acb601c2 100644 --- a/linux/drivers/media/video/saa7134/saa7134.h +++ b/linux/drivers/media/video/saa7134/saa7134.h @@ -566,7 +566,7 @@ struct saa7134_dev { /* SAA7134_MPEG_EMPRESS only */ struct video_device *empress_dev; struct videobuf_queue empress_tsq; - unsigned int empress_users; + atomic_t empress_users; struct work_struct empress_workqueue; int empress_started; |