From d86046f0cf50fb3fdd48ba9f6730c7c9fc2ad831 Mon Sep 17 00:00:00 2001 From: Olivier Matz Date: Wed, 18 May 2016 13:04:30 +0200 Subject: [PATCH] mempool: use the list to iterate the elements Now that the mempool objects are chained into a list, we can use it to browse them. This implies a rework of rte_mempool_obj_iter() API, that does not need to take as many arguments as before. The previous function is kept as a private function, and renamed in this commit. It will be removed in a next commit of the patch series. The only internal users of this function are the mellanox drivers. The code is updated accordingly. Introducing an API compatibility for this function has been considered, but it is not easy to do without keeping the old code, as the previous function could also be used to browse elements that were not added in a mempool. Moreover, the API is already be broken by other patches in this version. The library version was already updated in commit 213af31e0960 ("mempool: reduce structure size if no cache needed") Signed-off-by: Olivier Matz --- drivers/net/mlx4/mlx4.c | 51 +++++----------- drivers/net/mlx5/mlx5_rxtx.c | 51 +++++----------- lib/librte_mempool/rte_mempool.c | 37 +++++++++-- lib/librte_mempool/rte_mempool.h | 71 ++++++---------------- lib/librte_mempool/rte_mempool_version.map | 2 +- 5 files changed, 83 insertions(+), 129 deletions(-) diff --git a/drivers/net/mlx4/mlx4.c b/drivers/net/mlx4/mlx4.c index 2dcb5b48b3..ce518cf21b 100644 --- a/drivers/net/mlx4/mlx4.c +++ b/drivers/net/mlx4/mlx4.c @@ -1320,7 +1320,6 @@ txq_mp2mr(struct txq *txq, const struct rte_mempool *mp) } struct txq_mp2mr_mbuf_check_data { - const struct rte_mempool *mp; int ret; }; @@ -1328,34 +1327,26 @@ struct txq_mp2mr_mbuf_check_data { * Callback function for rte_mempool_obj_iter() to check whether a given * mempool object looks like a mbuf. * - * @param[in, out] arg - * Context data (struct txq_mp2mr_mbuf_check_data). Contains mempool pointer - * and return value. - * @param[in] start - * Object start address. - * @param[in] end - * Object end address. + * @param[in] mp + * The mempool pointer + * @param[in] arg + * Context data (struct txq_mp2mr_mbuf_check_data). Contains the + * return value. + * @param[in] obj + * Object address. * @param index - * Unused. - * - * @return - * Nonzero value when object is not a mbuf. + * Object index, unused. */ static void -txq_mp2mr_mbuf_check(void *arg, void *start, void *end, - uint32_t index __rte_unused) +txq_mp2mr_mbuf_check(struct rte_mempool *mp, void *arg, void *obj, + uint32_t index __rte_unused) { struct txq_mp2mr_mbuf_check_data *data = arg; - struct rte_mbuf *buf = - (void *)((uintptr_t)start + data->mp->header_size); + struct rte_mbuf *buf = obj; - (void)index; /* Check whether mbuf structure fits element size and whether mempool * pointer is valid. */ - if (((uintptr_t)end >= (uintptr_t)(buf + 1)) && - (buf->pool == data->mp)) - data->ret = 0; - else + if (sizeof(*buf) > mp->elt_size || buf->pool != mp) data->ret = -1; } @@ -1373,24 +1364,12 @@ txq_mp2mr_iter(struct rte_mempool *mp, void *arg) { struct txq *txq = arg; struct txq_mp2mr_mbuf_check_data data = { - .mp = mp, - .ret = -1, + .ret = 0, }; - /* Discard empty mempools. */ - if (mp->size == 0) - return; /* Register mempool only if the first element looks like a mbuf. */ - rte_mempool_obj_iter((void *)mp->elt_va_start, - 1, - mp->header_size + mp->elt_size + mp->trailer_size, - 1, - mp->elt_pa, - mp->pg_num, - mp->pg_shift, - txq_mp2mr_mbuf_check, - &data); - if (data.ret) + if (rte_mempool_obj_iter(mp, txq_mp2mr_mbuf_check, &data) == 0 || + data.ret == -1) return; txq_mp2mr(txq, mp); } diff --git a/drivers/net/mlx5/mlx5_rxtx.c b/drivers/net/mlx5/mlx5_rxtx.c index 73a9a1c62b..f2fe98b7cc 100644 --- a/drivers/net/mlx5/mlx5_rxtx.c +++ b/drivers/net/mlx5/mlx5_rxtx.c @@ -262,7 +262,6 @@ txq_mp2mr(struct txq *txq, const struct rte_mempool *mp) } struct txq_mp2mr_mbuf_check_data { - const struct rte_mempool *mp; int ret; }; @@ -270,34 +269,26 @@ struct txq_mp2mr_mbuf_check_data { * Callback function for rte_mempool_obj_iter() to check whether a given * mempool object looks like a mbuf. * - * @param[in, out] arg - * Context data (struct txq_mp2mr_mbuf_check_data). Contains mempool pointer - * and return value. - * @param[in] start - * Object start address. - * @param[in] end - * Object end address. + * @param[in] mp + * The mempool pointer + * @param[in] arg + * Context data (struct txq_mp2mr_mbuf_check_data). Contains the + * return value. + * @param[in] obj + * Object address. * @param index - * Unused. - * - * @return - * Nonzero value when object is not a mbuf. + * Object index, unused. */ static void -txq_mp2mr_mbuf_check(void *arg, void *start, void *end, - uint32_t index __rte_unused) +txq_mp2mr_mbuf_check(struct rte_mempool *mp, void *arg, void *obj, + uint32_t index __rte_unused) { struct txq_mp2mr_mbuf_check_data *data = arg; - struct rte_mbuf *buf = - (void *)((uintptr_t)start + data->mp->header_size); + struct rte_mbuf *buf = obj; - (void)index; /* Check whether mbuf structure fits element size and whether mempool * pointer is valid. */ - if (((uintptr_t)end >= (uintptr_t)(buf + 1)) && - (buf->pool == data->mp)) - data->ret = 0; - else + if (sizeof(*buf) > mp->elt_size || buf->pool != mp) data->ret = -1; } @@ -315,24 +306,12 @@ txq_mp2mr_iter(struct rte_mempool *mp, void *arg) { struct txq *txq = arg; struct txq_mp2mr_mbuf_check_data data = { - .mp = mp, - .ret = -1, + .ret = 0, }; - /* Discard empty mempools. */ - if (mp->size == 0) - return; /* Register mempool only if the first element looks like a mbuf. */ - rte_mempool_obj_iter((void *)mp->elt_va_start, - 1, - mp->header_size + mp->elt_size + mp->trailer_size, - 1, - mp->elt_pa, - mp->pg_num, - mp->pg_shift, - txq_mp2mr_mbuf_check, - &data); - if (data.ret) + if (rte_mempool_obj_iter(mp, txq_mp2mr_mbuf_check, &data) == 0 || + data.ret == -1) return; txq_mp2mr(txq, mp); } diff --git a/lib/librte_mempool/rte_mempool.c b/lib/librte_mempool/rte_mempool.c index ad1895d2af..256ec04133 100644 --- a/lib/librte_mempool/rte_mempool.c +++ b/lib/librte_mempool/rte_mempool.c @@ -2,6 +2,7 @@ * BSD LICENSE * * Copyright(c) 2010-2014 Intel Corporation. All rights reserved. + * Copyright(c) 2016 6WIND S.A. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -126,6 +127,14 @@ static unsigned optimize_object_size(unsigned obj_size) return new_obj_size * RTE_MEMPOOL_ALIGN; } +/** + * A mempool object iterator callback function. + */ +typedef void (*rte_mempool_obj_iter_t)(void * /*obj_iter_arg*/, + void * /*obj_start*/, + void * /*obj_end*/, + uint32_t /*obj_index */); + static void mempool_add_elem(struct rte_mempool *mp, void *obj, uint32_t obj_idx, rte_mempool_obj_cb_t *obj_init, void *obj_init_arg) @@ -161,8 +170,8 @@ mempool_add_elem(struct rte_mempool *mp, void *obj, uint32_t obj_idx, * chunk, invoke a callback. It returns the effective number of objects * in this memory. */ -uint32_t -rte_mempool_obj_iter(void *vaddr, uint32_t elt_num, size_t total_elt_sz, +static uint32_t +rte_mempool_obj_mem_iter(void *vaddr, uint32_t elt_num, size_t total_elt_sz, size_t align, const phys_addr_t paddr[], uint32_t pg_num, uint32_t pg_shift, rte_mempool_obj_iter_t obj_iter, void *obj_iter_arg) { @@ -220,6 +229,24 @@ rte_mempool_obj_iter(void *vaddr, uint32_t elt_num, size_t total_elt_sz, return i; } +/* call obj_cb() for each mempool element */ +uint32_t +rte_mempool_obj_iter(struct rte_mempool *mp, + rte_mempool_obj_cb_t *obj_cb, void *obj_cb_arg) +{ + struct rte_mempool_objhdr *hdr; + void *obj; + unsigned n = 0; + + STAILQ_FOREACH(hdr, &mp->elt_list, next) { + obj = (char *)hdr + sizeof(*hdr); + obj_cb(mp, obj_cb_arg, obj, n); + n++; + } + + return n; +} + /* * Populate mempool with the objects. */ @@ -251,7 +278,7 @@ mempool_populate(struct rte_mempool *mp, size_t num, size_t align, arg.obj_init = obj_init; arg.obj_init_arg = obj_init_arg; - mp->size = rte_mempool_obj_iter((void *)mp->elt_va_start, + mp->size = rte_mempool_obj_mem_iter((void *)mp->elt_va_start, num, elt_sz, align, mp->elt_pa, mp->pg_num, mp->pg_shift, mempool_obj_populate, &arg); @@ -366,7 +393,7 @@ rte_mempool_xmem_usage(void *vaddr, uint32_t elt_num, size_t total_elt_sz, va = (uintptr_t)vaddr; uv = va; - if ((n = rte_mempool_obj_iter(vaddr, elt_num, total_elt_sz, 1, + if ((n = rte_mempool_obj_mem_iter(vaddr, elt_num, total_elt_sz, 1, paddr, pg_num, pg_shift, mempool_lelem_iter, &uv)) != elt_num) { return -(ssize_t)n; @@ -798,7 +825,7 @@ mempool_audit_cookies(struct rte_mempool *mp) arg.obj_end = mp->elt_va_start; arg.obj_num = 0; - num = rte_mempool_obj_iter((void *)mp->elt_va_start, + num = rte_mempool_obj_mem_iter((void *)mp->elt_va_start, mp->size, elt_sz, 1, mp->elt_pa, mp->pg_num, mp->pg_shift, mempool_obj_audit, &arg); diff --git a/lib/librte_mempool/rte_mempool.h b/lib/librte_mempool/rte_mempool.h index c7a2fd6db9..bdb217b3b7 100644 --- a/lib/librte_mempool/rte_mempool.h +++ b/lib/librte_mempool/rte_mempool.h @@ -2,6 +2,7 @@ * BSD LICENSE * * Copyright(c) 2010-2014 Intel Corporation. All rights reserved. + * Copyright(c) 2016 6WIND S.A. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -334,62 +335,12 @@ void rte_mempool_check_cookies(const struct rte_mempool *mp, /** * An object callback function for mempool. * - * Arguments are the mempool, the opaque pointer given by the user in - * rte_mempool_create(), the pointer to the element and the index of - * the element in the pool. + * Used by rte_mempool_create() and rte_mempool_obj_iter(). */ typedef void (rte_mempool_obj_cb_t)(struct rte_mempool *mp, void *opaque, void *obj, unsigned obj_idx); typedef rte_mempool_obj_cb_t rte_mempool_obj_ctor_t; /* compat */ -/** - * A mempool object iterator callback function. - */ -typedef void (*rte_mempool_obj_iter_t)(void * /*obj_iter_arg*/, - void * /*obj_start*/, - void * /*obj_end*/, - uint32_t /*obj_index */); - -/** - * Call a function for each mempool object in a memory chunk - * - * Iterate across objects of the given size and alignment in the - * provided chunk of memory. The given memory buffer can consist of - * disjointed physical pages. - * - * For each object, call the provided callback (if any). This function - * is used to populate a mempool, or walk through all the elements of a - * mempool, or estimate how many elements of the given size could be - * created in the given memory buffer. - * - * @param vaddr - * Virtual address of the memory buffer. - * @param elt_num - * Maximum number of objects to iterate through. - * @param elt_sz - * Size of each object. - * @param align - * Alignment of each object. - * @param paddr - * Array of physical addresses of the pages that comprises given memory - * buffer. - * @param pg_num - * Number of elements in the paddr array. - * @param pg_shift - * LOG2 of the physical pages size. - * @param obj_iter - * Object iterator callback function (could be NULL). - * @param obj_iter_arg - * User defined parameter for the object iterator callback function. - * - * @return - * Number of objects iterated through. - */ -uint32_t rte_mempool_obj_iter(void *vaddr, - uint32_t elt_num, size_t elt_sz, size_t align, - const phys_addr_t paddr[], uint32_t pg_num, uint32_t pg_shift, - rte_mempool_obj_iter_t obj_iter, void *obj_iter_arg); - /** * A mempool constructor callback function. * @@ -642,6 +593,24 @@ rte_dom0_mempool_create(const char *name, unsigned n, unsigned elt_size, int socket_id, unsigned flags); +/** + * Call a function for each mempool element + * + * Iterate across all objects attached to a rte_mempool and call the + * callback function on it. + * + * @param mp + * A pointer to an initialized mempool. + * @param obj_cb + * A function pointer that is called for each object. + * @param obj_cb_arg + * An opaque pointer passed to the callback function. + * @return + * Number of objects iterated. + */ +uint32_t rte_mempool_obj_iter(struct rte_mempool *mp, + rte_mempool_obj_cb_t *obj_cb, void *obj_cb_arg); + /** * Dump the status of the mempool to the console. * diff --git a/lib/librte_mempool/rte_mempool_version.map b/lib/librte_mempool/rte_mempool_version.map index ff80ac2219..72bc967994 100644 --- a/lib/librte_mempool/rte_mempool_version.map +++ b/lib/librte_mempool/rte_mempool_version.map @@ -9,7 +9,6 @@ DPDK_2.0 { rte_mempool_dump; rte_mempool_list_dump; rte_mempool_lookup; - rte_mempool_obj_iter; rte_mempool_walk; rte_mempool_xmem_create; rte_mempool_xmem_size; @@ -22,6 +21,7 @@ DPDK_16.07 { global: rte_mempool_check_cookies; + rte_mempool_obj_iter; local: *; } DPDK_2.0; -- 2.20.1