From a182620042aa297ba1dc88f3089537d94b51bcf9 Mon Sep 17 00:00:00 2001 From: Olivier Matz Date: Fri, 9 May 2014 12:14:52 +0200 Subject: [PATCH] ring: get size in memory Add a function that returns the amount of memory occupied by a rte_ring structure and its object table. This commit prepares the next one that will allow to allocate a ring dynamically. Signed-off-by: Olivier Matz Acked-by: Konstantin Ananyev --- lib/librte_ring/rte_ring.c | 30 +++++++++++++++++++++++------- lib/librte_ring/rte_ring.h | 16 ++++++++++++++++ 2 files changed, 39 insertions(+), 7 deletions(-) diff --git a/lib/librte_ring/rte_ring.c b/lib/librte_ring/rte_ring.c index 0d43a55982..156fe49f31 100644 --- a/lib/librte_ring/rte_ring.c +++ b/lib/librte_ring/rte_ring.c @@ -94,6 +94,25 @@ TAILQ_HEAD(rte_ring_list, rte_ring); /* true if x is a power of 2 */ #define POWEROF2(x) ((((x)-1) & (x)) == 0) +/* return the size of memory occupied by a ring */ +ssize_t +rte_ring_get_memsize(unsigned count) +{ + ssize_t sz; + + /* count must be a power of 2 */ + if ((!POWEROF2(count)) || (count > RTE_RING_SZ_MASK )) { + RTE_LOG(ERR, RING, + "Requested size is invalid, must be power of 2, and " + "do not exceed the size limit %u\n", RTE_RING_SZ_MASK); + return -EINVAL; + } + + sz = sizeof(struct rte_ring) + count * sizeof(void *); + sz = RTE_ALIGN(sz, CACHE_LINE_SIZE); + return sz; +} + /* create the ring */ struct rte_ring * rte_ring_create(const char *name, unsigned count, int socket_id, @@ -102,7 +121,7 @@ rte_ring_create(const char *name, unsigned count, int socket_id, char mz_name[RTE_MEMZONE_NAMESIZE]; struct rte_ring *r; const struct rte_memzone *mz; - size_t ring_size; + ssize_t ring_size; int mz_flags = 0; struct rte_ring_list* ring_list = NULL; @@ -129,16 +148,13 @@ rte_ring_create(const char *name, unsigned count, int socket_id, return NULL; } - /* count must be a power of 2 */ - if ((!POWEROF2(count)) || (count > RTE_RING_SZ_MASK )) { - rte_errno = EINVAL; - RTE_LOG(ERR, RING, "Requested size is invalid, must be power of 2, and " - "do not exceed the size limit %u\n", RTE_RING_SZ_MASK); + ring_size = rte_ring_get_memsize(count); + if (ring_size < 0) { + rte_errno = ring_size; return NULL; } rte_snprintf(mz_name, sizeof(mz_name), "%s%s", RTE_RING_MZ_PREFIX, name); - ring_size = count * sizeof(void *) + sizeof(struct rte_ring); rte_rwlock_write_lock(RTE_EAL_TAILQ_RWLOCK); diff --git a/lib/librte_ring/rte_ring.h b/lib/librte_ring/rte_ring.h index 775ea790ea..e8493f2687 100644 --- a/lib/librte_ring/rte_ring.h +++ b/lib/librte_ring/rte_ring.h @@ -198,6 +198,22 @@ struct rte_ring { #define __RING_STAT_ADD(r, name, n) do {} while(0) #endif +/** + * Calculate the memory size needed for a ring + * + * This function returns the number of bytes needed for a ring, given + * the number of elements in it. This value is the sum of the size of + * the structure rte_ring and the size of the memory needed by the + * objects pointers. The value is aligned to a cache line size. + * + * @param count + * The number of elements in the ring (must be a power of 2). + * @return + * - The memory size needed for the ring on success. + * - -EINVAL if count is not a power of 2. + */ +ssize_t rte_ring_get_memsize(unsigned count); + /** * Create a new ring named *name* in memory. * -- 2.20.1