test: use SPDX tag for Intel copyright files
[dpdk.git] / test / test / test_memzone.c
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright(c) 2010-2014 Intel Corporation
3  */
4
5 #include <stdio.h>
6 #include <stdint.h>
7 #include <inttypes.h>
8 #include <sys/queue.h>
9
10 #include <rte_random.h>
11 #include <rte_cycles.h>
12 #include <rte_memory.h>
13 #include <rte_memzone.h>
14 #include <rte_eal.h>
15 #include <rte_eal_memconfig.h>
16 #include <rte_common.h>
17 #include <rte_string_fns.h>
18 #include <rte_errno.h>
19 #include <rte_malloc.h>
20 #include "../../lib/librte_eal/common/malloc_elem.h"
21
22 #include "test.h"
23
24 /*
25  * Memzone
26  * =======
27  *
28  * - Search for three reserved zones or reserve them if they do not exist:
29  *
30  *   - One is on any socket id.
31  *   - The second is on socket 0.
32  *   - The last one is on socket 1 (if socket 1 exists).
33  *
34  * - Check that the zones exist.
35  *
36  * - Check that the zones are cache-aligned.
37  *
38  * - Check that zones do not overlap.
39  *
40  * - Check that the zones are on the correct socket id.
41  *
42  * - Check that a lookup of the first zone returns the same pointer.
43  *
44  * - Check that it is not possible to create another zone with the
45  *   same name as an existing zone.
46  *
47  * - Check flags for specific huge page size reservation
48  */
49
50 /* Test if memory overlaps: return 1 if true, or 0 if false. */
51 static int
52 is_memory_overlap(rte_iova_t ptr1, size_t len1, rte_iova_t ptr2, size_t len2)
53 {
54         if (ptr2 >= ptr1 && (ptr2 - ptr1) < len1)
55                 return 1;
56         else if (ptr2 < ptr1 && (ptr1 - ptr2) < len2)
57                 return 1;
58         return 0;
59 }
60
61 static int
62 test_memzone_invalid_alignment(void)
63 {
64         const struct rte_memzone * mz;
65
66         mz = rte_memzone_lookup("invalid_alignment");
67         if (mz != NULL) {
68                 printf("Zone with invalid alignment has been reserved\n");
69                 return -1;
70         }
71
72         mz = rte_memzone_reserve_aligned("invalid_alignment", 100,
73                         SOCKET_ID_ANY, 0, 100);
74         if (mz != NULL) {
75                 printf("Zone with invalid alignment has been reserved\n");
76                 return -1;
77         }
78         return 0;
79 }
80
81 static int
82 test_memzone_reserving_zone_size_bigger_than_the_maximum(void)
83 {
84         const struct rte_memzone * mz;
85
86         mz = rte_memzone_lookup("zone_size_bigger_than_the_maximum");
87         if (mz != NULL) {
88                 printf("zone_size_bigger_than_the_maximum has been reserved\n");
89                 return -1;
90         }
91
92         mz = rte_memzone_reserve("zone_size_bigger_than_the_maximum", (size_t)-1,
93                         SOCKET_ID_ANY, 0);
94         if (mz != NULL) {
95                 printf("It is impossible to reserve such big a memzone\n");
96                 return -1;
97         }
98
99         return 0;
100 }
101
102 static int
103 test_memzone_reserve_flags(void)
104 {
105         const struct rte_memzone *mz;
106         const struct rte_memseg *ms;
107         int hugepage_2MB_avail = 0;
108         int hugepage_1GB_avail = 0;
109         int hugepage_16MB_avail = 0;
110         int hugepage_16GB_avail = 0;
111         const size_t size = 100;
112         int i = 0;
113         ms = rte_eal_get_physmem_layout();
114         for (i = 0; i < RTE_MAX_MEMSEG; i++) {
115                 if (ms[i].hugepage_sz == RTE_PGSIZE_2M)
116                         hugepage_2MB_avail = 1;
117                 if (ms[i].hugepage_sz == RTE_PGSIZE_1G)
118                         hugepage_1GB_avail = 1;
119                 if (ms[i].hugepage_sz == RTE_PGSIZE_16M)
120                         hugepage_16MB_avail = 1;
121                 if (ms[i].hugepage_sz == RTE_PGSIZE_16G)
122                         hugepage_16GB_avail = 1;
123         }
124         /* Display the availability of 2MB ,1GB, 16MB, 16GB pages */
125         if (hugepage_2MB_avail)
126                 printf("2MB Huge pages available\n");
127         if (hugepage_1GB_avail)
128                 printf("1GB Huge pages available\n");
129         if (hugepage_16MB_avail)
130                 printf("16MB Huge pages available\n");
131         if (hugepage_16GB_avail)
132                 printf("16GB Huge pages available\n");
133         /*
134          * If 2MB pages available, check that a small memzone is correctly
135          * reserved from 2MB huge pages when requested by the RTE_MEMZONE_2MB flag.
136          * Also check that RTE_MEMZONE_SIZE_HINT_ONLY flag only defaults to an
137          * available page size (i.e 1GB ) when 2MB pages are unavailable.
138          */
139         if (hugepage_2MB_avail) {
140                 mz = rte_memzone_reserve("flag_zone_2M", size, SOCKET_ID_ANY,
141                                 RTE_MEMZONE_2MB);
142                 if (mz == NULL) {
143                         printf("MEMZONE FLAG 2MB\n");
144                         return -1;
145                 }
146                 if (mz->hugepage_sz != RTE_PGSIZE_2M) {
147                         printf("hugepage_sz not equal 2M\n");
148                         return -1;
149                 }
150                 if (rte_memzone_free(mz)) {
151                         printf("Fail memzone free\n");
152                         return -1;
153                 }
154
155                 mz = rte_memzone_reserve("flag_zone_2M_HINT", size, SOCKET_ID_ANY,
156                                 RTE_MEMZONE_2MB|RTE_MEMZONE_SIZE_HINT_ONLY);
157                 if (mz == NULL) {
158                         printf("MEMZONE FLAG 2MB\n");
159                         return -1;
160                 }
161                 if (mz->hugepage_sz != RTE_PGSIZE_2M) {
162                         printf("hugepage_sz not equal 2M\n");
163                         return -1;
164                 }
165                 if (rte_memzone_free(mz)) {
166                         printf("Fail memzone free\n");
167                         return -1;
168                 }
169
170                 /* Check if 1GB huge pages are unavailable, that function fails unless
171                  * HINT flag is indicated
172                  */
173                 if (!hugepage_1GB_avail) {
174                         mz = rte_memzone_reserve("flag_zone_1G_HINT", size, SOCKET_ID_ANY,
175                                         RTE_MEMZONE_1GB|RTE_MEMZONE_SIZE_HINT_ONLY);
176                         if (mz == NULL) {
177                                 printf("MEMZONE FLAG 1GB & HINT\n");
178                                 return -1;
179                         }
180                         if (mz->hugepage_sz != RTE_PGSIZE_2M) {
181                                 printf("hugepage_sz not equal 2M\n");
182                                 return -1;
183                         }
184                         if (rte_memzone_free(mz)) {
185                                 printf("Fail memzone free\n");
186                                 return -1;
187                         }
188
189                         mz = rte_memzone_reserve("flag_zone_1G", size, SOCKET_ID_ANY,
190                                         RTE_MEMZONE_1GB);
191                         if (mz != NULL) {
192                                 printf("MEMZONE FLAG 1GB\n");
193                                 return -1;
194                         }
195                 }
196         }
197
198         /*As with 2MB tests above for 1GB huge page requests*/
199         if (hugepage_1GB_avail) {
200                 mz = rte_memzone_reserve("flag_zone_1G", size, SOCKET_ID_ANY,
201                                 RTE_MEMZONE_1GB);
202                 if (mz == NULL) {
203                         printf("MEMZONE FLAG 1GB\n");
204                         return -1;
205                 }
206                 if (mz->hugepage_sz != RTE_PGSIZE_1G) {
207                         printf("hugepage_sz not equal 1G\n");
208                         return -1;
209                 }
210                 if (rte_memzone_free(mz)) {
211                         printf("Fail memzone free\n");
212                         return -1;
213                 }
214
215                 mz = rte_memzone_reserve("flag_zone_1G_HINT", size, SOCKET_ID_ANY,
216                                 RTE_MEMZONE_1GB|RTE_MEMZONE_SIZE_HINT_ONLY);
217                 if (mz == NULL) {
218                         printf("MEMZONE FLAG 1GB\n");
219                         return -1;
220                 }
221                 if (mz->hugepage_sz != RTE_PGSIZE_1G) {
222                         printf("hugepage_sz not equal 1G\n");
223                         return -1;
224                 }
225                 if (rte_memzone_free(mz)) {
226                         printf("Fail memzone free\n");
227                         return -1;
228                 }
229
230                 /* Check if 1GB huge pages are unavailable, that function fails unless
231                  * HINT flag is indicated
232                  */
233                 if (!hugepage_2MB_avail) {
234                         mz = rte_memzone_reserve("flag_zone_2M_HINT", size, SOCKET_ID_ANY,
235                                         RTE_MEMZONE_2MB|RTE_MEMZONE_SIZE_HINT_ONLY);
236                         if (mz == NULL){
237                                 printf("MEMZONE FLAG 2MB & HINT\n");
238                                 return -1;
239                         }
240                         if (mz->hugepage_sz != RTE_PGSIZE_1G) {
241                                 printf("hugepage_sz not equal 1G\n");
242                                 return -1;
243                         }
244                         if (rte_memzone_free(mz)) {
245                                 printf("Fail memzone free\n");
246                                 return -1;
247                         }
248                         mz = rte_memzone_reserve("flag_zone_2M", size, SOCKET_ID_ANY,
249                                         RTE_MEMZONE_2MB);
250                         if (mz != NULL) {
251                                 printf("MEMZONE FLAG 2MB\n");
252                                 return -1;
253                         }
254                         if (rte_memzone_free(mz)) {
255                                 printf("Fail memzone free\n");
256                                 return -1;
257                         }
258                 }
259
260                 if (hugepage_2MB_avail && hugepage_1GB_avail) {
261                         mz = rte_memzone_reserve("flag_zone_2M_HINT", size, SOCKET_ID_ANY,
262                                                                 RTE_MEMZONE_2MB|RTE_MEMZONE_1GB);
263                         if (mz != NULL) {
264                                 printf("BOTH SIZES SET\n");
265                                 return -1;
266                         }
267                 }
268         }
269         /*
270          * This option is for IBM Power. If 16MB pages available, check
271          * that a small memzone is correctly reserved from 16MB huge pages
272          * when requested by the RTE_MEMZONE_16MB flag. Also check that
273          * RTE_MEMZONE_SIZE_HINT_ONLY flag only defaults to an available
274          * page size (i.e 16GB ) when 16MB pages are unavailable.
275          */
276         if (hugepage_16MB_avail) {
277                 mz = rte_memzone_reserve("flag_zone_16M", size, SOCKET_ID_ANY,
278                                 RTE_MEMZONE_16MB);
279                 if (mz == NULL) {
280                         printf("MEMZONE FLAG 16MB\n");
281                         return -1;
282                 }
283                 if (mz->hugepage_sz != RTE_PGSIZE_16M) {
284                         printf("hugepage_sz not equal 16M\n");
285                         return -1;
286                 }
287                 if (rte_memzone_free(mz)) {
288                         printf("Fail memzone free\n");
289                         return -1;
290                 }
291
292                 mz = rte_memzone_reserve("flag_zone_16M_HINT", size,
293                 SOCKET_ID_ANY, RTE_MEMZONE_16MB|RTE_MEMZONE_SIZE_HINT_ONLY);
294                 if (mz == NULL) {
295                         printf("MEMZONE FLAG 2MB\n");
296                         return -1;
297                 }
298                 if (mz->hugepage_sz != RTE_PGSIZE_16M) {
299                         printf("hugepage_sz not equal 16M\n");
300                         return -1;
301                 }
302                 if (rte_memzone_free(mz)) {
303                         printf("Fail memzone free\n");
304                         return -1;
305                 }
306
307                 /* Check if 1GB huge pages are unavailable, that function fails
308                  * unless HINT flag is indicated
309                  */
310                 if (!hugepage_16GB_avail) {
311                         mz = rte_memzone_reserve("flag_zone_16G_HINT", size,
312                                 SOCKET_ID_ANY,
313                                 RTE_MEMZONE_16GB|RTE_MEMZONE_SIZE_HINT_ONLY);
314                         if (mz == NULL) {
315                                 printf("MEMZONE FLAG 16GB & HINT\n");
316                                 return -1;
317                         }
318                         if (mz->hugepage_sz != RTE_PGSIZE_16M) {
319                                 printf("hugepage_sz not equal 16M\n");
320                                 return -1;
321                         }
322                         if (rte_memzone_free(mz)) {
323                                 printf("Fail memzone free\n");
324                                 return -1;
325                         }
326
327                         mz = rte_memzone_reserve("flag_zone_16G", size,
328                                 SOCKET_ID_ANY, RTE_MEMZONE_16GB);
329                         if (mz != NULL) {
330                                 printf("MEMZONE FLAG 16GB\n");
331                                 return -1;
332                         }
333                 }
334         }
335         /*As with 16MB tests above for 16GB huge page requests*/
336         if (hugepage_16GB_avail) {
337                 mz = rte_memzone_reserve("flag_zone_16G", size, SOCKET_ID_ANY,
338                                 RTE_MEMZONE_16GB);
339                 if (mz == NULL) {
340                         printf("MEMZONE FLAG 16GB\n");
341                         return -1;
342                 }
343                 if (mz->hugepage_sz != RTE_PGSIZE_16G) {
344                         printf("hugepage_sz not equal 16G\n");
345                         return -1;
346                 }
347                 if (rte_memzone_free(mz)) {
348                         printf("Fail memzone free\n");
349                         return -1;
350                 }
351
352                 mz = rte_memzone_reserve("flag_zone_16G_HINT", size,
353                 SOCKET_ID_ANY, RTE_MEMZONE_16GB|RTE_MEMZONE_SIZE_HINT_ONLY);
354                 if (mz == NULL) {
355                         printf("MEMZONE FLAG 16GB\n");
356                         return -1;
357                 }
358                 if (mz->hugepage_sz != RTE_PGSIZE_16G) {
359                         printf("hugepage_sz not equal 16G\n");
360                         return -1;
361                 }
362                 if (rte_memzone_free(mz)) {
363                         printf("Fail memzone free\n");
364                         return -1;
365                 }
366
367                 /* Check if 1GB huge pages are unavailable, that function fails
368                  * unless HINT flag is indicated
369                  */
370                 if (!hugepage_16MB_avail) {
371                         mz = rte_memzone_reserve("flag_zone_16M_HINT", size,
372                                 SOCKET_ID_ANY,
373                                 RTE_MEMZONE_16MB|RTE_MEMZONE_SIZE_HINT_ONLY);
374                         if (mz == NULL) {
375                                 printf("MEMZONE FLAG 16MB & HINT\n");
376                                 return -1;
377                         }
378                         if (mz->hugepage_sz != RTE_PGSIZE_16G) {
379                                 printf("hugepage_sz not equal 16G\n");
380                                 return -1;
381                         }
382                         if (rte_memzone_free(mz)) {
383                                 printf("Fail memzone free\n");
384                                 return -1;
385                         }
386                         mz = rte_memzone_reserve("flag_zone_16M", size,
387                                 SOCKET_ID_ANY, RTE_MEMZONE_16MB);
388                         if (mz != NULL) {
389                                 printf("MEMZONE FLAG 16MB\n");
390                                 return -1;
391                         }
392                 }
393
394                 if (hugepage_16MB_avail && hugepage_16GB_avail) {
395                         mz = rte_memzone_reserve("flag_zone_16M_HINT", size,
396                                 SOCKET_ID_ANY,
397                                 RTE_MEMZONE_16MB|RTE_MEMZONE_16GB);
398                         if (mz != NULL) {
399                                 printf("BOTH SIZES SET\n");
400                                 return -1;
401                         }
402                 }
403         }
404         return 0;
405 }
406
407
408 /* Find the heap with the greatest free block size */
409 static size_t
410 find_max_block_free_size(const unsigned _align)
411 {
412         struct rte_malloc_socket_stats stats;
413         unsigned i, align = _align;
414         size_t len = 0;
415
416         for (i = 0; i < RTE_MAX_NUMA_NODES; i++) {
417                 rte_malloc_get_socket_stats(i, &stats);
418                 if (stats.greatest_free_size > len)
419                         len = stats.greatest_free_size;
420         }
421
422         if (align < RTE_CACHE_LINE_SIZE)
423                 align = RTE_CACHE_LINE_ROUNDUP(align+1);
424
425         if (len <= MALLOC_ELEM_OVERHEAD + align)
426                 return 0;
427
428         return len - MALLOC_ELEM_OVERHEAD - align;
429 }
430
431 static int
432 test_memzone_reserve_max(void)
433 {
434         const struct rte_memzone *mz;
435         size_t maxlen;
436
437         maxlen = find_max_block_free_size(0);
438
439         if (maxlen == 0) {
440                 printf("There is no space left!\n");
441                 return 0;
442         }
443
444         mz = rte_memzone_reserve("max_zone", 0, SOCKET_ID_ANY, 0);
445         if (mz == NULL){
446                 printf("Failed to reserve a big chunk of memory - %s\n",
447                                 rte_strerror(rte_errno));
448                 rte_dump_physmem_layout(stdout);
449                 rte_memzone_dump(stdout);
450                 return -1;
451         }
452
453         if (mz->len != maxlen) {
454                 printf("Memzone reserve with 0 size did not return bigest block\n");
455                 printf("Expected size = %zu, actual size = %zu\n", maxlen, mz->len);
456                 rte_dump_physmem_layout(stdout);
457                 rte_memzone_dump(stdout);
458                 return -1;
459         }
460
461         if (rte_memzone_free(mz)) {
462                 printf("Fail memzone free\n");
463                 return -1;
464         }
465
466         return 0;
467 }
468
469 static int
470 test_memzone_reserve_max_aligned(void)
471 {
472         const struct rte_memzone *mz;
473         size_t maxlen = 0;
474
475         /* random alignment */
476         rte_srand((unsigned)rte_rdtsc());
477         const unsigned align = 1 << ((rte_rand() % 8) + 5); /* from 128 up to 4k alignment */
478
479         maxlen = find_max_block_free_size(align);
480
481         if (maxlen == 0) {
482                 printf("There is no space left for biggest %u-aligned memzone!\n", align);
483                 return 0;
484         }
485
486         mz = rte_memzone_reserve_aligned("max_zone_aligned", 0,
487                         SOCKET_ID_ANY, 0, align);
488         if (mz == NULL){
489                 printf("Failed to reserve a big chunk of memory - %s\n",
490                                 rte_strerror(rte_errno));
491                 rte_dump_physmem_layout(stdout);
492                 rte_memzone_dump(stdout);
493                 return -1;
494         }
495
496         if (mz->len != maxlen) {
497                 printf("Memzone reserve with 0 size and alignment %u did not return"
498                                 " bigest block\n", align);
499                 printf("Expected size = %zu, actual size = %zu\n",
500                                 maxlen, mz->len);
501                 rte_dump_physmem_layout(stdout);
502                 rte_memzone_dump(stdout);
503                 return -1;
504         }
505
506         if (rte_memzone_free(mz)) {
507                 printf("Fail memzone free\n");
508                 return -1;
509         }
510
511         return 0;
512 }
513
514 static int
515 test_memzone_aligned(void)
516 {
517         const struct rte_memzone *memzone_aligned_32;
518         const struct rte_memzone *memzone_aligned_128;
519         const struct rte_memzone *memzone_aligned_256;
520         const struct rte_memzone *memzone_aligned_512;
521         const struct rte_memzone *memzone_aligned_1024;
522
523         /* memzone that should automatically be adjusted to align on 64 bytes */
524         memzone_aligned_32 = rte_memzone_reserve_aligned("aligned_32", 100,
525                                 SOCKET_ID_ANY, 0, 32);
526
527         /* memzone that is supposed to be aligned on a 128 byte boundary */
528         memzone_aligned_128 = rte_memzone_reserve_aligned("aligned_128", 100,
529                                 SOCKET_ID_ANY, 0, 128);
530
531         /* memzone that is supposed to be aligned on a 256 byte boundary */
532         memzone_aligned_256 = rte_memzone_reserve_aligned("aligned_256", 100,
533                                 SOCKET_ID_ANY, 0, 256);
534
535         /* memzone that is supposed to be aligned on a 512 byte boundary */
536         memzone_aligned_512 = rte_memzone_reserve_aligned("aligned_512", 100,
537                                 SOCKET_ID_ANY, 0, 512);
538
539         /* memzone that is supposed to be aligned on a 1024 byte boundary */
540         memzone_aligned_1024 = rte_memzone_reserve_aligned("aligned_1024", 100,
541                                 SOCKET_ID_ANY, 0, 1024);
542
543         printf("check alignments and lengths\n");
544         if (memzone_aligned_32 == NULL) {
545                 printf("Unable to reserve 64-byte aligned memzone!\n");
546                 return -1;
547         }
548         if ((memzone_aligned_32->iova & RTE_CACHE_LINE_MASK) != 0)
549                 return -1;
550         if (((uintptr_t) memzone_aligned_32->addr & RTE_CACHE_LINE_MASK) != 0)
551                 return -1;
552         if ((memzone_aligned_32->len & RTE_CACHE_LINE_MASK) != 0)
553                 return -1;
554
555         if (memzone_aligned_128 == NULL) {
556                 printf("Unable to reserve 128-byte aligned memzone!\n");
557                 return -1;
558         }
559         if ((memzone_aligned_128->iova & 127) != 0)
560                 return -1;
561         if (((uintptr_t) memzone_aligned_128->addr & 127) != 0)
562                 return -1;
563         if ((memzone_aligned_128->len & RTE_CACHE_LINE_MASK) != 0)
564                 return -1;
565
566         if (memzone_aligned_256 == NULL) {
567                 printf("Unable to reserve 256-byte aligned memzone!\n");
568                 return -1;
569         }
570         if ((memzone_aligned_256->iova & 255) != 0)
571                 return -1;
572         if (((uintptr_t) memzone_aligned_256->addr & 255) != 0)
573                 return -1;
574         if ((memzone_aligned_256->len & RTE_CACHE_LINE_MASK) != 0)
575                 return -1;
576
577         if (memzone_aligned_512 == NULL) {
578                 printf("Unable to reserve 512-byte aligned memzone!\n");
579                 return -1;
580         }
581         if ((memzone_aligned_512->iova & 511) != 0)
582                 return -1;
583         if (((uintptr_t) memzone_aligned_512->addr & 511) != 0)
584                 return -1;
585         if ((memzone_aligned_512->len & RTE_CACHE_LINE_MASK) != 0)
586                 return -1;
587
588         if (memzone_aligned_1024 == NULL) {
589                 printf("Unable to reserve 1024-byte aligned memzone!\n");
590                 return -1;
591         }
592         if ((memzone_aligned_1024->iova & 1023) != 0)
593                 return -1;
594         if (((uintptr_t) memzone_aligned_1024->addr & 1023) != 0)
595                 return -1;
596         if ((memzone_aligned_1024->len & RTE_CACHE_LINE_MASK) != 0)
597                 return -1;
598
599         /* check that zones don't overlap */
600         printf("check overlapping\n");
601         if (is_memory_overlap(memzone_aligned_32->iova, memzone_aligned_32->len,
602                                         memzone_aligned_128->iova, memzone_aligned_128->len))
603                 return -1;
604         if (is_memory_overlap(memzone_aligned_32->iova, memzone_aligned_32->len,
605                                         memzone_aligned_256->iova, memzone_aligned_256->len))
606                 return -1;
607         if (is_memory_overlap(memzone_aligned_32->iova, memzone_aligned_32->len,
608                                         memzone_aligned_512->iova, memzone_aligned_512->len))
609                 return -1;
610         if (is_memory_overlap(memzone_aligned_32->iova, memzone_aligned_32->len,
611                                         memzone_aligned_1024->iova, memzone_aligned_1024->len))
612                 return -1;
613         if (is_memory_overlap(memzone_aligned_128->iova, memzone_aligned_128->len,
614                                         memzone_aligned_256->iova, memzone_aligned_256->len))
615                 return -1;
616         if (is_memory_overlap(memzone_aligned_128->iova, memzone_aligned_128->len,
617                                         memzone_aligned_512->iova, memzone_aligned_512->len))
618                 return -1;
619         if (is_memory_overlap(memzone_aligned_128->iova, memzone_aligned_128->len,
620                                         memzone_aligned_1024->iova, memzone_aligned_1024->len))
621                 return -1;
622         if (is_memory_overlap(memzone_aligned_256->iova, memzone_aligned_256->len,
623                                         memzone_aligned_512->iova, memzone_aligned_512->len))
624                 return -1;
625         if (is_memory_overlap(memzone_aligned_256->iova, memzone_aligned_256->len,
626                                         memzone_aligned_1024->iova, memzone_aligned_1024->len))
627                 return -1;
628         if (is_memory_overlap(memzone_aligned_512->iova, memzone_aligned_512->len,
629                                         memzone_aligned_1024->iova, memzone_aligned_1024->len))
630                 return -1;
631
632         /* free all used zones */
633         if (rte_memzone_free(memzone_aligned_32)) {
634                 printf("Fail memzone free\n");
635                 return -1;
636         }
637         if (rte_memzone_free(memzone_aligned_128)) {
638                 printf("Fail memzone free\n");
639                 return -1;
640         }
641         if (rte_memzone_free(memzone_aligned_256)) {
642                 printf("Fail memzone free\n");
643                 return -1;
644         }
645         if (rte_memzone_free(memzone_aligned_512)) {
646                 printf("Fail memzone free\n");
647                 return -1;
648         }
649         if (rte_memzone_free(memzone_aligned_1024)) {
650                 printf("Fail memzone free\n");
651                 return -1;
652         }
653         return 0;
654 }
655
656 static int
657 check_memzone_bounded(const char *name, uint32_t len,  uint32_t align,
658         uint32_t bound)
659 {
660         const struct rte_memzone *mz;
661         rte_iova_t bmask;
662
663         bmask = ~((rte_iova_t)bound - 1);
664
665         if ((mz = rte_memzone_reserve_bounded(name, len, SOCKET_ID_ANY, 0,
666                         align, bound)) == NULL) {
667                 printf("%s(%s): memzone creation failed\n",
668                         __func__, name);
669                 return -1;
670         }
671
672         if ((mz->iova & ((rte_iova_t)align - 1)) != 0) {
673                 printf("%s(%s): invalid phys addr alignment\n",
674                         __func__, mz->name);
675                 return -1;
676         }
677
678         if (((uintptr_t) mz->addr & ((uintptr_t)align - 1)) != 0) {
679                 printf("%s(%s): invalid virtual addr alignment\n",
680                         __func__, mz->name);
681                 return -1;
682         }
683
684         if ((mz->len & RTE_CACHE_LINE_MASK) != 0 || mz->len < len ||
685                         mz->len < RTE_CACHE_LINE_SIZE) {
686                 printf("%s(%s): invalid length\n",
687                         __func__, mz->name);
688                 return -1;
689         }
690
691         if ((mz->iova & bmask) !=
692                         ((mz->iova + mz->len - 1) & bmask)) {
693                 printf("%s(%s): invalid memzone boundary %u crossed\n",
694                         __func__, mz->name, bound);
695                 return -1;
696         }
697
698         if (rte_memzone_free(mz)) {
699                 printf("Fail memzone free\n");
700                 return -1;
701         }
702
703         return 0;
704 }
705
706 static int
707 test_memzone_bounded(void)
708 {
709         const struct rte_memzone *memzone_err;
710         const char *name;
711         int rc;
712
713         /* should fail as boundary is not power of two */
714         name = "bounded_error_31";
715         if ((memzone_err = rte_memzone_reserve_bounded(name,
716                         100, SOCKET_ID_ANY, 0, 32, UINT32_MAX)) != NULL) {
717                 printf("%s(%s)created a memzone with invalid boundary "
718                         "conditions\n", __func__, memzone_err->name);
719                 return -1;
720         }
721
722         /* should fail as len is greater then boundary */
723         name = "bounded_error_32";
724         if ((memzone_err = rte_memzone_reserve_bounded(name,
725                         100, SOCKET_ID_ANY, 0, 32, 32)) != NULL) {
726                 printf("%s(%s)created a memzone with invalid boundary "
727                         "conditions\n", __func__, memzone_err->name);
728                 return -1;
729         }
730
731         if ((rc = check_memzone_bounded("bounded_128", 100, 128, 128)) != 0)
732                 return rc;
733
734         if ((rc = check_memzone_bounded("bounded_256", 100, 256, 128)) != 0)
735                 return rc;
736
737         if ((rc = check_memzone_bounded("bounded_1K", 100, 64, 1024)) != 0)
738                 return rc;
739
740         if ((rc = check_memzone_bounded("bounded_1K_MAX", 0, 64, 1024)) != 0)
741                 return rc;
742
743         return 0;
744 }
745
746 static int
747 test_memzone_free(void)
748 {
749         const struct rte_memzone *mz[RTE_MAX_MEMZONE];
750         int i;
751         char name[20];
752
753         mz[0] = rte_memzone_reserve("tempzone0", 2000, SOCKET_ID_ANY, 0);
754         mz[1] = rte_memzone_reserve("tempzone1", 4000, SOCKET_ID_ANY, 0);
755
756         if (mz[0] > mz[1])
757                 return -1;
758         if (!rte_memzone_lookup("tempzone0"))
759                 return -1;
760         if (!rte_memzone_lookup("tempzone1"))
761                 return -1;
762
763         if (rte_memzone_free(mz[0])) {
764                 printf("Fail memzone free - tempzone0\n");
765                 return -1;
766         }
767         if (rte_memzone_lookup("tempzone0")) {
768                 printf("Found previously free memzone - tempzone0\n");
769                 return -1;
770         }
771         mz[2] = rte_memzone_reserve("tempzone2", 2000, SOCKET_ID_ANY, 0);
772
773         if (mz[2] > mz[1]) {
774                 printf("tempzone2 should have gotten the free entry from tempzone0\n");
775                 return -1;
776         }
777         if (rte_memzone_free(mz[2])) {
778                 printf("Fail memzone free - tempzone2\n");
779                 return -1;
780         }
781         if (rte_memzone_lookup("tempzone2")) {
782                 printf("Found previously free memzone - tempzone2\n");
783                 return -1;
784         }
785         if (rte_memzone_free(mz[1])) {
786                 printf("Fail memzone free - tempzone1\n");
787                 return -1;
788         }
789         if (rte_memzone_lookup("tempzone1")) {
790                 printf("Found previously free memzone - tempzone1\n");
791                 return -1;
792         }
793
794         i = 0;
795         do {
796                 snprintf(name, sizeof(name), "tempzone%u", i);
797                 mz[i] = rte_memzone_reserve(name, 1, SOCKET_ID_ANY, 0);
798         } while (mz[i++] != NULL);
799
800         if (rte_memzone_free(mz[0])) {
801                 printf("Fail memzone free - tempzone0\n");
802                 return -1;
803         }
804         mz[0] = rte_memzone_reserve("tempzone0new", 0, SOCKET_ID_ANY, 0);
805
806         if (mz[0] == NULL) {
807                 printf("Fail to create memzone - tempzone0new - when MAX memzones were "
808                                 "created and one was free\n");
809                 return -1;
810         }
811
812         for (i = i - 2; i >= 0; i--) {
813                 if (rte_memzone_free(mz[i])) {
814                         printf("Fail memzone free - tempzone%d\n", i);
815                         return -1;
816                 }
817         }
818
819         return 0;
820 }
821
822 static int
823 test_memzone_basic(void)
824 {
825         const struct rte_memzone *memzone1;
826         const struct rte_memzone *memzone2;
827         const struct rte_memzone *memzone3;
828         const struct rte_memzone *memzone4;
829         const struct rte_memzone *mz;
830
831         memzone1 = rte_memzone_reserve("testzone1", 100,
832                                 SOCKET_ID_ANY, 0);
833
834         memzone2 = rte_memzone_reserve("testzone2", 1000,
835                                 0, 0);
836
837         memzone3 = rte_memzone_reserve("testzone3", 1000,
838                                 1, 0);
839
840         memzone4 = rte_memzone_reserve("testzone4", 1024,
841                                 SOCKET_ID_ANY, 0);
842
843         /* memzone3 may be NULL if we don't have NUMA */
844         if (memzone1 == NULL || memzone2 == NULL || memzone4 == NULL)
845                 return -1;
846
847         rte_memzone_dump(stdout);
848
849         /* check cache-line alignments */
850         printf("check alignments and lengths\n");
851
852         if ((memzone1->iova & RTE_CACHE_LINE_MASK) != 0)
853                 return -1;
854         if ((memzone2->iova & RTE_CACHE_LINE_MASK) != 0)
855                 return -1;
856         if (memzone3 != NULL && (memzone3->iova & RTE_CACHE_LINE_MASK) != 0)
857                 return -1;
858         if ((memzone1->len & RTE_CACHE_LINE_MASK) != 0 || memzone1->len == 0)
859                 return -1;
860         if ((memzone2->len & RTE_CACHE_LINE_MASK) != 0 || memzone2->len == 0)
861                 return -1;
862         if (memzone3 != NULL && ((memzone3->len & RTE_CACHE_LINE_MASK) != 0 ||
863                         memzone3->len == 0))
864                 return -1;
865         if (memzone4->len != 1024)
866                 return -1;
867
868         /* check that zones don't overlap */
869         printf("check overlapping\n");
870
871         if (is_memory_overlap(memzone1->iova, memzone1->len,
872                         memzone2->iova, memzone2->len))
873                 return -1;
874         if (memzone3 != NULL &&
875                         is_memory_overlap(memzone1->iova, memzone1->len,
876                                         memzone3->iova, memzone3->len))
877                 return -1;
878         if (memzone3 != NULL &&
879                         is_memory_overlap(memzone2->iova, memzone2->len,
880                                         memzone3->iova, memzone3->len))
881                 return -1;
882
883         printf("check socket ID\n");
884
885         /* memzone2 must be on socket id 0 and memzone3 on socket 1 */
886         if (memzone2->socket_id != 0)
887                 return -1;
888         if (memzone3 != NULL && memzone3->socket_id != 1)
889                 return -1;
890
891         printf("test zone lookup\n");
892         mz = rte_memzone_lookup("testzone1");
893         if (mz != memzone1)
894                 return -1;
895
896         printf("test duplcate zone name\n");
897         mz = rte_memzone_reserve("testzone1", 100,
898                         SOCKET_ID_ANY, 0);
899         if (mz != NULL)
900                 return -1;
901
902         if (rte_memzone_free(memzone1)) {
903                 printf("Fail memzone free - memzone1\n");
904                 return -1;
905         }
906         if (rte_memzone_free(memzone2)) {
907                 printf("Fail memzone free - memzone2\n");
908                 return -1;
909         }
910         if (memzone3 && rte_memzone_free(memzone3)) {
911                 printf("Fail memzone free - memzone3\n");
912                 return -1;
913         }
914         if (rte_memzone_free(memzone4)) {
915                 printf("Fail memzone free - memzone4\n");
916                 return -1;
917         }
918
919         return 0;
920 }
921
922 static int memzone_calk_called;
923 static void memzone_walk_clb(const struct rte_memzone *mz __rte_unused,
924                              void *arg __rte_unused)
925 {
926         memzone_calk_called = 1;
927 }
928
929 static int
930 test_memzone(void)
931 {
932         printf("test basic memzone API\n");
933         if (test_memzone_basic() < 0)
934                 return -1;
935
936         printf("test free memzone\n");
937         if (test_memzone_free() < 0)
938                 return -1;
939
940         printf("test reserving memzone with bigger size than the maximum\n");
941         if (test_memzone_reserving_zone_size_bigger_than_the_maximum() < 0)
942                 return -1;
943
944         printf("test memzone_reserve flags\n");
945         if (test_memzone_reserve_flags() < 0)
946                 return -1;
947
948         printf("test alignment for memzone_reserve\n");
949         if (test_memzone_aligned() < 0)
950                 return -1;
951
952         printf("test boundary alignment for memzone_reserve\n");
953         if (test_memzone_bounded() < 0)
954                 return -1;
955
956         printf("test invalid alignment for memzone_reserve\n");
957         if (test_memzone_invalid_alignment() < 0)
958                 return -1;
959
960         printf("test reserving the largest size memzone possible\n");
961         if (test_memzone_reserve_max() < 0)
962                 return -1;
963
964         printf("test reserving the largest size aligned memzone possible\n");
965         if (test_memzone_reserve_max_aligned() < 0)
966                 return -1;
967
968         printf("check memzone cleanup\n");
969         rte_memzone_walk(memzone_walk_clb, NULL);
970         if (memzone_calk_called) {
971                 printf("there are some memzones left after test\n");
972                 rte_memzone_dump(stdout);
973                 return -1;
974         }
975
976         return 0;
977 }
978
979 REGISTER_TEST_COMMAND(memzone_autotest, test_memzone);