d596ba872b1aef64d92657cd217dc0ea81e41b25
[dpdk.git] / lib / librte_compressdev / rte_comp.c
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright(c) 2017-2018 Intel Corporation
3  */
4
5 #include "rte_comp.h"
6 #include "rte_compressdev.h"
7 #include "rte_compressdev_internal.h"
8
9 const char * __rte_experimental
10 rte_comp_get_feature_name(uint64_t flag)
11 {
12         switch (flag) {
13         case RTE_COMP_FF_STATEFUL_COMPRESSION:
14                 return "STATEFUL_COMPRESSION";
15         case RTE_COMP_FF_STATEFUL_DECOMPRESSION:
16                 return "STATEFUL_DECOMPRESSION";
17         case RTE_COMP_FF_MBUF_SCATTER_GATHER:
18                 return "MBUF_SCATTER_GATHER";
19         case RTE_COMP_FF_MULTI_PKT_CHECKSUM:
20                 return "MULTI_PKT_CHECKSUM";
21         case RTE_COMP_FF_ADLER32_CHECKSUM:
22                 return "ADLER32_CHECKSUM";
23         case RTE_COMP_FF_CRC32_CHECKSUM:
24                 return "CRC32_CHECKSUM";
25         case RTE_COMP_FF_CRC32_ADLER32_CHECKSUM:
26                 return "CRC32_ADLER32_CHECKSUM";
27         case RTE_COMP_FF_NONCOMPRESSED_BLOCKS:
28                 return "NONCOMPRESSED_BLOCKS";
29         case RTE_COMP_FF_SHA1_HASH:
30                 return "SHA1_HASH";
31         case RTE_COMP_FF_SHA2_SHA256_HASH:
32                 return "SHA2_SHA256_HASH";
33         case RTE_COMP_FF_SHAREABLE_PRIV_XFORM:
34                 return "SHAREABLE_PRIV_XFORM";
35         default:
36                 return NULL;
37         }
38 }
39
40 /**
41  * Reset the fields of an operation to their default values.
42  *
43  * @note The private data associated with the operation is not zeroed.
44  *
45  * @param op
46  *   The operation to be reset
47  */
48 static inline void
49 rte_comp_op_reset(struct rte_comp_op *op)
50 {
51         struct rte_mempool *tmp_mp = op->mempool;
52         rte_iova_t tmp_iova_addr = op->iova_addr;
53
54         memset(op, 0, sizeof(struct rte_comp_op));
55         op->status = RTE_COMP_OP_STATUS_NOT_PROCESSED;
56         op->iova_addr = tmp_iova_addr;
57         op->mempool = tmp_mp;
58 }
59
60 /**
61  * Private data structure belonging to an operation pool.
62  */
63 struct rte_comp_op_pool_private {
64         uint16_t user_size;
65         /**< Size of private user data with each operation. */
66 };
67
68 /**
69  * Bulk allocate raw element from mempool and return as comp operations
70  *
71  * @param mempool
72  *   Compress operation mempool
73  * @param ops
74  *   Array to place allocated operations
75  * @param nb_ops
76  *   Number of operations to allocate
77  * @return
78  *   - 0: Success
79  *   - -ENOENT: Not enough entries in the mempool; no ops are retrieved.
80  */
81 static inline int
82 rte_comp_op_raw_bulk_alloc(struct rte_mempool *mempool,
83                 struct rte_comp_op **ops, uint16_t nb_ops)
84 {
85         if (rte_mempool_get_bulk(mempool, (void **)ops, nb_ops) == 0)
86                 return nb_ops;
87
88         return 0;
89 }
90
91 /** Initialise rte_comp_op mempool element */
92 static void
93 rte_comp_op_init(struct rte_mempool *mempool,
94                 __rte_unused void *opaque_arg,
95                 void *_op_data,
96                 __rte_unused unsigned int i)
97 {
98         struct rte_comp_op *op = _op_data;
99
100         memset(_op_data, 0, mempool->elt_size);
101
102         op->status = RTE_COMP_OP_STATUS_NOT_PROCESSED;
103         op->iova_addr = rte_mem_virt2iova(_op_data);
104         op->mempool = mempool;
105 }
106
107 struct rte_mempool * __rte_experimental
108 rte_comp_op_pool_create(const char *name,
109                 unsigned int nb_elts, unsigned int cache_size,
110                 uint16_t user_size, int socket_id)
111 {
112         struct rte_comp_op_pool_private *priv;
113
114         unsigned int elt_size = sizeof(struct rte_comp_op) + user_size;
115
116         /* lookup mempool in case already allocated */
117         struct rte_mempool *mp = rte_mempool_lookup(name);
118
119         if (mp != NULL) {
120                 priv = (struct rte_comp_op_pool_private *)
121                                 rte_mempool_get_priv(mp);
122
123                 if (mp->elt_size != elt_size ||
124                                 mp->cache_size < cache_size ||
125                                 mp->size < nb_elts ||
126                                 priv->user_size <  user_size) {
127                         mp = NULL;
128                         COMPRESSDEV_LOG(ERR,
129                 "Mempool %s already exists but with incompatible parameters",
130                                         name);
131                         return NULL;
132                 }
133                 return mp;
134         }
135
136         mp = rte_mempool_create(
137                         name,
138                         nb_elts,
139                         elt_size,
140                         cache_size,
141                         sizeof(struct rte_comp_op_pool_private),
142                         NULL,
143                         NULL,
144                         rte_comp_op_init,
145                         NULL,
146                         socket_id,
147                         0);
148
149         if (mp == NULL) {
150                 COMPRESSDEV_LOG(ERR, "Failed to create mempool %s", name);
151                 return NULL;
152         }
153
154         priv = (struct rte_comp_op_pool_private *)
155                         rte_mempool_get_priv(mp);
156
157         priv->user_size = user_size;
158
159         return mp;
160 }
161
162 struct rte_comp_op * __rte_experimental
163 rte_comp_op_alloc(struct rte_mempool *mempool)
164 {
165         struct rte_comp_op *op = NULL;
166         int retval;
167
168         retval = rte_comp_op_raw_bulk_alloc(mempool, &op, 1);
169         if (unlikely(retval < 0))
170                 return NULL;
171
172         rte_comp_op_reset(op);
173
174         return op;
175 }
176
177 int __rte_experimental
178 rte_comp_op_bulk_alloc(struct rte_mempool *mempool,
179                 struct rte_comp_op **ops, uint16_t nb_ops)
180 {
181         int ret;
182         uint16_t i;
183
184         ret = rte_comp_op_raw_bulk_alloc(mempool, ops, nb_ops);
185         if (unlikely(ret < nb_ops))
186                 return ret;
187
188         for (i = 0; i < nb_ops; i++)
189                 rte_comp_op_reset(ops[i]);
190
191         return nb_ops;
192 }
193
194 /**
195  * free operation structure
196  * If operation has been allocate from a rte_mempool, then the operation will
197  * be returned to the mempool.
198  *
199  * @param op
200  *   Compress operation
201  */
202 void __rte_experimental
203 rte_comp_op_free(struct rte_comp_op *op)
204 {
205         if (op != NULL && op->mempool != NULL)
206                 rte_mempool_put(op->mempool, op);
207 }