bus/pci: use SPDX tags in 6WIND copyrighted 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                 }
255
256                 if (hugepage_2MB_avail && hugepage_1GB_avail) {
257                         mz = rte_memzone_reserve("flag_zone_2M_HINT", size, SOCKET_ID_ANY,
258                                                                 RTE_MEMZONE_2MB|RTE_MEMZONE_1GB);
259                         if (mz == NULL) {
260                                 printf("BOTH SIZES SET\n");
261                                 return -1;
262                         }
263                         if (mz->hugepage_sz != RTE_PGSIZE_1G &&
264                                         mz->hugepage_sz != RTE_PGSIZE_2M) {
265                                 printf("Wrong size when both sizes set\n");
266                                 return -1;
267                         }
268                         if (rte_memzone_free(mz)) {
269                                 printf("Fail memzone free\n");
270                                 return -1;
271                         }
272                 }
273         }
274         /*
275          * This option is for IBM Power. If 16MB pages available, check
276          * that a small memzone is correctly reserved from 16MB huge pages
277          * when requested by the RTE_MEMZONE_16MB flag. Also check that
278          * RTE_MEMZONE_SIZE_HINT_ONLY flag only defaults to an available
279          * page size (i.e 16GB ) when 16MB pages are unavailable.
280          */
281         if (hugepage_16MB_avail) {
282                 mz = rte_memzone_reserve("flag_zone_16M", size, SOCKET_ID_ANY,
283                                 RTE_MEMZONE_16MB);
284                 if (mz == NULL) {
285                         printf("MEMZONE FLAG 16MB\n");
286                         return -1;
287                 }
288                 if (mz->hugepage_sz != RTE_PGSIZE_16M) {
289                         printf("hugepage_sz not equal 16M\n");
290                         return -1;
291                 }
292                 if (rte_memzone_free(mz)) {
293                         printf("Fail memzone free\n");
294                         return -1;
295                 }
296
297                 mz = rte_memzone_reserve("flag_zone_16M_HINT", size,
298                 SOCKET_ID_ANY, RTE_MEMZONE_16MB|RTE_MEMZONE_SIZE_HINT_ONLY);
299                 if (mz == NULL) {
300                         printf("MEMZONE FLAG 16MB\n");
301                         return -1;
302                 }
303                 if (mz->hugepage_sz != RTE_PGSIZE_16M) {
304                         printf("hugepage_sz not equal 16M\n");
305                         return -1;
306                 }
307                 if (rte_memzone_free(mz)) {
308                         printf("Fail memzone free\n");
309                         return -1;
310                 }
311
312                 /* Check if 1GB huge pages are unavailable, that function fails
313                  * unless HINT flag is indicated
314                  */
315                 if (!hugepage_16GB_avail) {
316                         mz = rte_memzone_reserve("flag_zone_16G_HINT", size,
317                                 SOCKET_ID_ANY,
318                                 RTE_MEMZONE_16GB|RTE_MEMZONE_SIZE_HINT_ONLY);
319                         if (mz == NULL) {
320                                 printf("MEMZONE FLAG 16GB & HINT\n");
321                                 return -1;
322                         }
323                         if (mz->hugepage_sz != RTE_PGSIZE_16M) {
324                                 printf("hugepage_sz not equal 16M\n");
325                                 return -1;
326                         }
327                         if (rte_memzone_free(mz)) {
328                                 printf("Fail memzone free\n");
329                                 return -1;
330                         }
331
332                         mz = rte_memzone_reserve("flag_zone_16G", size,
333                                 SOCKET_ID_ANY, RTE_MEMZONE_16GB);
334                         if (mz != NULL) {
335                                 printf("MEMZONE FLAG 16GB\n");
336                                 return -1;
337                         }
338                 }
339         }
340         /*As with 16MB tests above for 16GB huge page requests*/
341         if (hugepage_16GB_avail) {
342                 mz = rte_memzone_reserve("flag_zone_16G", size, SOCKET_ID_ANY,
343                                 RTE_MEMZONE_16GB);
344                 if (mz == NULL) {
345                         printf("MEMZONE FLAG 16GB\n");
346                         return -1;
347                 }
348                 if (mz->hugepage_sz != RTE_PGSIZE_16G) {
349                         printf("hugepage_sz not equal 16G\n");
350                         return -1;
351                 }
352                 if (rte_memzone_free(mz)) {
353                         printf("Fail memzone free\n");
354                         return -1;
355                 }
356
357                 mz = rte_memzone_reserve("flag_zone_16G_HINT", size,
358                 SOCKET_ID_ANY, RTE_MEMZONE_16GB|RTE_MEMZONE_SIZE_HINT_ONLY);
359                 if (mz == NULL) {
360                         printf("MEMZONE FLAG 16GB\n");
361                         return -1;
362                 }
363                 if (mz->hugepage_sz != RTE_PGSIZE_16G) {
364                         printf("hugepage_sz not equal 16G\n");
365                         return -1;
366                 }
367                 if (rte_memzone_free(mz)) {
368                         printf("Fail memzone free\n");
369                         return -1;
370                 }
371
372                 /* Check if 1GB huge pages are unavailable, that function fails
373                  * unless HINT flag is indicated
374                  */
375                 if (!hugepage_16MB_avail) {
376                         mz = rte_memzone_reserve("flag_zone_16M_HINT", size,
377                                 SOCKET_ID_ANY,
378                                 RTE_MEMZONE_16MB|RTE_MEMZONE_SIZE_HINT_ONLY);
379                         if (mz == NULL) {
380                                 printf("MEMZONE FLAG 16MB & HINT\n");
381                                 return -1;
382                         }
383                         if (mz->hugepage_sz != RTE_PGSIZE_16G) {
384                                 printf("hugepage_sz not equal 16G\n");
385                                 return -1;
386                         }
387                         if (rte_memzone_free(mz)) {
388                                 printf("Fail memzone free\n");
389                                 return -1;
390                         }
391                         mz = rte_memzone_reserve("flag_zone_16M", size,
392                                 SOCKET_ID_ANY, RTE_MEMZONE_16MB);
393                         if (mz != NULL) {
394                                 printf("MEMZONE FLAG 16MB\n");
395                                 return -1;
396                         }
397                 }
398
399                 if (hugepage_16MB_avail && hugepage_16GB_avail) {
400                         mz = rte_memzone_reserve("flag_zone_16M_HINT", size,
401                                 SOCKET_ID_ANY,
402                                 RTE_MEMZONE_16MB|RTE_MEMZONE_16GB);
403                         if (mz == NULL) {
404                                 printf("BOTH SIZES SET\n");
405                                 return -1;
406                         }
407                         if (mz->hugepage_sz != RTE_PGSIZE_16G &&
408                                         mz->hugepage_sz != RTE_PGSIZE_16M) {
409                                 printf("Wrong size when both sizes set\n");
410                                 return -1;
411                         }
412                         if (rte_memzone_free(mz)) {
413                                 printf("Fail memzone free\n");
414                                 return -1;
415                         }
416                 }
417         }
418         return 0;
419 }
420
421
422 /* Find the heap with the greatest free block size */
423 static size_t
424 find_max_block_free_size(const unsigned _align)
425 {
426         struct rte_malloc_socket_stats stats;
427         unsigned i, align = _align;
428         size_t len = 0;
429
430         for (i = 0; i < RTE_MAX_NUMA_NODES; i++) {
431                 rte_malloc_get_socket_stats(i, &stats);
432                 if (stats.greatest_free_size > len)
433                         len = stats.greatest_free_size;
434         }
435
436         if (align < RTE_CACHE_LINE_SIZE)
437                 align = RTE_CACHE_LINE_ROUNDUP(align+1);
438
439         if (len <= MALLOC_ELEM_OVERHEAD + align)
440                 return 0;
441
442         return len - MALLOC_ELEM_OVERHEAD - align;
443 }
444
445 static int
446 test_memzone_reserve_max(void)
447 {
448         const struct rte_memzone *mz;
449         size_t maxlen;
450
451         maxlen = find_max_block_free_size(0);
452
453         if (maxlen == 0) {
454                 printf("There is no space left!\n");
455                 return 0;
456         }
457
458         mz = rte_memzone_reserve("max_zone", 0, SOCKET_ID_ANY, 0);
459         if (mz == NULL){
460                 printf("Failed to reserve a big chunk of memory - %s\n",
461                                 rte_strerror(rte_errno));
462                 rte_dump_physmem_layout(stdout);
463                 rte_memzone_dump(stdout);
464                 return -1;
465         }
466
467         if (mz->len != maxlen) {
468                 printf("Memzone reserve with 0 size did not return bigest block\n");
469                 printf("Expected size = %zu, actual size = %zu\n", maxlen, mz->len);
470                 rte_dump_physmem_layout(stdout);
471                 rte_memzone_dump(stdout);
472                 return -1;
473         }
474
475         if (rte_memzone_free(mz)) {
476                 printf("Fail memzone free\n");
477                 return -1;
478         }
479
480         return 0;
481 }
482
483 static int
484 test_memzone_reserve_max_aligned(void)
485 {
486         const struct rte_memzone *mz;
487         size_t maxlen = 0;
488
489         /* random alignment */
490         rte_srand((unsigned)rte_rdtsc());
491         const unsigned align = 1 << ((rte_rand() % 8) + 5); /* from 128 up to 4k alignment */
492
493         maxlen = find_max_block_free_size(align);
494
495         if (maxlen == 0) {
496                 printf("There is no space left for biggest %u-aligned memzone!\n", align);
497                 return 0;
498         }
499
500         mz = rte_memzone_reserve_aligned("max_zone_aligned", 0,
501                         SOCKET_ID_ANY, 0, align);
502         if (mz == NULL){
503                 printf("Failed to reserve a big chunk of memory - %s\n",
504                                 rte_strerror(rte_errno));
505                 rte_dump_physmem_layout(stdout);
506                 rte_memzone_dump(stdout);
507                 return -1;
508         }
509
510         if (mz->len != maxlen) {
511                 printf("Memzone reserve with 0 size and alignment %u did not return"
512                                 " bigest block\n", align);
513                 printf("Expected size = %zu, actual size = %zu\n",
514                                 maxlen, mz->len);
515                 rte_dump_physmem_layout(stdout);
516                 rte_memzone_dump(stdout);
517                 return -1;
518         }
519
520         if (rte_memzone_free(mz)) {
521                 printf("Fail memzone free\n");
522                 return -1;
523         }
524
525         return 0;
526 }
527
528 static int
529 test_memzone_aligned(void)
530 {
531         const struct rte_memzone *memzone_aligned_32;
532         const struct rte_memzone *memzone_aligned_128;
533         const struct rte_memzone *memzone_aligned_256;
534         const struct rte_memzone *memzone_aligned_512;
535         const struct rte_memzone *memzone_aligned_1024;
536
537         /* memzone that should automatically be adjusted to align on 64 bytes */
538         memzone_aligned_32 = rte_memzone_reserve_aligned("aligned_32", 100,
539                                 SOCKET_ID_ANY, 0, 32);
540
541         /* memzone that is supposed to be aligned on a 128 byte boundary */
542         memzone_aligned_128 = rte_memzone_reserve_aligned("aligned_128", 100,
543                                 SOCKET_ID_ANY, 0, 128);
544
545         /* memzone that is supposed to be aligned on a 256 byte boundary */
546         memzone_aligned_256 = rte_memzone_reserve_aligned("aligned_256", 100,
547                                 SOCKET_ID_ANY, 0, 256);
548
549         /* memzone that is supposed to be aligned on a 512 byte boundary */
550         memzone_aligned_512 = rte_memzone_reserve_aligned("aligned_512", 100,
551                                 SOCKET_ID_ANY, 0, 512);
552
553         /* memzone that is supposed to be aligned on a 1024 byte boundary */
554         memzone_aligned_1024 = rte_memzone_reserve_aligned("aligned_1024", 100,
555                                 SOCKET_ID_ANY, 0, 1024);
556
557         printf("check alignments and lengths\n");
558         if (memzone_aligned_32 == NULL) {
559                 printf("Unable to reserve 64-byte aligned memzone!\n");
560                 return -1;
561         }
562         if ((memzone_aligned_32->iova & RTE_CACHE_LINE_MASK) != 0)
563                 return -1;
564         if (((uintptr_t) memzone_aligned_32->addr & RTE_CACHE_LINE_MASK) != 0)
565                 return -1;
566         if ((memzone_aligned_32->len & RTE_CACHE_LINE_MASK) != 0)
567                 return -1;
568
569         if (memzone_aligned_128 == NULL) {
570                 printf("Unable to reserve 128-byte aligned memzone!\n");
571                 return -1;
572         }
573         if ((memzone_aligned_128->iova & 127) != 0)
574                 return -1;
575         if (((uintptr_t) memzone_aligned_128->addr & 127) != 0)
576                 return -1;
577         if ((memzone_aligned_128->len & RTE_CACHE_LINE_MASK) != 0)
578                 return -1;
579
580         if (memzone_aligned_256 == NULL) {
581                 printf("Unable to reserve 256-byte aligned memzone!\n");
582                 return -1;
583         }
584         if ((memzone_aligned_256->iova & 255) != 0)
585                 return -1;
586         if (((uintptr_t) memzone_aligned_256->addr & 255) != 0)
587                 return -1;
588         if ((memzone_aligned_256->len & RTE_CACHE_LINE_MASK) != 0)
589                 return -1;
590
591         if (memzone_aligned_512 == NULL) {
592                 printf("Unable to reserve 512-byte aligned memzone!\n");
593                 return -1;
594         }
595         if ((memzone_aligned_512->iova & 511) != 0)
596                 return -1;
597         if (((uintptr_t) memzone_aligned_512->addr & 511) != 0)
598                 return -1;
599         if ((memzone_aligned_512->len & RTE_CACHE_LINE_MASK) != 0)
600                 return -1;
601
602         if (memzone_aligned_1024 == NULL) {
603                 printf("Unable to reserve 1024-byte aligned memzone!\n");
604                 return -1;
605         }
606         if ((memzone_aligned_1024->iova & 1023) != 0)
607                 return -1;
608         if (((uintptr_t) memzone_aligned_1024->addr & 1023) != 0)
609                 return -1;
610         if ((memzone_aligned_1024->len & RTE_CACHE_LINE_MASK) != 0)
611                 return -1;
612
613         /* check that zones don't overlap */
614         printf("check overlapping\n");
615         if (is_memory_overlap(memzone_aligned_32->iova, memzone_aligned_32->len,
616                                         memzone_aligned_128->iova, memzone_aligned_128->len))
617                 return -1;
618         if (is_memory_overlap(memzone_aligned_32->iova, memzone_aligned_32->len,
619                                         memzone_aligned_256->iova, memzone_aligned_256->len))
620                 return -1;
621         if (is_memory_overlap(memzone_aligned_32->iova, memzone_aligned_32->len,
622                                         memzone_aligned_512->iova, memzone_aligned_512->len))
623                 return -1;
624         if (is_memory_overlap(memzone_aligned_32->iova, memzone_aligned_32->len,
625                                         memzone_aligned_1024->iova, memzone_aligned_1024->len))
626                 return -1;
627         if (is_memory_overlap(memzone_aligned_128->iova, memzone_aligned_128->len,
628                                         memzone_aligned_256->iova, memzone_aligned_256->len))
629                 return -1;
630         if (is_memory_overlap(memzone_aligned_128->iova, memzone_aligned_128->len,
631                                         memzone_aligned_512->iova, memzone_aligned_512->len))
632                 return -1;
633         if (is_memory_overlap(memzone_aligned_128->iova, memzone_aligned_128->len,
634                                         memzone_aligned_1024->iova, memzone_aligned_1024->len))
635                 return -1;
636         if (is_memory_overlap(memzone_aligned_256->iova, memzone_aligned_256->len,
637                                         memzone_aligned_512->iova, memzone_aligned_512->len))
638                 return -1;
639         if (is_memory_overlap(memzone_aligned_256->iova, memzone_aligned_256->len,
640                                         memzone_aligned_1024->iova, memzone_aligned_1024->len))
641                 return -1;
642         if (is_memory_overlap(memzone_aligned_512->iova, memzone_aligned_512->len,
643                                         memzone_aligned_1024->iova, memzone_aligned_1024->len))
644                 return -1;
645
646         /* free all used zones */
647         if (rte_memzone_free(memzone_aligned_32)) {
648                 printf("Fail memzone free\n");
649                 return -1;
650         }
651         if (rte_memzone_free(memzone_aligned_128)) {
652                 printf("Fail memzone free\n");
653                 return -1;
654         }
655         if (rte_memzone_free(memzone_aligned_256)) {
656                 printf("Fail memzone free\n");
657                 return -1;
658         }
659         if (rte_memzone_free(memzone_aligned_512)) {
660                 printf("Fail memzone free\n");
661                 return -1;
662         }
663         if (rte_memzone_free(memzone_aligned_1024)) {
664                 printf("Fail memzone free\n");
665                 return -1;
666         }
667         return 0;
668 }
669
670 static int
671 check_memzone_bounded(const char *name, uint32_t len,  uint32_t align,
672         uint32_t bound)
673 {
674         const struct rte_memzone *mz;
675         rte_iova_t bmask;
676
677         bmask = ~((rte_iova_t)bound - 1);
678
679         if ((mz = rte_memzone_reserve_bounded(name, len, SOCKET_ID_ANY, 0,
680                         align, bound)) == NULL) {
681                 printf("%s(%s): memzone creation failed\n",
682                         __func__, name);
683                 return -1;
684         }
685
686         if ((mz->iova & ((rte_iova_t)align - 1)) != 0) {
687                 printf("%s(%s): invalid phys addr alignment\n",
688                         __func__, mz->name);
689                 return -1;
690         }
691
692         if (((uintptr_t) mz->addr & ((uintptr_t)align - 1)) != 0) {
693                 printf("%s(%s): invalid virtual addr alignment\n",
694                         __func__, mz->name);
695                 return -1;
696         }
697
698         if ((mz->len & RTE_CACHE_LINE_MASK) != 0 || mz->len < len ||
699                         mz->len < RTE_CACHE_LINE_SIZE) {
700                 printf("%s(%s): invalid length\n",
701                         __func__, mz->name);
702                 return -1;
703         }
704
705         if ((mz->iova & bmask) !=
706                         ((mz->iova + mz->len - 1) & bmask)) {
707                 printf("%s(%s): invalid memzone boundary %u crossed\n",
708                         __func__, mz->name, bound);
709                 return -1;
710         }
711
712         if (rte_memzone_free(mz)) {
713                 printf("Fail memzone free\n");
714                 return -1;
715         }
716
717         return 0;
718 }
719
720 static int
721 test_memzone_bounded(void)
722 {
723         const struct rte_memzone *memzone_err;
724         const char *name;
725         int rc;
726
727         /* should fail as boundary is not power of two */
728         name = "bounded_error_31";
729         if ((memzone_err = rte_memzone_reserve_bounded(name,
730                         100, SOCKET_ID_ANY, 0, 32, UINT32_MAX)) != NULL) {
731                 printf("%s(%s)created a memzone with invalid boundary "
732                         "conditions\n", __func__, memzone_err->name);
733                 return -1;
734         }
735
736         /* should fail as len is greater then boundary */
737         name = "bounded_error_32";
738         if ((memzone_err = rte_memzone_reserve_bounded(name,
739                         100, SOCKET_ID_ANY, 0, 32, 32)) != NULL) {
740                 printf("%s(%s)created a memzone with invalid boundary "
741                         "conditions\n", __func__, memzone_err->name);
742                 return -1;
743         }
744
745         if ((rc = check_memzone_bounded("bounded_128", 100, 128, 128)) != 0)
746                 return rc;
747
748         if ((rc = check_memzone_bounded("bounded_256", 100, 256, 128)) != 0)
749                 return rc;
750
751         if ((rc = check_memzone_bounded("bounded_1K", 100, 64, 1024)) != 0)
752                 return rc;
753
754         if ((rc = check_memzone_bounded("bounded_1K_MAX", 0, 64, 1024)) != 0)
755                 return rc;
756
757         return 0;
758 }
759
760 static int
761 test_memzone_free(void)
762 {
763         const struct rte_memzone *mz[RTE_MAX_MEMZONE + 1];
764         int i;
765         char name[20];
766
767         mz[0] = rte_memzone_reserve("tempzone0", 2000, SOCKET_ID_ANY, 0);
768         mz[1] = rte_memzone_reserve("tempzone1", 4000, SOCKET_ID_ANY, 0);
769
770         if (mz[0] > mz[1])
771                 return -1;
772         if (!rte_memzone_lookup("tempzone0"))
773                 return -1;
774         if (!rte_memzone_lookup("tempzone1"))
775                 return -1;
776
777         if (rte_memzone_free(mz[0])) {
778                 printf("Fail memzone free - tempzone0\n");
779                 return -1;
780         }
781         if (rte_memzone_lookup("tempzone0")) {
782                 printf("Found previously free memzone - tempzone0\n");
783                 return -1;
784         }
785         mz[2] = rte_memzone_reserve("tempzone2", 2000, SOCKET_ID_ANY, 0);
786
787         if (mz[2] > mz[1]) {
788                 printf("tempzone2 should have gotten the free entry from tempzone0\n");
789                 return -1;
790         }
791         if (rte_memzone_free(mz[2])) {
792                 printf("Fail memzone free - tempzone2\n");
793                 return -1;
794         }
795         if (rte_memzone_lookup("tempzone2")) {
796                 printf("Found previously free memzone - tempzone2\n");
797                 return -1;
798         }
799         if (rte_memzone_free(mz[1])) {
800                 printf("Fail memzone free - tempzone1\n");
801                 return -1;
802         }
803         if (rte_memzone_lookup("tempzone1")) {
804                 printf("Found previously free memzone - tempzone1\n");
805                 return -1;
806         }
807
808         i = 0;
809         do {
810                 snprintf(name, sizeof(name), "tempzone%u", i);
811                 mz[i] = rte_memzone_reserve(name, 1, SOCKET_ID_ANY, 0);
812         } while (mz[i++] != NULL);
813
814         if (rte_memzone_free(mz[0])) {
815                 printf("Fail memzone free - tempzone0\n");
816                 return -1;
817         }
818         mz[0] = rte_memzone_reserve("tempzone0new", 0, SOCKET_ID_ANY, 0);
819
820         if (mz[0] == NULL) {
821                 printf("Fail to create memzone - tempzone0new - when MAX memzones were "
822                                 "created and one was free\n");
823                 return -1;
824         }
825
826         for (i = i - 2; i >= 0; i--) {
827                 if (rte_memzone_free(mz[i])) {
828                         printf("Fail memzone free - tempzone%d\n", i);
829                         return -1;
830                 }
831         }
832
833         return 0;
834 }
835
836 static int
837 test_memzone_basic(void)
838 {
839         const struct rte_memzone *memzone1;
840         const struct rte_memzone *memzone2;
841         const struct rte_memzone *memzone3;
842         const struct rte_memzone *memzone4;
843         const struct rte_memzone *mz;
844
845         memzone1 = rte_memzone_reserve("testzone1", 100,
846                                 SOCKET_ID_ANY, 0);
847
848         memzone2 = rte_memzone_reserve("testzone2", 1000,
849                                 0, 0);
850
851         memzone3 = rte_memzone_reserve("testzone3", 1000,
852                                 1, 0);
853
854         memzone4 = rte_memzone_reserve("testzone4", 1024,
855                                 SOCKET_ID_ANY, 0);
856
857         /* memzone3 may be NULL if we don't have NUMA */
858         if (memzone1 == NULL || memzone2 == NULL || memzone4 == NULL)
859                 return -1;
860
861         rte_memzone_dump(stdout);
862
863         /* check cache-line alignments */
864         printf("check alignments and lengths\n");
865
866         if ((memzone1->iova & RTE_CACHE_LINE_MASK) != 0)
867                 return -1;
868         if ((memzone2->iova & RTE_CACHE_LINE_MASK) != 0)
869                 return -1;
870         if (memzone3 != NULL && (memzone3->iova & RTE_CACHE_LINE_MASK) != 0)
871                 return -1;
872         if ((memzone1->len & RTE_CACHE_LINE_MASK) != 0 || memzone1->len == 0)
873                 return -1;
874         if ((memzone2->len & RTE_CACHE_LINE_MASK) != 0 || memzone2->len == 0)
875                 return -1;
876         if (memzone3 != NULL && ((memzone3->len & RTE_CACHE_LINE_MASK) != 0 ||
877                         memzone3->len == 0))
878                 return -1;
879         if (memzone4->len != 1024)
880                 return -1;
881
882         /* check that zones don't overlap */
883         printf("check overlapping\n");
884
885         if (is_memory_overlap(memzone1->iova, memzone1->len,
886                         memzone2->iova, memzone2->len))
887                 return -1;
888         if (memzone3 != NULL &&
889                         is_memory_overlap(memzone1->iova, memzone1->len,
890                                         memzone3->iova, memzone3->len))
891                 return -1;
892         if (memzone3 != NULL &&
893                         is_memory_overlap(memzone2->iova, memzone2->len,
894                                         memzone3->iova, memzone3->len))
895                 return -1;
896
897         printf("check socket ID\n");
898
899         /* memzone2 must be on socket id 0 and memzone3 on socket 1 */
900         if (memzone2->socket_id != 0)
901                 return -1;
902         if (memzone3 != NULL && memzone3->socket_id != 1)
903                 return -1;
904
905         printf("test zone lookup\n");
906         mz = rte_memzone_lookup("testzone1");
907         if (mz != memzone1)
908                 return -1;
909
910         printf("test duplcate zone name\n");
911         mz = rte_memzone_reserve("testzone1", 100,
912                         SOCKET_ID_ANY, 0);
913         if (mz != NULL)
914                 return -1;
915
916         if (rte_memzone_free(memzone1)) {
917                 printf("Fail memzone free - memzone1\n");
918                 return -1;
919         }
920         if (rte_memzone_free(memzone2)) {
921                 printf("Fail memzone free - memzone2\n");
922                 return -1;
923         }
924         if (memzone3 && rte_memzone_free(memzone3)) {
925                 printf("Fail memzone free - memzone3\n");
926                 return -1;
927         }
928         if (rte_memzone_free(memzone4)) {
929                 printf("Fail memzone free - memzone4\n");
930                 return -1;
931         }
932
933         return 0;
934 }
935
936 static int memzone_walk_called;
937 static void memzone_walk_clb(const struct rte_memzone *mz __rte_unused,
938                              void *arg __rte_unused)
939 {
940         memzone_walk_called = 1;
941 }
942
943 static int
944 test_memzone(void)
945 {
946         printf("test basic memzone API\n");
947         if (test_memzone_basic() < 0)
948                 return -1;
949
950         printf("test free memzone\n");
951         if (test_memzone_free() < 0)
952                 return -1;
953
954         printf("test reserving memzone with bigger size than the maximum\n");
955         if (test_memzone_reserving_zone_size_bigger_than_the_maximum() < 0)
956                 return -1;
957
958         printf("test memzone_reserve flags\n");
959         if (test_memzone_reserve_flags() < 0)
960                 return -1;
961
962         printf("test alignment for memzone_reserve\n");
963         if (test_memzone_aligned() < 0)
964                 return -1;
965
966         printf("test boundary alignment for memzone_reserve\n");
967         if (test_memzone_bounded() < 0)
968                 return -1;
969
970         printf("test invalid alignment for memzone_reserve\n");
971         if (test_memzone_invalid_alignment() < 0)
972                 return -1;
973
974         printf("test reserving the largest size memzone possible\n");
975         if (test_memzone_reserve_max() < 0)
976                 return -1;
977
978         printf("test reserving the largest size aligned memzone possible\n");
979         if (test_memzone_reserve_max_aligned() < 0)
980                 return -1;
981
982         printf("check memzone cleanup\n");
983         rte_memzone_walk(memzone_walk_clb, NULL);
984         if (memzone_walk_called) {
985                 printf("there are some memzones left after test\n");
986                 rte_memzone_dump(stdout);
987                 return -1;
988         }
989
990         return 0;
991 }
992
993 REGISTER_TEST_COMMAND(memzone_autotest, test_memzone);