提交 1052efe0 编写于 作者: H Hans Verkuil 提交者: Mauro Carvalho Chehab

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: NHans Verkuil <hverkuil@xs4all.nl>
Signed-off-by: NMauro Carvalho Chehab <mchehab@infradead.org>
上级 feb75f07
......@@ -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);
}
}
......
......@@ -561,7 +561,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;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册