Skip to content

Commit

Permalink
media: vb2: Allow reqbufs(0) with "in use" MMAP buffers
Browse files Browse the repository at this point in the history
Upstream commit d644cca

Videobuf2 presently does not allow VIDIOC_REQBUFS to destroy outstanding
buffers if the queue is of type V4L2_MEMORY_MMAP, and if the buffers are
considered "in use".  This is different behavior than for other memory
types and prevents us from deallocating buffers in following two cases:

1) There are outstanding mmap()ed views on the buffer. However even if
   we put the buffer in reqbufs(0), there will be remaining references,
   due to vma .open/close() adjusting vb2 buffer refcount appropriately.
   This means that the buffer will be in fact freed only when the last
   mmap()ed view is unmapped.

2) Buffer has been exported as a DMABUF. Refcount of the vb2 buffer
   is managed properly by VB2 DMABUF ops, i.e. incremented on DMABUF
   get and decremented on DMABUF release. This means that the buffer
   will be alive until all importers release it.

Considering both cases above, there does not seem to be any need to
prevent reqbufs(0) operation, because buffer lifetime is already
properly managed by both mmap() and DMABUF code paths. Let's remove it
and allow userspace freeing the queue (and potentially allocating a new
one) even though old buffers might be still in processing.

To let userspace know that the kernel now supports orphaning buffers
that are still in use, add a new V4L2_BUF_CAP_SUPPORTS_ORPHANED_BUFS
to be set by reqbufs and create_bufs.

[[email protected]: added V4L2_BUF_CAP_SUPPORTS_ORPHANED_BUFS,
 updated documentation, and added back debug message]

Signed-off-by: John Sheu <[email protected]>
Reviewed-by: Pawel Osciak <[email protected]>
Signed-off-by: Tomasz Figa <[email protected]>
Signed-off-by: Philipp Zabel <[email protected]>
Acked-by: Sakari Ailus <[email protected]>
Signed-off-by: Hans Verkuil <[email protected]>
[[email protected]: added V4L2-BUF-CAP-SUPPORTS-ORPHANED-BUFS ref]
Signed-off-by: Mauro Carvalho Chehab <[email protected]>
  • Loading branch information
John Sheu authored and popcornmix committed Jul 4, 2019
1 parent 20db870 commit 6e787b8
Show file tree
Hide file tree
Showing 4 changed files with 19 additions and 9 deletions.
17 changes: 14 additions & 3 deletions Documentation/media/uapi/v4l/vidioc-reqbufs.rst
Original file line number Diff line number Diff line change
Expand Up @@ -59,9 +59,14 @@ When the I/O method is not supported the ioctl returns an ``EINVAL`` error
code.
Applications can call :ref:`VIDIOC_REQBUFS` again to change the number of
buffers, however this cannot succeed when any buffers are still mapped.
A ``count`` value of zero frees all buffers, after aborting or finishing
any DMA in progress, an implicit
buffers. Note that if any buffers are still mapped or exported via DMABUF,
then :ref:`VIDIOC_REQBUFS` can only succeed if the
``V4L2_BUF_CAP_SUPPORTS_ORPHANED_BUFS`` capability is set. Otherwise
:ref:`VIDIOC_REQBUFS` will return the ``EBUSY`` error code.
If ``V4L2_BUF_CAP_SUPPORTS_ORPHANED_BUFS`` is set, then these buffers are
orphaned and will be freed when they are unmapped or when the exported DMABUF
fds are closed. A ``count`` value of zero frees or orphans all buffers, after
aborting or finishing any DMA in progress, an implicit
:ref:`VIDIOC_STREAMOFF <VIDIOC_STREAMON>`.
Expand Down Expand Up @@ -112,6 +117,7 @@ any DMA in progress, an implicit
.. _V4L2-BUF-CAP-SUPPORTS-USERPTR:
.. _V4L2-BUF-CAP-SUPPORTS-DMABUF:
.. _V4L2-BUF-CAP-SUPPORTS-REQUESTS:
.. _V4L2-BUF-CAP-SUPPORTS-ORPHANED-BUFS:
.. cssclass:: longtable
Expand All @@ -132,6 +138,11 @@ any DMA in progress, an implicit
* - ``V4L2_BUF_CAP_SUPPORTS_REQUESTS``
- 0x00000008
- This buffer type supports :ref:`requests <media-request-api>`.
* - ``V4L2_BUF_CAP_SUPPORTS_ORPHANED_BUFS``
- 0x00000010
- The kernel allows calling :ref:`VIDIOC_REQBUFS` while buffers are still
mapped or exported via DMABUF. These orphaned buffers will be freed
when they are unmapped or when the exported DMABUF fds are closed.
Return Value
============
Expand Down
8 changes: 3 additions & 5 deletions drivers/media/common/videobuf2/videobuf2-core.c
Original file line number Diff line number Diff line change
Expand Up @@ -680,11 +680,9 @@ int vb2_core_reqbufs(struct vb2_queue *q, enum vb2_memory memory,
* are not in use and can be freed.
*/
mutex_lock(&q->mmap_lock);
if (q->memory == VB2_MEMORY_MMAP && __buffers_in_use(q)) {
mutex_unlock(&q->mmap_lock);
dprintk(1, "memory in use, cannot free\n");
return -EBUSY;
}
if (debug && q->memory == VB2_MEMORY_MMAP &&
__buffers_in_use(q))
dprintk(1, "memory in use, orphaning buffers\n");

/*
* Call queue_cancel to clean up any buffers in the PREPARED or
Expand Down
2 changes: 1 addition & 1 deletion drivers/media/common/videobuf2/videobuf2-v4l2.c
Original file line number Diff line number Diff line change
Expand Up @@ -484,7 +484,7 @@ EXPORT_SYMBOL(vb2_querybuf);

static void fill_buf_caps(struct vb2_queue *q, u32 *caps)
{
*caps = 0;
*caps = V4L2_BUF_CAP_SUPPORTS_ORPHANED_BUFS;
if (q->io_modes & VB2_MMAP)
*caps |= V4L2_BUF_CAP_SUPPORTS_MMAP;
if (q->io_modes & VB2_USERPTR)
Expand Down
1 change: 1 addition & 0 deletions include/uapi/linux/videodev2.h
Original file line number Diff line number Diff line change
Expand Up @@ -881,6 +881,7 @@ struct v4l2_requestbuffers {
#define V4L2_BUF_CAP_SUPPORTS_USERPTR (1 << 1)
#define V4L2_BUF_CAP_SUPPORTS_DMABUF (1 << 2)
#define V4L2_BUF_CAP_SUPPORTS_REQUESTS (1 << 3)
#define V4L2_BUF_CAP_SUPPORTS_ORPHANED_BUFS (1 << 4)

/**
* struct v4l2_plane - plane info for multi-planar buffers
Expand Down

0 comments on commit 6e787b8

Please sign in to comment.