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