dc9d0b0f49cc29c66adcc34269964ee39d0a5be7
[dpdk.git] / app / test-compress-perf / comp_perf_test_common.c
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright(c) 2019 Intel Corporation
3  */
4
5 #include <rte_malloc.h>
6 #include <rte_eal.h>
7 #include <rte_log.h>
8 #include <rte_compressdev.h>
9
10 #include "comp_perf_options.h"
11 #include "comp_perf_test_verify.h"
12 #include "comp_perf_test_benchmark.h"
13 #include "comp_perf.h"
14 #include "comp_perf_test_common.h"
15
16 #define DIV_CEIL(a, b)  ((a) / (b) + ((a) % (b) != 0))
17
18 int
19 param_range_check(uint16_t size, const struct rte_param_log2_range *range)
20 {
21         unsigned int next_size;
22
23         /* Check lower/upper bounds */
24         if (size < range->min)
25                 return -1;
26
27         if (size > range->max)
28                 return -1;
29
30         /* If range is actually only one value, size is correct */
31         if (range->increment == 0)
32                 return 0;
33
34         /* Check if value is one of the supported sizes */
35         for (next_size = range->min; next_size <= range->max;
36                         next_size += range->increment)
37                 if (size == next_size)
38                         return 0;
39
40         return -1;
41 }
42
43 static uint32_t
44 find_buf_size(uint32_t input_size)
45 {
46         uint32_t i;
47
48         /* From performance point of view the buffer size should be a
49          * power of 2 but also should be enough to store incompressible data
50          */
51
52         /* We're looking for nearest power of 2 buffer size, which is greather
53          * than input_size
54          */
55         uint32_t size =
56                 !input_size ? MIN_COMPRESSED_BUF_SIZE : (input_size << 1);
57
58         for (i = UINT16_MAX + 1; !(i & size); i >>= 1)
59                 ;
60
61         return i > ((UINT16_MAX + 1) >> 1)
62                         ? (uint32_t)((float)input_size * EXPANSE_RATIO)
63                         : i;
64 }
65
66 void
67 comp_perf_free_memory(struct cperf_mem_resources *mem)
68 {
69         uint32_t i;
70
71         for (i = 0; i < mem->total_bufs; i++) {
72                 rte_pktmbuf_free(mem->comp_bufs[i]);
73                 rte_pktmbuf_free(mem->decomp_bufs[i]);
74         }
75
76         rte_free(mem->decomp_bufs);
77         rte_free(mem->comp_bufs);
78         rte_free(mem->decompressed_data);
79         rte_free(mem->compressed_data);
80         rte_mempool_free(mem->op_pool);
81         rte_mempool_free(mem->decomp_buf_pool);
82         rte_mempool_free(mem->comp_buf_pool);
83 }
84
85 int
86 comp_perf_allocate_memory(struct comp_test_data *test_data,
87                           struct cperf_mem_resources *mem)
88 {
89         test_data->out_seg_sz = find_buf_size(test_data->seg_sz);
90         /* Number of segments for input and output
91          * (compression and decompression)
92          */
93         uint32_t total_segs = DIV_CEIL(test_data->input_data_sz,
94                         test_data->seg_sz);
95         char pool_name[32] = "";
96
97         snprintf(pool_name, sizeof(pool_name), "comp_buf_pool_%u_qp_%u",
98                         mem->dev_id, mem->qp_id);
99         mem->comp_buf_pool = rte_pktmbuf_pool_create(pool_name,
100                                 total_segs,
101                                 0, 0,
102                                 test_data->out_seg_sz + RTE_PKTMBUF_HEADROOM,
103                                 rte_socket_id());
104         if (mem->comp_buf_pool == NULL) {
105                 RTE_LOG(ERR, USER1, "Mbuf mempool could not be created\n");
106                 return -1;
107         }
108
109         snprintf(pool_name, sizeof(pool_name), "decomp_buf_pool_%u_qp_%u",
110                         mem->dev_id, mem->qp_id);
111         mem->decomp_buf_pool = rte_pktmbuf_pool_create(pool_name,
112                                 total_segs,
113                                 0, 0, test_data->seg_sz + RTE_PKTMBUF_HEADROOM,
114                                 rte_socket_id());
115         if (mem->decomp_buf_pool == NULL) {
116                 RTE_LOG(ERR, USER1, "Mbuf mempool could not be created\n");
117                 return -1;
118         }
119
120         mem->total_bufs = DIV_CEIL(total_segs, test_data->max_sgl_segs);
121
122         snprintf(pool_name, sizeof(pool_name), "op_pool_%u_qp_%u",
123                         mem->dev_id, mem->qp_id);
124         mem->op_pool = rte_comp_op_pool_create(pool_name,
125                                   mem->total_bufs,
126                                   0, 0, rte_socket_id());
127         if (mem->op_pool == NULL) {
128                 RTE_LOG(ERR, USER1, "Comp op mempool could not be created\n");
129                 return -1;
130         }
131
132         /*
133          * Compressed data might be a bit larger than input data,
134          * if data cannot be compressed
135          */
136         mem->compressed_data = rte_zmalloc_socket(NULL,
137                                 test_data->input_data_sz * EXPANSE_RATIO
138                                                 + MIN_COMPRESSED_BUF_SIZE, 0,
139                                 rte_socket_id());
140         if (mem->compressed_data == NULL) {
141                 RTE_LOG(ERR, USER1, "Memory to hold the data from the input "
142                                 "file could not be allocated\n");
143                 return -1;
144         }
145
146         mem->decompressed_data = rte_zmalloc_socket(NULL,
147                                 test_data->input_data_sz, 0,
148                                 rte_socket_id());
149         if (mem->decompressed_data == NULL) {
150                 RTE_LOG(ERR, USER1, "Memory to hold the data from the input "
151                                 "file could not be allocated\n");
152                 return -1;
153         }
154
155         mem->comp_bufs = rte_zmalloc_socket(NULL,
156                         mem->total_bufs * sizeof(struct rte_mbuf *),
157                         0, rte_socket_id());
158         if (mem->comp_bufs == NULL) {
159                 RTE_LOG(ERR, USER1, "Memory to hold the compression mbufs"
160                                 " could not be allocated\n");
161                 return -1;
162         }
163
164         mem->decomp_bufs = rte_zmalloc_socket(NULL,
165                         mem->total_bufs * sizeof(struct rte_mbuf *),
166                         0, rte_socket_id());
167         if (mem->decomp_bufs == NULL) {
168                 RTE_LOG(ERR, USER1, "Memory to hold the decompression mbufs"
169                                 " could not be allocated\n");
170                 return -1;
171         }
172         return 0;
173 }
174
175 int
176 prepare_bufs(struct comp_test_data *test_data, struct cperf_mem_resources *mem)
177 {
178         uint32_t remaining_data = test_data->input_data_sz;
179         uint8_t *input_data_ptr = test_data->input_data;
180         size_t data_sz;
181         uint8_t *data_addr;
182         uint32_t i, j;
183
184         for (i = 0; i < mem->total_bufs; i++) {
185                 /* Allocate data in input mbuf and copy data from input file */
186                 mem->decomp_bufs[i] =
187                         rte_pktmbuf_alloc(mem->decomp_buf_pool);
188                 if (mem->decomp_bufs[i] == NULL) {
189                         RTE_LOG(ERR, USER1, "Could not allocate mbuf\n");
190                         return -1;
191                 }
192
193                 data_sz = RTE_MIN(remaining_data, test_data->seg_sz);
194                 data_addr = (uint8_t *) rte_pktmbuf_append(
195                                         mem->decomp_bufs[i], data_sz);
196                 if (data_addr == NULL) {
197                         RTE_LOG(ERR, USER1, "Could not append data\n");
198                         return -1;
199                 }
200                 rte_memcpy(data_addr, input_data_ptr, data_sz);
201
202                 input_data_ptr += data_sz;
203                 remaining_data -= data_sz;
204
205                 /* Already one segment in the mbuf */
206                 uint16_t segs_per_mbuf = 1;
207
208                 /* Chain mbufs if needed for input mbufs */
209                 while (segs_per_mbuf < test_data->max_sgl_segs
210                                 && remaining_data > 0) {
211                         struct rte_mbuf *next_seg =
212                                 rte_pktmbuf_alloc(mem->decomp_buf_pool);
213
214                         if (next_seg == NULL) {
215                                 RTE_LOG(ERR, USER1,
216                                         "Could not allocate mbuf\n");
217                                 return -1;
218                         }
219
220                         data_sz = RTE_MIN(remaining_data, test_data->seg_sz);
221                         data_addr = (uint8_t *)rte_pktmbuf_append(next_seg,
222                                 data_sz);
223
224                         if (data_addr == NULL) {
225                                 RTE_LOG(ERR, USER1, "Could not append data\n");
226                                 return -1;
227                         }
228
229                         rte_memcpy(data_addr, input_data_ptr, data_sz);
230                         input_data_ptr += data_sz;
231                         remaining_data -= data_sz;
232
233                         if (rte_pktmbuf_chain(mem->decomp_bufs[i],
234                                         next_seg) < 0) {
235                                 RTE_LOG(ERR, USER1, "Could not chain mbufs\n");
236                                 return -1;
237                         }
238                         segs_per_mbuf++;
239                 }
240
241                 /* Allocate data in output mbuf */
242                 mem->comp_bufs[i] =
243                         rte_pktmbuf_alloc(mem->comp_buf_pool);
244                 if (mem->comp_bufs[i] == NULL) {
245                         RTE_LOG(ERR, USER1, "Could not allocate mbuf\n");
246                         return -1;
247                 }
248                 data_addr = (uint8_t *) rte_pktmbuf_append(
249                                         mem->comp_bufs[i],
250                                         test_data->out_seg_sz);
251                 if (data_addr == NULL) {
252                         RTE_LOG(ERR, USER1, "Could not append data\n");
253                         return -1;
254                 }
255
256                 /* Chain mbufs if needed for output mbufs */
257                 for (j = 1; j < segs_per_mbuf; j++) {
258                         struct rte_mbuf *next_seg =
259                                 rte_pktmbuf_alloc(mem->comp_buf_pool);
260
261                         if (next_seg == NULL) {
262                                 RTE_LOG(ERR, USER1,
263                                         "Could not allocate mbuf\n");
264                                 return -1;
265                         }
266
267                         data_addr = (uint8_t *)rte_pktmbuf_append(next_seg,
268                                 test_data->out_seg_sz);
269
270                         if (data_addr == NULL) {
271                                 RTE_LOG(ERR, USER1, "Could not append data\n");
272                                 return -1;
273                         }
274
275                         if (rte_pktmbuf_chain(mem->comp_bufs[i],
276                                         next_seg) < 0) {
277                                 RTE_LOG(ERR, USER1, "Could not chain mbufs\n");
278                                 return -1;
279                         }
280                 }
281         }
282
283         return 0;
284 }