xref: /dpdk/doc/guides/dmadevs/idxd.rst (revision 4334b7b405500254b8a3ddb056f78c5b4745f1ef)
1..  SPDX-License-Identifier: BSD-3-Clause
2    Copyright(c) 2021 Intel Corporation.
3
4.. include:: <isonum.txt>
5
6IDXD DMA Device Driver
7======================
8
9The ``idxd`` dmadev driver provides a poll-mode driver (PMD) for Intel\ |reg|
10Data Streaming Accelerator `(Intel DSA)
11<https://software.intel.com/content/www/us/en/develop/articles/intel-data-streaming-accelerator-architecture-specification.html>`_.
12This PMD can be used in conjunction with Intel\ |reg| DSA devices to offload
13data operations, such as data copies, to hardware, freeing up CPU cycles for
14other tasks.
15
16Hardware Requirements
17----------------------
18
19The ``dpdk-devbind.py`` script, included with DPDK, can be used to show the
20presence of supported hardware. Running ``dpdk-devbind.py --status-dev dma``
21will show all the DMA devices on the system, including IDXD supported devices.
22Intel\ |reg| DSA devices, are currently (at time of writing) appearing
23as devices with type “0b25”, due to the absence of pci-id database entries for
24them at this point.
25
26Compilation
27------------
28
29For builds using ``meson`` and ``ninja``, the driver will be built when the
30target platform is x86-based. No additional compilation steps are necessary.
31
32Device Setup
33-------------
34
35Intel\ |reg| DSA devices can use the IDXD kernel driver or DPDK-supported drivers,
36such as ``vfio-pci``. Both are supported by the IDXD PMD.
37
38.. note::
39
40   To use Intel\ |reg| DSA devices in DPDK multi-process applications,
41   the devices should be bound to the vfio-pci driver.
42   Multi-process is not supported when using the kernel IDXD driver.
43
44Intel\ |reg| DSA devices using IDXD kernel driver
45~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
46
47To use an Intel\ |reg| DSA device bound to the IDXD kernel driver, the device must first be configured.
48The `accel-config <https://github.com/intel/idxd-config>`_ utility library can be used for configuration.
49
50.. note::
51        The device configuration can also be done by directly interacting with the sysfs nodes.
52        An example of how this may be done can be seen in the script ``dpdk_idxd_cfg.py``
53        included in the driver source directory.
54
55There are some mandatory configuration steps before being able to use a device with an application.
56The internal engines, which do the copies or other operations,
57and the work-queues, which are used by applications to assign work to the device,
58need to be assigned to groups, and the various other configuration options,
59such as priority or queue depth, need to be set for each queue.
60
61To assign an engine to a group::
62
63        $ accel-config config-engine dsa0/engine0.0 --group-id=0
64
65To assign work queues to groups for passing descriptors to the engines a similar accel-config command can be used.
66However, the work queues also need to be configured depending on the use case.
67Some configuration options include:
68
69* mode (Dedicated/Shared): Indicates whether a WQ may accept jobs from multiple queues simultaneously.
70* priority: WQ priority between 1 and 15. Larger value means higher priority.
71* wq-size: the size of the WQ. Sum of all WQ sizes must be less that the total-size defined by the device.
72* type: WQ type (kernel/mdev/user). Determines how the device is presented.
73* name: identifier given to the WQ.
74
75Example configuration for a work queue::
76
77        $ accel-config config-wq dsa0/wq0.0 --group-id=0 \
78           --mode=dedicated --priority=10 --wq-size=8 \
79           --max-batch-size=512 --type=user --name=dpdk_app1
80
81Once the devices have been configured, they need to be enabled::
82
83        $ accel-config enable-device dsa0
84        $ accel-config enable-wq dsa0/wq0.0
85
86Check the device configuration::
87
88        $ accel-config list
89
90Every Intel\ |reg| DSA instance supports multiple queues and each should be similarly configured.
91As a further example, the following set of commands will configure and enable 4 queues on instance 0,
92giving each an equal share of resources::
93
94        # configure 4 groups, each with one engine
95        accel-config config-engine dsa0/engine0.0 --group-id=0
96        accel-config config-engine dsa0/engine0.1 --group-id=1
97        accel-config config-engine dsa0/engine0.2 --group-id=2
98        accel-config config-engine dsa0/engine0.3 --group-id=3
99
100        # configure 4 queues, putting each in a different group, so each
101        # is backed by a single engine
102        accel-config config-wq dsa0/wq0.0 --group-id=0 --type=user --wq-size=32 \
103            --priority=10 --max-batch-size=1024 --mode=dedicated --name=dpdk_app1
104        accel-config config-wq dsa0/wq0.1 --group-id=1 --type=user --wq-size=32 \
105            --priority=10 --max-batch-size=1024 --mode=dedicated --name=dpdk_app1
106        accel-config config-wq dsa0/wq0.2 --group-id=2 --type=user --wq-size=32 \
107            --priority=10 --max-batch-size=1024 --mode=dedicated --name=dpdk_app1
108        accel-config config-wq dsa0/wq0.3 --group-id=3 --type=user --wq-size=32 \
109            --priority=10 --max-batch-size=1024 --mode=dedicated --name=dpdk_app1
110
111        # enable device and queues
112        accel-config enable-device dsa0
113        accel-config enable-wq dsa0/wq0.0 dsa0/wq0.1 dsa0/wq0.2 dsa0/wq0.3
114
115
116Devices using VFIO/UIO drivers
117~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
118
119The HW devices to be used will need to be bound to a user-space IO driver for use.
120The ``dpdk-devbind.py`` script can be used to view the state of the devices
121and to bind them to a suitable DPDK-supported driver, such as ``vfio-pci``.
122For example::
123
124	$ dpdk-devbind.py -b vfio-pci 6a:01.0
125
126.. note::
127
128   Since each individual queue on the HW device is its own separate dmadev instance,
129   the internal DMA device name includes the HW queue ID as a suffix on the PCI address.
130   The above device when used by a DPDK application will be accessible via dmadevs with names:
131   ``0000:6a:01.0-q0``, ``00006a:01.0-q1``, etc.
132
133Device Probing and Initialization
134~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
135
136For devices bound to a suitable DPDK-supported VFIO/UIO driver, the HW devices will
137be found as part of the device scan done at application initialization time without
138the need to pass parameters to the application.
139
140For Intel\ |reg| DSA devices, DPDK will automatically configure the device with the
141maximum number of workqueues available on it, partitioning all resources equally
142among the queues.
143If fewer workqueues are required, then the ``max_queues`` parameter may be passed to
144the device driver on the EAL commandline, via the ``allowlist`` or ``-a`` flag e.g.::
145
146	$ dpdk-test -a <b:d:f>,max_queues=4
147
148For devices bound to the IDXD kernel driver,
149the DPDK IDXD driver will automatically perform a scan for available workqueues
150to use. Any workqueues found listed in ``/dev/dsa`` on the system will be checked
151in ``/sys``, and any which have ``dpdk_`` prefix in their name will be automatically
152probed by the driver to make them available to the application.
153Alternatively, to support use by multiple DPDK processes simultaneously,
154the value used as the DPDK ``--file-prefix`` parameter may be used as a workqueue
155name prefix, instead of ``dpdk_``, allowing each DPDK application instance to only
156use a subset of configured queues.
157
158Additionally, the -a (allowlist) or -b (blocklist) commandline parameters
159are also available to further restrict the device list that will be used.
160If the -a option is used, then any device that passes the ``dpdk_``
161or ``--file-prefix`` prefix condition must also be present in the allow list.
162Similarly, when the block list is used,
163any device that passes the prefix condition must not be in the block list.
164For example, to only use ``wq0.3``, assuming the name prefix condition is met::
165
166	$ dpdk-test -a wq0.3
167
168Once probed successfully, irrespective of kernel driver, the device will appear as a ``dmadev``,
169that is a "DMA device type" inside DPDK, and can be accessed using APIs from the
170``rte_dmadev`` library.
171
172Using IDXD DMAdev Devices
173--------------------------
174
175To use the devices from an application, the dmadev API can be used.
176
177Device Configuration
178~~~~~~~~~~~~~~~~~~~~~
179
180IDXD configuration requirements:
181
182* ``ring_size`` must be a power of two, between 64 and 4096.
183* Only one ``vchan`` is supported per device (work queue).
184* IDXD devices do not support silent mode.
185* The transfer direction must be set to ``RTE_DMA_DIR_MEM_TO_MEM`` to copy from memory to memory.
186
187Once configured, the device can then be made ready for use by calling the
188``rte_dma_start()`` API.
189
190Performing Data Copies
191~~~~~~~~~~~~~~~~~~~~~~~
192
193Refer to the :ref:`Enqueue / Dequeue APIs <dmadev_enqueue_dequeue>` section of the dmadev library
194documentation for details on operation enqueue, submission and completion API usage.
195
196It is expected that, for efficiency reasons, a burst of operations will be enqueued to the
197device via multiple enqueue calls between calls to the ``rte_dma_submit()`` function.
198
199When gathering completions, ``rte_dma_completed()`` should be used, up until the point an error
200occurs in an operation. If an error was encountered, ``rte_dma_completed_status()`` must be used
201to kick the device off to continue processing operations and also to gather the status of each
202individual operations which is filled in to the ``status`` array provided as parameter by the
203application.
204
205The following status codes are supported by IDXD:
206
207* ``RTE_DMA_STATUS_SUCCESSFUL``: The operation was successful.
208* ``RTE_DMA_STATUS_INVALID_OPCODE``: The operation failed due to an invalid operation code.
209* ``RTE_DMA_STATUS_INVALID_LENGTH``: The operation failed due to an invalid data length.
210* ``RTE_DMA_STATUS_NOT_ATTEMPTED``: The operation was not attempted.
211* ``RTE_DMA_STATUS_ERROR_UNKNOWN``: The operation failed due to an unspecified error.
212
213The following code shows how to retrieve the number of successfully completed
214copies within a burst and then using ``rte_dma_completed_status()`` to check
215which operation failed and kick off the device to continue processing operations:
216
217.. code-block:: C
218
219   enum rte_dma_status_code status[COMP_BURST_SZ];
220   uint16_t count, idx, status_count;
221   bool error = 0;
222
223   count = rte_dma_completed(dev_id, vchan, COMP_BURST_SZ, &idx, &error);
224
225   if (error){
226      status_count = rte_dma_completed_status(dev_id, vchan, COMP_BURST_SZ, &idx, status);
227   }
228