xref: /dpdk/doc/guides/prog_guide/compressdev.rst (revision a584d3bea902cf52a7d07b8a5a6cd1318dfcf88b)
1*a584d3beSAshish Gupta..  SPDX-License-Identifier: BSD-3-Clause
2*a584d3beSAshish Gupta    Copyright(c) 2017-2018 Cavium Networks.
3*a584d3beSAshish Gupta
4*a584d3beSAshish GuptaCompression Device Library
5*a584d3beSAshish Gupta===========================
6*a584d3beSAshish Gupta
7*a584d3beSAshish GuptaThe compression framework provides a generic set of APIs to perform compression services
8*a584d3beSAshish Guptaas well as to query and configure compression devices both physical(hardware) and virtual(software)
9*a584d3beSAshish Guptato perform those services. The framework currently only supports lossless compression schemes:
10*a584d3beSAshish GuptaDeflate and LZS.
11*a584d3beSAshish Gupta
12*a584d3beSAshish GuptaDevice Management
13*a584d3beSAshish Gupta-----------------
14*a584d3beSAshish Gupta
15*a584d3beSAshish GuptaDevice Creation
16*a584d3beSAshish Gupta~~~~~~~~~~~~~~~
17*a584d3beSAshish Gupta
18*a584d3beSAshish GuptaPhysical compression devices are discovered during the bus probe of the EAL function
19*a584d3beSAshish Guptawhich is executed at DPDK initialization, based on their unique device identifier.
20*a584d3beSAshish GuptaFor eg. PCI devices can be identified using PCI BDF (bus/bridge, device, function).
21*a584d3beSAshish GuptaSpecific physical compression devices, like other physical devices in DPDK can be
22*a584d3beSAshish Guptawhite-listed or black-listed using the EAL command line options.
23*a584d3beSAshish Gupta
24*a584d3beSAshish GuptaVirtual devices can be created by two mechanisms, either using the EAL command
25*a584d3beSAshish Guptaline options or from within the application using an EAL API directly.
26*a584d3beSAshish Gupta
27*a584d3beSAshish GuptaFrom the command line using the --vdev EAL option
28*a584d3beSAshish Gupta
29*a584d3beSAshish Gupta.. code-block:: console
30*a584d3beSAshish Gupta
31*a584d3beSAshish Gupta   --vdev  '<pmd name>,socket_id=0'
32*a584d3beSAshish Gupta
33*a584d3beSAshish Gupta.. Note::
34*a584d3beSAshish Gupta
35*a584d3beSAshish Gupta   * If DPDK application requires multiple software compression PMD devices then required
36*a584d3beSAshish Gupta     number of ``--vdev`` with appropriate libraries are to be added.
37*a584d3beSAshish Gupta
38*a584d3beSAshish Gupta   * An Application with multiple compression device instances exposed by the same PMD must
39*a584d3beSAshish Gupta     specify a unique name for each device.
40*a584d3beSAshish Gupta
41*a584d3beSAshish Gupta   Example: ``--vdev  'pmd0' --vdev  'pmd1'``
42*a584d3beSAshish Gupta
43*a584d3beSAshish GuptaOr, by using the rte_vdev_init API within the application code.
44*a584d3beSAshish Gupta
45*a584d3beSAshish Gupta.. code-block:: c
46*a584d3beSAshish Gupta
47*a584d3beSAshish Gupta   rte_vdev_init("<pmd_name>","socket_id=0")
48*a584d3beSAshish Gupta
49*a584d3beSAshish GuptaAll virtual compression devices support the following initialization parameters:
50*a584d3beSAshish Gupta
51*a584d3beSAshish Gupta* ``socket_id`` - socket on which to allocate the device resources on.
52*a584d3beSAshish Gupta
53*a584d3beSAshish GuptaDevice Identification
54*a584d3beSAshish Gupta~~~~~~~~~~~~~~~~~~~~~
55*a584d3beSAshish Gupta
56*a584d3beSAshish GuptaEach device, whether virtual or physical is uniquely designated by two
57*a584d3beSAshish Guptaidentifiers:
58*a584d3beSAshish Gupta
59*a584d3beSAshish Gupta- A unique device index used to designate the compression device in all functions
60*a584d3beSAshish Gupta  exported by the compressdev API.
61*a584d3beSAshish Gupta
62*a584d3beSAshish Gupta- A device name used to designate the compression device in console messages, for
63*a584d3beSAshish Gupta  administration or debugging purposes.
64*a584d3beSAshish Gupta
65*a584d3beSAshish GuptaDevice Configuration
66*a584d3beSAshish Gupta~~~~~~~~~~~~~~~~~~~~
67*a584d3beSAshish Gupta
68*a584d3beSAshish GuptaThe configuration of each compression device includes the following operations:
69*a584d3beSAshish Gupta
70*a584d3beSAshish Gupta- Allocation of resources, including hardware resources if a physical device.
71*a584d3beSAshish Gupta- Resetting the device into a well-known default state.
72*a584d3beSAshish Gupta- Initialization of statistics counters.
73*a584d3beSAshish Gupta
74*a584d3beSAshish GuptaThe ``rte_compressdev_configure`` API is used to configure a compression device.
75*a584d3beSAshish Gupta
76*a584d3beSAshish GuptaThe ``rte_compressdev_config`` structure is used to pass the configuration
77*a584d3beSAshish Guptaparameters.
78*a584d3beSAshish Gupta
79*a584d3beSAshish GuptaSee *DPDK API Reference* for details.
80*a584d3beSAshish Gupta
81*a584d3beSAshish GuptaConfiguration of Queue Pairs
82*a584d3beSAshish Gupta~~~~~~~~~~~~~~~~~~~~~~~~~~~~
83*a584d3beSAshish Gupta
84*a584d3beSAshish GuptaEach compression device queue pair is individually configured through the
85*a584d3beSAshish Gupta``rte_compressdev_queue_pair_setup`` API.
86*a584d3beSAshish Gupta
87*a584d3beSAshish GuptaThe ``max_inflight_ops`` is used to pass maximum number of
88*a584d3beSAshish Guptarte_comp_op that could be present in a queue at-a-time.
89*a584d3beSAshish GuptaPMD then can allocate resources accordingly on a specified socket.
90*a584d3beSAshish Gupta
91*a584d3beSAshish GuptaSee *DPDK API Reference* for details.
92*a584d3beSAshish Gupta
93*a584d3beSAshish GuptaLogical Cores, Memory and Queues Pair Relationships
94*a584d3beSAshish Gupta~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
95*a584d3beSAshish Gupta
96*a584d3beSAshish GuptaLibrary supports NUMA similarly as described in Cryptodev library section.
97*a584d3beSAshish Gupta
98*a584d3beSAshish GuptaA queue pair cannot be shared and should be exclusively used by a single processing
99*a584d3beSAshish Guptacontext for enqueuing operations or dequeuing operations on the same compression device
100*a584d3beSAshish Guptasince sharing would require global locks and hinder performance. It is however possible
101*a584d3beSAshish Guptato use a different logical core to dequeue an operation on a queue pair from the logical
102*a584d3beSAshish Guptacore on which it was enqueued. This means that a compression burst enqueue/dequeue
103*a584d3beSAshish GuptaAPIs are a logical place to transition from one logical core to another in a
104*a584d3beSAshish Guptadata processing pipeline.
105*a584d3beSAshish Gupta
106*a584d3beSAshish GuptaDevice Features and Capabilities
107*a584d3beSAshish Gupta---------------------------------
108*a584d3beSAshish Gupta
109*a584d3beSAshish GuptaCompression devices define their functionality through two mechanisms, global device
110*a584d3beSAshish Guptafeatures and algorithm features. Global devices features identify device
111*a584d3beSAshish Guptawide level features which are applicable to the whole device such as supported hardware
112*a584d3beSAshish Guptaacceleration and CPU features. List of compression device features can be seen in the
113*a584d3beSAshish GuptaRTE_COMPDEV_FF_XXX macros.
114*a584d3beSAshish Gupta
115*a584d3beSAshish GuptaThe algorithm features lists individual algo feature which device supports per-algorithm,
116*a584d3beSAshish Guptasuch as a stateful compression/decompression, checksums operation etc. List of algorithm
117*a584d3beSAshish Guptafeatures can be seen in the RTE_COMP_FF_XXX macros.
118*a584d3beSAshish Gupta
119*a584d3beSAshish GuptaCapabilities
120*a584d3beSAshish Gupta~~~~~~~~~~~~
121*a584d3beSAshish GuptaEach PMD has a list of capabilities, including algorithms listed in
122*a584d3beSAshish Guptaenum ``rte_comp_algorithm`` and its associated feature flag and
123*a584d3beSAshish Guptasliding window range in log base 2 value. Sliding window tells
124*a584d3beSAshish Guptathe minimum and maximum size of lookup window that algorithm uses
125*a584d3beSAshish Guptato find duplicates.
126*a584d3beSAshish Gupta
127*a584d3beSAshish GuptaSee *DPDK API Reference* for details.
128*a584d3beSAshish Gupta
129*a584d3beSAshish GuptaEach Compression poll mode driver defines its array of capabilities
130*a584d3beSAshish Guptafor each algorithm it supports. See PMD implementation for capability
131*a584d3beSAshish Guptainitialization.
132*a584d3beSAshish Gupta
133*a584d3beSAshish GuptaCapabilities Discovery
134*a584d3beSAshish Gupta~~~~~~~~~~~~~~~~~~~~~~
135*a584d3beSAshish Gupta
136*a584d3beSAshish GuptaPMD capability and features are discovered via ``rte_compressdev_info_get`` function.
137*a584d3beSAshish Gupta
138*a584d3beSAshish GuptaThe ``rte_compressdev_info`` structure contains all the relevant information for the device.
139*a584d3beSAshish Gupta
140*a584d3beSAshish GuptaSee *DPDK API Reference* for details.
141*a584d3beSAshish Gupta
142*a584d3beSAshish GuptaCompression Operation
143*a584d3beSAshish Gupta----------------------
144*a584d3beSAshish Gupta
145*a584d3beSAshish GuptaDPDK compression supports two types of compression methodologies:
146*a584d3beSAshish Gupta
147*a584d3beSAshish Gupta- Stateless, data associated to a compression operation is compressed without any reference
148*a584d3beSAshish Gupta  to another compression operation.
149*a584d3beSAshish Gupta
150*a584d3beSAshish Gupta- Stateful, data in each compression operation is compressed with reference to previous compression
151*a584d3beSAshish Gupta  operations in the same data stream i.e. history of data is maintained between the operations.
152*a584d3beSAshish Gupta
153*a584d3beSAshish GuptaFor more explanation, please refer RFC https://www.ietf.org/rfc/rfc1951.txt
154*a584d3beSAshish Gupta
155*a584d3beSAshish GuptaOperation Representation
156*a584d3beSAshish Gupta~~~~~~~~~~~~~~~~~~~~~~~~
157*a584d3beSAshish Gupta
158*a584d3beSAshish GuptaCompression operation is described via ``struct rte_comp_op``, which contains both input and
159*a584d3beSAshish Guptaoutput data. The operation structure includes the operation type (stateless or stateful),
160*a584d3beSAshish Guptathe operation status and the priv_xform/stream handle, source, destination and checksum buffer
161*a584d3beSAshish Guptapointers. It also contains the source mempool from which the operation is allocated.
162*a584d3beSAshish GuptaPMD updates consumed field with amount of data read from source buffer and produced
163*a584d3beSAshish Guptafield with amount of data of written into destination buffer along with status of
164*a584d3beSAshish Guptaoperation. See section *Produced, Consumed And Operation Status* for more details.
165*a584d3beSAshish Gupta
166*a584d3beSAshish GuptaCompression operations mempool also has an ability to allocate private memory with the
167*a584d3beSAshish Guptaoperation for application's purposes. Application software is responsible for specifying
168*a584d3beSAshish Guptaall the operation specific fields in the ``rte_comp_op`` structure which are then used
169*a584d3beSAshish Guptaby the compression PMD to process the requested operation.
170*a584d3beSAshish Gupta
171*a584d3beSAshish Gupta
172*a584d3beSAshish GuptaOperation Management and Allocation
173*a584d3beSAshish Gupta~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
174*a584d3beSAshish Gupta
175*a584d3beSAshish GuptaThe compressdev library provides an API set for managing compression operations which
176*a584d3beSAshish Guptautilize the Mempool Library to allocate operation buffers. Therefore, it ensures
177*a584d3beSAshish Guptathat the compression operation is interleaved optimally across the channels and
178*a584d3beSAshish Guptaranks for optimal processing.
179*a584d3beSAshish Gupta
180*a584d3beSAshish GuptaA ``rte_comp_op`` contains a field indicating the pool it originated from.
181*a584d3beSAshish Gupta
182*a584d3beSAshish Gupta``rte_comp_op_alloc()`` and ``rte_comp_op_bulk_alloc()`` are used to allocate
183*a584d3beSAshish Guptacompression operations from a given compression operation mempool.
184*a584d3beSAshish GuptaThe operation gets reset before being returned to a user so that operation
185*a584d3beSAshish Guptais always in a good known state before use by the application.
186*a584d3beSAshish Gupta
187*a584d3beSAshish Gupta``rte_comp_op_free()`` is called by the application to return an operation to
188*a584d3beSAshish Guptaits allocating pool.
189*a584d3beSAshish Gupta
190*a584d3beSAshish GuptaSee *DPDK API Reference* for details.
191*a584d3beSAshish Gupta
192*a584d3beSAshish GuptaPassing source data as mbuf-chain
193*a584d3beSAshish Gupta~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
194*a584d3beSAshish GuptaIf input data is scattered across several different buffers, then
195*a584d3beSAshish GuptaApplication can either parse through all such buffers and make one
196*a584d3beSAshish Guptambuf-chain and enqueue it for processing or, alternatively, it can
197*a584d3beSAshish Guptamake multiple sequential enqueue_burst() calls for each of them
198*a584d3beSAshish Guptaprocessing them statefully. See *Compression API Stateful Operation*
199*a584d3beSAshish Guptafor stateful processing of ops.
200*a584d3beSAshish Gupta
201*a584d3beSAshish GuptaOperation Status
202*a584d3beSAshish Gupta~~~~~~~~~~~~~~~~
203*a584d3beSAshish GuptaEach operation carries a status information updated by PMD after it is processed.
204*a584d3beSAshish Guptafollowing are currently supported status:
205*a584d3beSAshish Gupta
206*a584d3beSAshish Gupta- RTE_COMP_OP_STATUS_SUCCESS,
207*a584d3beSAshish Gupta    Operation is successfully completed
208*a584d3beSAshish Gupta
209*a584d3beSAshish Gupta- RTE_COMP_OP_STATUS_NOT_PROCESSED,
210*a584d3beSAshish Gupta    Operation has not yet been processed by the device
211*a584d3beSAshish Gupta
212*a584d3beSAshish Gupta- RTE_COMP_OP_STATUS_INVALID_ARGS,
213*a584d3beSAshish Gupta    Operation failed due to invalid arguments in request
214*a584d3beSAshish Gupta
215*a584d3beSAshish Gupta- RTE_COMP_OP_STATUS_ERROR,
216*a584d3beSAshish Gupta    Operation failed because of internal error
217*a584d3beSAshish Gupta
218*a584d3beSAshish Gupta- RTE_COMP_OP_STATUS_INVALID_STATE,
219*a584d3beSAshish Gupta    Operation is invoked in invalid state
220*a584d3beSAshish Gupta
221*a584d3beSAshish Gupta- RTE_COMP_OP_STATUS_OUT_OF_SPACE_TERMINATED,
222*a584d3beSAshish Gupta    Output buffer ran out of space during processing. Error case,
223*a584d3beSAshish Gupta    PMD cannot continue from here.
224*a584d3beSAshish Gupta
225*a584d3beSAshish Gupta- RTE_COMP_OP_STATUS_OUT_OF_SPACE_RECOVERABLE,
226*a584d3beSAshish Gupta    Output buffer ran out of space before operation completed, but this
227*a584d3beSAshish Gupta    is not an error case. Output data up to op.produced can be used and
228*a584d3beSAshish Gupta    next op in the stream should continue on from op.consumed+1.
229*a584d3beSAshish Gupta
230*a584d3beSAshish GuptaProduced, Consumed And Operation Status
231*a584d3beSAshish Gupta~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
232*a584d3beSAshish Gupta
233*a584d3beSAshish Gupta- If status is RTE_COMP_OP_STATUS_SUCCESS,
234*a584d3beSAshish Gupta    consumed = amount of data read from input buffer, and
235*a584d3beSAshish Gupta    produced = amount of data written in destination buffer
236*a584d3beSAshish Gupta- If status is RTE_COMP_OP_STATUS_FAILURE,
237*a584d3beSAshish Gupta    consumed = produced = 0 or undefined
238*a584d3beSAshish Gupta- If status is RTE_COMP_OP_STATUS_OUT_OF_SPACE_TERMINATED,
239*a584d3beSAshish Gupta    consumed = 0 and
240*a584d3beSAshish Gupta    produced = usually 0, but in decompression cases a PMD may return > 0
241*a584d3beSAshish Gupta    i.e. amount of data successfully produced until out of space condition
242*a584d3beSAshish Gupta    hit. Application can consume output data in this case, if required.
243*a584d3beSAshish Gupta- If status is RTE_COMP_OP_STATUS_OUT_OF_SPACE_RECOVERABLE,
244*a584d3beSAshish Gupta    consumed = amount of data read, and
245*a584d3beSAshish Gupta    produced = amount of data successfully produced until
246*a584d3beSAshish Gupta    out of space condition hit. PMD has ability to recover
247*a584d3beSAshish Gupta    from here, so application can submit next op from
248*a584d3beSAshish Gupta    consumed+1 and a destination buffer with available space.
249*a584d3beSAshish Gupta
250*a584d3beSAshish GuptaTransforms
251*a584d3beSAshish Gupta----------
252*a584d3beSAshish Gupta
253*a584d3beSAshish GuptaCompression transforms (``rte_comp_xform``) are the mechanism
254*a584d3beSAshish Guptato specify the details of the compression operation such as algorithm,
255*a584d3beSAshish Guptawindow size and checksum.
256*a584d3beSAshish Gupta
257*a584d3beSAshish GuptaCompression API Hash support
258*a584d3beSAshish Gupta----------------------------
259*a584d3beSAshish Gupta
260*a584d3beSAshish GuptaCompression API allows application to enable digest calculation
261*a584d3beSAshish Guptaalongside compression and decompression of data. A PMD reflects its
262*a584d3beSAshish Guptasupport for hash algorithms via capability algo feature flags.
263*a584d3beSAshish GuptaIf supported, PMD calculates digest always on plaintext i.e.
264*a584d3beSAshish Guptabefore compression and after decompression.
265*a584d3beSAshish Gupta
266*a584d3beSAshish GuptaCurrently supported list of hash algos are SHA-1 and SHA2 family
267*a584d3beSAshish GuptaSHA256.
268*a584d3beSAshish Gupta
269*a584d3beSAshish GuptaSee *DPDK API Reference* for details.
270*a584d3beSAshish Gupta
271*a584d3beSAshish GuptaIf required, application should set valid hash algo in compress
272*a584d3beSAshish Guptaor decompress xforms during ``rte_compressdev_stream_create()``
273*a584d3beSAshish Guptaor ``rte_compressdev_private_xform_create()`` and pass a valid
274*a584d3beSAshish Guptaoutput buffer in ``rte_comp_op`` hash field struct to store the
275*a584d3beSAshish Guptaresulting digest. Buffer passed should be contiguous and large
276*a584d3beSAshish Guptaenough to store digest which is 20 bytes for SHA-1 and
277*a584d3beSAshish Gupta32 bytes for SHA2-256.
278*a584d3beSAshish Gupta
279*a584d3beSAshish GuptaCompression API Stateless operation
280*a584d3beSAshish Gupta------------------------------------
281*a584d3beSAshish Gupta
282*a584d3beSAshish GuptaAn op is processed stateless if it has
283*a584d3beSAshish Gupta- op_type set to RTE_COMP_OP_STATELESS
284*a584d3beSAshish Gupta- flush value set to RTE_FLUSH_FULL or RTE_FLUSH_FINAL
285*a584d3beSAshish Gupta(required only on compression side),
286*a584d3beSAshish Gupta- All required input in source buffer
287*a584d3beSAshish Gupta
288*a584d3beSAshish GuptaWhen all of the above conditions are met, PMD initiates stateless processing
289*a584d3beSAshish Guptaand releases acquired resources after processing of current operation is
290*a584d3beSAshish Guptacomplete. Application can enqueue multiple stateless ops in a single burst
291*a584d3beSAshish Guptaand must attach priv_xform handle to such ops.
292*a584d3beSAshish Gupta
293*a584d3beSAshish Guptapriv_xform in Stateless operation
294*a584d3beSAshish Gupta~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
295*a584d3beSAshish Gupta
296*a584d3beSAshish Guptapriv_xform is PMD internally managed private data that it maintains to do stateless processing.
297*a584d3beSAshish Guptapriv_xforms are initialized provided a generic xform structure by an application via making call
298*a584d3beSAshish Guptato ``rte_comp_private_xform_create``, at an output PMD returns an opaque priv_xform reference.
299*a584d3beSAshish GuptaIf PMD support SHAREABLE priv_xform indicated via algorithm feature flag, then application can
300*a584d3beSAshish Guptaattach same priv_xform with many stateless ops at-a-time. If not, then application needs to
301*a584d3beSAshish Guptacreate as many priv_xforms as it expects to have stateless operations in-flight.
302*a584d3beSAshish Gupta
303*a584d3beSAshish Gupta.. figure:: img/stateless-op.*
304*a584d3beSAshish Gupta
305*a584d3beSAshish Gupta   Stateless Ops using Non-Shareable priv_xform
306*a584d3beSAshish Gupta
307*a584d3beSAshish Gupta
308*a584d3beSAshish Gupta.. figure:: img/stateless-op-shared.*
309*a584d3beSAshish Gupta
310*a584d3beSAshish Gupta   Stateless Ops using Shareable priv_xform
311*a584d3beSAshish Gupta
312*a584d3beSAshish Gupta
313*a584d3beSAshish GuptaApplication should call ``rte_compressdev_private_xform_create()`` and attach to stateless op before
314*a584d3beSAshish Guptaenqueuing them for processing and free via ``rte_compressdev_private_xform_free()`` during termination.
315*a584d3beSAshish Gupta
316*a584d3beSAshish GuptaAn example pseudocode to setup and process NUM_OPS stateless ops with each of length OP_LEN
317*a584d3beSAshish Guptausing priv_xform would look like:
318*a584d3beSAshish Gupta
319*a584d3beSAshish Gupta.. code-block:: c
320*a584d3beSAshish Gupta
321*a584d3beSAshish Gupta    /*
322*a584d3beSAshish Gupta     * pseudocode for stateless compression
323*a584d3beSAshish Gupta     */
324*a584d3beSAshish Gupta
325*a584d3beSAshish Gupta    uint8_t cdev_id = rte_compdev_get_dev_id(<pmd name>);
326*a584d3beSAshish Gupta
327*a584d3beSAshish Gupta    /* configure the device. */
328*a584d3beSAshish Gupta    if (rte_compressdev_configure(cdev_id, &conf) < 0)
329*a584d3beSAshish Gupta        rte_exit(EXIT_FAILURE, "Failed to configure compressdev %u", cdev_id);
330*a584d3beSAshish Gupta
331*a584d3beSAshish Gupta    if (rte_compressdev_queue_pair_setup(cdev_id, 0, NUM_MAX_INFLIGHT_OPS,
332*a584d3beSAshish Gupta                            socket_id()) < 0)
333*a584d3beSAshish Gupta        rte_exit(EXIT_FAILURE, "Failed to setup queue pair\n");
334*a584d3beSAshish Gupta
335*a584d3beSAshish Gupta    if (rte_compressdev_start(cdev_id) < 0)
336*a584d3beSAshish Gupta        rte_exit(EXIT_FAILURE, "Failed to start device\n");
337*a584d3beSAshish Gupta
338*a584d3beSAshish Gupta    /* setup compress transform */
339*a584d3beSAshish Gupta    struct rte_compress_compress_xform compress_xform = {
340*a584d3beSAshish Gupta        .type = RTE_COMP_COMPRESS,
341*a584d3beSAshish Gupta        .compress = {
342*a584d3beSAshish Gupta            .algo = RTE_COMP_ALGO_DEFLATE,
343*a584d3beSAshish Gupta            .deflate = {
344*a584d3beSAshish Gupta                .huffman = RTE_COMP_HUFFMAN_DEFAULT
345*a584d3beSAshish Gupta            },
346*a584d3beSAshish Gupta            .level = RTE_COMP_LEVEL_PMD_DEFAULT,
347*a584d3beSAshish Gupta            .chksum = RTE_COMP_CHECKSUM_NONE,
348*a584d3beSAshish Gupta            .window_size = DEFAULT_WINDOW_SIZE,
349*a584d3beSAshish Gupta            .hash_algo = RTE_COMP_HASH_ALGO_NONE
350*a584d3beSAshish Gupta        }
351*a584d3beSAshish Gupta    };
352*a584d3beSAshish Gupta
353*a584d3beSAshish Gupta    /* create priv_xform and initialize it for the compression device. */
354*a584d3beSAshish Gupta    void *priv_xform = NULL;
355*a584d3beSAshish Gupta    rte_compressdev_info_get(cdev_id, &dev_info);
356*a584d3beSAshish Gupta    if(dev_info.capability->comps_feature_flag & RTE_COMP_FF_SHAREABLE_PRIV_XFORM) {
357*a584d3beSAshish Gupta        rte_comp_priv_xform_create(cdev_id, &compress_xform, &priv_xform);
358*a584d3beSAshish Gupta    } else {
359*a584d3beSAshish Gupta        shareable = 0;
360*a584d3beSAshish Gupta    }
361*a584d3beSAshish Gupta
362*a584d3beSAshish Gupta    /* create operation pool via call to rte_comp_op_pool_create and alloc ops */
363*a584d3beSAshish Gupta    rte_comp_op_bulk_alloc(op_pool, comp_ops, NUM_OPS);
364*a584d3beSAshish Gupta
365*a584d3beSAshish Gupta    /* prepare ops for compression operations */
366*a584d3beSAshish Gupta    for (i = 0; i < NUM_OPS; i++) {
367*a584d3beSAshish Gupta        struct rte_comp_op *op = comp_ops[i];
368*a584d3beSAshish Gupta        if (!shareable)
369*a584d3beSAshish Gupta            rte_priv_xform_create(cdev_id, &compress_xform, &op->priv_xform)
370*a584d3beSAshish Gupta        else
371*a584d3beSAshish Gupta            op->priv_xform = priv_xform;
372*a584d3beSAshish Gupta        op->type = RTE_COMP_OP_STATELESS;
373*a584d3beSAshish Gupta        op->flush = RTE_COMP_FLUSH_FINAL;
374*a584d3beSAshish Gupta
375*a584d3beSAshish Gupta        op->src.offset = 0;
376*a584d3beSAshish Gupta        op->dst.offset = 0;
377*a584d3beSAshish Gupta        op->src.length = OP_LEN;
378*a584d3beSAshish Gupta        op->input_chksum = 0;
379*a584d3beSAshish Gupta        setup op->m_src and op->m_dst;
380*a584d3beSAshish Gupta    }
381*a584d3beSAshish Gupta    num_enqd = rte_compressdev_enqueue_burst(cdev_id, 0, comp_ops, NUM_OPS);
382*a584d3beSAshish Gupta    /* wait for this to complete before enqueing next*/
383*a584d3beSAshish Gupta    do {
384*a584d3beSAshish Gupta        num_deque = rte_compressdev_dequeue_burst(cdev_id, 0 , &processed_ops, NUM_OPS);
385*a584d3beSAshish Gupta    } while (num_dqud < num_enqd);
386*a584d3beSAshish Gupta
387*a584d3beSAshish Gupta
388*a584d3beSAshish GuptaStateless and OUT_OF_SPACE
389*a584d3beSAshish Gupta~~~~~~~~~~~~~~~~~~~~~~~~~~~~
390*a584d3beSAshish Gupta
391*a584d3beSAshish GuptaOUT_OF_SPACE is a condition when output buffer runs out of space and where PMD
392*a584d3beSAshish Guptastill has more data to produce. If PMD runs into such condition, then PMD returns
393*a584d3beSAshish GuptaRTE_COMP_OP_OUT_OF_SPACE_TERMINATED error. In such case, PMD resets itself and can set
394*a584d3beSAshish Guptaconsumed=0 and produced=amount of output it could produce before hitting out_of_space.
395*a584d3beSAshish GuptaApplication would need to resubmit the whole input with a larger output buffer, if it
396*a584d3beSAshish Guptawants the operation to be completed.
397*a584d3beSAshish Gupta
398*a584d3beSAshish GuptaHash in Stateless
399*a584d3beSAshish Gupta~~~~~~~~~~~~~~~~~
400*a584d3beSAshish GuptaIf hash is enabled, digest buffer will contain valid data after op is successfully
401*a584d3beSAshish Guptaprocessed i.e. dequeued with status = RTE_COMP_OP_STATUS_SUCCESS.
402*a584d3beSAshish Gupta
403*a584d3beSAshish GuptaChecksum in Stateless
404*a584d3beSAshish Gupta~~~~~~~~~~~~~~~~~~~~~
405*a584d3beSAshish GuptaIf checksum is enabled, checksum will only be available after op is successfully
406*a584d3beSAshish Guptaprocessed i.e. dequeued with status = RTE_COMP_OP_STATUS_SUCCESS.
407*a584d3beSAshish Gupta
408*a584d3beSAshish GuptaCompression API Stateful operation
409*a584d3beSAshish Gupta-----------------------------------
410*a584d3beSAshish Gupta
411*a584d3beSAshish GuptaCompression API provide RTE_COMP_FF_STATEFUL_COMPRESSION and
412*a584d3beSAshish GuptaRTE_COMP_FF_STATEFUL_DECOMPRESSION feature flag for PMD to reflect
413*a584d3beSAshish Guptaits support for Stateful operations.
414*a584d3beSAshish Gupta
415*a584d3beSAshish GuptaA Stateful operation in DPDK compression means application invokes enqueue
416*a584d3beSAshish Guptaburst() multiple times to process related chunk of data because
417*a584d3beSAshish Guptaapplication broke data into several ops.
418*a584d3beSAshish Gupta
419*a584d3beSAshish GuptaIn such case
420*a584d3beSAshish Gupta- ops are setup with op_type RTE_COMP_OP_STATEFUL,
421*a584d3beSAshish Gupta- all ops except last set to flush value = RTE_COMP_NO/SYNC_FLUSH
422*a584d3beSAshish Guptaand last set to flush value RTE_COMP_FULL/FINAL_FLUSH.
423*a584d3beSAshish Gupta
424*a584d3beSAshish GuptaIn case of either one or all of the above conditions, PMD initiates
425*a584d3beSAshish Guptastateful processing and releases acquired resources after processing
426*a584d3beSAshish Guptaoperation with flush value = RTE_COMP_FLUSH_FULL/FINAL is complete.
427*a584d3beSAshish GuptaUnlike stateless, application can enqueue only one stateful op from
428*a584d3beSAshish Guptaa particular stream at a time and must attach stream handle
429*a584d3beSAshish Guptato each op.
430*a584d3beSAshish Gupta
431*a584d3beSAshish GuptaStream in Stateful operation
432*a584d3beSAshish Gupta~~~~~~~~~~~~~~~~~~~~~~~~~~~~
433*a584d3beSAshish Gupta
434*a584d3beSAshish Gupta`stream` in DPDK compression is a logical entity which identifies related set of ops, say, a one large
435*a584d3beSAshish Guptafile broken into multiple chunks then file is represented by a stream and each chunk of that file is
436*a584d3beSAshish Guptarepresented by compression op `rte_comp_op`. Whenever application wants a stateful processing of such
437*a584d3beSAshish Guptadata, then it must get a stream handle via making call to ``rte_comp_stream_create()``
438*a584d3beSAshish Guptawith xform, at an output the target PMD will return an opaque stream handle to application which
439*a584d3beSAshish Guptait must attach to all of the ops carrying data of that stream. In stateful processing, every op
440*a584d3beSAshish Guptarequires previous op data for compression/decompression. A PMD allocates and set up resources such
441*a584d3beSAshish Guptaas history, states, etc. within a stream, which are maintained during the processing of the related ops.
442*a584d3beSAshish Gupta
443*a584d3beSAshish GuptaUnlike priv_xforms, stream is always a NON_SHAREABLE entity. One stream handle must be attached to only
444*a584d3beSAshish Guptaone set of related ops and cannot be reused until all of them are processed with status Success or failure.
445*a584d3beSAshish Gupta
446*a584d3beSAshish Gupta.. figure:: img/stateful-op.*
447*a584d3beSAshish Gupta
448*a584d3beSAshish Gupta   Stateful Ops
449*a584d3beSAshish Gupta
450*a584d3beSAshish Gupta
451*a584d3beSAshish GuptaApplication should call ``rte_comp_stream_create()`` and attach to op before
452*a584d3beSAshish Guptaenqueuing them for processing and free via ``rte_comp_stream_free()`` during
453*a584d3beSAshish Guptatermination. All ops that are to be processed statefully should carry *same* stream.
454*a584d3beSAshish Gupta
455*a584d3beSAshish GuptaSee *DPDK API Reference* document for details.
456*a584d3beSAshish Gupta
457*a584d3beSAshish GuptaAn example pseudocode to set up and process a stream having NUM_CHUNKS with each chunk size of CHUNK_LEN would look like:
458*a584d3beSAshish Gupta
459*a584d3beSAshish Gupta.. code-block:: c
460*a584d3beSAshish Gupta
461*a584d3beSAshish Gupta    /*
462*a584d3beSAshish Gupta     * pseudocode for stateful compression
463*a584d3beSAshish Gupta     */
464*a584d3beSAshish Gupta
465*a584d3beSAshish Gupta    uint8_t cdev_id = rte_compdev_get_dev_id(<pmd name>);
466*a584d3beSAshish Gupta
467*a584d3beSAshish Gupta    /* configure the  device. */
468*a584d3beSAshish Gupta    if (rte_compressdev_configure(cdev_id, &conf) < 0)
469*a584d3beSAshish Gupta        rte_exit(EXIT_FAILURE, "Failed to configure compressdev %u", cdev_id);
470*a584d3beSAshish Gupta
471*a584d3beSAshish Gupta    if (rte_compressdev_queue_pair_setup(cdev_id, 0, NUM_MAX_INFLIGHT_OPS,
472*a584d3beSAshish Gupta                                    socket_id()) < 0)
473*a584d3beSAshish Gupta        rte_exit(EXIT_FAILURE, "Failed to setup queue pair\n");
474*a584d3beSAshish Gupta
475*a584d3beSAshish Gupta    if (rte_compressdev_start(cdev_id) < 0)
476*a584d3beSAshish Gupta        rte_exit(EXIT_FAILURE, "Failed to start device\n");
477*a584d3beSAshish Gupta
478*a584d3beSAshish Gupta    /* setup compress transform. */
479*a584d3beSAshish Gupta    struct rte_compress_compress_xform compress_xform = {
480*a584d3beSAshish Gupta        .type = RTE_COMP_COMPRESS,
481*a584d3beSAshish Gupta        .compress = {
482*a584d3beSAshish Gupta            .algo = RTE_COMP_ALGO_DEFLATE,
483*a584d3beSAshish Gupta            .deflate = {
484*a584d3beSAshish Gupta                .huffman = RTE_COMP_HUFFMAN_DEFAULT
485*a584d3beSAshish Gupta            },
486*a584d3beSAshish Gupta            .level = RTE_COMP_LEVEL_PMD_DEFAULT,
487*a584d3beSAshish Gupta            .chksum = RTE_COMP_CHECKSUM_NONE,
488*a584d3beSAshish Gupta            .window_size = DEFAULT_WINDOW_SIZE,
489*a584d3beSAshish Gupta                        .hash_algo = RTE_COMP_HASH_ALGO_NONE
490*a584d3beSAshish Gupta        }
491*a584d3beSAshish Gupta    };
492*a584d3beSAshish Gupta
493*a584d3beSAshish Gupta    /* create stream */
494*a584d3beSAshish Gupta    rte_comp_stream_create(cdev_id, &compress_xform, &stream);
495*a584d3beSAshish Gupta
496*a584d3beSAshish Gupta    /* create an op pool and allocate ops */
497*a584d3beSAshish Gupta    rte_comp_op_bulk_alloc(op_pool, comp_ops, NUM_CHUNKS);
498*a584d3beSAshish Gupta
499*a584d3beSAshish Gupta    /* Prepare source and destination mbufs for compression operations */
500*a584d3beSAshish Gupta    unsigned int i;
501*a584d3beSAshish Gupta    for (i = 0; i < NUM_CHUNKS; i++) {
502*a584d3beSAshish Gupta        if (rte_pktmbuf_append(mbufs[i], CHUNK_LEN) == NULL)
503*a584d3beSAshish Gupta            rte_exit(EXIT_FAILURE, "Not enough room in the mbuf\n");
504*a584d3beSAshish Gupta        comp_ops[i]->m_src = mbufs[i];
505*a584d3beSAshish Gupta        if (rte_pktmbuf_append(dst_mbufs[i], CHUNK_LEN) == NULL)
506*a584d3beSAshish Gupta            rte_exit(EXIT_FAILURE, "Not enough room in the mbuf\n");
507*a584d3beSAshish Gupta        comp_ops[i]->m_dst = dst_mbufs[i];
508*a584d3beSAshish Gupta    }
509*a584d3beSAshish Gupta
510*a584d3beSAshish Gupta    /* Set up the compress operations. */
511*a584d3beSAshish Gupta    for (i = 0; i < NUM_CHUNKS; i++) {
512*a584d3beSAshish Gupta        struct rte_comp_op *op = comp_ops[i];
513*a584d3beSAshish Gupta        op->stream = stream;
514*a584d3beSAshish Gupta        op->m_src = src_buf[i];
515*a584d3beSAshish Gupta        op->m_dst = dst_buf[i];
516*a584d3beSAshish Gupta        op->type = RTE_COMP_OP_STATEFUL;
517*a584d3beSAshish Gupta        if(i == NUM_CHUNKS-1) {
518*a584d3beSAshish Gupta            /* set to final, if last chunk*/
519*a584d3beSAshish Gupta            op->flush = RTE_COMP_FLUSH_FINAL;
520*a584d3beSAshish Gupta        } else {
521*a584d3beSAshish Gupta            /* set to NONE, for all intermediary ops */
522*a584d3beSAshish Gupta            op->flush = RTE_COMP_FLUSH_NONE;
523*a584d3beSAshish Gupta        }
524*a584d3beSAshish Gupta        op->src.offset = 0;
525*a584d3beSAshish Gupta        op->dst.offset = 0;
526*a584d3beSAshish Gupta        op->src.length = CHUNK_LEN;
527*a584d3beSAshish Gupta        op->input_chksum = 0;
528*a584d3beSAshish Gupta        num_enqd = rte_compressdev_enqueue_burst(cdev_id, 0, &op[i], 1);
529*a584d3beSAshish Gupta        /* wait for this to complete before enqueing next*/
530*a584d3beSAshish Gupta        do {
531*a584d3beSAshish Gupta            num_deqd = rte_compressdev_dequeue_burst(cdev_id, 0 , &processed_ops, 1);
532*a584d3beSAshish Gupta        } while (num_deqd < num_enqd);
533*a584d3beSAshish Gupta        /* push next op*/
534*a584d3beSAshish Gupta    }
535*a584d3beSAshish Gupta
536*a584d3beSAshish Gupta
537*a584d3beSAshish GuptaStateful and OUT_OF_SPACE
538*a584d3beSAshish Gupta~~~~~~~~~~~~~~~~~~~~~~~~~~~
539*a584d3beSAshish Gupta
540*a584d3beSAshish GuptaIf PMD supports stateful operation, then OUT_OF_SPACE status is not an actual
541*a584d3beSAshish Guptaerror for the PMD. In such case, PMD returns with status
542*a584d3beSAshish GuptaRTE_COMP_OP_STATUS_OUT_OF_SPACE_RECOVERABLE with consumed = number of input bytes
543*a584d3beSAshish Guptaread and produced = length of complete output buffer.
544*a584d3beSAshish GuptaApplication should enqueue next op with source starting at consumed+1 and an
545*a584d3beSAshish Guptaoutput buffer with available space.
546*a584d3beSAshish Gupta
547*a584d3beSAshish GuptaHash in Stateful
548*a584d3beSAshish Gupta~~~~~~~~~~~~~~~~
549*a584d3beSAshish GuptaIf enabled, digest buffer will contain valid digest after last op in stream
550*a584d3beSAshish Gupta(having flush = RTE_COMP_OP_FLUSH_FINAL) is successfully processed i.e. dequeued
551*a584d3beSAshish Guptawith status = RTE_COMP_OP_STATUS_SUCCESS.
552*a584d3beSAshish Gupta
553*a584d3beSAshish GuptaChecksum in Stateful
554*a584d3beSAshish Gupta~~~~~~~~~~~~~~~~~~~~
555*a584d3beSAshish GuptaIf enabled, checksum will only be available after last op in stream
556*a584d3beSAshish Gupta(having flush = RTE_COMP_OP_FLUSH_FINAL) is successfully processed i.e. dequeued
557*a584d3beSAshish Guptawith status = RTE_COMP_OP_STATUS_SUCCESS.
558*a584d3beSAshish Gupta
559*a584d3beSAshish GuptaBurst in compression API
560*a584d3beSAshish Gupta-------------------------
561*a584d3beSAshish Gupta
562*a584d3beSAshish GuptaScheduling of compression operations on DPDK's application data path is
563*a584d3beSAshish Guptaperformed using a burst oriented asynchronous API set. A queue pair on a compression
564*a584d3beSAshish Guptadevice accepts a burst of compression operations using enqueue burst API. On physical
565*a584d3beSAshish Guptadevices the enqueue burst API will place the operations to be processed
566*a584d3beSAshish Guptaon the device's hardware input queue, for virtual devices the processing of the
567*a584d3beSAshish Guptaoperations is usually completed during the enqueue call to the compression
568*a584d3beSAshish Guptadevice. The dequeue burst API will retrieve any processed operations available
569*a584d3beSAshish Guptafrom the queue pair on the compression device, from physical devices this is usually
570*a584d3beSAshish Guptadirectly from the devices processed queue, and for virtual device's from a
571*a584d3beSAshish Gupta``rte_ring`` where processed operations are place after being processed on the
572*a584d3beSAshish Guptaenqueue call.
573*a584d3beSAshish Gupta
574*a584d3beSAshish GuptaA burst in DPDK compression can be a combination of stateless and stateful operations with a condition
575*a584d3beSAshish Guptathat for stateful ops only one op at-a-time should be enqueued from a particular stream i.e. no-two ops
576*a584d3beSAshish Guptashould belong to same stream in a single burst. However a burst may contain multiple stateful ops as long
577*a584d3beSAshish Guptaas each op is attached to a different stream i.e. a burst can look like:
578*a584d3beSAshish Gupta
579*a584d3beSAshish Gupta+---------------+--------------+--------------+-----------------+--------------+--------------+
580*a584d3beSAshish Gupta| enqueue_burst | op1.no_flush | op2.no_flush | op3.flush_final | op4.no_flush | op5.no_flush |
581*a584d3beSAshish Gupta+---------------+--------------+--------------+-----------------+--------------+--------------+
582*a584d3beSAshish Gupta
583*a584d3beSAshish GuptaWhere, op1 .. op5 all belong to different independent data units. op1, op2, op4, op5 must be stateful
584*a584d3beSAshish Guptaas stateless ops can only use flush full or final and op3 can be of type stateless or stateful.
585*a584d3beSAshish GuptaEvery op with type set to RTE_COMP_OP_TYPE_STATELESS must be attached to priv_xform and
586*a584d3beSAshish GuptaEvery op with type set to RTE_COMP_OP_TYPE_STATEFUL *must* be attached to stream.
587*a584d3beSAshish Gupta
588*a584d3beSAshish GuptaSince each operation in a burst is independent and thus can be completed
589*a584d3beSAshish Guptaout-of-order,  applications which need ordering, should setup per-op user data
590*a584d3beSAshish Guptaarea with reordering information so that it can determine enqueue order at
591*a584d3beSAshish Guptadequeue.
592*a584d3beSAshish Gupta
593*a584d3beSAshish GuptaAlso if multiple threads calls enqueue_burst() on same queue pair then it’s
594*a584d3beSAshish Guptaapplication onus to use proper locking mechanism to ensure exclusive enqueuing
595*a584d3beSAshish Guptaof operations.
596*a584d3beSAshish Gupta
597*a584d3beSAshish GuptaEnqueue / Dequeue Burst APIs
598*a584d3beSAshish Gupta~~~~~~~~~~~~~~~~~~~~~~~~~~~~
599*a584d3beSAshish Gupta
600*a584d3beSAshish GuptaThe burst enqueue API uses a compression device identifier and a queue pair
601*a584d3beSAshish Guptaidentifier to specify the compression device queue pair to schedule the processing on.
602*a584d3beSAshish GuptaThe ``nb_ops`` parameter is the number of operations to process which are
603*a584d3beSAshish Guptasupplied in the ``ops`` array of ``rte_comp_op`` structures.
604*a584d3beSAshish GuptaThe enqueue function returns the number of operations it actually enqueued for
605*a584d3beSAshish Guptaprocessing, a return value equal to ``nb_ops`` means that all packets have been
606*a584d3beSAshish Guptaenqueued.
607*a584d3beSAshish Gupta
608*a584d3beSAshish GuptaThe dequeue API uses the same format as the enqueue API but
609*a584d3beSAshish Guptathe ``nb_ops`` and ``ops`` parameters are now used to specify the max processed
610*a584d3beSAshish Guptaoperations the user wishes to retrieve and the location in which to store them.
611*a584d3beSAshish GuptaThe API call returns the actual number of processed operations returned, this
612*a584d3beSAshish Guptacan never be larger than ``nb_ops``.
613*a584d3beSAshish Gupta
614*a584d3beSAshish GuptaSample code
615*a584d3beSAshish Gupta-----------
616*a584d3beSAshish Gupta
617*a584d3beSAshish GuptaThere are unit test applications that show how to use the compressdev library inside
618*a584d3beSAshish Guptatest/test/test_compressdev.c
619*a584d3beSAshish Gupta
620*a584d3beSAshish GuptaCompression Device API
621*a584d3beSAshish Gupta~~~~~~~~~~~~~~~~~~~~~~
622*a584d3beSAshish Gupta
623*a584d3beSAshish GuptaThe compressdev Library API is described in the *DPDK API Reference* document.
624