mempool: add op to populate objects using provided memory
[dpdk.git] / lib / librte_mempool / rte_mempool.c
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright(c) 2010-2014 Intel Corporation.
3  * Copyright(c) 2016 6WIND S.A.
4  */
5
6 #include <stdbool.h>
7 #include <stdio.h>
8 #include <string.h>
9 #include <stdint.h>
10 #include <stdarg.h>
11 #include <unistd.h>
12 #include <inttypes.h>
13 #include <errno.h>
14 #include <sys/queue.h>
15 #include <sys/mman.h>
16
17 #include <rte_common.h>
18 #include <rte_log.h>
19 #include <rte_debug.h>
20 #include <rte_memory.h>
21 #include <rte_memzone.h>
22 #include <rte_malloc.h>
23 #include <rte_atomic.h>
24 #include <rte_launch.h>
25 #include <rte_eal.h>
26 #include <rte_eal_memconfig.h>
27 #include <rte_per_lcore.h>
28 #include <rte_lcore.h>
29 #include <rte_branch_prediction.h>
30 #include <rte_errno.h>
31 #include <rte_string_fns.h>
32 #include <rte_spinlock.h>
33
34 #include "rte_mempool.h"
35
36 TAILQ_HEAD(rte_mempool_list, rte_tailq_entry);
37
38 static struct rte_tailq_elem rte_mempool_tailq = {
39         .name = "RTE_MEMPOOL",
40 };
41 EAL_REGISTER_TAILQ(rte_mempool_tailq)
42
43 #define CACHE_FLUSHTHRESH_MULTIPLIER 1.5
44 #define CALC_CACHE_FLUSHTHRESH(c)       \
45         ((typeof(c))((c) * CACHE_FLUSHTHRESH_MULTIPLIER))
46
47 /*
48  * return the greatest common divisor between a and b (fast algorithm)
49  *
50  */
51 static unsigned get_gcd(unsigned a, unsigned b)
52 {
53         unsigned c;
54
55         if (0 == a)
56                 return b;
57         if (0 == b)
58                 return a;
59
60         if (a < b) {
61                 c = a;
62                 a = b;
63                 b = c;
64         }
65
66         while (b != 0) {
67                 c = a % b;
68                 a = b;
69                 b = c;
70         }
71
72         return a;
73 }
74
75 /*
76  * Depending on memory configuration, objects addresses are spread
77  * between channels and ranks in RAM: the pool allocator will add
78  * padding between objects. This function return the new size of the
79  * object.
80  */
81 static unsigned optimize_object_size(unsigned obj_size)
82 {
83         unsigned nrank, nchan;
84         unsigned new_obj_size;
85
86         /* get number of channels */
87         nchan = rte_memory_get_nchannel();
88         if (nchan == 0)
89                 nchan = 4;
90
91         nrank = rte_memory_get_nrank();
92         if (nrank == 0)
93                 nrank = 1;
94
95         /* process new object size */
96         new_obj_size = (obj_size + RTE_MEMPOOL_ALIGN_MASK) / RTE_MEMPOOL_ALIGN;
97         while (get_gcd(new_obj_size, nrank * nchan) != 1)
98                 new_obj_size++;
99         return new_obj_size * RTE_MEMPOOL_ALIGN;
100 }
101
102 static int
103 find_min_pagesz(const struct rte_memseg_list *msl, void *arg)
104 {
105         size_t *min = arg;
106
107         if (msl->page_sz < *min)
108                 *min = msl->page_sz;
109
110         return 0;
111 }
112
113 static size_t
114 get_min_page_size(void)
115 {
116         size_t min_pagesz = SIZE_MAX;
117
118         rte_memseg_list_walk(find_min_pagesz, &min_pagesz);
119
120         return min_pagesz == SIZE_MAX ? (size_t) getpagesize() : min_pagesz;
121 }
122
123
124 static void
125 mempool_add_elem(struct rte_mempool *mp, __rte_unused void *opaque,
126                  void *obj, rte_iova_t iova)
127 {
128         struct rte_mempool_objhdr *hdr;
129         struct rte_mempool_objtlr *tlr __rte_unused;
130
131         /* set mempool ptr in header */
132         hdr = RTE_PTR_SUB(obj, sizeof(*hdr));
133         hdr->mp = mp;
134         hdr->iova = iova;
135         STAILQ_INSERT_TAIL(&mp->elt_list, hdr, next);
136         mp->populated_size++;
137
138 #ifdef RTE_LIBRTE_MEMPOOL_DEBUG
139         hdr->cookie = RTE_MEMPOOL_HEADER_COOKIE2;
140         tlr = __mempool_get_trailer(obj);
141         tlr->cookie = RTE_MEMPOOL_TRAILER_COOKIE;
142 #endif
143 }
144
145 /* call obj_cb() for each mempool element */
146 uint32_t
147 rte_mempool_obj_iter(struct rte_mempool *mp,
148         rte_mempool_obj_cb_t *obj_cb, void *obj_cb_arg)
149 {
150         struct rte_mempool_objhdr *hdr;
151         void *obj;
152         unsigned n = 0;
153
154         STAILQ_FOREACH(hdr, &mp->elt_list, next) {
155                 obj = (char *)hdr + sizeof(*hdr);
156                 obj_cb(mp, obj_cb_arg, obj, n);
157                 n++;
158         }
159
160         return n;
161 }
162
163 /* call mem_cb() for each mempool memory chunk */
164 uint32_t
165 rte_mempool_mem_iter(struct rte_mempool *mp,
166         rte_mempool_mem_cb_t *mem_cb, void *mem_cb_arg)
167 {
168         struct rte_mempool_memhdr *hdr;
169         unsigned n = 0;
170
171         STAILQ_FOREACH(hdr, &mp->mem_list, next) {
172                 mem_cb(mp, mem_cb_arg, hdr, n);
173                 n++;
174         }
175
176         return n;
177 }
178
179 /* get the header, trailer and total size of a mempool element. */
180 uint32_t
181 rte_mempool_calc_obj_size(uint32_t elt_size, uint32_t flags,
182         struct rte_mempool_objsz *sz)
183 {
184         struct rte_mempool_objsz lsz;
185
186         sz = (sz != NULL) ? sz : &lsz;
187
188         sz->header_size = sizeof(struct rte_mempool_objhdr);
189         if ((flags & MEMPOOL_F_NO_CACHE_ALIGN) == 0)
190                 sz->header_size = RTE_ALIGN_CEIL(sz->header_size,
191                         RTE_MEMPOOL_ALIGN);
192
193 #ifdef RTE_LIBRTE_MEMPOOL_DEBUG
194         sz->trailer_size = sizeof(struct rte_mempool_objtlr);
195 #else
196         sz->trailer_size = 0;
197 #endif
198
199         /* element size is 8 bytes-aligned at least */
200         sz->elt_size = RTE_ALIGN_CEIL(elt_size, sizeof(uint64_t));
201
202         /* expand trailer to next cache line */
203         if ((flags & MEMPOOL_F_NO_CACHE_ALIGN) == 0) {
204                 sz->total_size = sz->header_size + sz->elt_size +
205                         sz->trailer_size;
206                 sz->trailer_size += ((RTE_MEMPOOL_ALIGN -
207                                   (sz->total_size & RTE_MEMPOOL_ALIGN_MASK)) &
208                                  RTE_MEMPOOL_ALIGN_MASK);
209         }
210
211         /*
212          * increase trailer to add padding between objects in order to
213          * spread them across memory channels/ranks
214          */
215         if ((flags & MEMPOOL_F_NO_SPREAD) == 0) {
216                 unsigned new_size;
217                 new_size = optimize_object_size(sz->header_size + sz->elt_size +
218                         sz->trailer_size);
219                 sz->trailer_size = new_size - sz->header_size - sz->elt_size;
220         }
221
222         /* this is the size of an object, including header and trailer */
223         sz->total_size = sz->header_size + sz->elt_size + sz->trailer_size;
224
225         return sz->total_size;
226 }
227
228
229 /*
230  * Calculate maximum amount of memory required to store given number of objects.
231  */
232 size_t
233 rte_mempool_xmem_size(uint32_t elt_num, size_t total_elt_sz, uint32_t pg_shift,
234                       unsigned int flags)
235 {
236         size_t obj_per_page, pg_num, pg_sz;
237         unsigned int mask;
238
239         mask = MEMPOOL_F_CAPA_BLK_ALIGNED_OBJECTS | MEMPOOL_F_CAPA_PHYS_CONTIG;
240         if ((flags & mask) == mask)
241                 /* alignment need one additional object */
242                 elt_num += 1;
243
244         if (total_elt_sz == 0)
245                 return 0;
246
247         if (pg_shift == 0)
248                 return total_elt_sz * elt_num;
249
250         pg_sz = (size_t)1 << pg_shift;
251         obj_per_page = pg_sz / total_elt_sz;
252         if (obj_per_page == 0)
253                 return RTE_ALIGN_CEIL(total_elt_sz, pg_sz) * elt_num;
254
255         pg_num = (elt_num + obj_per_page - 1) / obj_per_page;
256         return pg_num << pg_shift;
257 }
258
259 /*
260  * Calculate how much memory would be actually required with the
261  * given memory footprint to store required number of elements.
262  */
263 ssize_t
264 rte_mempool_xmem_usage(__rte_unused void *vaddr, uint32_t elt_num,
265         size_t total_elt_sz, const rte_iova_t iova[], uint32_t pg_num,
266         uint32_t pg_shift, unsigned int flags)
267 {
268         uint32_t elt_cnt = 0;
269         rte_iova_t start, end;
270         uint32_t iova_idx;
271         size_t pg_sz = (size_t)1 << pg_shift;
272         unsigned int mask;
273
274         mask = MEMPOOL_F_CAPA_BLK_ALIGNED_OBJECTS | MEMPOOL_F_CAPA_PHYS_CONTIG;
275         if ((flags & mask) == mask)
276                 /* alignment need one additional object */
277                 elt_num += 1;
278
279         /* if iova is NULL, assume contiguous memory */
280         if (iova == NULL) {
281                 start = 0;
282                 end = pg_sz * pg_num;
283                 iova_idx = pg_num;
284         } else {
285                 start = iova[0];
286                 end = iova[0] + pg_sz;
287                 iova_idx = 1;
288         }
289         while (elt_cnt < elt_num) {
290
291                 if (end - start >= total_elt_sz) {
292                         /* enough contiguous memory, add an object */
293                         start += total_elt_sz;
294                         elt_cnt++;
295                 } else if (iova_idx < pg_num) {
296                         /* no room to store one obj, add a page */
297                         if (end == iova[iova_idx]) {
298                                 end += pg_sz;
299                         } else {
300                                 start = iova[iova_idx];
301                                 end = iova[iova_idx] + pg_sz;
302                         }
303                         iova_idx++;
304
305                 } else {
306                         /* no more page, return how many elements fit */
307                         return -(size_t)elt_cnt;
308                 }
309         }
310
311         return (size_t)iova_idx << pg_shift;
312 }
313
314 /* free a memchunk allocated with rte_memzone_reserve() */
315 static void
316 rte_mempool_memchunk_mz_free(__rte_unused struct rte_mempool_memhdr *memhdr,
317         void *opaque)
318 {
319         const struct rte_memzone *mz = opaque;
320         rte_memzone_free(mz);
321 }
322
323 /* Free memory chunks used by a mempool. Objects must be in pool */
324 static void
325 rte_mempool_free_memchunks(struct rte_mempool *mp)
326 {
327         struct rte_mempool_memhdr *memhdr;
328         void *elt;
329
330         while (!STAILQ_EMPTY(&mp->elt_list)) {
331                 rte_mempool_ops_dequeue_bulk(mp, &elt, 1);
332                 (void)elt;
333                 STAILQ_REMOVE_HEAD(&mp->elt_list, next);
334                 mp->populated_size--;
335         }
336
337         while (!STAILQ_EMPTY(&mp->mem_list)) {
338                 memhdr = STAILQ_FIRST(&mp->mem_list);
339                 STAILQ_REMOVE_HEAD(&mp->mem_list, next);
340                 if (memhdr->free_cb != NULL)
341                         memhdr->free_cb(memhdr, memhdr->opaque);
342                 rte_free(memhdr);
343                 mp->nb_mem_chunks--;
344         }
345 }
346
347 static int
348 mempool_ops_alloc_once(struct rte_mempool *mp)
349 {
350         int ret;
351
352         /* create the internal ring if not already done */
353         if ((mp->flags & MEMPOOL_F_POOL_CREATED) == 0) {
354                 ret = rte_mempool_ops_alloc(mp);
355                 if (ret != 0)
356                         return ret;
357                 mp->flags |= MEMPOOL_F_POOL_CREATED;
358         }
359         return 0;
360 }
361
362 /* Add objects in the pool, using a physically contiguous memory
363  * zone. Return the number of objects added, or a negative value
364  * on error.
365  */
366 int
367 rte_mempool_populate_iova(struct rte_mempool *mp, char *vaddr,
368         rte_iova_t iova, size_t len, rte_mempool_memchunk_free_cb_t *free_cb,
369         void *opaque)
370 {
371         unsigned total_elt_sz;
372         unsigned int mp_capa_flags;
373         unsigned i = 0;
374         size_t off;
375         struct rte_mempool_memhdr *memhdr;
376         int ret;
377
378         ret = mempool_ops_alloc_once(mp);
379         if (ret != 0)
380                 return ret;
381
382         /* Notify memory area to mempool */
383         ret = rte_mempool_ops_register_memory_area(mp, vaddr, iova, len);
384         if (ret != -ENOTSUP && ret < 0)
385                 return ret;
386
387         /* mempool is already populated */
388         if (mp->populated_size >= mp->size)
389                 return -ENOSPC;
390
391         total_elt_sz = mp->header_size + mp->elt_size + mp->trailer_size;
392
393         /* Get mempool capabilities */
394         mp_capa_flags = 0;
395         ret = rte_mempool_ops_get_capabilities(mp, &mp_capa_flags);
396         if ((ret < 0) && (ret != -ENOTSUP))
397                 return ret;
398
399         /* update mempool capabilities */
400         mp->flags |= mp_capa_flags;
401
402         memhdr = rte_zmalloc("MEMPOOL_MEMHDR", sizeof(*memhdr), 0);
403         if (memhdr == NULL)
404                 return -ENOMEM;
405
406         memhdr->mp = mp;
407         memhdr->addr = vaddr;
408         memhdr->iova = iova;
409         memhdr->len = len;
410         memhdr->free_cb = free_cb;
411         memhdr->opaque = opaque;
412
413         if (mp_capa_flags & MEMPOOL_F_CAPA_BLK_ALIGNED_OBJECTS)
414                 /* align object start address to a multiple of total_elt_sz */
415                 off = total_elt_sz - ((uintptr_t)vaddr % total_elt_sz);
416         else if (mp->flags & MEMPOOL_F_NO_CACHE_ALIGN)
417                 off = RTE_PTR_ALIGN_CEIL(vaddr, 8) - vaddr;
418         else
419                 off = RTE_PTR_ALIGN_CEIL(vaddr, RTE_CACHE_LINE_SIZE) - vaddr;
420
421         if (off > len) {
422                 ret = -EINVAL;
423                 goto fail;
424         }
425
426         i = rte_mempool_ops_populate(mp, mp->size - mp->populated_size,
427                 (char *)vaddr + off,
428                 (iova == RTE_BAD_IOVA) ? RTE_BAD_IOVA : (iova + off),
429                 len - off, mempool_add_elem, NULL);
430
431         /* not enough room to store one object */
432         if (i == 0) {
433                 ret = -EINVAL;
434                 goto fail;
435         }
436
437         STAILQ_INSERT_TAIL(&mp->mem_list, memhdr, next);
438         mp->nb_mem_chunks++;
439         return i;
440
441 fail:
442         rte_free(memhdr);
443         return ret;
444 }
445
446 int
447 rte_mempool_populate_phys(struct rte_mempool *mp, char *vaddr,
448         phys_addr_t paddr, size_t len, rte_mempool_memchunk_free_cb_t *free_cb,
449         void *opaque)
450 {
451         return rte_mempool_populate_iova(mp, vaddr, paddr, len, free_cb, opaque);
452 }
453
454 /* Add objects in the pool, using a table of physical pages. Return the
455  * number of objects added, or a negative value on error.
456  */
457 int
458 rte_mempool_populate_iova_tab(struct rte_mempool *mp, char *vaddr,
459         const rte_iova_t iova[], uint32_t pg_num, uint32_t pg_shift,
460         rte_mempool_memchunk_free_cb_t *free_cb, void *opaque)
461 {
462         uint32_t i, n;
463         int ret, cnt = 0;
464         size_t pg_sz = (size_t)1 << pg_shift;
465
466         /* mempool must not be populated */
467         if (mp->nb_mem_chunks != 0)
468                 return -EEXIST;
469
470         if (mp->flags & MEMPOOL_F_NO_IOVA_CONTIG)
471                 return rte_mempool_populate_iova(mp, vaddr, RTE_BAD_IOVA,
472                         pg_num * pg_sz, free_cb, opaque);
473
474         for (i = 0; i < pg_num && mp->populated_size < mp->size; i += n) {
475
476                 /* populate with the largest group of contiguous pages */
477                 for (n = 1; (i + n) < pg_num &&
478                              iova[i + n - 1] + pg_sz == iova[i + n]; n++)
479                         ;
480
481                 ret = rte_mempool_populate_iova(mp, vaddr + i * pg_sz,
482                         iova[i], n * pg_sz, free_cb, opaque);
483                 if (ret < 0) {
484                         rte_mempool_free_memchunks(mp);
485                         return ret;
486                 }
487                 /* no need to call the free callback for next chunks */
488                 free_cb = NULL;
489                 cnt += ret;
490         }
491         return cnt;
492 }
493
494 int
495 rte_mempool_populate_phys_tab(struct rte_mempool *mp, char *vaddr,
496         const phys_addr_t paddr[], uint32_t pg_num, uint32_t pg_shift,
497         rte_mempool_memchunk_free_cb_t *free_cb, void *opaque)
498 {
499         return rte_mempool_populate_iova_tab(mp, vaddr, paddr, pg_num, pg_shift,
500                         free_cb, opaque);
501 }
502
503 /* Populate the mempool with a virtual area. Return the number of
504  * objects added, or a negative value on error.
505  */
506 int
507 rte_mempool_populate_virt(struct rte_mempool *mp, char *addr,
508         size_t len, size_t pg_sz, rte_mempool_memchunk_free_cb_t *free_cb,
509         void *opaque)
510 {
511         rte_iova_t iova;
512         size_t off, phys_len;
513         int ret, cnt = 0;
514
515         /* mempool must not be populated */
516         if (mp->nb_mem_chunks != 0)
517                 return -EEXIST;
518         /* address and len must be page-aligned */
519         if (RTE_PTR_ALIGN_CEIL(addr, pg_sz) != addr)
520                 return -EINVAL;
521         if (RTE_ALIGN_CEIL(len, pg_sz) != len)
522                 return -EINVAL;
523
524         if (mp->flags & MEMPOOL_F_NO_IOVA_CONTIG)
525                 return rte_mempool_populate_iova(mp, addr, RTE_BAD_IOVA,
526                         len, free_cb, opaque);
527
528         for (off = 0; off + pg_sz <= len &&
529                      mp->populated_size < mp->size; off += phys_len) {
530
531                 iova = rte_mem_virt2iova(addr + off);
532
533                 if (iova == RTE_BAD_IOVA && rte_eal_has_hugepages()) {
534                         ret = -EINVAL;
535                         goto fail;
536                 }
537
538                 /* populate with the largest group of contiguous pages */
539                 for (phys_len = pg_sz; off + phys_len < len; phys_len += pg_sz) {
540                         rte_iova_t iova_tmp;
541
542                         iova_tmp = rte_mem_virt2iova(addr + off + phys_len);
543
544                         if (iova_tmp != iova + phys_len)
545                                 break;
546                 }
547
548                 ret = rte_mempool_populate_iova(mp, addr + off, iova,
549                         phys_len, free_cb, opaque);
550                 if (ret < 0)
551                         goto fail;
552                 /* no need to call the free callback for next chunks */
553                 free_cb = NULL;
554                 cnt += ret;
555         }
556
557         return cnt;
558
559  fail:
560         rte_mempool_free_memchunks(mp);
561         return ret;
562 }
563
564 /* Default function to populate the mempool: allocate memory in memzones,
565  * and populate them. Return the number of objects added, or a negative
566  * value on error.
567  */
568 int
569 rte_mempool_populate_default(struct rte_mempool *mp)
570 {
571         unsigned int mz_flags = RTE_MEMZONE_1GB|RTE_MEMZONE_SIZE_HINT_ONLY;
572         char mz_name[RTE_MEMZONE_NAMESIZE];
573         const struct rte_memzone *mz;
574         ssize_t mem_size;
575         size_t align, pg_sz, pg_shift;
576         rte_iova_t iova;
577         unsigned mz_id, n;
578         int ret;
579         bool no_contig, try_contig, no_pageshift;
580
581         ret = mempool_ops_alloc_once(mp);
582         if (ret != 0)
583                 return ret;
584
585         /* mempool must not be populated */
586         if (mp->nb_mem_chunks != 0)
587                 return -EEXIST;
588
589         no_contig = mp->flags & MEMPOOL_F_NO_IOVA_CONTIG;
590
591         /*
592          * the following section calculates page shift and page size values.
593          *
594          * these values impact the result of calc_mem_size operation, which
595          * returns the amount of memory that should be allocated to store the
596          * desired number of objects. when not zero, it allocates more memory
597          * for the padding between objects, to ensure that an object does not
598          * cross a page boundary. in other words, page size/shift are to be set
599          * to zero if mempool elements won't care about page boundaries.
600          * there are several considerations for page size and page shift here.
601          *
602          * if we don't need our mempools to have physically contiguous objects,
603          * then just set page shift and page size to 0, because the user has
604          * indicated that there's no need to care about anything.
605          *
606          * if we do need contiguous objects, there is also an option to reserve
607          * the entire mempool memory as one contiguous block of memory, in
608          * which case the page shift and alignment wouldn't matter as well.
609          *
610          * if we require contiguous objects, but not necessarily the entire
611          * mempool reserved space to be contiguous, then there are two options.
612          *
613          * if our IO addresses are virtual, not actual physical (IOVA as VA
614          * case), then no page shift needed - our memory allocation will give us
615          * contiguous IO memory as far as the hardware is concerned, so
616          * act as if we're getting contiguous memory.
617          *
618          * if our IO addresses are physical, we may get memory from bigger
619          * pages, or we might get memory from smaller pages, and how much of it
620          * we require depends on whether we want bigger or smaller pages.
621          * However, requesting each and every memory size is too much work, so
622          * what we'll do instead is walk through the page sizes available, pick
623          * the smallest one and set up page shift to match that one. We will be
624          * wasting some space this way, but it's much nicer than looping around
625          * trying to reserve each and every page size.
626          *
627          * However, since size calculation will produce page-aligned sizes, it
628          * makes sense to first try and see if we can reserve the entire memzone
629          * in one contiguous chunk as well (otherwise we might end up wasting a
630          * 1G page on a 10MB memzone). If we fail to get enough contiguous
631          * memory, then we'll go and reserve space page-by-page.
632          */
633         no_pageshift = no_contig || rte_eal_iova_mode() == RTE_IOVA_VA;
634         try_contig = !no_contig && !no_pageshift && rte_eal_has_hugepages();
635
636         if (no_pageshift) {
637                 pg_sz = 0;
638                 pg_shift = 0;
639         } else if (try_contig) {
640                 pg_sz = get_min_page_size();
641                 pg_shift = rte_bsf32(pg_sz);
642         } else {
643                 pg_sz = getpagesize();
644                 pg_shift = rte_bsf32(pg_sz);
645         }
646
647         for (mz_id = 0, n = mp->size; n > 0; mz_id++, n -= ret) {
648                 size_t min_chunk_size;
649                 unsigned int flags;
650
651                 if (try_contig || no_pageshift)
652                         mem_size = rte_mempool_ops_calc_mem_size(mp, n,
653                                         0, &min_chunk_size, &align);
654                 else
655                         mem_size = rte_mempool_ops_calc_mem_size(mp, n,
656                                         pg_shift, &min_chunk_size, &align);
657
658                 if (mem_size < 0) {
659                         ret = mem_size;
660                         goto fail;
661                 }
662
663                 ret = snprintf(mz_name, sizeof(mz_name),
664                         RTE_MEMPOOL_MZ_FORMAT "_%d", mp->name, mz_id);
665                 if (ret < 0 || ret >= (int)sizeof(mz_name)) {
666                         ret = -ENAMETOOLONG;
667                         goto fail;
668                 }
669
670                 flags = mz_flags;
671
672                 /* if we're trying to reserve contiguous memory, add appropriate
673                  * memzone flag.
674                  */
675                 if (try_contig)
676                         flags |= RTE_MEMZONE_IOVA_CONTIG;
677
678                 mz = rte_memzone_reserve_aligned(mz_name, mem_size,
679                                 mp->socket_id, flags, align);
680
681                 /* if we were trying to allocate contiguous memory, failed and
682                  * minimum required contiguous chunk fits minimum page, adjust
683                  * memzone size to the page size, and try again.
684                  */
685                 if (mz == NULL && try_contig && min_chunk_size <= pg_sz) {
686                         try_contig = false;
687                         flags &= ~RTE_MEMZONE_IOVA_CONTIG;
688
689                         mem_size = rte_mempool_ops_calc_mem_size(mp, n,
690                                         pg_shift, &min_chunk_size, &align);
691                         if (mem_size < 0) {
692                                 ret = mem_size;
693                                 goto fail;
694                         }
695
696                         mz = rte_memzone_reserve_aligned(mz_name, mem_size,
697                                 mp->socket_id, flags, align);
698                 }
699                 /* don't try reserving with 0 size if we were asked to reserve
700                  * IOVA-contiguous memory.
701                  */
702                 if (min_chunk_size < (size_t)mem_size && mz == NULL) {
703                         /* not enough memory, retry with the biggest zone we
704                          * have
705                          */
706                         mz = rte_memzone_reserve_aligned(mz_name, 0,
707                                         mp->socket_id, flags, align);
708                 }
709                 if (mz == NULL) {
710                         ret = -rte_errno;
711                         goto fail;
712                 }
713
714                 if (mz->len < min_chunk_size) {
715                         rte_memzone_free(mz);
716                         ret = -ENOMEM;
717                         goto fail;
718                 }
719
720                 if (no_contig)
721                         iova = RTE_BAD_IOVA;
722                 else
723                         iova = mz->iova;
724
725                 if (no_pageshift || try_contig)
726                         ret = rte_mempool_populate_iova(mp, mz->addr,
727                                 iova, mz->len,
728                                 rte_mempool_memchunk_mz_free,
729                                 (void *)(uintptr_t)mz);
730                 else
731                         ret = rte_mempool_populate_virt(mp, mz->addr,
732                                 mz->len, pg_sz,
733                                 rte_mempool_memchunk_mz_free,
734                                 (void *)(uintptr_t)mz);
735                 if (ret < 0) {
736                         rte_memzone_free(mz);
737                         goto fail;
738                 }
739         }
740
741         return mp->size;
742
743  fail:
744         rte_mempool_free_memchunks(mp);
745         return ret;
746 }
747
748 /* return the memory size required for mempool objects in anonymous mem */
749 static ssize_t
750 get_anon_size(const struct rte_mempool *mp)
751 {
752         ssize_t size;
753         size_t pg_sz, pg_shift;
754         size_t min_chunk_size;
755         size_t align;
756
757         pg_sz = getpagesize();
758         pg_shift = rte_bsf32(pg_sz);
759         size = rte_mempool_ops_calc_mem_size(mp, mp->size, pg_shift,
760                                              &min_chunk_size, &align);
761
762         return size;
763 }
764
765 /* unmap a memory zone mapped by rte_mempool_populate_anon() */
766 static void
767 rte_mempool_memchunk_anon_free(struct rte_mempool_memhdr *memhdr,
768         void *opaque)
769 {
770         ssize_t size;
771
772         /*
773          * Calculate size since memhdr->len has contiguous chunk length
774          * which may be smaller if anon map is split into many contiguous
775          * chunks. Result must be the same as we calculated on populate.
776          */
777         size = get_anon_size(memhdr->mp);
778         if (size < 0)
779                 return;
780
781         munmap(opaque, size);
782 }
783
784 /* populate the mempool with an anonymous mapping */
785 int
786 rte_mempool_populate_anon(struct rte_mempool *mp)
787 {
788         ssize_t size;
789         int ret;
790         char *addr;
791
792         /* mempool is already populated, error */
793         if (!STAILQ_EMPTY(&mp->mem_list)) {
794                 rte_errno = EINVAL;
795                 return 0;
796         }
797
798         ret = mempool_ops_alloc_once(mp);
799         if (ret != 0)
800                 return ret;
801
802         size = get_anon_size(mp);
803         if (size < 0) {
804                 rte_errno = -size;
805                 return 0;
806         }
807
808         /* get chunk of virtually continuous memory */
809         addr = mmap(NULL, size, PROT_READ | PROT_WRITE,
810                 MAP_SHARED | MAP_ANONYMOUS, -1, 0);
811         if (addr == MAP_FAILED) {
812                 rte_errno = errno;
813                 return 0;
814         }
815         /* can't use MMAP_LOCKED, it does not exist on BSD */
816         if (mlock(addr, size) < 0) {
817                 rte_errno = errno;
818                 munmap(addr, size);
819                 return 0;
820         }
821
822         ret = rte_mempool_populate_virt(mp, addr, size, getpagesize(),
823                 rte_mempool_memchunk_anon_free, addr);
824         if (ret == 0)
825                 goto fail;
826
827         return mp->populated_size;
828
829  fail:
830         rte_mempool_free_memchunks(mp);
831         return 0;
832 }
833
834 /* free a mempool */
835 void
836 rte_mempool_free(struct rte_mempool *mp)
837 {
838         struct rte_mempool_list *mempool_list = NULL;
839         struct rte_tailq_entry *te;
840
841         if (mp == NULL)
842                 return;
843
844         mempool_list = RTE_TAILQ_CAST(rte_mempool_tailq.head, rte_mempool_list);
845         rte_rwlock_write_lock(RTE_EAL_TAILQ_RWLOCK);
846         /* find out tailq entry */
847         TAILQ_FOREACH(te, mempool_list, next) {
848                 if (te->data == (void *)mp)
849                         break;
850         }
851
852         if (te != NULL) {
853                 TAILQ_REMOVE(mempool_list, te, next);
854                 rte_free(te);
855         }
856         rte_rwlock_write_unlock(RTE_EAL_TAILQ_RWLOCK);
857
858         rte_mempool_free_memchunks(mp);
859         rte_mempool_ops_free(mp);
860         rte_memzone_free(mp->mz);
861 }
862
863 static void
864 mempool_cache_init(struct rte_mempool_cache *cache, uint32_t size)
865 {
866         cache->size = size;
867         cache->flushthresh = CALC_CACHE_FLUSHTHRESH(size);
868         cache->len = 0;
869 }
870
871 /*
872  * Create and initialize a cache for objects that are retrieved from and
873  * returned to an underlying mempool. This structure is identical to the
874  * local_cache[lcore_id] pointed to by the mempool structure.
875  */
876 struct rte_mempool_cache *
877 rte_mempool_cache_create(uint32_t size, int socket_id)
878 {
879         struct rte_mempool_cache *cache;
880
881         if (size == 0 || size > RTE_MEMPOOL_CACHE_MAX_SIZE) {
882                 rte_errno = EINVAL;
883                 return NULL;
884         }
885
886         cache = rte_zmalloc_socket("MEMPOOL_CACHE", sizeof(*cache),
887                                   RTE_CACHE_LINE_SIZE, socket_id);
888         if (cache == NULL) {
889                 RTE_LOG(ERR, MEMPOOL, "Cannot allocate mempool cache.\n");
890                 rte_errno = ENOMEM;
891                 return NULL;
892         }
893
894         mempool_cache_init(cache, size);
895
896         return cache;
897 }
898
899 /*
900  * Free a cache. It's the responsibility of the user to make sure that any
901  * remaining objects in the cache are flushed to the corresponding
902  * mempool.
903  */
904 void
905 rte_mempool_cache_free(struct rte_mempool_cache *cache)
906 {
907         rte_free(cache);
908 }
909
910 /* create an empty mempool */
911 struct rte_mempool *
912 rte_mempool_create_empty(const char *name, unsigned n, unsigned elt_size,
913         unsigned cache_size, unsigned private_data_size,
914         int socket_id, unsigned flags)
915 {
916         char mz_name[RTE_MEMZONE_NAMESIZE];
917         struct rte_mempool_list *mempool_list;
918         struct rte_mempool *mp = NULL;
919         struct rte_tailq_entry *te = NULL;
920         const struct rte_memzone *mz = NULL;
921         size_t mempool_size;
922         unsigned int mz_flags = RTE_MEMZONE_1GB|RTE_MEMZONE_SIZE_HINT_ONLY;
923         struct rte_mempool_objsz objsz;
924         unsigned lcore_id;
925         int ret;
926
927         /* compilation-time checks */
928         RTE_BUILD_BUG_ON((sizeof(struct rte_mempool) &
929                           RTE_CACHE_LINE_MASK) != 0);
930         RTE_BUILD_BUG_ON((sizeof(struct rte_mempool_cache) &
931                           RTE_CACHE_LINE_MASK) != 0);
932 #ifdef RTE_LIBRTE_MEMPOOL_DEBUG
933         RTE_BUILD_BUG_ON((sizeof(struct rte_mempool_debug_stats) &
934                           RTE_CACHE_LINE_MASK) != 0);
935         RTE_BUILD_BUG_ON((offsetof(struct rte_mempool, stats) &
936                           RTE_CACHE_LINE_MASK) != 0);
937 #endif
938
939         mempool_list = RTE_TAILQ_CAST(rte_mempool_tailq.head, rte_mempool_list);
940
941         /* asked cache too big */
942         if (cache_size > RTE_MEMPOOL_CACHE_MAX_SIZE ||
943             CALC_CACHE_FLUSHTHRESH(cache_size) > n) {
944                 rte_errno = EINVAL;
945                 return NULL;
946         }
947
948         /* "no cache align" imply "no spread" */
949         if (flags & MEMPOOL_F_NO_CACHE_ALIGN)
950                 flags |= MEMPOOL_F_NO_SPREAD;
951
952         /* calculate mempool object sizes. */
953         if (!rte_mempool_calc_obj_size(elt_size, flags, &objsz)) {
954                 rte_errno = EINVAL;
955                 return NULL;
956         }
957
958         rte_rwlock_write_lock(RTE_EAL_MEMPOOL_RWLOCK);
959
960         /*
961          * reserve a memory zone for this mempool: private data is
962          * cache-aligned
963          */
964         private_data_size = (private_data_size +
965                              RTE_MEMPOOL_ALIGN_MASK) & (~RTE_MEMPOOL_ALIGN_MASK);
966
967
968         /* try to allocate tailq entry */
969         te = rte_zmalloc("MEMPOOL_TAILQ_ENTRY", sizeof(*te), 0);
970         if (te == NULL) {
971                 RTE_LOG(ERR, MEMPOOL, "Cannot allocate tailq entry!\n");
972                 goto exit_unlock;
973         }
974
975         mempool_size = MEMPOOL_HEADER_SIZE(mp, cache_size);
976         mempool_size += private_data_size;
977         mempool_size = RTE_ALIGN_CEIL(mempool_size, RTE_MEMPOOL_ALIGN);
978
979         ret = snprintf(mz_name, sizeof(mz_name), RTE_MEMPOOL_MZ_FORMAT, name);
980         if (ret < 0 || ret >= (int)sizeof(mz_name)) {
981                 rte_errno = ENAMETOOLONG;
982                 goto exit_unlock;
983         }
984
985         mz = rte_memzone_reserve(mz_name, mempool_size, socket_id, mz_flags);
986         if (mz == NULL)
987                 goto exit_unlock;
988
989         /* init the mempool structure */
990         mp = mz->addr;
991         memset(mp, 0, MEMPOOL_HEADER_SIZE(mp, cache_size));
992         ret = snprintf(mp->name, sizeof(mp->name), "%s", name);
993         if (ret < 0 || ret >= (int)sizeof(mp->name)) {
994                 rte_errno = ENAMETOOLONG;
995                 goto exit_unlock;
996         }
997         mp->mz = mz;
998         mp->size = n;
999         mp->flags = flags;
1000         mp->socket_id = socket_id;
1001         mp->elt_size = objsz.elt_size;
1002         mp->header_size = objsz.header_size;
1003         mp->trailer_size = objsz.trailer_size;
1004         /* Size of default caches, zero means disabled. */
1005         mp->cache_size = cache_size;
1006         mp->private_data_size = private_data_size;
1007         STAILQ_INIT(&mp->elt_list);
1008         STAILQ_INIT(&mp->mem_list);
1009
1010         /*
1011          * local_cache pointer is set even if cache_size is zero.
1012          * The local_cache points to just past the elt_pa[] array.
1013          */
1014         mp->local_cache = (struct rte_mempool_cache *)
1015                 RTE_PTR_ADD(mp, MEMPOOL_HEADER_SIZE(mp, 0));
1016
1017         /* Init all default caches. */
1018         if (cache_size != 0) {
1019                 for (lcore_id = 0; lcore_id < RTE_MAX_LCORE; lcore_id++)
1020                         mempool_cache_init(&mp->local_cache[lcore_id],
1021                                            cache_size);
1022         }
1023
1024         te->data = mp;
1025
1026         rte_rwlock_write_lock(RTE_EAL_TAILQ_RWLOCK);
1027         TAILQ_INSERT_TAIL(mempool_list, te, next);
1028         rte_rwlock_write_unlock(RTE_EAL_TAILQ_RWLOCK);
1029         rte_rwlock_write_unlock(RTE_EAL_MEMPOOL_RWLOCK);
1030
1031         return mp;
1032
1033 exit_unlock:
1034         rte_rwlock_write_unlock(RTE_EAL_MEMPOOL_RWLOCK);
1035         rte_free(te);
1036         rte_mempool_free(mp);
1037         return NULL;
1038 }
1039
1040 /* create the mempool */
1041 struct rte_mempool *
1042 rte_mempool_create(const char *name, unsigned n, unsigned elt_size,
1043         unsigned cache_size, unsigned private_data_size,
1044         rte_mempool_ctor_t *mp_init, void *mp_init_arg,
1045         rte_mempool_obj_cb_t *obj_init, void *obj_init_arg,
1046         int socket_id, unsigned flags)
1047 {
1048         int ret;
1049         struct rte_mempool *mp;
1050
1051         mp = rte_mempool_create_empty(name, n, elt_size, cache_size,
1052                 private_data_size, socket_id, flags);
1053         if (mp == NULL)
1054                 return NULL;
1055
1056         /*
1057          * Since we have 4 combinations of the SP/SC/MP/MC examine the flags to
1058          * set the correct index into the table of ops structs.
1059          */
1060         if ((flags & MEMPOOL_F_SP_PUT) && (flags & MEMPOOL_F_SC_GET))
1061                 ret = rte_mempool_set_ops_byname(mp, "ring_sp_sc", NULL);
1062         else if (flags & MEMPOOL_F_SP_PUT)
1063                 ret = rte_mempool_set_ops_byname(mp, "ring_sp_mc", NULL);
1064         else if (flags & MEMPOOL_F_SC_GET)
1065                 ret = rte_mempool_set_ops_byname(mp, "ring_mp_sc", NULL);
1066         else
1067                 ret = rte_mempool_set_ops_byname(mp, "ring_mp_mc", NULL);
1068
1069         if (ret)
1070                 goto fail;
1071
1072         /* call the mempool priv initializer */
1073         if (mp_init)
1074                 mp_init(mp, mp_init_arg);
1075
1076         if (rte_mempool_populate_default(mp) < 0)
1077                 goto fail;
1078
1079         /* call the object initializers */
1080         if (obj_init)
1081                 rte_mempool_obj_iter(mp, obj_init, obj_init_arg);
1082
1083         return mp;
1084
1085  fail:
1086         rte_mempool_free(mp);
1087         return NULL;
1088 }
1089
1090 /*
1091  * Create the mempool over already allocated chunk of memory.
1092  * That external memory buffer can consists of physically disjoint pages.
1093  * Setting vaddr to NULL, makes mempool to fallback to rte_mempool_create()
1094  * behavior.
1095  */
1096 struct rte_mempool *
1097 rte_mempool_xmem_create(const char *name, unsigned n, unsigned elt_size,
1098                 unsigned cache_size, unsigned private_data_size,
1099                 rte_mempool_ctor_t *mp_init, void *mp_init_arg,
1100                 rte_mempool_obj_cb_t *obj_init, void *obj_init_arg,
1101                 int socket_id, unsigned flags, void *vaddr,
1102                 const rte_iova_t iova[], uint32_t pg_num, uint32_t pg_shift)
1103 {
1104         struct rte_mempool *mp = NULL;
1105         int ret;
1106
1107         /* no virtual address supplied, use rte_mempool_create() */
1108         if (vaddr == NULL)
1109                 return rte_mempool_create(name, n, elt_size, cache_size,
1110                         private_data_size, mp_init, mp_init_arg,
1111                         obj_init, obj_init_arg, socket_id, flags);
1112
1113         /* check that we have both VA and PA */
1114         if (iova == NULL) {
1115                 rte_errno = EINVAL;
1116                 return NULL;
1117         }
1118
1119         /* Check that pg_shift parameter is valid. */
1120         if (pg_shift > MEMPOOL_PG_SHIFT_MAX) {
1121                 rte_errno = EINVAL;
1122                 return NULL;
1123         }
1124
1125         mp = rte_mempool_create_empty(name, n, elt_size, cache_size,
1126                 private_data_size, socket_id, flags);
1127         if (mp == NULL)
1128                 return NULL;
1129
1130         /* call the mempool priv initializer */
1131         if (mp_init)
1132                 mp_init(mp, mp_init_arg);
1133
1134         ret = rte_mempool_populate_iova_tab(mp, vaddr, iova, pg_num, pg_shift,
1135                 NULL, NULL);
1136         if (ret < 0 || ret != (int)mp->size)
1137                 goto fail;
1138
1139         /* call the object initializers */
1140         if (obj_init)
1141                 rte_mempool_obj_iter(mp, obj_init, obj_init_arg);
1142
1143         return mp;
1144
1145  fail:
1146         rte_mempool_free(mp);
1147         return NULL;
1148 }
1149
1150 /* Return the number of entries in the mempool */
1151 unsigned int
1152 rte_mempool_avail_count(const struct rte_mempool *mp)
1153 {
1154         unsigned count;
1155         unsigned lcore_id;
1156
1157         count = rte_mempool_ops_get_count(mp);
1158
1159         if (mp->cache_size == 0)
1160                 return count;
1161
1162         for (lcore_id = 0; lcore_id < RTE_MAX_LCORE; lcore_id++)
1163                 count += mp->local_cache[lcore_id].len;
1164
1165         /*
1166          * due to race condition (access to len is not locked), the
1167          * total can be greater than size... so fix the result
1168          */
1169         if (count > mp->size)
1170                 return mp->size;
1171         return count;
1172 }
1173
1174 /* return the number of entries allocated from the mempool */
1175 unsigned int
1176 rte_mempool_in_use_count(const struct rte_mempool *mp)
1177 {
1178         return mp->size - rte_mempool_avail_count(mp);
1179 }
1180
1181 /* dump the cache status */
1182 static unsigned
1183 rte_mempool_dump_cache(FILE *f, const struct rte_mempool *mp)
1184 {
1185         unsigned lcore_id;
1186         unsigned count = 0;
1187         unsigned cache_count;
1188
1189         fprintf(f, "  internal cache infos:\n");
1190         fprintf(f, "    cache_size=%"PRIu32"\n", mp->cache_size);
1191
1192         if (mp->cache_size == 0)
1193                 return count;
1194
1195         for (lcore_id = 0; lcore_id < RTE_MAX_LCORE; lcore_id++) {
1196                 cache_count = mp->local_cache[lcore_id].len;
1197                 fprintf(f, "    cache_count[%u]=%"PRIu32"\n",
1198                         lcore_id, cache_count);
1199                 count += cache_count;
1200         }
1201         fprintf(f, "    total_cache_count=%u\n", count);
1202         return count;
1203 }
1204
1205 #ifndef __INTEL_COMPILER
1206 #pragma GCC diagnostic ignored "-Wcast-qual"
1207 #endif
1208
1209 /* check and update cookies or panic (internal) */
1210 void rte_mempool_check_cookies(const struct rte_mempool *mp,
1211         void * const *obj_table_const, unsigned n, int free)
1212 {
1213 #ifdef RTE_LIBRTE_MEMPOOL_DEBUG
1214         struct rte_mempool_objhdr *hdr;
1215         struct rte_mempool_objtlr *tlr;
1216         uint64_t cookie;
1217         void *tmp;
1218         void *obj;
1219         void **obj_table;
1220
1221         /* Force to drop the "const" attribute. This is done only when
1222          * DEBUG is enabled */
1223         tmp = (void *) obj_table_const;
1224         obj_table = tmp;
1225
1226         while (n--) {
1227                 obj = obj_table[n];
1228
1229                 if (rte_mempool_from_obj(obj) != mp)
1230                         rte_panic("MEMPOOL: object is owned by another "
1231                                   "mempool\n");
1232
1233                 hdr = __mempool_get_header(obj);
1234                 cookie = hdr->cookie;
1235
1236                 if (free == 0) {
1237                         if (cookie != RTE_MEMPOOL_HEADER_COOKIE1) {
1238                                 RTE_LOG(CRIT, MEMPOOL,
1239                                         "obj=%p, mempool=%p, cookie=%" PRIx64 "\n",
1240                                         obj, (const void *) mp, cookie);
1241                                 rte_panic("MEMPOOL: bad header cookie (put)\n");
1242                         }
1243                         hdr->cookie = RTE_MEMPOOL_HEADER_COOKIE2;
1244                 } else if (free == 1) {
1245                         if (cookie != RTE_MEMPOOL_HEADER_COOKIE2) {
1246                                 RTE_LOG(CRIT, MEMPOOL,
1247                                         "obj=%p, mempool=%p, cookie=%" PRIx64 "\n",
1248                                         obj, (const void *) mp, cookie);
1249                                 rte_panic("MEMPOOL: bad header cookie (get)\n");
1250                         }
1251                         hdr->cookie = RTE_MEMPOOL_HEADER_COOKIE1;
1252                 } else if (free == 2) {
1253                         if (cookie != RTE_MEMPOOL_HEADER_COOKIE1 &&
1254                             cookie != RTE_MEMPOOL_HEADER_COOKIE2) {
1255                                 RTE_LOG(CRIT, MEMPOOL,
1256                                         "obj=%p, mempool=%p, cookie=%" PRIx64 "\n",
1257                                         obj, (const void *) mp, cookie);
1258                                 rte_panic("MEMPOOL: bad header cookie (audit)\n");
1259                         }
1260                 }
1261                 tlr = __mempool_get_trailer(obj);
1262                 cookie = tlr->cookie;
1263                 if (cookie != RTE_MEMPOOL_TRAILER_COOKIE) {
1264                         RTE_LOG(CRIT, MEMPOOL,
1265                                 "obj=%p, mempool=%p, cookie=%" PRIx64 "\n",
1266                                 obj, (const void *) mp, cookie);
1267                         rte_panic("MEMPOOL: bad trailer cookie\n");
1268                 }
1269         }
1270 #else
1271         RTE_SET_USED(mp);
1272         RTE_SET_USED(obj_table_const);
1273         RTE_SET_USED(n);
1274         RTE_SET_USED(free);
1275 #endif
1276 }
1277
1278 #ifdef RTE_LIBRTE_MEMPOOL_DEBUG
1279 static void
1280 mempool_obj_audit(struct rte_mempool *mp, __rte_unused void *opaque,
1281         void *obj, __rte_unused unsigned idx)
1282 {
1283         __mempool_check_cookies(mp, &obj, 1, 2);
1284 }
1285
1286 static void
1287 mempool_audit_cookies(struct rte_mempool *mp)
1288 {
1289         unsigned num;
1290
1291         num = rte_mempool_obj_iter(mp, mempool_obj_audit, NULL);
1292         if (num != mp->size) {
1293                 rte_panic("rte_mempool_obj_iter(mempool=%p, size=%u) "
1294                         "iterated only over %u elements\n",
1295                         mp, mp->size, num);
1296         }
1297 }
1298 #else
1299 #define mempool_audit_cookies(mp) do {} while(0)
1300 #endif
1301
1302 #ifndef __INTEL_COMPILER
1303 #pragma GCC diagnostic error "-Wcast-qual"
1304 #endif
1305
1306 /* check cookies before and after objects */
1307 static void
1308 mempool_audit_cache(const struct rte_mempool *mp)
1309 {
1310         /* check cache size consistency */
1311         unsigned lcore_id;
1312
1313         if (mp->cache_size == 0)
1314                 return;
1315
1316         for (lcore_id = 0; lcore_id < RTE_MAX_LCORE; lcore_id++) {
1317                 const struct rte_mempool_cache *cache;
1318                 cache = &mp->local_cache[lcore_id];
1319                 if (cache->len > cache->flushthresh) {
1320                         RTE_LOG(CRIT, MEMPOOL, "badness on cache[%u]\n",
1321                                 lcore_id);
1322                         rte_panic("MEMPOOL: invalid cache len\n");
1323                 }
1324         }
1325 }
1326
1327 /* check the consistency of mempool (size, cookies, ...) */
1328 void
1329 rte_mempool_audit(struct rte_mempool *mp)
1330 {
1331         mempool_audit_cache(mp);
1332         mempool_audit_cookies(mp);
1333
1334         /* For case where mempool DEBUG is not set, and cache size is 0 */
1335         RTE_SET_USED(mp);
1336 }
1337
1338 /* dump the status of the mempool on the console */
1339 void
1340 rte_mempool_dump(FILE *f, struct rte_mempool *mp)
1341 {
1342 #ifdef RTE_LIBRTE_MEMPOOL_DEBUG
1343         struct rte_mempool_debug_stats sum;
1344         unsigned lcore_id;
1345 #endif
1346         struct rte_mempool_memhdr *memhdr;
1347         unsigned common_count;
1348         unsigned cache_count;
1349         size_t mem_len = 0;
1350
1351         RTE_ASSERT(f != NULL);
1352         RTE_ASSERT(mp != NULL);
1353
1354         fprintf(f, "mempool <%s>@%p\n", mp->name, mp);
1355         fprintf(f, "  flags=%x\n", mp->flags);
1356         fprintf(f, "  pool=%p\n", mp->pool_data);
1357         fprintf(f, "  iova=0x%" PRIx64 "\n", mp->mz->iova);
1358         fprintf(f, "  nb_mem_chunks=%u\n", mp->nb_mem_chunks);
1359         fprintf(f, "  size=%"PRIu32"\n", mp->size);
1360         fprintf(f, "  populated_size=%"PRIu32"\n", mp->populated_size);
1361         fprintf(f, "  header_size=%"PRIu32"\n", mp->header_size);
1362         fprintf(f, "  elt_size=%"PRIu32"\n", mp->elt_size);
1363         fprintf(f, "  trailer_size=%"PRIu32"\n", mp->trailer_size);
1364         fprintf(f, "  total_obj_size=%"PRIu32"\n",
1365                mp->header_size + mp->elt_size + mp->trailer_size);
1366
1367         fprintf(f, "  private_data_size=%"PRIu32"\n", mp->private_data_size);
1368
1369         STAILQ_FOREACH(memhdr, &mp->mem_list, next)
1370                 mem_len += memhdr->len;
1371         if (mem_len != 0) {
1372                 fprintf(f, "  avg bytes/object=%#Lf\n",
1373                         (long double)mem_len / mp->size);
1374         }
1375
1376         cache_count = rte_mempool_dump_cache(f, mp);
1377         common_count = rte_mempool_ops_get_count(mp);
1378         if ((cache_count + common_count) > mp->size)
1379                 common_count = mp->size - cache_count;
1380         fprintf(f, "  common_pool_count=%u\n", common_count);
1381
1382         /* sum and dump statistics */
1383 #ifdef RTE_LIBRTE_MEMPOOL_DEBUG
1384         memset(&sum, 0, sizeof(sum));
1385         for (lcore_id = 0; lcore_id < RTE_MAX_LCORE; lcore_id++) {
1386                 sum.put_bulk += mp->stats[lcore_id].put_bulk;
1387                 sum.put_objs += mp->stats[lcore_id].put_objs;
1388                 sum.get_success_bulk += mp->stats[lcore_id].get_success_bulk;
1389                 sum.get_success_objs += mp->stats[lcore_id].get_success_objs;
1390                 sum.get_fail_bulk += mp->stats[lcore_id].get_fail_bulk;
1391                 sum.get_fail_objs += mp->stats[lcore_id].get_fail_objs;
1392         }
1393         fprintf(f, "  stats:\n");
1394         fprintf(f, "    put_bulk=%"PRIu64"\n", sum.put_bulk);
1395         fprintf(f, "    put_objs=%"PRIu64"\n", sum.put_objs);
1396         fprintf(f, "    get_success_bulk=%"PRIu64"\n", sum.get_success_bulk);
1397         fprintf(f, "    get_success_objs=%"PRIu64"\n", sum.get_success_objs);
1398         fprintf(f, "    get_fail_bulk=%"PRIu64"\n", sum.get_fail_bulk);
1399         fprintf(f, "    get_fail_objs=%"PRIu64"\n", sum.get_fail_objs);
1400 #else
1401         fprintf(f, "  no statistics available\n");
1402 #endif
1403
1404         rte_mempool_audit(mp);
1405 }
1406
1407 /* dump the status of all mempools on the console */
1408 void
1409 rte_mempool_list_dump(FILE *f)
1410 {
1411         struct rte_mempool *mp = NULL;
1412         struct rte_tailq_entry *te;
1413         struct rte_mempool_list *mempool_list;
1414
1415         mempool_list = RTE_TAILQ_CAST(rte_mempool_tailq.head, rte_mempool_list);
1416
1417         rte_rwlock_read_lock(RTE_EAL_MEMPOOL_RWLOCK);
1418
1419         TAILQ_FOREACH(te, mempool_list, next) {
1420                 mp = (struct rte_mempool *) te->data;
1421                 rte_mempool_dump(f, mp);
1422         }
1423
1424         rte_rwlock_read_unlock(RTE_EAL_MEMPOOL_RWLOCK);
1425 }
1426
1427 /* search a mempool from its name */
1428 struct rte_mempool *
1429 rte_mempool_lookup(const char *name)
1430 {
1431         struct rte_mempool *mp = NULL;
1432         struct rte_tailq_entry *te;
1433         struct rte_mempool_list *mempool_list;
1434
1435         mempool_list = RTE_TAILQ_CAST(rte_mempool_tailq.head, rte_mempool_list);
1436
1437         rte_rwlock_read_lock(RTE_EAL_MEMPOOL_RWLOCK);
1438
1439         TAILQ_FOREACH(te, mempool_list, next) {
1440                 mp = (struct rte_mempool *) te->data;
1441                 if (strncmp(name, mp->name, RTE_MEMPOOL_NAMESIZE) == 0)
1442                         break;
1443         }
1444
1445         rte_rwlock_read_unlock(RTE_EAL_MEMPOOL_RWLOCK);
1446
1447         if (te == NULL) {
1448                 rte_errno = ENOENT;
1449                 return NULL;
1450         }
1451
1452         return mp;
1453 }
1454
1455 void rte_mempool_walk(void (*func)(struct rte_mempool *, void *),
1456                       void *arg)
1457 {
1458         struct rte_tailq_entry *te = NULL;
1459         struct rte_mempool_list *mempool_list;
1460         void *tmp_te;
1461
1462         mempool_list = RTE_TAILQ_CAST(rte_mempool_tailq.head, rte_mempool_list);
1463
1464         rte_rwlock_read_lock(RTE_EAL_MEMPOOL_RWLOCK);
1465
1466         TAILQ_FOREACH_SAFE(te, mempool_list, next, tmp_te) {
1467                 (*func)((struct rte_mempool *) te->data, arg);
1468         }
1469
1470         rte_rwlock_read_unlock(RTE_EAL_MEMPOOL_RWLOCK);
1471 }