compressdev: add operation management
[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 /**
10  * Reset the fields of an operation to their default values.
11  *
12  * @note The private data associated with the operation is not zeroed.
13  *
14  * @param op
15  *   The operation to be reset
16  */
17 static inline void
18 rte_comp_op_reset(struct rte_comp_op *op)
19 {
20         struct rte_mempool *tmp_mp = op->mempool;
21         rte_iova_t tmp_iova_addr = op->iova_addr;
22
23         memset(op, 0, sizeof(struct rte_comp_op));
24         op->status = RTE_COMP_OP_STATUS_NOT_PROCESSED;
25         op->iova_addr = tmp_iova_addr;
26         op->mempool = tmp_mp;
27 }
28
29 /**
30  * Private data structure belonging to an operation pool.
31  */
32 struct rte_comp_op_pool_private {
33         uint16_t user_size;
34         /**< Size of private user data with each operation. */
35 };
36
37 /**
38  * Bulk allocate raw element from mempool and return as comp operations
39  *
40  * @param mempool
41  *   Compress operation mempool
42  * @param ops
43  *   Array to place allocated operations
44  * @param nb_ops
45  *   Number of operations to allocate
46  * @return
47  *   - 0: Success
48  *   - -ENOENT: Not enough entries in the mempool; no ops are retrieved.
49  */
50 static inline int
51 rte_comp_op_raw_bulk_alloc(struct rte_mempool *mempool,
52                 struct rte_comp_op **ops, uint16_t nb_ops)
53 {
54         if (rte_mempool_get_bulk(mempool, (void **)ops, nb_ops) == 0)
55                 return nb_ops;
56
57         return 0;
58 }
59
60 /** Initialise rte_comp_op mempool element */
61 static void
62 rte_comp_op_init(struct rte_mempool *mempool,
63                 __rte_unused void *opaque_arg,
64                 void *_op_data,
65                 __rte_unused unsigned int i)
66 {
67         struct rte_comp_op *op = _op_data;
68
69         memset(_op_data, 0, mempool->elt_size);
70
71         op->status = RTE_COMP_OP_STATUS_NOT_PROCESSED;
72         op->iova_addr = rte_mem_virt2iova(_op_data);
73         op->mempool = mempool;
74 }
75
76 struct rte_mempool * __rte_experimental
77 rte_comp_op_pool_create(const char *name,
78                 unsigned int nb_elts, unsigned int cache_size,
79                 uint16_t user_size, int socket_id)
80 {
81         struct rte_comp_op_pool_private *priv;
82
83         unsigned int elt_size = sizeof(struct rte_comp_op) + user_size;
84
85         /* lookup mempool in case already allocated */
86         struct rte_mempool *mp = rte_mempool_lookup(name);
87
88         if (mp != NULL) {
89                 priv = (struct rte_comp_op_pool_private *)
90                                 rte_mempool_get_priv(mp);
91
92                 if (mp->elt_size != elt_size ||
93                                 mp->cache_size < cache_size ||
94                                 mp->size < nb_elts ||
95                                 priv->user_size <  user_size) {
96                         mp = NULL;
97                         COMPRESSDEV_LOG(ERR,
98                 "Mempool %s already exists but with incompatible parameters",
99                                         name);
100                         return NULL;
101                 }
102                 return mp;
103         }
104
105         mp = rte_mempool_create(
106                         name,
107                         nb_elts,
108                         elt_size,
109                         cache_size,
110                         sizeof(struct rte_comp_op_pool_private),
111                         NULL,
112                         NULL,
113                         rte_comp_op_init,
114                         NULL,
115                         socket_id,
116                         0);
117
118         if (mp == NULL) {
119                 COMPRESSDEV_LOG(ERR, "Failed to create mempool %s", name);
120                 return NULL;
121         }
122
123         priv = (struct rte_comp_op_pool_private *)
124                         rte_mempool_get_priv(mp);
125
126         priv->user_size = user_size;
127
128         return mp;
129 }
130
131 struct rte_comp_op * __rte_experimental
132 rte_comp_op_alloc(struct rte_mempool *mempool)
133 {
134         struct rte_comp_op *op = NULL;
135         int retval;
136
137         retval = rte_comp_op_raw_bulk_alloc(mempool, &op, 1);
138         if (unlikely(retval < 0))
139                 return NULL;
140
141         rte_comp_op_reset(op);
142
143         return op;
144 }
145
146 int __rte_experimental
147 rte_comp_op_bulk_alloc(struct rte_mempool *mempool,
148                 struct rte_comp_op **ops, uint16_t nb_ops)
149 {
150         int ret;
151         uint16_t i;
152
153         ret = rte_comp_op_raw_bulk_alloc(mempool, ops, nb_ops);
154         if (unlikely(ret < nb_ops))
155                 return ret;
156
157         for (i = 0; i < nb_ops; i++)
158                 rte_comp_op_reset(ops[i]);
159
160         return nb_ops;
161 }
162
163 /**
164  * free operation structure
165  * If operation has been allocate from a rte_mempool, then the operation will
166  * be returned to the mempool.
167  *
168  * @param op
169  *   Compress operation
170  */
171 void __rte_experimental
172 rte_comp_op_free(struct rte_comp_op *op)
173 {
174         if (op != NULL && op->mempool != NULL)
175                 rte_mempool_put(op->mempool, op);
176 }