Branch data Line data Source code
1 : : /* SPDX-License-Identifier: BSD-3-Clause
2 : : * Copyright(c) 2010-2019 Intel Corporation
3 : : */
4 : :
5 : : #include "test.h"
6 : :
7 : : #include <stdio.h>
8 : : #include <stdint.h>
9 : : #include <string.h>
10 : : #include <stdarg.h>
11 : : #include <errno.h>
12 : : #include <stdlib.h>
13 : : #ifndef RTE_EXEC_ENV_WINDOWS
14 : : #include <sys/mman.h>
15 : : #endif
16 : : #include <sys/queue.h>
17 : : #include <unistd.h>
18 : :
19 : : #include <rte_common.h>
20 : : #include <rte_memory.h>
21 : : #include <rte_per_lcore.h>
22 : : #include <rte_launch.h>
23 : : #include <rte_eal.h>
24 : : #include <rte_lcore.h>
25 : : #include <rte_malloc.h>
26 : : #include <rte_cycles.h>
27 : : #include <rte_random.h>
28 : : #include <rte_eal_paging.h>
29 : : #include <rte_string_fns.h>
30 : :
31 : : #define N 10000
32 : :
33 : : static int
34 : : is_mem_on_socket(int32_t socket);
35 : :
36 : : static int32_t
37 : : addr_to_socket(void *addr);
38 : :
39 : : /*
40 : : * Malloc
41 : : * ======
42 : : *
43 : : * Allocate some dynamic memory from heap (3 areas). Check that areas
44 : : * don't overlap and that alignment constraints match. This test is
45 : : * done many times on different lcores simultaneously.
46 : : */
47 : :
48 : : /* Test if memory overlaps: return 1 if true, or 0 if false. */
49 : : static int
50 : : is_memory_overlap(void *p1, size_t len1, void *p2, size_t len2)
51 : : {
52 : 10030 : uintptr_t ptr1 = (uintptr_t)p1;
53 : 20060 : uintptr_t ptr2 = (uintptr_t)p2;
54 : :
55 [ - + - - : 30090 : if (ptr2 >= ptr1 && (ptr2 - ptr1) < len1)
- + - - -
+ - - - +
- - - + -
- - + -
- ]
56 : : return 1;
57 [ + - - + : 30090 : else if (ptr2 < ptr1 && (ptr1 - ptr2) < len2)
+ - - + +
- - + + -
- + + - -
+ + - -
+ ]
58 : : return 1;
59 : : return 0;
60 : : }
61 : :
62 : : static int
63 : : is_aligned(void *p, int align)
64 : : {
65 : : uintptr_t addr = (uintptr_t)p;
66 : : unsigned mask = align - 1;
67 : :
68 : : if (addr & mask)
69 : : return 0;
70 : : return 1;
71 : : }
72 : :
73 : : static int
74 : 1 : test_align_overlap_per_lcore(__rte_unused void *arg)
75 : : {
76 : : const unsigned align1 = 8,
77 : : align2 = 64,
78 : : align3 = 2048;
79 : : unsigned i,j;
80 : : void *p1 = NULL, *p2 = NULL, *p3 = NULL;
81 : : int ret = 0;
82 : :
83 [ + + ]: 10001 : for (i = 0; i < N; i++) {
84 : 10000 : p1 = rte_zmalloc("dummy", 1000, align1);
85 [ + - ]: 10000 : if (!p1){
86 : : printf("rte_zmalloc returned NULL (i=%u)\n", i);
87 : : ret = -1;
88 : 0 : break;
89 : : }
90 [ + + ]: 10010000 : for(j = 0; j < 1000 ; j++) {
91 [ - + ]: 10000000 : if( *(char *)p1 != 0) {
92 : : printf("rte_zmalloc didn't zero the allocated memory\n");
93 : : ret = -1;
94 : : }
95 : : }
96 : 10000 : p2 = rte_malloc("dummy", 1000, align2);
97 [ - + ]: 10000 : if (!p2){
98 : : printf("rte_malloc returned NULL (i=%u)\n", i);
99 : : ret = -1;
100 : 0 : rte_free(p1);
101 : 0 : break;
102 : : }
103 : 10000 : p3 = rte_malloc("dummy", 1000, align3);
104 [ - + ]: 10000 : if (!p3){
105 : : printf("rte_malloc returned NULL (i=%u)\n", i);
106 : : ret = -1;
107 : 0 : rte_free(p1);
108 : 0 : rte_free(p2);
109 : 0 : break;
110 : : }
111 : : if (is_memory_overlap(p1, 1000, p2, 1000)) {
112 : : printf("p1 and p2 overlaps\n");
113 : : ret = -1;
114 : : }
115 : : if (is_memory_overlap(p2, 1000, p3, 1000)) {
116 : : printf("p2 and p3 overlaps\n");
117 : : ret = -1;
118 : : }
119 : : if (is_memory_overlap(p1, 1000, p3, 1000)) {
120 : : printf("p1 and p3 overlaps\n");
121 : : ret = -1;
122 : : }
123 : : if (!is_aligned(p1, align1)) {
124 : : printf("p1 is not aligned\n");
125 : : ret = -1;
126 : : }
127 : : if (!is_aligned(p2, align2)) {
128 : : printf("p2 is not aligned\n");
129 : : ret = -1;
130 : : }
131 : : if (!is_aligned(p3, align3)) {
132 : : printf("p3 is not aligned\n");
133 : : ret = -1;
134 : : }
135 : 10000 : rte_free(p1);
136 : 10000 : rte_free(p2);
137 : 10000 : rte_free(p3);
138 : : }
139 : 1 : rte_malloc_dump_stats(stdout, "dummy");
140 : :
141 : 1 : return ret;
142 : : }
143 : :
144 : : static int
145 : 1 : test_align_overlap(void)
146 : : {
147 : : unsigned int lcore_id;
148 : : int ret = 0;
149 : :
150 [ + + ]: 2 : RTE_LCORE_FOREACH_WORKER(lcore_id) {
151 : 1 : rte_eal_remote_launch(test_align_overlap_per_lcore, NULL, lcore_id);
152 : : }
153 : :
154 [ + + ]: 2 : RTE_LCORE_FOREACH_WORKER(lcore_id) {
155 [ - + ]: 1 : if (rte_eal_wait_lcore(lcore_id) < 0)
156 : : ret = -1;
157 : : }
158 : :
159 : 1 : return ret;
160 : : }
161 : :
162 : : static int
163 : 1 : test_reordered_free_per_lcore(__rte_unused void *arg)
164 : : {
165 : : const unsigned align1 = 8,
166 : : align2 = 64,
167 : : align3 = 2048;
168 : : unsigned i,j;
169 : : void *p1, *p2, *p3;
170 : : int ret = 0;
171 : :
172 [ + + ]: 31 : for (i = 0; i < 30; i++) {
173 : 30 : p1 = rte_zmalloc("dummy", 1000, align1);
174 [ + - ]: 30 : if (!p1){
175 : : printf("rte_zmalloc returned NULL (i=%u)\n", i);
176 : : ret = -1;
177 : 0 : break;
178 : : }
179 [ + + ]: 30030 : for(j = 0; j < 1000 ; j++) {
180 [ - + ]: 30000 : if( *(char *)p1 != 0) {
181 : : printf("rte_zmalloc didn't zero the allocated memory\n");
182 : : ret = -1;
183 : : }
184 : : }
185 : : /* use calloc to allocate 1000 16-byte items this time */
186 : 30 : p2 = rte_calloc("dummy", 1000, 16, align2);
187 : : /* for third request use regular malloc again */
188 : 30 : p3 = rte_malloc("dummy", 1000, align3);
189 [ - + ]: 30 : if (!p2 || !p3){
190 : : printf("rte_malloc returned NULL (i=%u)\n", i);
191 : : ret = -1;
192 : 0 : break;
193 : : }
194 : : if (is_memory_overlap(p1, 1000, p2, 1000)) {
195 : : printf("p1 and p2 overlaps\n");
196 : : ret = -1;
197 : : }
198 : : if (is_memory_overlap(p2, 1000, p3, 1000)) {
199 : : printf("p2 and p3 overlaps\n");
200 : : ret = -1;
201 : : }
202 : : if (is_memory_overlap(p1, 1000, p3, 1000)) {
203 : : printf("p1 and p3 overlaps\n");
204 : : ret = -1;
205 : : }
206 : : if (!is_aligned(p1, align1)) {
207 : : printf("p1 is not aligned\n");
208 : : ret = -1;
209 : : }
210 : : if (!is_aligned(p2, align2)) {
211 : : printf("p2 is not aligned\n");
212 : : ret = -1;
213 : : }
214 : : if (!is_aligned(p3, align3)) {
215 : : printf("p3 is not aligned\n");
216 : : ret = -1;
217 : : }
218 : : /* try freeing in every possible order */
219 [ + + + + : 30 : switch (i%6){
+ + ]
220 : 5 : case 0:
221 : 5 : rte_free(p1);
222 : 5 : rte_free(p2);
223 : 5 : rte_free(p3);
224 : 5 : break;
225 : 5 : case 1:
226 : 5 : rte_free(p1);
227 : 5 : rte_free(p3);
228 : 5 : rte_free(p2);
229 : 5 : break;
230 : 5 : case 2:
231 : 5 : rte_free(p2);
232 : 5 : rte_free(p1);
233 : 5 : rte_free(p3);
234 : 5 : break;
235 : 5 : case 3:
236 : 5 : rte_free(p2);
237 : 5 : rte_free(p3);
238 : 5 : rte_free(p1);
239 : 5 : break;
240 : 5 : case 4:
241 : 5 : rte_free(p3);
242 : 5 : rte_free(p1);
243 : 5 : rte_free(p2);
244 : 5 : break;
245 : 5 : case 5:
246 : 5 : rte_free(p3);
247 : 5 : rte_free(p2);
248 : 5 : rte_free(p1);
249 : 5 : break;
250 : : }
251 : : }
252 : 1 : rte_malloc_dump_stats(stdout, "dummy");
253 : :
254 : 1 : return ret;
255 : : }
256 : :
257 : : static int
258 : 1 : test_reordered_free(void)
259 : : {
260 : : unsigned int lcore_id;
261 : : int ret = 0;
262 : :
263 [ + + ]: 2 : RTE_LCORE_FOREACH_WORKER(lcore_id) {
264 : 1 : rte_eal_remote_launch(test_reordered_free_per_lcore, NULL, lcore_id);
265 : : }
266 : :
267 [ + + ]: 2 : RTE_LCORE_FOREACH_WORKER(lcore_id) {
268 [ - + ]: 1 : if (rte_eal_wait_lcore(lcore_id) < 0)
269 : : ret = -1;
270 : : }
271 : 1 : return ret;
272 : : }
273 : :
274 : : /* test function inside the malloc lib*/
275 : : static int
276 : 1 : test_str_to_size(void)
277 : : {
278 : : struct {
279 : : const char *str;
280 : : uint64_t value;
281 : 1 : } test_values[] =
282 : : {{ "5G", (uint64_t)5 * 1024 * 1024 *1024 },
283 : : {"0x20g", (uint64_t)0x20 * 1024 * 1024 *1024},
284 : : {"10M", 10 * 1024 * 1024},
285 : : {"050m", 050 * 1024 * 1024},
286 : : {"8K", 8 * 1024},
287 : : {"15k", 15 * 1024},
288 : : {"0200", 0200},
289 : : {"0x103", 0x103},
290 : : {"432", 432},
291 : : {"-1", 0}, /* negative values return 0 */
292 : : {" -2", 0},
293 : : {" -3MB", 0},
294 : : {"18446744073709551616", 0} /* ULLONG_MAX + 1 == out of range*/
295 : : };
296 : : unsigned i;
297 [ + + ]: 14 : for (i = 0; i < RTE_DIM(test_values); i++)
298 [ + - ]: 13 : if (rte_str_to_size(test_values[i].str) != test_values[i].value)
299 : : return -1;
300 : : return 0;
301 : : }
302 : :
303 : : static int
304 : 1 : test_multi_alloc_statistics(void)
305 : : {
306 : : int ret = -1; /* default return is error, cleared at end on success */
307 : : int socket = 0;
308 : : struct rte_malloc_socket_stats pre_stats, post_stats ,first_stats, second_stats;
309 : : size_t size = 2048;
310 : : int align = 1024;
311 : : int overhead = 0;
312 : 1 : const size_t pgsz = rte_mem_page_size();
313 : : const size_t heap_size = (1 << 22);
314 : :
315 [ - + ]: 1 : if (pgsz > heap_size) {
316 : : printf("Page size (%zu) is bigger than heap size, skipping alloc stats test\n",
317 : : pgsz);
318 : 0 : return TEST_SKIPPED;
319 : : }
320 [ - + ]: 1 : if (heap_size % pgsz != 0) {
321 : : printf("Heap size (%zu) is not a multiple of page size (%zu), skipping alloc stats test\n",
322 : : heap_size, pgsz);
323 : 0 : return TEST_SKIPPED;
324 : : }
325 : :
326 [ - + ]: 1 : if (rte_malloc_heap_create(__func__) != 0) {
327 : : printf("Failed to create test malloc heap\n");
328 : 0 : goto end;
329 : : }
330 : :
331 : : /* Allocate some memory using malloc and add it to our test heap. */
332 : 1 : void *unaligned_memory = malloc(heap_size + pgsz);
333 [ - + ]: 1 : if (unaligned_memory == NULL) {
334 : : printf("Failed to allocate memory\n");
335 : 0 : goto cleanup_empty_heap;
336 : : }
337 : 1 : void *memory = RTE_PTR_ALIGN(unaligned_memory, pgsz);
338 [ - + ]: 1 : if (rte_malloc_heap_memory_add(__func__, memory, heap_size, NULL,
339 : 1 : heap_size / pgsz, pgsz) != 0) {
340 : : printf("Failed to add memory to heap\n");
341 : 0 : goto cleanup_allocated_memory;
342 : : }
343 : 1 : socket = rte_malloc_heap_get_socket(__func__);
344 [ - + ]: 1 : if (socket < 0) {
345 : : printf("Failed to get socket for test malloc heap.\n");
346 : 0 : goto cleanup_all;
347 : : }
348 : :
349 : : /* Dynamically calculate the overhead by allocating one cacheline and
350 : : * then comparing what was allocated from the heap.
351 : : */
352 : 1 : rte_malloc_get_socket_stats(socket, &pre_stats);
353 : :
354 : 1 : void *dummy = rte_malloc_socket(NULL, RTE_CACHE_LINE_SIZE, 0, socket);
355 [ - + ]: 1 : if (dummy == NULL)
356 : 0 : goto cleanup_all;
357 : :
358 : 1 : rte_malloc_get_socket_stats(socket, &post_stats);
359 : :
360 : : /* after subtracting cache line, remainder is overhead */
361 : 1 : overhead = post_stats.heap_allocsz_bytes - pre_stats.heap_allocsz_bytes;
362 : : overhead -= RTE_CACHE_LINE_SIZE;
363 : :
364 : 1 : rte_free(dummy);
365 : :
366 : : /* Now start the real tests */
367 : 1 : rte_malloc_get_socket_stats(socket, &pre_stats);
368 : :
369 : 1 : void *p1 = rte_malloc_socket("stats", size , align, socket);
370 [ - + ]: 1 : if (!p1)
371 : 0 : goto cleanup_all;
372 : :
373 : 1 : rte_free(p1);
374 : 1 : rte_malloc_dump_stats(stdout, "stats");
375 : :
376 : 1 : rte_malloc_get_socket_stats(socket,&post_stats);
377 : : /* Check statistics reported are correct */
378 : : /* All post stats should be equal to pre stats after alloc freed */
379 [ + - ]: 1 : if ((post_stats.heap_totalsz_bytes != pre_stats.heap_totalsz_bytes) ||
380 [ + - ]: 1 : (post_stats.heap_freesz_bytes != pre_stats.heap_freesz_bytes) ||
381 [ + - ]: 1 : (post_stats.heap_allocsz_bytes != pre_stats.heap_allocsz_bytes) ||
382 [ - + ]: 1 : (post_stats.alloc_count != pre_stats.alloc_count) ||
383 : : (post_stats.free_count != pre_stats.free_count)) {
384 : : printf("Malloc statistics are incorrect - freed alloc\n");
385 : 0 : goto cleanup_all;
386 : : }
387 : : /* Check two consecutive allocations */
388 : : size = 1024;
389 : : align = 0;
390 : 1 : rte_malloc_get_socket_stats(socket,&pre_stats);
391 : 1 : void *p2 = rte_malloc_socket("add", size ,align, socket);
392 [ - + ]: 1 : if (!p2)
393 : 0 : goto cleanup_all;
394 : 1 : rte_malloc_get_socket_stats(socket,&first_stats);
395 : :
396 : 1 : void *p3 = rte_malloc_socket("add2", size,align, socket);
397 [ - + ]: 1 : if (!p3)
398 : 0 : goto cleanup_all;
399 : :
400 : 1 : rte_malloc_get_socket_stats(socket,&second_stats);
401 : :
402 : 1 : rte_free(p2);
403 : 1 : rte_free(p3);
404 : :
405 : : /* After freeing both allocations check stats return to original */
406 : 1 : rte_malloc_get_socket_stats(socket, &post_stats);
407 : :
408 [ - + ]: 1 : if(second_stats.heap_totalsz_bytes != first_stats.heap_totalsz_bytes) {
409 : : printf("Incorrect heap statistics: Total size \n");
410 : 0 : goto cleanup_all;
411 : : }
412 : : /* Check allocated size is equal to two additions plus overhead */
413 : 1 : if(second_stats.heap_allocsz_bytes !=
414 [ - + ]: 1 : size + overhead + first_stats.heap_allocsz_bytes) {
415 : : printf("Incorrect heap statistics: Allocated size \n");
416 : 0 : goto cleanup_all;
417 : : }
418 : : /* Check that allocation count increments correctly i.e. +1 */
419 [ - + ]: 1 : if (second_stats.alloc_count != first_stats.alloc_count + 1) {
420 : : printf("Incorrect heap statistics: Allocated count \n");
421 : 0 : goto cleanup_all;
422 : : }
423 : :
424 [ - + ]: 1 : if (second_stats.free_count != first_stats.free_count){
425 : : printf("Incorrect heap statistics: Free count \n");
426 : 0 : goto cleanup_all;
427 : : }
428 : :
429 : : /* Make sure that we didn't touch our greatest chunk: 2 * 11M) */
430 [ - + ]: 1 : if (post_stats.greatest_free_size != pre_stats.greatest_free_size) {
431 : : printf("Incorrect heap statistics: Greatest free size \n");
432 : 0 : goto cleanup_all;
433 : : }
434 : : /* Free size must equal the original free size minus the new allocation*/
435 [ - + ]: 1 : if (first_stats.heap_freesz_bytes <= second_stats.heap_freesz_bytes) {
436 : : printf("Incorrect heap statistics: Free size \n");
437 : 0 : goto cleanup_all;
438 : : }
439 : :
440 [ + - ]: 1 : if ((post_stats.heap_totalsz_bytes != pre_stats.heap_totalsz_bytes) ||
441 [ + - ]: 1 : (post_stats.heap_freesz_bytes != pre_stats.heap_freesz_bytes) ||
442 [ + - ]: 1 : (post_stats.heap_allocsz_bytes != pre_stats.heap_allocsz_bytes) ||
443 [ - + ]: 1 : (post_stats.alloc_count != pre_stats.alloc_count) ||
444 : : (post_stats.free_count != pre_stats.free_count)) {
445 : : printf("Malloc statistics are incorrect - freed alloc\n");
446 : 0 : goto cleanup_all;
447 : : }
448 : :
449 : : /* set return value as success before cleanup */
450 : : ret = 0;
451 : :
452 : : /* cleanup */
453 : 1 : cleanup_all:
454 : 1 : rte_malloc_heap_memory_remove(__func__, memory, heap_size);
455 : 1 : cleanup_allocated_memory:
456 : 1 : free(unaligned_memory);
457 : 1 : cleanup_empty_heap:
458 : 1 : rte_malloc_heap_destroy(__func__);
459 : : end:
460 : : return ret;
461 : : }
462 : :
463 : : #ifdef RTE_EXEC_ENV_WINDOWS
464 : : static int
465 : : test_realloc(void)
466 : : {
467 : : return TEST_SKIPPED;
468 : : }
469 : : #else
470 : :
471 : : static int
472 : 1 : test_realloc_socket(int socket)
473 : : {
474 : 1 : const char hello_str[] = "Hello, world!";
475 : : const unsigned size1 = 1024;
476 : : const unsigned size2 = size1 + 1024;
477 : : const unsigned size3 = size2;
478 : : const unsigned size4 = size3 + 1024;
479 : :
480 : : /* test data is the same even if element is moved*/
481 : 1 : char *ptr1 = rte_zmalloc_socket(
482 : : NULL, size1, RTE_CACHE_LINE_SIZE, socket);
483 [ - + ]: 1 : if (!ptr1){
484 : : printf("NULL pointer returned from rte_zmalloc\n");
485 : 0 : return -1;
486 : : }
487 : : strlcpy(ptr1, hello_str, size1);
488 : 1 : char *ptr2 = rte_realloc_socket(
489 : : ptr1, size2, RTE_CACHE_LINE_SIZE, socket);
490 [ - + ]: 1 : if (!ptr2){
491 : 0 : rte_free(ptr1);
492 : : printf("NULL pointer returned from rte_realloc\n");
493 : 0 : return -1;
494 : : }
495 [ - + ]: 1 : if (ptr1 == ptr2){
496 : : printf("unexpected - ptr1 == ptr2\n");
497 : : }
498 [ - + ]: 1 : if (strcmp(ptr2, hello_str) != 0){
499 : : printf("Error - lost data from pointed area\n");
500 : 0 : rte_free(ptr2);
501 : 0 : return -1;
502 : : }
503 : : unsigned i;
504 [ + + ]: 1012 : for (i = strnlen(hello_str, sizeof(hello_str)); i < size1; i++)
505 [ - + ]: 1011 : if (ptr2[i] != 0){
506 : : printf("Bad data in realloc\n");
507 : 0 : rte_free(ptr2);
508 : 0 : return -1;
509 : : }
510 : : /* now allocate third element, free the second
511 : : * and resize third. It should not move. (ptr1 is now invalid)
512 : : */
513 : 1 : char *ptr3 = rte_zmalloc_socket(
514 : : NULL, size3, RTE_CACHE_LINE_SIZE, socket);
515 [ - + ]: 1 : if (!ptr3){
516 : : printf("NULL pointer returned from rte_zmalloc\n");
517 : 0 : rte_free(ptr2);
518 : 0 : return -1;
519 : : }
520 [ + + ]: 2049 : for (i = 0; i < size3; i++)
521 [ - + ]: 2048 : if (ptr3[i] != 0){
522 : : printf("Bad data in zmalloc\n");
523 : 0 : rte_free(ptr3);
524 : 0 : rte_free(ptr2);
525 : 0 : return -1;
526 : : }
527 : 1 : rte_free(ptr2);
528 : : /* first resize to half the size of the freed block */
529 : 1 : char *ptr4 = rte_realloc_socket(
530 : : ptr3, size4, RTE_CACHE_LINE_SIZE, socket);
531 [ - + ]: 1 : if (!ptr4){
532 : : printf("NULL pointer returned from rte_realloc\n");
533 : 0 : rte_free(ptr3);
534 : 0 : return -1;
535 : : }
536 [ - + ]: 1 : if (ptr3 != ptr4){
537 : : printf("Unexpected - ptr4 != ptr3\n");
538 : 0 : rte_free(ptr4);
539 : 0 : return -1;
540 : : }
541 : : /* now resize again to the full size of the freed block */
542 : 1 : ptr4 = rte_realloc_socket(ptr3, size3 + size2 + size1,
543 : : RTE_CACHE_LINE_SIZE, socket);
544 [ - + ]: 1 : if (ptr3 != ptr4){
545 : : printf("Unexpected - ptr4 != ptr3 on second resize\n");
546 : 0 : rte_free(ptr4);
547 : 0 : return -1;
548 : : }
549 : 1 : rte_free(ptr4);
550 : :
551 : : /* now try a resize to a smaller size, see if it works */
552 : : const unsigned size5 = 1024;
553 : : const unsigned size6 = size5 / 2;
554 : 1 : char *ptr5 = rte_malloc_socket(
555 : : NULL, size5, RTE_CACHE_LINE_SIZE, socket);
556 [ - + ]: 1 : if (!ptr5){
557 : : printf("NULL pointer returned from rte_malloc\n");
558 : 0 : return -1;
559 : : }
560 : 1 : char *ptr6 = rte_realloc_socket(
561 : : ptr5, size6, RTE_CACHE_LINE_SIZE, socket);
562 [ - + ]: 1 : if (!ptr6){
563 : : printf("NULL pointer returned from rte_realloc\n");
564 : 0 : rte_free(ptr5);
565 : 0 : return -1;
566 : : }
567 [ - + ]: 1 : if (ptr5 != ptr6){
568 : : printf("Error, resizing to a smaller size moved data\n");
569 : 0 : rte_free(ptr6);
570 : 0 : return -1;
571 : : }
572 : 1 : rte_free(ptr6);
573 : :
574 : : /* check for behaviour changing alignment */
575 : : const unsigned size7 = 1024;
576 : : const unsigned orig_align = RTE_CACHE_LINE_SIZE;
577 : : unsigned new_align = RTE_CACHE_LINE_SIZE * 2;
578 : 1 : char *ptr7 = rte_malloc_socket(NULL, size7, orig_align, socket);
579 [ - + ]: 1 : if (!ptr7){
580 : : printf("NULL pointer returned from rte_malloc\n");
581 : 0 : return -1;
582 : : }
583 : : /* calc an alignment we don't already have */
584 [ + + ]: 5 : while(RTE_PTR_ALIGN(ptr7, new_align) == ptr7)
585 : 4 : new_align *= 2;
586 : 1 : char *ptr8 = rte_realloc_socket(ptr7, size7, new_align, socket);
587 [ - + ]: 1 : if (!ptr8){
588 : : printf("NULL pointer returned from rte_realloc\n");
589 : 0 : rte_free(ptr7);
590 : 0 : return -1;
591 : : }
592 [ - + ]: 1 : if (RTE_PTR_ALIGN(ptr8, new_align) != ptr8){
593 : : printf("Failure to re-align data\n");
594 : 0 : rte_free(ptr8);
595 : 0 : return -1;
596 : : }
597 : 1 : rte_free(ptr8);
598 : :
599 : : /* test behaviour when there is a free block after current one,
600 : : * but its not big enough
601 : : */
602 : : unsigned size9 = 1024, size10 = 1024;
603 : : unsigned size11 = size9 + size10 + 256;
604 : 1 : char *ptr9 = rte_malloc_socket(
605 : : NULL, size9, RTE_CACHE_LINE_SIZE, socket);
606 [ - + ]: 1 : if (!ptr9){
607 : : printf("NULL pointer returned from rte_malloc\n");
608 : 0 : return -1;
609 : : }
610 : 1 : char *ptr10 = rte_malloc_socket(
611 : : NULL, size10, RTE_CACHE_LINE_SIZE, socket);
612 [ - + ]: 1 : if (!ptr10){
613 : : printf("NULL pointer returned from rte_malloc\n");
614 : 0 : return -1;
615 : : }
616 : 1 : rte_free(ptr9);
617 : 1 : char *ptr11 = rte_realloc_socket(
618 : : ptr10, size11, RTE_CACHE_LINE_SIZE, socket);
619 [ - + ]: 1 : if (!ptr11){
620 : : printf("NULL pointer returned from rte_realloc\n");
621 : 0 : rte_free(ptr10);
622 : 0 : return -1;
623 : : }
624 [ - + ]: 1 : if (ptr11 == ptr10){
625 : : printf("Error, unexpected that realloc has not created new buffer\n");
626 : 0 : rte_free(ptr11);
627 : 0 : return -1;
628 : : }
629 : 1 : rte_free(ptr11);
630 : :
631 : : /* check we don't crash if we pass null to realloc
632 : : * We should get a malloc of the size requested*/
633 : : const size_t size12 = 1024;
634 : : size_t size12_check;
635 : 1 : char *ptr12 = rte_realloc_socket(
636 : : NULL, size12, RTE_CACHE_LINE_SIZE, socket);
637 [ - + ]: 1 : if (!ptr12){
638 : : printf("NULL pointer returned from rte_realloc\n");
639 : 0 : return -1;
640 : : }
641 [ + - ]: 1 : if (rte_malloc_validate(ptr12, &size12_check) < 0 ||
642 [ - + ]: 1 : size12_check != size12){
643 : 0 : rte_free(ptr12);
644 : 0 : return -1;
645 : : }
646 : 1 : rte_free(ptr12);
647 : :
648 : : /* do the same, but for regular memory */
649 : 1 : ptr12 = rte_realloc(NULL, size12, RTE_CACHE_LINE_SIZE);
650 [ - + ]: 1 : if (!ptr12) {
651 : : printf("NULL pointer returned from rte_realloc\n");
652 : 0 : return -1;
653 : : }
654 [ + - ]: 1 : if (rte_malloc_validate(ptr12, &size12_check) < 0 ||
655 [ - + ]: 1 : size12_check != size12) {
656 : 0 : rte_free(ptr12);
657 : 0 : return -1;
658 : : }
659 : 1 : rte_free(ptr12);
660 : :
661 : 1 : return 0;
662 : : }
663 : :
664 : : static int
665 : 1 : test_realloc_numa(void)
666 : : {
667 : : /* check realloc_socket part */
668 : : int32_t socket_count = 0, socket_allocated, socket;
669 : : void *ptr1, *ptr2;
670 : : int ret = -1;
671 : : size_t size = 1024;
672 : :
673 : : ptr1 = NULL;
674 [ + + ]: 33 : for (socket = 0; socket < RTE_MAX_NUMA_NODES; socket++) {
675 [ + + ]: 32 : if (is_mem_on_socket(socket)) {
676 : : int j = 2;
677 : :
678 : 2 : socket_count++;
679 [ + + ]: 6 : while (j--) {
680 : : /* j == 1 -> resizing */
681 : 4 : ptr2 = rte_realloc_socket(ptr1, size,
682 : : RTE_CACHE_LINE_SIZE,
683 : : socket);
684 [ - + ]: 4 : if (ptr2 == NULL) {
685 : : printf("NULL pointer returned from rte_realloc_socket\n");
686 : 0 : goto end;
687 : : }
688 : :
689 : : ptr1 = ptr2;
690 : : socket_allocated = addr_to_socket(ptr2);
691 [ - + ]: 4 : if (socket_allocated != socket) {
692 : : printf("Requested socket (%d) doesn't mach allocated one (%d)\n",
693 : : socket, socket_allocated);
694 : 0 : goto end;
695 : : }
696 : 4 : size += RTE_CACHE_LINE_SIZE;
697 : : }
698 : : }
699 : : }
700 : :
701 : : /* Print warning if only a single socket, but don't fail the test */
702 [ - + ]: 1 : if (socket_count < 2)
703 : : printf("WARNING: realloc_socket test needs memory on multiple sockets!\n");
704 : :
705 : : ret = 0;
706 : 1 : end:
707 : 1 : rte_free(ptr1);
708 : 1 : return ret;
709 : : }
710 : :
711 : : static int
712 : 1 : test_realloc(void)
713 : : {
714 : : const char *heap_name = "realloc_heap";
715 : : int realloc_heap_socket;
716 : : unsigned int mem_sz = 1U << 13; /* 8K */
717 : 1 : unsigned int page_sz = sysconf(_SC_PAGESIZE);
718 : : void *mem;
719 : : int ret;
720 : :
721 : : /* page size may be bigger than total mem size, so adjust */
722 : 1 : mem_sz = RTE_MAX(mem_sz, page_sz);
723 : :
724 : : /*
725 : : * the realloc tests depend on specific layout of underlying memory, so
726 : : * to prevent accidental failures to do fragmented main heap, we will
727 : : * do all of our tests on an artificially created memory.
728 : : */
729 [ - + ]: 1 : if (rte_malloc_heap_create(heap_name) != 0) {
730 : : printf("Failed to create external heap\n");
731 : : ret = -1;
732 : 0 : goto end;
733 : : }
734 : 1 : realloc_heap_socket = rte_malloc_heap_get_socket(heap_name);
735 : :
736 : 1 : mem = mmap(NULL, mem_sz, PROT_READ | PROT_WRITE,
737 : : MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
738 [ - + ]: 1 : if (mem == MAP_FAILED) {
739 : : printf("Failed to allocate memory for external heap\n");
740 : : ret = -1;
741 : 0 : goto heap_destroy;
742 : : }
743 : :
744 [ - + ]: 1 : if (rte_malloc_heap_memory_add(
745 : : heap_name, mem, mem_sz, NULL, 0, page_sz) != 0) {
746 : : printf("Failed to add memory to external heap\n");
747 : : ret = -1;
748 : 0 : goto mem_free;
749 : : }
750 : :
751 : : /* run the socket-bound tests */
752 : 1 : ret = test_realloc_socket(realloc_heap_socket);
753 [ - + ]: 1 : if (ret != 0)
754 : 0 : goto mem_remove;
755 : :
756 : : /* now, run the NUMA node tests */
757 : 1 : ret = test_realloc_numa();
758 : :
759 : 1 : mem_remove:
760 : 1 : rte_malloc_heap_memory_remove(heap_name, mem, mem_sz);
761 : 1 : mem_free:
762 : 1 : munmap(mem, mem_sz);
763 : 1 : heap_destroy:
764 : 1 : rte_malloc_heap_destroy(heap_name);
765 : 1 : end:
766 : 1 : return ret;
767 : : }
768 : :
769 : : #endif /* !RTE_EXEC_ENV_WINDOWS */
770 : :
771 : : static int
772 : 1 : test_random_alloc_free(void *_ __rte_unused)
773 : : {
774 : : struct mem_list {
775 : : struct mem_list *next;
776 : : char data[0];
777 : : } *list_head = NULL;
778 : : unsigned i;
779 : : unsigned count = 0;
780 : :
781 [ + + ]: 10001 : for (i = 0; i < N; i++){
782 : : unsigned free_mem = 0;
783 : : size_t allocated_size;
784 [ + + ]: 60151 : while (!free_mem){
785 : 50151 : const unsigned mem_size = sizeof(struct mem_list) + \
786 : 50151 : rte_rand() % (64 * 1024);
787 : 50151 : const unsigned align = 1 << (rte_rand() % 12); /* up to 4k alignment */
788 : 50151 : struct mem_list *entry = rte_malloc(NULL,
789 : : mem_size, align);
790 [ + - ]: 50151 : if (entry == NULL)
791 : 0 : return -1;
792 [ + - ]: 50151 : if (RTE_PTR_ALIGN(entry, align)!= entry)
793 : : return -1;
794 [ + - ]: 50151 : if (rte_malloc_validate(entry, &allocated_size) == -1
795 [ + - ]: 50151 : || allocated_size < mem_size)
796 : : return -1;
797 : 50151 : memset(entry->data, rte_lcore_id(),
798 : : mem_size - sizeof(*entry));
799 : 50151 : entry->next = list_head;
800 [ + - ]: 50151 : if (rte_malloc_validate(entry, NULL) == -1)
801 : : return -1;
802 : : list_head = entry;
803 : :
804 : 50151 : count++;
805 : : /* switch to freeing the memory with a 20% probability */
806 : 50151 : free_mem = ((rte_rand() % 10) >= 8);
807 : : }
808 [ + + ]: 60151 : while (list_head){
809 : : struct mem_list *entry = list_head;
810 : 50151 : list_head = list_head->next;
811 : 50151 : rte_free(entry);
812 : : }
813 : : }
814 : : printf("Lcore %u allocated/freed %u blocks\n", rte_lcore_id(), count);
815 : 1 : return 0;
816 : : }
817 : :
818 : : static int
819 : 1 : test_random(void)
820 : : {
821 : : unsigned int lcore_id;
822 : : int ret = 0;
823 : :
824 [ + + ]: 2 : RTE_LCORE_FOREACH_WORKER(lcore_id) {
825 : 1 : rte_eal_remote_launch(test_random_alloc_free, NULL, lcore_id);
826 : : }
827 : :
828 [ + + ]: 2 : RTE_LCORE_FOREACH_WORKER(lcore_id) {
829 [ - + ]: 1 : if (rte_eal_wait_lcore(lcore_id) < 0)
830 : : ret = -1;
831 : : }
832 : 1 : return ret;
833 : : }
834 : :
835 : : #define err_return() do { \
836 : : printf("%s: %d - Error\n", __func__, __LINE__); \
837 : : goto err_return; \
838 : : } while (0)
839 : :
840 : : static int
841 : 1 : test_rte_malloc_validate(void)
842 : : {
843 : : const size_t request_size = 1024;
844 : : size_t allocated_size;
845 : 1 : char *data_ptr = rte_malloc(NULL, request_size, RTE_CACHE_LINE_SIZE);
846 : : #ifdef RTE_MALLOC_DEBUG
847 : : int retval;
848 : : char *over_write_vals = NULL;
849 : : #endif
850 : :
851 [ - + ]: 1 : if (data_ptr == NULL) {
852 : : printf("%s: %d - Allocation error\n", __func__, __LINE__);
853 : 0 : return -1;
854 : : }
855 : :
856 : : /* check that a null input returns -1 */
857 [ - + ]: 1 : if (rte_malloc_validate(NULL, NULL) != -1)
858 : 0 : err_return();
859 : :
860 : : /* check that we get ok on a valid pointer */
861 [ - + ]: 1 : if (rte_malloc_validate(data_ptr, &allocated_size) < 0)
862 : 0 : err_return();
863 : :
864 : : /* check that the returned size is ok */
865 [ - + ]: 1 : if (allocated_size < request_size)
866 : 0 : err_return();
867 : :
868 : : #ifdef RTE_MALLOC_DEBUG
869 : :
870 : : /****** change the header to be bad */
871 : : char save_buf[64];
872 : : over_write_vals = (char *)((uintptr_t)data_ptr - sizeof(save_buf));
873 : : /* first save the data as a backup before overwriting it */
874 : : memcpy(save_buf, over_write_vals, sizeof(save_buf));
875 : : memset(over_write_vals, 1, sizeof(save_buf));
876 : : /* then run validate */
877 : : retval = rte_malloc_validate(data_ptr, NULL);
878 : : /* finally restore the data again */
879 : : memcpy(over_write_vals, save_buf, sizeof(save_buf));
880 : : /* check we previously had an error */
881 : : if (retval != -1)
882 : : err_return();
883 : :
884 : : /* check all ok again */
885 : : if (rte_malloc_validate(data_ptr, &allocated_size) < 0)
886 : : err_return();
887 : :
888 : : /**** change the trailer to be bad */
889 : : over_write_vals = (char *)((uintptr_t)data_ptr + allocated_size);
890 : : /* first save the data as a backup before overwriting it */
891 : : memcpy(save_buf, over_write_vals, sizeof(save_buf));
892 : : memset(over_write_vals, 1, sizeof(save_buf));
893 : : /* then run validate */
894 : : retval = rte_malloc_validate(data_ptr, NULL);
895 : : /* finally restore the data again */
896 : : memcpy(over_write_vals, save_buf, sizeof(save_buf));
897 : : if (retval != -1)
898 : : err_return();
899 : :
900 : : /* check all ok again */
901 : : if (rte_malloc_validate(data_ptr, &allocated_size) < 0)
902 : : err_return();
903 : : #endif
904 : :
905 : 1 : rte_free(data_ptr);
906 : 1 : return 0;
907 : :
908 : 0 : err_return:
909 : : /*clean up */
910 : 0 : rte_free(data_ptr);
911 : 0 : return -1;
912 : : }
913 : :
914 : : static int
915 : 1 : test_zero_aligned_alloc(void)
916 : : {
917 : 1 : char *p1 = rte_malloc(NULL,1024, 0);
918 [ - + ]: 1 : if (!p1)
919 : 0 : goto err_return;
920 [ - + ]: 1 : if (!rte_is_aligned(p1, RTE_CACHE_LINE_SIZE))
921 : 0 : goto err_return;
922 : 1 : rte_free(p1);
923 : 1 : return 0;
924 : :
925 : 0 : err_return:
926 : : /*clean up */
927 : 0 : rte_free(p1);
928 : 0 : return -1;
929 : : }
930 : :
931 : : static int
932 : 1 : test_malloc_bad_params(void)
933 : : {
934 : : const char *type = NULL;
935 : : size_t size = 0;
936 : : unsigned align = RTE_CACHE_LINE_SIZE;
937 : :
938 : : /* rte_malloc expected to return null with inappropriate size */
939 : 1 : char *bad_ptr = rte_malloc(type, size, align);
940 [ - + ]: 1 : if (bad_ptr != NULL)
941 : 0 : goto err_return;
942 : :
943 : : /* rte_realloc expected to return null with inappropriate size */
944 : 1 : bad_ptr = rte_realloc(NULL, size, align);
945 [ - + ]: 1 : if (bad_ptr != NULL)
946 : 0 : goto err_return;
947 : :
948 : : /* rte_malloc expected to return null with inappropriate alignment */
949 : : align = 17;
950 : : size = 1024;
951 : :
952 : 1 : bad_ptr = rte_malloc(type, size, align);
953 [ - + ]: 1 : if (bad_ptr != NULL)
954 : 0 : goto err_return;
955 : :
956 : : /* rte_realloc expected to return null with inappropriate alignment */
957 : 1 : bad_ptr = rte_realloc(NULL, size, align);
958 [ - + ]: 1 : if (bad_ptr != NULL)
959 : 0 : goto err_return;
960 : :
961 : : #if defined(RTE_CC_GCC) || defined(RTE_CC_CLANG)
962 : : /* this test can not be built, will get trapped at compile time! */
963 : : #else
964 : : /* rte_malloc expected to return null with size will cause overflow */
965 : : align = RTE_CACHE_LINE_SIZE;
966 : : size = (size_t)-8;
967 : :
968 : : bad_ptr = rte_malloc(type, size, align);
969 : : if (bad_ptr != NULL)
970 : : goto err_return;
971 : :
972 : : bad_ptr = rte_realloc(NULL, size, align);
973 : : if (bad_ptr != NULL)
974 : : goto err_return;
975 : : #endif
976 : : return 0;
977 : :
978 : 0 : err_return:
979 : : /* clean up pointer */
980 : 0 : rte_free(bad_ptr);
981 : 0 : return -1;
982 : : }
983 : :
984 : : static int
985 : 522 : check_socket_mem(const struct rte_memseg_list *msl, void *arg)
986 : : {
987 : : int32_t *socket = arg;
988 : :
989 [ + + ]: 522 : if (msl->external)
990 : : return 0;
991 : :
992 : 492 : return *socket == msl->socket_id;
993 : : }
994 : :
995 : : /* Check if memory is available on a specific socket */
996 : : static int
997 : : is_mem_on_socket(int32_t socket)
998 : : {
999 : 32 : return rte_memseg_list_walk(check_socket_mem, &socket);
1000 : : }
1001 : :
1002 : :
1003 : : /*
1004 : : * Find what socket a memory address is on. Only works for addresses within
1005 : : * memsegs, not heap or stack...
1006 : : */
1007 : : static int32_t
1008 : : addr_to_socket(void * addr)
1009 : : {
1010 : 13 : const struct rte_memseg *ms = rte_mem_virt2memseg(addr, NULL);
1011 [ + - + - : 13 : return ms == NULL ? -1 : ms->socket_id;
+ - + - ]
1012 : :
1013 : : }
1014 : :
1015 : : /* Test using rte_[c|m|zm]alloc_socket() on a specific socket */
1016 : : static int
1017 : 33 : test_alloc_single_socket(int32_t socket)
1018 : : {
1019 : : const char *type = NULL;
1020 : : const size_t size = 10;
1021 : : const unsigned align = 0;
1022 : : char *mem = NULL;
1023 : : int32_t desired_socket = (socket == SOCKET_ID_ANY) ?
1024 [ + + ]: 33 : (int32_t)rte_socket_id() : socket;
1025 : :
1026 : : /* Test rte_calloc_socket() */
1027 : 33 : mem = rte_calloc_socket(type, size, sizeof(char), align, socket);
1028 [ + + ]: 33 : if (mem == NULL)
1029 : : return -1;
1030 [ - + ]: 3 : if (addr_to_socket(mem) != desired_socket) {
1031 : 0 : rte_free(mem);
1032 : 0 : return -1;
1033 : : }
1034 : 3 : rte_free(mem);
1035 : :
1036 : : /* Test rte_malloc_socket() */
1037 : 3 : mem = rte_malloc_socket(type, size, align, socket);
1038 [ + - ]: 3 : if (mem == NULL)
1039 : : return -1;
1040 [ - + ]: 3 : if (addr_to_socket(mem) != desired_socket) {
1041 : 0 : rte_free(mem);
1042 : 0 : return -1;
1043 : : }
1044 : 3 : rte_free(mem);
1045 : :
1046 : : /* Test rte_zmalloc_socket() */
1047 : 3 : mem = rte_zmalloc_socket(type, size, align, socket);
1048 [ + - ]: 3 : if (mem == NULL)
1049 : : return -1;
1050 [ - + ]: 3 : if (addr_to_socket(mem) != desired_socket) {
1051 : 0 : rte_free(mem);
1052 : 0 : return -1;
1053 : : }
1054 : 3 : rte_free(mem);
1055 : :
1056 : 3 : return 0;
1057 : : }
1058 : :
1059 : : static int
1060 : 1 : test_alloc_socket(void)
1061 : : {
1062 : : unsigned socket_count = 0;
1063 : : unsigned i;
1064 : :
1065 [ + - ]: 1 : if (test_alloc_single_socket(SOCKET_ID_ANY) < 0)
1066 : : return -1;
1067 : :
1068 [ + + ]: 33 : for (i = 0; i < RTE_MAX_NUMA_NODES; i++) {
1069 [ + + ]: 32 : if (is_mem_on_socket(i)) {
1070 : 2 : socket_count++;
1071 [ - + ]: 2 : if (test_alloc_single_socket(i) < 0) {
1072 : : printf("Fail: rte_malloc_socket(..., %u) did not succeed\n",
1073 : : i);
1074 : 0 : return -1;
1075 : : }
1076 : : }
1077 : : else {
1078 [ - + ]: 30 : if (test_alloc_single_socket(i) == 0) {
1079 : : printf("Fail: rte_malloc_socket(..., %u) succeeded\n",
1080 : : i);
1081 : 0 : return -1;
1082 : : }
1083 : : }
1084 : : }
1085 : :
1086 : : /* Print warning if only a single socket, but don't fail the test */
1087 [ - + ]: 1 : if (socket_count < 2) {
1088 : : printf("WARNING: alloc_socket test needs memory on multiple sockets!\n");
1089 : : }
1090 : :
1091 : : return 0;
1092 : : }
1093 : :
1094 : : static int
1095 : 1 : run_rte_free_sensitive(void *arg)
1096 : : {
1097 : 1 : rte_free_sensitive(arg);
1098 : 1 : return 0;
1099 : : }
1100 : :
1101 : : /* Check that memory freed is zero now.
1102 : : * Need to disable address sanitizer since use after free is intentional here.
1103 : : */
1104 : : __rte_no_asan
1105 : : static int
1106 : : check_free_memory_is_zero(const char *data, size_t sz)
1107 : : {
1108 [ + + ]: 129 : for (unsigned int i = 0; i < sz; i++)
1109 [ + - ]: 128 : if (data[i] != 0)
1110 : : return 0;
1111 : : return 1;
1112 : : }
1113 : :
1114 : : static int
1115 : 1 : test_free_sensitive(void)
1116 : : {
1117 : : #define SENSITIVE_KEY_SIZE 128
1118 : :
1119 [ - + ]: 1 : if (rte_lcore_count() < 2) {
1120 : : printf("Need multiple cores to run memzero explicit test.\n");
1121 : 0 : return TEST_SKIPPED;
1122 : : }
1123 : :
1124 : 1 : unsigned int worker_lcore_id = rte_get_next_lcore(-1, 1, 0);
1125 [ - + ]: 1 : TEST_ASSERT(worker_lcore_id < RTE_MAX_LCORE, "get_next_lcore failed");
1126 : :
1127 : : /* Allocate a buffer and fill with sensitive data */
1128 : 1 : char *key = rte_zmalloc("dummy", SENSITIVE_KEY_SIZE, 0);
1129 [ - + ]: 1 : TEST_ASSERT(key != NULL, "rte_zmalloc failed");
1130 : 1 : rte_strscpy(key, "Super secret key", SENSITIVE_KEY_SIZE);
1131 : :
1132 : : /* Pass that data to worker thread to free */
1133 : 1 : int rc = rte_eal_remote_launch(run_rte_free_sensitive, key, worker_lcore_id);
1134 [ - + ]: 1 : TEST_ASSERT(rc == 0, "Worker thread launch failed");
1135 : :
1136 : : /* Wait for worker */
1137 : 1 : rte_eal_mp_wait_lcore();
1138 : :
1139 [ - + ]: 1 : TEST_ASSERT(check_free_memory_is_zero(key, SENSITIVE_KEY_SIZE),
1140 : : "rte_free_sensitive data not zero");
1141 : :
1142 : : return 0;
1143 : : }
1144 : :
1145 : : static struct unit_test_suite test_suite = {
1146 : : .suite_name = "Malloc test suite",
1147 : : .unit_test_cases = {
1148 : : TEST_CASE(test_str_to_size),
1149 : : TEST_CASE(test_zero_aligned_alloc),
1150 : : TEST_CASE(test_malloc_bad_params),
1151 : : TEST_CASE(test_realloc),
1152 : : TEST_CASE(test_align_overlap),
1153 : : TEST_CASE(test_reordered_free),
1154 : : TEST_CASE(test_random),
1155 : : TEST_CASE(test_rte_malloc_validate),
1156 : : TEST_CASE(test_alloc_socket),
1157 : : TEST_CASE(test_multi_alloc_statistics),
1158 : : TEST_CASE(test_free_sensitive),
1159 : : TEST_CASES_END()
1160 : : }
1161 : : };
1162 : :
1163 : : static int
1164 : 1 : test_malloc(void)
1165 : : {
1166 : 1 : return unit_test_suite_runner(&test_suite);
1167 : : }
1168 : :
1169 : 253 : REGISTER_FAST_TEST(malloc_autotest, false, true, test_malloc);
|