Commit 4a77a836 authored by Hans Verkuil's avatar Hans Verkuil Committed by Mauro Carvalho Chehab

[media] v4l2-framework.txt: Update the locking documentation

This documents the new queue->lock and how to use it. It also removes the
documentation of v4l2_disable_ioctl_locking: this is only used in gspca and
will be removed once gspca has been converted to vb2.
Signed-off-by: default avatarHans Verkuil <hans.verkuil@cisco.com>
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab@redhat.com>
parent 387c71b2
......@@ -594,6 +594,15 @@ You should also set these fields:
unlocked_ioctl file operation is called this lock will be taken by the
core and released afterwards. See the next section for more details.
- queue: a pointer to the struct vb2_queue associated with this device node.
If queue is non-NULL, and queue->lock is non-NULL, then queue->lock is
used for the queuing ioctls (VIDIOC_REQBUFS, CREATE_BUFS, QBUF, DQBUF,
QUERYBUF, PREPARE_BUF, STREAMON and STREAMOFF) instead of the lock above.
That way the vb2 queuing framework does not have to wait for other ioctls.
This queue pointer is also used by the vb2 helper functions to check for
queuing ownership (i.e. is the filehandle calling it allowed to do the
operation).
- prio: keeps track of the priorities. Used to implement VIDIOC_G/S_PRIORITY.
If left to NULL, then it will use the struct v4l2_prio_state in v4l2_device.
If you want to have a separate priority state per (group of) device node(s),
......@@ -647,47 +656,43 @@ manually set the struct media_entity type and name fields.
A reference to the entity will be automatically acquired/released when the
video device is opened/closed.
v4l2_file_operations and locking
--------------------------------
You can set a pointer to a mutex_lock in struct video_device. Usually this
will be either a top-level mutex or a mutex per device node. By default this
lock will be used for unlocked_ioctl, but you can disable locking for
selected ioctls by calling:
void v4l2_disable_ioctl_locking(struct video_device *vdev, unsigned int cmd);
E.g.: v4l2_disable_ioctl_locking(vdev, VIDIOC_DQBUF);
ioctls and locking
------------------
You have to call this before you register the video_device.
The V4L core provides optional locking services. The main service is the
lock field in struct video_device, which is a pointer to a mutex. If you set
this pointer, then that will be used by unlocked_ioctl to serialize all ioctls.
Particularly with USB drivers where certain commands such as setting controls
can take a long time you may want to do your own locking for the buffer queuing
ioctls.
If you are using the videobuf2 framework, then there is a second lock that you
can set: video_device->queue->lock. If set, then this lock will be used instead
of video_device->lock to serialize all queuing ioctls (see the previous section
for the full list of those ioctls).
If you want still finer-grained locking then you have to set mutex_lock to NULL
and do you own locking completely.
The advantage of using a different lock for the queuing ioctls is that for some
drivers (particularly USB drivers) certain commands such as setting controls
can take a long time, so you want to use a separate lock for the buffer queuing
ioctls. That way your VIDIOC_DQBUF doesn't stall because the driver is busy
changing the e.g. exposure of the webcam.
It is up to the driver developer to decide which method to use. However, if
your driver has high-latency operations (for example, changing the exposure
of a USB webcam might take a long time), then you might be better off with
doing your own locking if you want to allow the user to do other things with
the device while waiting for the high-latency command to finish.
Of course, you can always do all the locking yourself by leaving both lock
pointers at NULL.
If a lock is specified then all ioctl commands will be serialized on that
lock. If you use videobuf then you must pass the same lock to the videobuf
queue initialize function: if videobuf has to wait for a frame to arrive, then
it will temporarily unlock the lock and relock it afterwards. If your driver
also waits in the code, then you should do the same to allow other processes
to access the device node while the first process is waiting for something.
If you use the old videobuf then you must pass the video_device lock to the
videobuf queue initialize function: if videobuf has to wait for a frame to
arrive, then it will temporarily unlock the lock and relock it afterwards. If
your driver also waits in the code, then you should do the same to allow other
processes to access the device node while the first process is waiting for
something.
In the case of videobuf2 you will need to implement the wait_prepare and
wait_finish callbacks to unlock/lock if applicable. In particular, if you use
the lock in struct video_device then you must unlock/lock this mutex in
wait_prepare and wait_finish.
The implementation of a hotplug disconnect should also take the lock before
calling v4l2_device_disconnect.
wait_finish callbacks to unlock/lock if applicable. If you use the queue->lock
pointer, then you can use the helper functions vb2_ops_wait_prepare/finish.
The implementation of a hotplug disconnect should also take the lock from
video_device before calling v4l2_device_disconnect. If you are also using
video_device->queue->lock, then you have to first lock video_device->queue->lock
followed by video_device->lock. That way you can be sure no ioctl is running
when you call v4l2_device_disconnect.
video_device registration
-------------------------
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment