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