[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: Hans Verkuil <hans.verkuil@cisco.com> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
This commit is contained in:
parent
387c71b262
commit
4a77a8361f
|
@ -594,6 +594,15 @@ You should also set these fields:
|
||||||
unlocked_ioctl file operation is called this lock will be taken by the
|
unlocked_ioctl file operation is called this lock will be taken by the
|
||||||
core and released afterwards. See the next section for more details.
|
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.
|
- 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 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),
|
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
|
A reference to the entity will be automatically acquired/released when the
|
||||||
video device is opened/closed.
|
video device is opened/closed.
|
||||||
|
|
||||||
v4l2_file_operations and locking
|
ioctls and locking
|
||||||
--------------------------------
|
------------------
|
||||||
|
|
||||||
You can set a pointer to a mutex_lock in struct video_device. Usually this
|
The V4L core provides optional locking services. The main service is the
|
||||||
will be either a top-level mutex or a mutex per device node. By default this
|
lock field in struct video_device, which is a pointer to a mutex. If you set
|
||||||
lock will be used for unlocked_ioctl, but you can disable locking for
|
this pointer, then that will be used by unlocked_ioctl to serialize all ioctls.
|
||||||
selected ioctls by calling:
|
|
||||||
|
|
||||||
void v4l2_disable_ioctl_locking(struct video_device *vdev, unsigned int cmd);
|
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).
|
||||||
|
|
||||||
E.g.: v4l2_disable_ioctl_locking(vdev, VIDIOC_DQBUF);
|
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.
|
||||||
|
|
||||||
You have to call this before you register the video_device.
|
Of course, you can always do all the locking yourself by leaving both lock
|
||||||
|
pointers at NULL.
|
||||||
|
|
||||||
Particularly with USB drivers where certain commands such as setting controls
|
If you use the old videobuf then you must pass the video_device lock to the
|
||||||
can take a long time you may want to do your own locking for the buffer queuing
|
videobuf queue initialize function: if videobuf has to wait for a frame to
|
||||||
ioctls.
|
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
|
||||||
If you want still finer-grained locking then you have to set mutex_lock to NULL
|
processes to access the device node while the first process is waiting for
|
||||||
and do you own locking completely.
|
something.
|
||||||
|
|
||||||
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.
|
|
||||||
|
|
||||||
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.
|
|
||||||
|
|
||||||
In the case of videobuf2 you will need to implement the wait_prepare and
|
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
|
wait_finish callbacks to unlock/lock if applicable. If you use the queue->lock
|
||||||
the lock in struct video_device then you must unlock/lock this mutex in
|
pointer, then you can use the helper functions vb2_ops_wait_prepare/finish.
|
||||||
wait_prepare and wait_finish.
|
|
||||||
|
|
||||||
The implementation of a hotplug disconnect should also take the lock before
|
The implementation of a hotplug disconnect should also take the lock from
|
||||||
calling v4l2_device_disconnect.
|
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
|
video_device registration
|
||||||
-------------------------
|
-------------------------
|
||||||
|
|
Loading…
Reference in New Issue