diff options
author | Hans Verkuil <hans.verkuil@cisco.com> | 2018-05-21 10:54:34 +0200 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab+samsung@kernel.org> | 2018-08-31 17:07:51 +0200 |
commit | cc6eddcd37ce6be403b5820ffd84cb84b33b653f (patch) | |
tree | eb462214042304f56bbea9cb34127618b051b5d4 /drivers/media/v4l2-core/v4l2-dev.c | |
parent | media: v4l2-device.h: add v4l2_device_supports_requests() helper (diff) | |
download | linux-cc6eddcd37ce6be403b5820ffd84cb84b33b653f.tar.xz linux-cc6eddcd37ce6be403b5820ffd84cb84b33b653f.zip |
media: v4l2-dev: lock req_queue_mutex
We need to serialize streamon/off with queueing new requests.
These ioctls may trigger the cancellation of a streaming
operation, and that should not be mixed with queuing a new
request at the same time.
Finally close() needs this lock since that too can trigger the
cancellation of a streaming operation.
We take the req_queue_mutex here before any other locks since
it is a very high-level lock.
Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com>
Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>
Reviewed-by: Mauro Carvalho Chehab <mchehab+samsung@kernel.org>
Signed-off-by: Mauro Carvalho Chehab <mchehab+samsung@kernel.org>
Diffstat (limited to 'drivers/media/v4l2-core/v4l2-dev.c')
-rw-r--r-- | drivers/media/v4l2-core/v4l2-dev.c | 18 |
1 files changed, 16 insertions, 2 deletions
diff --git a/drivers/media/v4l2-core/v4l2-dev.c b/drivers/media/v4l2-core/v4l2-dev.c index 69e775930fc4..feb749aaaa42 100644 --- a/drivers/media/v4l2-core/v4l2-dev.c +++ b/drivers/media/v4l2-core/v4l2-dev.c @@ -444,8 +444,22 @@ static int v4l2_release(struct inode *inode, struct file *filp) struct video_device *vdev = video_devdata(filp); int ret = 0; - if (vdev->fops->release) - ret = vdev->fops->release(filp); + /* + * We need to serialize the release() with queueing new requests. + * The release() may trigger the cancellation of a streaming + * operation, and that should not be mixed with queueing a new + * request at the same time. + */ + if (vdev->fops->release) { + if (v4l2_device_supports_requests(vdev->v4l2_dev)) { + mutex_lock(&vdev->v4l2_dev->mdev->req_queue_mutex); + ret = vdev->fops->release(filp); + mutex_unlock(&vdev->v4l2_dev->mdev->req_queue_mutex); + } else { + ret = vdev->fops->release(filp); + } + } + if (vdev->dev_debug & V4L2_DEV_DEBUG_FOP) dprintk("%s: release\n", video_device_node_name(vdev)); |