All of lore.kernel.org
 help / color / mirror / Atom feed
From: Alexandru Ardelean <alexandru.ardelean@analog.com>
To: <linux-kernel@vger.kernel.org>, <linux-iio@vger.kernel.org>
Cc: <lars@metafoo.de>, <Michael.Hennerich@analog.com>,
	<jic23@kernel.org>, <nuno.sa@analog.com>,
	<dragos.bogdan@analog.com>,
	Alexandru Ardelean <alexandru.ardelean@analog.com>
Subject: [PATCH v3 2/5] Documentation: iio: add doc for high-speed buffer API
Date: Mon, 15 Feb 2021 16:32:31 +0200	[thread overview]
Message-ID: <20210215143234.3248-3-alexandru.ardelean@analog.com> (raw)
In-Reply-To: <20210215143234.3248-1-alexandru.ardelean@analog.com>

This change takes the comment from the commit that introduces the IIO
high-speed buffer API, and formats it into rst format.

Signed-off-by: Alexandru Ardelean <alexandru.ardelean@analog.com>
---
 Documentation/iio/iio_high_speed_buffers.rst | 100 +++++++++++++++++++
 Documentation/iio/index.rst                  |   2 +
 include/uapi/linux/iio/buffer.h              |   5 +
 3 files changed, 107 insertions(+)
 create mode 100644 Documentation/iio/iio_high_speed_buffers.rst

diff --git a/Documentation/iio/iio_high_speed_buffers.rst b/Documentation/iio/iio_high_speed_buffers.rst
new file mode 100644
index 000000000000..f326e68efe49
--- /dev/null
+++ b/Documentation/iio/iio_high_speed_buffers.rst
@@ -0,0 +1,100 @@
+===================================
+Industrial IO High-Speed Buffer API
+===================================
+
+1. Overview
+===========
+
+Industrial IO supports access to buffers via an mmap interface. The
+advantage of the mmap based interface compared to the read() based
+interface is that it avoids an extra copy of the data between kernel and
+userspace. This is particular useful for high-speed devices which produce
+several megabytes or even gigabytes of data per second.
+
+The data for the mmap interface is managed at the granularity of so called
+blocks. A block is a contiguous region of memory (at the moment both
+physically and virtually contiguous). Reducing the granularity from byte
+level to block level is done to reduce the userspace-kernelspace
+synchronization overhead since performing syscalls for each byte at a
+data-rate of a few megabytes is not feasible.
+
+This of course leads to a slightly increased latency. For this reason an
+application can choose the size of the blocks as well as how many blocks it
+allocates. E.g. two blocks would be a traditional double buffering scheme.
+But using a higher number might be necessary to avoid underflow/overflow
+situations in the presence of scheduling latencies.
+
+A block can either be owned by kernel space or userspace. When owned by
+userspace it is safe to access the data in the block and process it. When
+owned by kernel space the block can be in one of 3 states:
+
+* It can be in the incoming queue where all blocks submitted from userspace
+  are placed and are waiting to be processed by the kernel driver.
+* It can be currently being processed by the kernel driver, this means it is
+  actively placing capturing data in it (usually using DMA).
+* Or it can be in the outgoing queue where all blocks that have been
+  processed by the kernel are placed. Userspace can dequeue the blocks as
+  necessary.
+
+2. Interface
+============
+
+As part of the interface 5 IOCTLs are used to manage the blocks and exchange
+them between userspace and kernelspace. The IOCTLs can be accessed through
+a open file descriptor to a IIO device.
+
+* **IIO_BUFFER_BLOCK_ALLOC_IOCTL(struct iio_buffer_block_alloc_req *)**:
+    Allocates new blocks. Can be called multiple times if necessary. A newly
+    allocated block is initially owned by userspace.
+
+* **IIO_BUFFER_BLOCK_FREE_IOCTL(void)**:
+   Frees all previously allocated blocks. If the backing memory of a block is
+   still in use by a kernel driver (i.e. active DMA transfer) it will be
+   freed once the kernel driver has released it.
+
+* **IIO_BUFFER_BLOCK_QUERY_IOCTL(struct iio_buffer_block *)**:
+   Queries information about a block. The id of the block about which
+   information is to be queried needs to be set by userspace.
+
+* **IIO_BUFFER_BLOCK_ENQUEUE_IOCTL(struct iio_buffer_block *)**:
+   Places a block on the incoming queue. This transfers ownership of the
+   block from userspace to kernelspace. Userspace must populate the id field
+   of the block to indicate which block to enqueue.
+
+* **IIO_BUFFER_BLOCK_DEQUEUE_IOCTL(struct iio_buffer_block *)**:
+   Removes the first block from the outgoing queue. This transfers ownership
+   of the block from kernelspace to userspace. Kernelspace will populate all
+   fields of the block. If the queue is empty and the file descriptor is set
+   to blocking the IOCTL will block until a new block is available on the
+   outgoing queue.
+
+3. Usage
+========
+
+To access the data stored in a block by userspace the block must be mapped
+to the process's memory. This is done by calling mmap() on the IIO device
+file descriptor. Each block has a unique offset assigned to it which should
+be passed to the mmap interface. E.g.
+
+  mmap(0, block.size, PROT_READ | PROT_WRITE, MAP_SHARED, fd,
+       block.offset);
+
+A typical workflow for the new interface is:
+
+  BLOCK_ALLOC
+
+  foreach block
+     BLOCK_QUERY block
+	 mmap block.data.offset
+	 BLOCK_ENQUEUE block
+
+  enable buffer
+
+  while !done
+	BLOCK_DEQUEUE block
+	process data
+	BLOCK_ENQUEUE block
+
+  disable buffer
+
+  BLOCK_FREE
diff --git a/Documentation/iio/index.rst b/Documentation/iio/index.rst
index 58b7a4ebac51..aaba78770b47 100644
--- a/Documentation/iio/index.rst
+++ b/Documentation/iio/index.rst
@@ -9,4 +9,6 @@ Industrial I/O
 
    iio_configfs
 
+   iio_high_speed_buffers
+
    ep93xx_adc
diff --git a/include/uapi/linux/iio/buffer.h b/include/uapi/linux/iio/buffer.h
index 8c1a2f27e5a2..d8c64210c9cc 100644
--- a/include/uapi/linux/iio/buffer.h
+++ b/include/uapi/linux/iio/buffer.h
@@ -5,6 +5,11 @@
 #ifndef _UAPI_IIO_BUFFER_H_
 #define _UAPI_IIO_BUFFER_H_
 
+/**
+ * See for more details:
+ *   Documentation/iio/iio_high_speed_buffers.rst
+ */
+
 /**
  * struct iio_buffer_block_alloc_req - Descriptor for allocating IIO buffer blocks
  * @type:	type of block(s) to allocate (currently unused, reserved)
-- 
2.17.1


  parent reply	other threads:[~2021-02-15 14:31 UTC|newest]

Thread overview: 9+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-02-15 14:32 [PATCH v3 0/5] iio: core: Add mmap interface infrastructure Alexandru Ardelean
2021-02-15 14:32 ` [PATCH v3 1/5] " Alexandru Ardelean
2021-02-15 14:32 ` Alexandru Ardelean [this message]
2021-02-15 14:32 ` [PATCH v3 3/5] iio: buffer-dma: split iio_dma_buffer_fileio_free() function Alexandru Ardelean
2021-02-15 14:32 ` [PATCH v3 4/5] iio: buffer-dma: Add mmap support Alexandru Ardelean
2021-02-15 14:32 ` [PATCH v3 5/5] tools: iio: add example for high-speed buffer support Alexandru Ardelean
2021-02-16 19:45   ` Jonathan Cameron
2021-02-16 20:00 ` [PATCH v3 0/5] iio: core: Add mmap interface infrastructure Jonathan Cameron
2021-02-17  7:18   ` Alexandru Ardelean

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20210215143234.3248-3-alexandru.ardelean@analog.com \
    --to=alexandru.ardelean@analog.com \
    --cc=Michael.Hennerich@analog.com \
    --cc=dragos.bogdan@analog.com \
    --cc=jic23@kernel.org \
    --cc=lars@metafoo.de \
    --cc=linux-iio@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=nuno.sa@analog.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.