DPDK 26.07.0-rc1
rte_mempool.h
Go to the documentation of this file.
1/* SPDX-License-Identifier: BSD-3-Clause
2 * Copyright(c) 2010-2014 Intel Corporation.
3 * Copyright(c) 2016 6WIND S.A.
4 * Copyright(c) 2022 SmartShare Systems
5 */
6
7#ifndef _RTE_MEMPOOL_H_
8#define _RTE_MEMPOOL_H_
9
37#include <stdalign.h>
38#include <stdio.h>
39#include <stdint.h>
40#include <inttypes.h>
41
42#include <rte_compat.h>
43#include <rte_config.h>
44#include <rte_spinlock.h>
45#include <rte_debug.h>
46#include <rte_lcore.h>
47#include <rte_log.h>
49#include <rte_ring.h>
50#include <rte_memcpy.h>
51#include <rte_common.h>
52
54
55#ifdef __cplusplus
56extern "C" {
57#endif
58
59#define RTE_MEMPOOL_HEADER_COOKIE1 0xbadbadbadadd2e55ULL
60#define RTE_MEMPOOL_HEADER_COOKIE2 0xf2eef2eedadd2e55ULL
61#define RTE_MEMPOOL_TRAILER_COOKIE 0xadd2e55badbadbadULL
63#ifdef RTE_LIBRTE_MEMPOOL_STATS
70struct __rte_cache_aligned rte_mempool_debug_stats {
71 uint64_t put_bulk;
72 uint64_t put_objs;
73 uint64_t put_common_pool_bulk;
74 uint64_t put_common_pool_objs;
75 uint64_t get_common_pool_bulk;
76 uint64_t get_common_pool_objs;
77 uint64_t get_success_bulk;
78 uint64_t get_success_objs;
79 uint64_t get_fail_bulk;
80 uint64_t get_fail_objs;
81 uint64_t get_success_blks;
82 uint64_t get_fail_blks;
84};
85#endif
86
91 uint32_t size;
92 uint32_t flushthresh;
93 uint32_t len;
94#ifdef RTE_LIBRTE_MEMPOOL_STATS
95 uint32_t unused;
96 /*
97 * Alternative location for the most frequently updated mempool statistics (per-lcore),
98 * providing faster update access when using a mempool cache.
99 */
100 struct {
101 uint64_t put_bulk;
102 uint64_t put_objs;
103 uint64_t get_success_bulk;
104 uint64_t get_success_objs;
105 } stats;
106#endif
115 alignas(RTE_CACHE_LINE_SIZE) void *objs[RTE_MEMPOOL_CACHE_MAX_SIZE * 2];
116};
117
122 uint32_t elt_size;
123 uint32_t header_size;
124 uint32_t trailer_size;
125 uint32_t total_size;
127};
128
130#define RTE_MEMPOOL_NAMESIZE (RTE_RING_NAMESIZE - \
131 sizeof(RTE_MEMPOOL_MZ_PREFIX) + 1)
132#define RTE_MEMPOOL_MZ_PREFIX "MP_"
133
134/* "MP_<name>" */
135#define RTE_MEMPOOL_MZ_FORMAT RTE_MEMPOOL_MZ_PREFIX "%s"
136
137#ifndef RTE_MEMPOOL_ALIGN
141#define RTE_MEMPOOL_ALIGN RTE_CACHE_LINE_SIZE
142#endif
143
144#define RTE_MEMPOOL_ALIGN_MASK (RTE_MEMPOOL_ALIGN - 1)
145
157 struct rte_mempool *mp;
159#ifdef RTE_LIBRTE_MEMPOOL_DEBUG
160 uint64_t cookie;
161#endif
162};
163
167RTE_STAILQ_HEAD(rte_mempool_objhdr_list, rte_mempool_objhdr);
168
169#ifdef RTE_LIBRTE_MEMPOOL_DEBUG
170
177struct rte_mempool_objtlr {
178 uint64_t cookie;
179};
180
181#endif
182
186extern int rte_mempool_logtype;
187#define RTE_LOGTYPE_MEMPOOL rte_mempool_logtype
188#define RTE_MEMPOOL_LOG(level, ...) \
189 RTE_LOG_LINE(level, MEMPOOL, "" __VA_ARGS__)
190
194RTE_STAILQ_HEAD(rte_mempool_memhdr_list, rte_mempool_memhdr);
195
200 void *opaque);
201
210 struct rte_mempool *mp;
211 void *addr;
213 size_t len;
215 void *opaque;
216};
217
226 unsigned int contig_block_size;
227};
228
233 char name[RTE_MEMPOOL_NAMESIZE];
234 union {
235 void *pool_data;
236 uint64_t pool_id;
237 };
239 const struct rte_memzone *mz;
240 unsigned int flags;
242 uint32_t size;
243 uint32_t cache_size;
246 uint32_t elt_size;
247 uint32_t header_size;
248 uint32_t trailer_size;
258 int32_t ops_index;
259
262 uint32_t populated_size;
263 struct rte_mempool_objhdr_list elt_list;
264 uint32_t nb_mem_chunks;
265 struct rte_mempool_memhdr_list mem_list;
267#ifdef RTE_LIBRTE_MEMPOOL_STATS
272 struct rte_mempool_debug_stats stats[RTE_MAX_LCORE + 1];
273#endif
274};
275
277#define RTE_MEMPOOL_F_NO_SPREAD 0x0001
282#define MEMPOOL_F_NO_SPREAD RTE_MEMPOOL_F_NO_SPREAD
284#define RTE_MEMPOOL_F_NO_CACHE_ALIGN 0x0002
289#define MEMPOOL_F_NO_CACHE_ALIGN RTE_MEMPOOL_F_NO_CACHE_ALIGN
291#define RTE_MEMPOOL_F_SP_PUT 0x0004
296#define MEMPOOL_F_SP_PUT RTE_MEMPOOL_F_SP_PUT
298#define RTE_MEMPOOL_F_SC_GET 0x0008
303#define MEMPOOL_F_SC_GET RTE_MEMPOOL_F_SC_GET
305#define RTE_MEMPOOL_F_POOL_CREATED 0x0010
307#define RTE_MEMPOOL_F_NO_IOVA_CONTIG 0x0020
312#define MEMPOOL_F_NO_IOVA_CONTIG RTE_MEMPOOL_F_NO_IOVA_CONTIG
314#define RTE_MEMPOOL_F_NON_IO 0x0040
315
319#define RTE_MEMPOOL_VALID_USER_FLAGS (RTE_MEMPOOL_F_NO_SPREAD \
320 | RTE_MEMPOOL_F_NO_CACHE_ALIGN \
321 | RTE_MEMPOOL_F_SP_PUT \
322 | RTE_MEMPOOL_F_SC_GET \
323 | RTE_MEMPOOL_F_NO_IOVA_CONTIG \
324 )
325
336#ifdef RTE_LIBRTE_MEMPOOL_STATS
337#define RTE_MEMPOOL_STAT_ADD(mp, name, n) do { \
338 unsigned int __lcore_id = rte_lcore_id(); \
339 if (likely(__lcore_id != LCORE_ID_ANY)) \
340 (mp)->stats[__lcore_id].name += (n); \
341 else \
342 rte_atomic_fetch_add_explicit(&((mp)->stats[RTE_MAX_LCORE].name), \
343 (n), rte_memory_order_relaxed); \
344 } while (0)
345#else
346#define RTE_MEMPOOL_STAT_ADD(mp, name, n) do {} while (0)
347#endif
348
359#ifdef RTE_LIBRTE_MEMPOOL_STATS
360#define RTE_MEMPOOL_CACHE_STAT_ADD(cache, name, n) ((cache)->stats.name += (n))
361#else
362#define RTE_MEMPOOL_CACHE_STAT_ADD(cache, name, n) do {} while (0)
363#endif
364
373#define RTE_MEMPOOL_HEADER_SIZE(mp, cs) \
374 (sizeof(*(mp)) + (((cs) == 0) ? 0 : \
375 (sizeof(struct rte_mempool_cache) * RTE_MAX_LCORE)))
376
377/* return the header of a mempool object (internal) */
378static inline struct rte_mempool_objhdr *
379rte_mempool_get_header(void *obj)
380{
381 return (struct rte_mempool_objhdr *)RTE_PTR_SUB(obj,
382 sizeof(struct rte_mempool_objhdr));
383}
384
394static inline struct rte_mempool *rte_mempool_from_obj(void *obj)
395{
396 struct rte_mempool_objhdr *hdr = rte_mempool_get_header(obj);
397 return hdr->mp;
398}
399
400/* return the trailer of a mempool object (internal) */
401static inline struct rte_mempool_objtlr *rte_mempool_get_trailer(void *obj)
402{
403 struct rte_mempool *mp = rte_mempool_from_obj(obj);
404 return (struct rte_mempool_objtlr *)RTE_PTR_ADD(obj, mp->elt_size);
405}
406
421void rte_mempool_check_cookies(const struct rte_mempool *mp,
422 void * const *obj_table_const, unsigned n, int free);
423
424#ifdef RTE_LIBRTE_MEMPOOL_DEBUG
425#define RTE_MEMPOOL_CHECK_COOKIES(mp, obj_table_const, n, free) \
426 rte_mempool_check_cookies(mp, obj_table_const, n, free)
427#else
428#define RTE_MEMPOOL_CHECK_COOKIES(mp, obj_table_const, n, free) do {} while (0)
429#endif /* RTE_LIBRTE_MEMPOOL_DEBUG */
430
446void rte_mempool_contig_blocks_check_cookies(const struct rte_mempool *mp,
447 void * const *first_obj_table_const, unsigned int n, int free);
448
449#ifdef RTE_LIBRTE_MEMPOOL_DEBUG
450#define RTE_MEMPOOL_CONTIG_BLOCKS_CHECK_COOKIES(mp, first_obj_table_const, n, \
451 free) \
452 rte_mempool_contig_blocks_check_cookies(mp, first_obj_table_const, n, \
453 free)
454#else
455#define RTE_MEMPOOL_CONTIG_BLOCKS_CHECK_COOKIES(mp, first_obj_table_const, n, \
456 free) \
457 do {} while (0)
458#endif /* RTE_LIBRTE_MEMPOOL_DEBUG */
459
460#define RTE_MEMPOOL_OPS_NAMESIZE 32
472typedef int (*rte_mempool_alloc_t)(struct rte_mempool *mp);
473
477typedef void (*rte_mempool_free_t)(struct rte_mempool *mp);
478
485typedef int (*rte_mempool_enqueue_t)(struct rte_mempool *mp,
486 void * const *obj_table, unsigned int n);
487
494typedef int (*rte_mempool_dequeue_t)(struct rte_mempool *mp,
495 void **obj_table, unsigned int n);
496
501 void **first_obj_table, unsigned int n);
502
506typedef unsigned (*rte_mempool_get_count)(const struct rte_mempool *mp);
507
531typedef ssize_t (*rte_mempool_calc_mem_size_t)(const struct rte_mempool *mp,
532 uint32_t obj_num, uint32_t pg_shift,
533 size_t *min_chunk_size, size_t *align);
534
570ssize_t rte_mempool_op_calc_mem_size_helper(const struct rte_mempool *mp,
571 uint32_t obj_num, uint32_t pg_shift, size_t chunk_reserve,
572 size_t *min_chunk_size, size_t *align);
573
582 uint32_t obj_num, uint32_t pg_shift,
583 size_t *min_chunk_size, size_t *align);
584
598 void *opaque, void *vaddr, rte_iova_t iova);
599
628typedef int (*rte_mempool_populate_t)(struct rte_mempool *mp,
629 unsigned int max_objs,
630 void *vaddr, rte_iova_t iova, size_t len,
631 rte_mempool_populate_obj_cb_t *obj_cb, void *obj_cb_arg);
632
636#define RTE_MEMPOOL_POPULATE_F_ALIGN_OBJ 0x0001
637
670int rte_mempool_op_populate_helper(struct rte_mempool *mp,
671 unsigned int flags, unsigned int max_objs,
672 void *vaddr, rte_iova_t iova, size_t len,
673 rte_mempool_populate_obj_cb_t *obj_cb, void *obj_cb_arg);
674
682 unsigned int max_objs,
683 void *vaddr, rte_iova_t iova, size_t len,
684 rte_mempool_populate_obj_cb_t *obj_cb, void *obj_cb_arg);
685
689typedef int (*rte_mempool_get_info_t)(const struct rte_mempool *mp,
690 struct rte_mempool_info *info);
691
692
719};
720
721#define RTE_MEMPOOL_MAX_OPS_IDX 16
734 uint32_t num_ops;
739};
740
743
753static inline struct rte_mempool_ops *
754rte_mempool_get_ops(int ops_index)
755{
756 RTE_ASSERT((ops_index >= 0) && (ops_index < RTE_MEMPOOL_MAX_OPS_IDX));
757
758 return &rte_mempool_ops_table.ops[ops_index];
759}
760
770int
771rte_mempool_ops_alloc(struct rte_mempool *mp);
772
786static inline int
787rte_mempool_ops_dequeue_bulk(struct rte_mempool *mp,
788 void **obj_table, unsigned n)
789{
790 struct rte_mempool_ops *ops;
791 int ret;
792
793 rte_mempool_trace_ops_dequeue_bulk(mp, obj_table, n);
794 ops = rte_mempool_get_ops(mp->ops_index);
795 ret = ops->dequeue(mp, obj_table, n);
796 RTE_ASSERT(ret <= 0);
797 if (likely(ret == 0)) {
798 RTE_MEMPOOL_STAT_ADD(mp, get_common_pool_bulk, 1);
799 RTE_MEMPOOL_STAT_ADD(mp, get_common_pool_objs, n);
800 }
801 return ret;
802}
803
817static inline int
818rte_mempool_ops_dequeue_contig_blocks(struct rte_mempool *mp,
819 void **first_obj_table, unsigned int n)
820{
821 struct rte_mempool_ops *ops;
822 int ret;
823
824 ops = rte_mempool_get_ops(mp->ops_index);
825 RTE_ASSERT(ops->dequeue_contig_blocks != NULL);
826 rte_mempool_trace_ops_dequeue_contig_blocks(mp, first_obj_table, n);
827 ret = ops->dequeue_contig_blocks(mp, first_obj_table, n);
828 RTE_ASSERT(ret <= 0);
829 return ret;
830}
831
845static inline int
846rte_mempool_ops_enqueue_bulk(struct rte_mempool *mp, void * const *obj_table,
847 unsigned n)
848{
849 struct rte_mempool_ops *ops;
850 int ret;
851
852 RTE_MEMPOOL_STAT_ADD(mp, put_common_pool_bulk, 1);
853 RTE_MEMPOOL_STAT_ADD(mp, put_common_pool_objs, n);
854 rte_mempool_trace_ops_enqueue_bulk(mp, obj_table, n);
855 ops = rte_mempool_get_ops(mp->ops_index);
856 ret = ops->enqueue(mp, obj_table, n);
857 RTE_ASSERT(ret <= 0);
858#ifdef RTE_LIBRTE_MEMPOOL_DEBUG
859 if (unlikely(ret < 0))
860 RTE_MEMPOOL_LOG(CRIT, "cannot enqueue %u objects to mempool %s",
861 n, mp->name);
862#endif
863 return ret;
864}
865
874unsigned
875rte_mempool_ops_get_count(const struct rte_mempool *mp);
876
896ssize_t rte_mempool_ops_calc_mem_size(const struct rte_mempool *mp,
897 uint32_t obj_num, uint32_t pg_shift,
898 size_t *min_chunk_size, size_t *align);
899
923int rte_mempool_ops_populate(struct rte_mempool *mp, unsigned int max_objs,
924 void *vaddr, rte_iova_t iova, size_t len,
926 void *obj_cb_arg);
927
941 struct rte_mempool_info *info);
942
949void
950rte_mempool_ops_free(struct rte_mempool *mp);
951
969int
971 void *pool_config);
972
984
990#define RTE_MEMPOOL_REGISTER_OPS(ops) \
991 RTE_INIT(mp_hdlr_init_##ops) \
992 { \
993 rte_mempool_register_ops(&ops); \
994 }
995
1001typedef void (rte_mempool_obj_cb_t)(struct rte_mempool *mp,
1002 void *opaque, void *obj, unsigned obj_idx);
1003typedef rte_mempool_obj_cb_t rte_mempool_obj_ctor_t; /* compat */
1004
1010typedef void (rte_mempool_mem_cb_t)(struct rte_mempool *mp,
1011 void *opaque, struct rte_mempool_memhdr *memhdr,
1012 unsigned mem_idx);
1013
1020typedef void (rte_mempool_ctor_t)(struct rte_mempool *, void *);
1021
1033void
1035
1115struct rte_mempool *
1116rte_mempool_create(const char *name, unsigned n, unsigned elt_size,
1117 unsigned cache_size, unsigned private_data_size,
1118 rte_mempool_ctor_t *mp_init, void *mp_init_arg,
1119 rte_mempool_obj_cb_t *obj_init, void *obj_init_arg,
1120 int socket_id, unsigned int flags)
1122
1155struct rte_mempool *
1156rte_mempool_create_empty(const char *name, unsigned int n, unsigned int elt_size,
1157 unsigned int cache_size, unsigned int private_data_size,
1158 int socket_id, unsigned int flags)
1160
1191int rte_mempool_populate_iova(struct rte_mempool *mp, char *vaddr,
1192 rte_iova_t iova, size_t len, rte_mempool_memchunk_free_cb_t *free_cb,
1193 void *opaque);
1194
1221int
1223 size_t len, size_t pg_sz, rte_mempool_memchunk_free_cb_t *free_cb,
1224 void *opaque);
1225
1240
1255
1272 rte_mempool_obj_cb_t *obj_cb, void *obj_cb_arg);
1273
1290 rte_mempool_mem_cb_t *mem_cb, void *mem_cb_arg);
1291
1318__rte_experimental
1320
1329void rte_mempool_dump(FILE *f, struct rte_mempool *mp);
1330
1345struct rte_mempool_cache *
1346rte_mempool_cache_create(uint32_t size, int socket_id);
1347
1354void
1356
1369rte_mempool_default_cache(struct rte_mempool *mp, unsigned lcore_id)
1370{
1371 if (unlikely(mp->cache_size == 0))
1372 return NULL;
1373
1374 if (unlikely(lcore_id == LCORE_ID_ANY))
1375 return NULL;
1376
1377 rte_mempool_trace_default_cache(mp, lcore_id,
1378 &mp->local_cache[lcore_id]);
1379 return &mp->local_cache[lcore_id];
1380}
1381
1390static __rte_always_inline void
1392 struct rte_mempool *mp)
1393{
1394 if (cache == NULL)
1396 if (cache == NULL || cache->len == 0)
1397 return;
1398 rte_mempool_trace_cache_flush(cache, mp);
1399 rte_mempool_ops_enqueue_bulk(mp, cache->objs, cache->len);
1400 cache->len = 0;
1401}
1402
1415static __rte_always_inline void
1416rte_mempool_do_generic_put(struct rte_mempool *mp, void * const *obj_table,
1417 unsigned int n, struct rte_mempool_cache *cache)
1418{
1419 void **cache_objs;
1420
1421 /* No cache provided? */
1422 if (unlikely(cache == NULL))
1423 goto driver_enqueue;
1424
1425 /* Increment stats now, adding in mempool always succeeds. */
1426 RTE_MEMPOOL_CACHE_STAT_ADD(cache, put_bulk, 1);
1427 RTE_MEMPOOL_CACHE_STAT_ADD(cache, put_objs, n);
1428
1429 __rte_assume(cache->size <= RTE_MEMPOOL_CACHE_MAX_SIZE);
1430 __rte_assume(cache->size / 2 <= RTE_MEMPOOL_CACHE_MAX_SIZE / 2);
1431 __rte_assume(cache->len <= RTE_MEMPOOL_CACHE_MAX_SIZE);
1432 __rte_assume(cache->len <= cache->size);
1433 if (likely(cache->len + n <= cache->size)) {
1434 /* Sufficient room in the cache for the objects. */
1435 cache_objs = &cache->objs[cache->len];
1436 cache->len += n;
1437 } else if (n <= cache->size / 2) {
1438 /*
1439 * The number of objects is within the cache bounce buffer limit,
1440 * but - as detected by the comparison above - the cache has
1441 * insufficient room for them.
1442 * Flush the cache to the backend to make room for the objects;
1443 * flush (size / 2) objects from the bottom of the cache, where
1444 * objects are less hot, and move down the remaining objects, which
1445 * are more hot, from the upper half of the cache.
1446 */
1447 __rte_assume(cache->len > cache->size / 2);
1448 rte_mempool_ops_enqueue_bulk(mp, &cache->objs[0], cache->size / 2);
1449 rte_memcpy(&cache->objs[0], &cache->objs[cache->size / 2],
1450 sizeof(void *) * (cache->len - cache->size / 2));
1451 cache_objs = &cache->objs[cache->len - cache->size / 2];
1452 cache->len = cache->len - cache->size / 2 + n;
1453 } else {
1454 /* The request itself is too big for the cache. */
1455 goto driver_enqueue_stats_incremented;
1456 }
1457
1458 /* Add the objects to the cache. */
1459 rte_memcpy(cache_objs, obj_table, sizeof(void *) * n);
1460
1461 return;
1462
1463driver_enqueue:
1464
1465 /* increment stat now, adding in mempool always success */
1466 RTE_MEMPOOL_STAT_ADD(mp, put_bulk, 1);
1467 RTE_MEMPOOL_STAT_ADD(mp, put_objs, n);
1468
1469driver_enqueue_stats_incremented:
1470
1471 /* push objects to the backend */
1472 rte_mempool_ops_enqueue_bulk(mp, obj_table, n);
1473}
1474
1475
1488static __rte_always_inline void
1489rte_mempool_generic_put(struct rte_mempool *mp, void * const *obj_table,
1490 unsigned int n, struct rte_mempool_cache *cache)
1491{
1492 rte_mempool_trace_generic_put(mp, obj_table, n, cache);
1493 RTE_MEMPOOL_CHECK_COOKIES(mp, obj_table, n, 0);
1494 rte_mempool_do_generic_put(mp, obj_table, n, cache);
1495}
1496
1511static __rte_always_inline void
1512rte_mempool_put_bulk(struct rte_mempool *mp, void * const *obj_table,
1513 unsigned int n)
1514{
1515 struct rte_mempool_cache *cache;
1517 rte_mempool_trace_put_bulk(mp, obj_table, n, cache);
1518 rte_mempool_generic_put(mp, obj_table, n, cache);
1519}
1520
1533static __rte_always_inline void
1534rte_mempool_put(struct rte_mempool *mp, void *obj)
1535{
1536 rte_mempool_put_bulk(mp, &obj, 1);
1537}
1538
1553static __rte_always_inline int
1554rte_mempool_do_generic_get(struct rte_mempool *mp, void **obj_table,
1555 unsigned int n, struct rte_mempool_cache *cache)
1556{
1557 int ret;
1558 unsigned int remaining;
1559 uint32_t index, len;
1560 void **cache_objs;
1561
1562 /* No cache provided? */
1563 if (unlikely(cache == NULL)) {
1564 remaining = n;
1565 goto driver_dequeue;
1566 }
1567
1568 /* The cache is a stack, so copy will be in reverse order. */
1569 cache_objs = &cache->objs[cache->len];
1570
1571 __rte_assume(cache->len <= RTE_MEMPOOL_CACHE_MAX_SIZE);
1572 if (likely(n <= cache->len)) {
1573 /* The entire request can be satisfied from the cache. */
1574 RTE_MEMPOOL_CACHE_STAT_ADD(cache, get_success_bulk, 1);
1575 RTE_MEMPOOL_CACHE_STAT_ADD(cache, get_success_objs, n);
1576
1577 /*
1578 * If the request size is known at build time,
1579 * the compiler unrolls the fixed length copy loop.
1580 */
1581 cache->len -= n;
1582 for (index = 0; index < n; index++)
1583 *obj_table++ = *--cache_objs;
1584
1585 return 0;
1586 }
1587
1588 /* Use the cache as much as we have to return hot objects first. */
1589 len = cache->len;
1590 remaining = n - len;
1591 cache->len = 0;
1592 for (index = 0; index < len; index++)
1593 *obj_table++ = *--cache_objs;
1594
1595 /* Dequeue below would exceed the cache bounce buffer limit? */
1596 __rte_assume(cache->size / 2 <= RTE_MEMPOOL_CACHE_MAX_SIZE / 2);
1597 if (unlikely(remaining > cache->size / 2))
1598 goto driver_dequeue;
1599
1600 /* Fill the cache from the backend; fetch (size / 2) objects. */
1601 ret = rte_mempool_ops_dequeue_bulk(mp, cache->objs, cache->size / 2);
1602 if (unlikely(ret < 0)) {
1603 /*
1604 * We are buffer constrained, and not able to fetch all that.
1605 * Do not fill the cache, just satisfy the remaining part of
1606 * the request directly from the backend.
1607 */
1608 goto driver_dequeue;
1609 }
1610
1611 /* Satisfy the remaining part of the request from the filled cache. */
1612 RTE_MEMPOOL_CACHE_STAT_ADD(cache, get_success_bulk, 1);
1613 RTE_MEMPOOL_CACHE_STAT_ADD(cache, get_success_objs, n);
1614
1615 __rte_assume(cache->size / 2 <= RTE_MEMPOOL_CACHE_MAX_SIZE / 2);
1616 __rte_assume(remaining <= RTE_MEMPOOL_CACHE_MAX_SIZE / 2);
1617 __rte_assume(remaining <= cache->size / 2);
1618 cache_objs = &cache->objs[cache->size / 2];
1619 cache->len = cache->size / 2 - remaining;
1620 for (index = 0; index < remaining; index++)
1621 *obj_table++ = *--cache_objs;
1622
1623 return 0;
1624
1625driver_dequeue:
1626
1627 /* Get remaining objects directly from the backend. */
1628 ret = rte_mempool_ops_dequeue_bulk(mp, obj_table, remaining);
1629
1630 if (unlikely(ret < 0)) {
1631 if (likely(cache != NULL)) {
1632 cache->len = n - remaining;
1633 /*
1634 * No further action is required to roll the first part
1635 * of the request back into the cache, as objects in
1636 * the cache are intact.
1637 */
1638 }
1639
1640 RTE_MEMPOOL_STAT_ADD(mp, get_fail_bulk, 1);
1641 RTE_MEMPOOL_STAT_ADD(mp, get_fail_objs, n);
1642 } else {
1643 if (likely(cache != NULL)) {
1644 RTE_MEMPOOL_CACHE_STAT_ADD(cache, get_success_bulk, 1);
1645 RTE_MEMPOOL_CACHE_STAT_ADD(cache, get_success_objs, n);
1646 } else {
1647 RTE_MEMPOOL_STAT_ADD(mp, get_success_bulk, 1);
1648 RTE_MEMPOOL_STAT_ADD(mp, get_success_objs, n);
1649 }
1650 __rte_assume(ret == 0);
1651 }
1652
1653 return ret;
1654}
1655
1676static __rte_always_inline int
1677rte_mempool_generic_get(struct rte_mempool *mp, void **obj_table,
1678 unsigned int n, struct rte_mempool_cache *cache)
1679{
1680 int ret;
1681 ret = rte_mempool_do_generic_get(mp, obj_table, n, cache);
1682 if (likely(ret == 0))
1683 RTE_MEMPOOL_CHECK_COOKIES(mp, obj_table, n, 1);
1684 rte_mempool_trace_generic_get(mp, obj_table, n, cache);
1685 return ret;
1686}
1687
1710static __rte_always_inline int
1711rte_mempool_get_bulk(struct rte_mempool *mp, void **obj_table, unsigned int n)
1712{
1713 struct rte_mempool_cache *cache;
1715 rte_mempool_trace_get_bulk(mp, obj_table, n, cache);
1716 return rte_mempool_generic_get(mp, obj_table, n, cache);
1717}
1718
1739static __rte_always_inline int
1740rte_mempool_get(struct rte_mempool *mp, void **obj_p)
1741{
1742 return rte_mempool_get_bulk(mp, obj_p, 1);
1743}
1744
1766static __rte_always_inline int
1768 void **first_obj_table, unsigned int n)
1769{
1770 int ret;
1771
1772 ret = rte_mempool_ops_dequeue_contig_blocks(mp, first_obj_table, n);
1773 if (likely(ret == 0)) {
1774 RTE_MEMPOOL_STAT_ADD(mp, get_success_bulk, 1);
1775 RTE_MEMPOOL_STAT_ADD(mp, get_success_blks, n);
1776 RTE_MEMPOOL_CONTIG_BLOCKS_CHECK_COOKIES(mp, first_obj_table, n,
1777 1);
1778 } else {
1779 RTE_MEMPOOL_STAT_ADD(mp, get_fail_bulk, 1);
1780 RTE_MEMPOOL_STAT_ADD(mp, get_fail_blks, n);
1781 }
1782
1783 rte_mempool_trace_get_contig_blocks(mp, first_obj_table, n);
1784 return ret;
1785}
1786
1799unsigned int rte_mempool_avail_count(const struct rte_mempool *mp);
1800
1813unsigned int
1815
1829static inline int
1831{
1832 return rte_mempool_avail_count(mp) == mp->size;
1833}
1834
1848static inline int
1850{
1851 return rte_mempool_avail_count(mp) == 0;
1852}
1853
1864static inline rte_iova_t
1866{
1867 const struct rte_mempool_objhdr *hdr;
1868 hdr = (const struct rte_mempool_objhdr *)RTE_PTR_SUB(elt,
1869 sizeof(*hdr));
1870 return hdr->iova;
1871}
1872
1884
1893static inline void *rte_mempool_get_priv(struct rte_mempool *mp)
1894{
1895 return (char *)mp +
1896 RTE_MEMPOOL_HEADER_SIZE(mp, mp->cache_size);
1897}
1898
1906
1919
1936uint32_t rte_mempool_calc_obj_size(uint32_t elt_size, uint32_t flags,
1937 struct rte_mempool_objsz *sz);
1938
1947void rte_mempool_walk(void (*func)(struct rte_mempool *, void *arg),
1948 void *arg);
1949
1956 void *start;
1958 size_t length;
1961};
1962
1978__rte_experimental
1979int
1981 struct rte_mempool_mem_range_info *mem_range);
1982
1994__rte_experimental
1995size_t
1997
2002int
2003rte_mempool_get_page_size(struct rte_mempool *mp, size_t *pg_sz);
2004
2014};
2015
2025typedef void (rte_mempool_event_callback)(
2026 enum rte_mempool_event event,
2027 struct rte_mempool *mp,
2028 void *user_data);
2029
2046__rte_internal
2047int
2048rte_mempool_event_callback_register(rte_mempool_event_callback *func,
2049 void *user_data);
2050
2064__rte_internal
2065int
2066rte_mempool_event_callback_unregister(rte_mempool_event_callback *func,
2067 void *user_data);
2068
2069#ifdef __cplusplus
2070}
2071#endif
2072
2073#endif /* _RTE_MEMPOOL_H_ */
#define likely(x)
#define unlikely(x)
#define __rte_assume(condition)
Definition: rte_common.h:533
#define __rte_dealloc(dealloc, argno)
Definition: rte_common.h:339
#define RTE_PTR_SUB(ptr, x)
Definition: rte_common.h:559
uint64_t rte_iova_t
Definition: rte_common.h:774
#define RTE_PTR_ADD(ptr, x)
Definition: rte_common.h:554
#define RTE_CACHE_GUARD
Definition: rte_common.h:759
#define __rte_cache_aligned
Definition: rte_common.h:739
#define __rte_malloc
Definition: rte_common.h:328
#define __rte_always_inline
Definition: rte_common.h:490
#define LCORE_ID_ANY
Definition: rte_lcore.h:26
static unsigned rte_lcore_id(void)
Definition: rte_lcore.h:78
static void * rte_memcpy(void *dst, const void *src, size_t n)
void() rte_mempool_memchunk_free_cb_t(struct rte_mempool_memhdr *memhdr, void *opaque)
Definition: rte_mempool.h:199
int rte_mempool_set_ops_byname(struct rte_mempool *mp, const char *name, void *pool_config)
struct rte_mempool * rte_mempool_create(const char *name, unsigned n, unsigned elt_size, unsigned cache_size, unsigned private_data_size, rte_mempool_ctor_t *mp_init, void *mp_init_arg, rte_mempool_obj_cb_t *obj_init, void *obj_init_arg, int socket_id, unsigned int flags) __rte_malloc __rte_dealloc(rte_mempool_free
static __rte_always_inline int rte_mempool_get_bulk(struct rte_mempool *mp, void **obj_table, unsigned int n)
Definition: rte_mempool.h:1711
int rte_mempool_op_populate_default(struct rte_mempool *mp, unsigned int max_objs, void *vaddr, rte_iova_t iova, size_t len, rte_mempool_populate_obj_cb_t *obj_cb, void *obj_cb_arg)
static __rte_always_inline struct rte_mempool_cache * rte_mempool_default_cache(struct rte_mempool *mp, unsigned lcore_id)
Definition: rte_mempool.h:1369
uint32_t rte_mempool_calc_obj_size(uint32_t elt_size, uint32_t flags, struct rte_mempool_objsz *sz)
void() rte_mempool_obj_cb_t(struct rte_mempool *mp, void *opaque, void *obj, unsigned obj_idx)
Definition: rte_mempool.h:1001
struct rte_mempool * rte_mempool_lookup(const char *name)
int(* rte_mempool_enqueue_t)(struct rte_mempool *mp, void *const *obj_table, unsigned int n)
Definition: rte_mempool.h:485
static struct rte_mempool * rte_mempool_from_obj(void *obj)
Definition: rte_mempool.h:394
static rte_iova_t rte_mempool_virt2iova(const void *elt)
Definition: rte_mempool.h:1865
int(* rte_mempool_dequeue_t)(struct rte_mempool *mp, void **obj_table, unsigned int n)
Definition: rte_mempool.h:494
void rte_mempool_free(struct rte_mempool *mp)
rte_mempool_event
Definition: rte_mempool.h:2009
@ RTE_MEMPOOL_EVENT_DESTROY
Definition: rte_mempool.h:2013
@ RTE_MEMPOOL_EVENT_READY
Definition: rte_mempool.h:2011
unsigned(* rte_mempool_get_count)(const struct rte_mempool *mp)
Definition: rte_mempool.h:506
void() rte_mempool_populate_obj_cb_t(struct rte_mempool *mp, void *opaque, void *vaddr, rte_iova_t iova)
Definition: rte_mempool.h:597
int rte_mempool_populate_default(struct rte_mempool *mp)
unsigned int rte_mempool_avail_count(const struct rte_mempool *mp)
static __rte_always_inline int rte_mempool_get_contig_blocks(struct rte_mempool *mp, void **first_obj_table, unsigned int n)
Definition: rte_mempool.h:1767
int(* rte_mempool_dequeue_contig_blocks_t)(struct rte_mempool *mp, void **first_obj_table, unsigned int n)
Definition: rte_mempool.h:500
void(* rte_mempool_free_t)(struct rte_mempool *mp)
Definition: rte_mempool.h:477
static __rte_always_inline void rte_mempool_cache_flush(struct rte_mempool_cache *cache, struct rte_mempool *mp)
Definition: rte_mempool.h:1391
static __rte_always_inline void rte_mempool_put_bulk(struct rte_mempool *mp, void *const *obj_table, unsigned int n)
Definition: rte_mempool.h:1512
static __rte_always_inline int rte_mempool_get(struct rte_mempool *mp, void **obj_p)
Definition: rte_mempool.h:1740
int rte_mempool_register_ops(const struct rte_mempool_ops *ops)
int rte_mempool_populate_virt(struct rte_mempool *mp, char *addr, size_t len, size_t pg_sz, rte_mempool_memchunk_free_cb_t *free_cb, void *opaque)
ssize_t rte_mempool_op_calc_mem_size_default(const struct rte_mempool *mp, uint32_t obj_num, uint32_t pg_shift, size_t *min_chunk_size, size_t *align)
int rte_mempool_populate_anon(struct rte_mempool *mp)
__rte_experimental size_t rte_mempool_get_obj_alignment(const struct rte_mempool *mp)
void rte_mempool_cache_free(struct rte_mempool_cache *cache)
static __rte_always_inline void rte_mempool_generic_put(struct rte_mempool *mp, void *const *obj_table, unsigned int n, struct rte_mempool_cache *cache)
Definition: rte_mempool.h:1489
static int rte_mempool_full(const struct rte_mempool *mp)
Definition: rte_mempool.h:1830
int(* rte_mempool_alloc_t)(struct rte_mempool *mp)
Definition: rte_mempool.h:472
void rte_mempool_dump(FILE *f, struct rte_mempool *mp)
static __rte_always_inline int rte_mempool_generic_get(struct rte_mempool *mp, void **obj_table, unsigned int n, struct rte_mempool_cache *cache)
Definition: rte_mempool.h:1677
struct rte_mempool_cache * rte_mempool_cache_create(uint32_t size, int socket_id)
void rte_mempool_audit(struct rte_mempool *mp)
void rte_mempool_walk(void(*func)(struct rte_mempool *, void *arg), void *arg)
#define RTE_MEMPOOL_OPS_NAMESIZE
Definition: rte_mempool.h:460
void() rte_mempool_ctor_t(struct rte_mempool *, void *)
Definition: rte_mempool.h:1020
void() rte_mempool_mem_cb_t(struct rte_mempool *mp, void *opaque, struct rte_mempool_memhdr *memhdr, unsigned mem_idx)
Definition: rte_mempool.h:1010
struct rte_mempool struct rte_mempool * rte_mempool_create_empty(const char *name, unsigned int n, unsigned int elt_size, unsigned int cache_size, unsigned int private_data_size, int socket_id, unsigned int flags) __rte_malloc __rte_dealloc(rte_mempool_free
ssize_t(* rte_mempool_calc_mem_size_t)(const struct rte_mempool *mp, uint32_t obj_num, uint32_t pg_shift, size_t *min_chunk_size, size_t *align)
Definition: rte_mempool.h:531
static __rte_always_inline void rte_mempool_put(struct rte_mempool *mp, void *obj)
Definition: rte_mempool.h:1534
int rte_mempool_ops_get_info(const struct rte_mempool *mp, struct rte_mempool_info *info)
unsigned int rte_mempool_in_use_count(const struct rte_mempool *mp)
uint32_t rte_mempool_obj_iter(struct rte_mempool *mp, rte_mempool_obj_cb_t *obj_cb, void *obj_cb_arg)
void rte_mempool_list_dump(FILE *f)
__rte_experimental int rte_mempool_get_mem_range(const struct rte_mempool *mp, struct rte_mempool_mem_range_info *mem_range)
#define RTE_MEMPOOL_MAX_OPS_IDX
Definition: rte_mempool.h:721
static int rte_mempool_empty(const struct rte_mempool *mp)
Definition: rte_mempool.h:1849
uint32_t rte_mempool_mem_iter(struct rte_mempool *mp, rte_mempool_mem_cb_t *mem_cb, void *mem_cb_arg)
__rte_experimental void rte_mempool_stats_reset(struct rte_mempool *mp)
int(* rte_mempool_populate_t)(struct rte_mempool *mp, unsigned int max_objs, void *vaddr, rte_iova_t iova, size_t len, rte_mempool_populate_obj_cb_t *obj_cb, void *obj_cb_arg)
Definition: rte_mempool.h:628
struct rte_mempool struct rte_mempool int rte_mempool_populate_iova(struct rte_mempool *mp, char *vaddr, rte_iova_t iova, size_t len, rte_mempool_memchunk_free_cb_t *free_cb, void *opaque)
static void * rte_mempool_get_priv(struct rte_mempool *mp)
Definition: rte_mempool.h:1893
RTE_STAILQ_HEAD(rte_mempool_objhdr_list, rte_mempool_objhdr)
int(* rte_mempool_get_info_t)(const struct rte_mempool *mp, struct rte_mempool_info *info)
Definition: rte_mempool.h:689
uint32_t flushthresh
Definition: rte_mempool.h:92
void * objs[RTE_MEMPOOL_CACHE_MAX_SIZE *2]
Definition: rte_mempool.h:115
unsigned int contig_block_size
Definition: rte_mempool.h:226
RTE_STAILQ_ENTRY(rte_mempool_memhdr) next
struct rte_mempool * mp
Definition: rte_mempool.h:210
rte_mempool_memchunk_free_cb_t * free_cb
Definition: rte_mempool.h:214
struct rte_mempool * mp
Definition: rte_mempool.h:157
RTE_STAILQ_ENTRY(rte_mempool_objhdr) next
uint32_t header_size
Definition: rte_mempool.h:123
uint32_t trailer_size
Definition: rte_mempool.h:124
uint32_t total_size
Definition: rte_mempool.h:125
struct rte_mempool_ops ops[RTE_MEMPOOL_MAX_OPS_IDX]
Definition: rte_mempool.h:738
rte_spinlock_t sl
Definition: rte_mempool.h:733
char name[RTE_MEMPOOL_OPS_NAMESIZE]
Definition: rte_mempool.h:695
rte_mempool_alloc_t alloc
Definition: rte_mempool.h:696
rte_mempool_dequeue_t dequeue
Definition: rte_mempool.h:699
rte_mempool_get_info_t get_info
Definition: rte_mempool.h:714
rte_mempool_calc_mem_size_t calc_mem_size
Definition: rte_mempool.h:705
rte_mempool_get_count get_count
Definition: rte_mempool.h:700
rte_mempool_populate_t populate
Definition: rte_mempool.h:710
rte_mempool_dequeue_contig_blocks_t dequeue_contig_blocks
Definition: rte_mempool.h:718
rte_mempool_free_t free
Definition: rte_mempool.h:697
rte_mempool_enqueue_t enqueue
Definition: rte_mempool.h:698
uint32_t nb_mem_chunks
Definition: rte_mempool.h:264
const struct rte_memzone * mz
Definition: rte_mempool.h:239
uint32_t populated_size
Definition: rte_mempool.h:262
uint32_t header_size
Definition: rte_mempool.h:247
uint64_t pool_id
Definition: rte_mempool.h:236
int32_t ops_index
Definition: rte_mempool.h:258
void * pool_config
Definition: rte_mempool.h:238
uint32_t trailer_size
Definition: rte_mempool.h:248
char name[RTE_MEMPOOL_NAMESIZE]
Definition: rte_mempool.h:233
uint32_t size
Definition: rte_mempool.h:242
uint32_t cache_size
Definition: rte_mempool.h:243
unsigned int flags
Definition: rte_mempool.h:240
uint32_t elt_size
Definition: rte_mempool.h:246
unsigned private_data_size
Definition: rte_mempool.h:250
struct rte_mempool_cache * local_cache
Definition: rte_mempool.h:260
void * pool_data
Definition: rte_mempool.h:235