cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

dmabuf.rst (6037B)


      1.. SPDX-License-Identifier: GFDL-1.1-no-invariants-or-later
      2.. c:namespace:: V4L
      3
      4.. _dmabuf:
      5
      6************************************
      7Streaming I/O (DMA buffer importing)
      8************************************
      9
     10The DMABUF framework provides a generic method for sharing buffers
     11between multiple devices. Device drivers that support DMABUF can export
     12a DMA buffer to userspace as a file descriptor (known as the exporter
     13role), import a DMA buffer from userspace using a file descriptor
     14previously exported for a different or the same device (known as the
     15importer role), or both. This section describes the DMABUF importer role
     16API in V4L2.
     17
     18Refer to :ref:`DMABUF exporting <VIDIOC_EXPBUF>` for details about
     19exporting V4L2 buffers as DMABUF file descriptors.
     20
     21Input and output devices support the streaming I/O method when the
     22``V4L2_CAP_STREAMING`` flag in the ``capabilities`` field of struct
     23:c:type:`v4l2_capability` returned by the
     24:ref:`VIDIOC_QUERYCAP <VIDIOC_QUERYCAP>` ioctl is set. Whether
     25importing DMA buffers through DMABUF file descriptors is supported is
     26determined by calling the :ref:`VIDIOC_REQBUFS <VIDIOC_REQBUFS>`
     27ioctl with the memory type set to ``V4L2_MEMORY_DMABUF``.
     28
     29This I/O method is dedicated to sharing DMA buffers between different
     30devices, which may be V4L devices or other video-related devices (e.g.
     31DRM). Buffers (planes) are allocated by a driver on behalf of an
     32application. Next, these buffers are exported to the application as file
     33descriptors using an API which is specific for an allocator driver. Only
     34such file descriptor are exchanged. The descriptors and meta-information
     35are passed in struct :c:type:`v4l2_buffer` (or in struct
     36:c:type:`v4l2_plane` in the multi-planar API case). The
     37driver must be switched into DMABUF I/O mode by calling the
     38:ref:`VIDIOC_REQBUFS <VIDIOC_REQBUFS>` with the desired buffer type.
     39
     40Example: Initiating streaming I/O with DMABUF file descriptors
     41==============================================================
     42
     43.. code-block:: c
     44
     45    struct v4l2_requestbuffers reqbuf;
     46
     47    memset(&reqbuf, 0, sizeof (reqbuf));
     48    reqbuf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
     49    reqbuf.memory = V4L2_MEMORY_DMABUF;
     50    reqbuf.count = 1;
     51
     52    if (ioctl(fd, VIDIOC_REQBUFS, &reqbuf) == -1) {
     53	if (errno == EINVAL)
     54	    printf("Video capturing or DMABUF streaming is not supported\\n");
     55	else
     56	    perror("VIDIOC_REQBUFS");
     57
     58	exit(EXIT_FAILURE);
     59    }
     60
     61The buffer (plane) file descriptor is passed on the fly with the
     62:ref:`VIDIOC_QBUF <VIDIOC_QBUF>` ioctl. In case of multiplanar
     63buffers, every plane can be associated with a different DMABUF
     64descriptor. Although buffers are commonly cycled, applications can pass
     65a different DMABUF descriptor at each :ref:`VIDIOC_QBUF <VIDIOC_QBUF>` call.
     66
     67Example: Queueing DMABUF using single plane API
     68===============================================
     69
     70.. code-block:: c
     71
     72    int buffer_queue(int v4lfd, int index, int dmafd)
     73    {
     74	struct v4l2_buffer buf;
     75
     76	memset(&buf, 0, sizeof buf);
     77	buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
     78	buf.memory = V4L2_MEMORY_DMABUF;
     79	buf.index = index;
     80	buf.m.fd = dmafd;
     81
     82	if (ioctl(v4lfd, VIDIOC_QBUF, &buf) == -1) {
     83	    perror("VIDIOC_QBUF");
     84	    return -1;
     85	}
     86
     87	return 0;
     88    }
     89
     90Example 3.6. Queueing DMABUF using multi plane API
     91==================================================
     92
     93.. code-block:: c
     94
     95    int buffer_queue_mp(int v4lfd, int index, int dmafd[], int n_planes)
     96    {
     97	struct v4l2_buffer buf;
     98	struct v4l2_plane planes[VIDEO_MAX_PLANES];
     99	int i;
    100
    101	memset(&buf, 0, sizeof buf);
    102	buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
    103	buf.memory = V4L2_MEMORY_DMABUF;
    104	buf.index = index;
    105	buf.m.planes = planes;
    106	buf.length = n_planes;
    107
    108	memset(&planes, 0, sizeof planes);
    109
    110	for (i = 0; i < n_planes; ++i)
    111	    buf.m.planes[i].m.fd = dmafd[i];
    112
    113	if (ioctl(v4lfd, VIDIOC_QBUF, &buf) == -1) {
    114	    perror("VIDIOC_QBUF");
    115	    return -1;
    116	}
    117
    118	return 0;
    119    }
    120
    121Captured or displayed buffers are dequeued with the
    122:ref:`VIDIOC_DQBUF <VIDIOC_QBUF>` ioctl. The driver can unlock the
    123buffer at any time between the completion of the DMA and this ioctl. The
    124memory is also unlocked when
    125:ref:`VIDIOC_STREAMOFF <VIDIOC_STREAMON>` is called,
    126:ref:`VIDIOC_REQBUFS <VIDIOC_REQBUFS>`, or when the device is closed.
    127
    128For capturing applications it is customary to enqueue a number of empty
    129buffers, to start capturing and enter the read loop. Here the
    130application waits until a filled buffer can be dequeued, and re-enqueues
    131the buffer when the data is no longer needed. Output applications fill
    132and enqueue buffers, when enough buffers are stacked up output is
    133started. In the write loop, when the application runs out of free
    134buffers it must wait until an empty buffer can be dequeued and reused.
    135Two methods exist to suspend execution of the application until one or
    136more buffers can be dequeued. By default :ref:`VIDIOC_DQBUF
    137<VIDIOC_QBUF>` blocks when no buffer is in the outgoing queue. When the
    138``O_NONBLOCK`` flag was given to the :c:func:`open()` function,
    139:ref:`VIDIOC_DQBUF <VIDIOC_QBUF>` returns immediately with an ``EAGAIN``
    140error code when no buffer is available. The
    141:c:func:`select()` and :c:func:`poll()`
    142functions are always available.
    143
    144To start and stop capturing or displaying applications call the
    145:ref:`VIDIOC_STREAMON <VIDIOC_STREAMON>` and
    146:ref:`VIDIOC_STREAMOFF <VIDIOC_STREAMON>` ioctls.
    147
    148.. note::
    149
    150   :ref:`VIDIOC_STREAMOFF <VIDIOC_STREAMON>` removes all buffers from
    151   both queues and unlocks all buffers as a side effect. Since there is no
    152   notion of doing anything "now" on a multitasking system, if an
    153   application needs to synchronize with another event it should examine
    154   the struct :c:type:`v4l2_buffer` ``timestamp`` of captured or
    155   outputted buffers.
    156
    157Drivers implementing DMABUF importing I/O must support the
    158:ref:`VIDIOC_REQBUFS <VIDIOC_REQBUFS>`, :ref:`VIDIOC_QBUF <VIDIOC_QBUF>`,
    159:ref:`VIDIOC_DQBUF <VIDIOC_QBUF>`, :ref:`VIDIOC_STREAMON
    160<VIDIOC_STREAMON>` and :ref:`VIDIOC_STREAMOFF <VIDIOC_STREAMON>` ioctls,
    161and the :c:func:`select()` and :c:func:`poll()`
    162functions.