All of lore.kernel.org
 help / color / mirror / Atom feed
From: David Hunt <david.hunt@intel.com>
To: dev@dpdk.org
Subject: [PATCH 1/6] mempool: add external mempool manager support
Date: Tue, 16 Feb 2016 14:48:10 +0000	[thread overview]
Message-ID: <1455634095-4183-2-git-send-email-david.hunt@intel.com> (raw)
In-Reply-To: <1455634095-4183-1-git-send-email-david.hunt@intel.com>

Adds the new rte_mempool_create_ext api and callback mechanism for
external mempool handlers

Modifies the existing rte_mempool_create to set up the handler_idx to
the relevant mempool handler based on the handler name:
    ring_sp_sc
    ring_mp_mc
    ring_sp_mc
    ring_mp_sc

v2: merges the duplicated code in rte_mempool_xmem_create and
rte_mempool_create_ext into one common function. The old functions
now call the new common function with the relevant parameters.

Signed-off-by: David Hunt <david.hunt@intel.com>
---
 app/test/test_mempool_perf.c               |   1 -
 lib/librte_mempool/Makefile                |   2 +
 lib/librte_mempool/rte_mempool.c           | 383 ++++++++++++++++++-----------
 lib/librte_mempool/rte_mempool.h           | 200 ++++++++++++---
 lib/librte_mempool/rte_mempool_default.c   | 236 ++++++++++++++++++
 lib/librte_mempool/rte_mempool_internal.h  |  75 ++++++
 lib/librte_mempool/rte_mempool_version.map |   1 +
 7 files changed, 717 insertions(+), 181 deletions(-)
 create mode 100644 lib/librte_mempool/rte_mempool_default.c
 create mode 100644 lib/librte_mempool/rte_mempool_internal.h

diff --git a/app/test/test_mempool_perf.c b/app/test/test_mempool_perf.c
index cdc02a0..091c1df 100644
--- a/app/test/test_mempool_perf.c
+++ b/app/test/test_mempool_perf.c
@@ -161,7 +161,6 @@ per_lcore_mempool_test(__attribute__((unused)) void *arg)
 							   n_get_bulk);
 				if (unlikely(ret < 0)) {
 					rte_mempool_dump(stdout, mp);
-					rte_ring_dump(stdout, mp->ring);
 					/* in this case, objects are lost... */
 					return -1;
 				}
diff --git a/lib/librte_mempool/Makefile b/lib/librte_mempool/Makefile
index a6898ef..aeaffd1 100644
--- a/lib/librte_mempool/Makefile
+++ b/lib/librte_mempool/Makefile
@@ -42,6 +42,8 @@ LIBABIVER := 1
 
 # all source are stored in SRCS-y
 SRCS-$(CONFIG_RTE_LIBRTE_MEMPOOL) +=  rte_mempool.c
+SRCS-$(CONFIG_RTE_LIBRTE_MEMPOOL) +=  rte_mempool_default.c
+
 ifeq ($(CONFIG_RTE_LIBRTE_XEN_DOM0),y)
 SRCS-$(CONFIG_RTE_LIBRTE_MEMPOOL) +=  rte_dom0_mempool.c
 endif
diff --git a/lib/librte_mempool/rte_mempool.c b/lib/librte_mempool/rte_mempool.c
index aff5f6d..a577a3e 100644
--- a/lib/librte_mempool/rte_mempool.c
+++ b/lib/librte_mempool/rte_mempool.c
@@ -59,10 +59,11 @@
 #include <rte_spinlock.h>
 
 #include "rte_mempool.h"
+#include "rte_mempool_internal.h"
 
 TAILQ_HEAD(rte_mempool_list, rte_tailq_entry);
 
-static struct rte_tailq_elem rte_mempool_tailq = {
+struct rte_tailq_elem rte_mempool_tailq = {
 	.name = "RTE_MEMPOOL",
 };
 EAL_REGISTER_TAILQ(rte_mempool_tailq)
@@ -149,7 +150,7 @@ mempool_add_elem(struct rte_mempool *mp, void *obj, uint32_t obj_idx,
 		obj_init(mp, obj_init_arg, obj, obj_idx);
 
 	/* enqueue in ring */
-	rte_ring_sp_enqueue(mp->ring, obj);
+	rte_mempool_ext_put_bulk(mp, &obj, 1);
 }
 
 uint32_t
@@ -375,26 +376,6 @@ rte_mempool_xmem_usage(void *vaddr, uint32_t elt_num, size_t elt_sz,
 	return usz;
 }
 
-#ifndef RTE_LIBRTE_XEN_DOM0
-/* stub if DOM0 support not configured */
-struct rte_mempool *
-rte_dom0_mempool_create(const char *name __rte_unused,
-			unsigned n __rte_unused,
-			unsigned elt_size __rte_unused,
-			unsigned cache_size __rte_unused,
-			unsigned private_data_size __rte_unused,
-			rte_mempool_ctor_t *mp_init __rte_unused,
-			void *mp_init_arg __rte_unused,
-			rte_mempool_obj_ctor_t *obj_init __rte_unused,
-			void *obj_init_arg __rte_unused,
-			int socket_id __rte_unused,
-			unsigned flags __rte_unused)
-{
-	rte_errno = EINVAL;
-	return NULL;
-}
-#endif
-
 /* create the mempool */
 struct rte_mempool *
 rte_mempool_create(const char *name, unsigned n, unsigned elt_size,
@@ -420,117 +401,76 @@ rte_mempool_create(const char *name, unsigned n, unsigned elt_size,
 }
 
 /*
+ * Common mempool create function.
  * Create the mempool over already allocated chunk of memory.
  * That external memory buffer can consists of physically disjoint pages.
  * Setting vaddr to NULL, makes mempool to fallback to original behaviour
- * and allocate space for mempool and it's elements as one big chunk of
- * physically continuos memory.
- * */
-struct rte_mempool *
-rte_mempool_xmem_create(const char *name, unsigned n, unsigned elt_size,
+ * which will call rte_mempool_ext_alloc to allocate the object memory.
+ * If it is an intenal mempool handler, it will allocate space for mempool
+ * and it's elements as one big chunk of physically continuous memory.
+ * If it is an external mempool handler, it will allocate space for mempool
+ * and call the rte_mempool_ext_alloc for the object memory.
+ */
+static struct rte_mempool *
+mempool_create(const char *name,
+		unsigned num_elt, unsigned elt_size,
 		unsigned cache_size, unsigned private_data_size,
 		rte_mempool_ctor_t *mp_init, void *mp_init_arg,
 		rte_mempool_obj_ctor_t *obj_init, void *obj_init_arg,
-		int socket_id, unsigned flags, void *vaddr,
-		const phys_addr_t paddr[], uint32_t pg_num, uint32_t pg_shift)
+		int socket_id, unsigned flags,
+		void *vaddr, const phys_addr_t paddr[],
+		uint32_t pg_num, uint32_t pg_shift,
+		const char *handler_name)
 {
-	char mz_name[RTE_MEMZONE_NAMESIZE];
-	char rg_name[RTE_RING_NAMESIZE];
+	const struct rte_memzone *mz;
 	struct rte_mempool_list *mempool_list;
 	struct rte_mempool *mp = NULL;
 	struct rte_tailq_entry *te;
-	struct rte_ring *r;
-	const struct rte_memzone *mz;
-	size_t mempool_size;
+	char mz_name[RTE_MEMZONE_NAMESIZE];
 	int mz_flags = RTE_MEMZONE_1GB|RTE_MEMZONE_SIZE_HINT_ONLY;
-	int rg_flags = 0;
-	void *obj;
 	struct rte_mempool_objsz objsz;
-	void *startaddr;
+	void *startaddr = NULL;
 	int page_size = getpagesize();
-
-	/* compilation-time checks */
-	RTE_BUILD_BUG_ON((sizeof(struct rte_mempool) &
-			  RTE_CACHE_LINE_MASK) != 0);
-#if RTE_MEMPOOL_CACHE_MAX_SIZE > 0
-	RTE_BUILD_BUG_ON((sizeof(struct rte_mempool_cache) &
-			  RTE_CACHE_LINE_MASK) != 0);
-	RTE_BUILD_BUG_ON((offsetof(struct rte_mempool, local_cache) &
-			  RTE_CACHE_LINE_MASK) != 0);
-#endif
-#ifdef RTE_LIBRTE_MEMPOOL_DEBUG
-	RTE_BUILD_BUG_ON((sizeof(struct rte_mempool_debug_stats) &
-			  RTE_CACHE_LINE_MASK) != 0);
-	RTE_BUILD_BUG_ON((offsetof(struct rte_mempool, stats) &
-			  RTE_CACHE_LINE_MASK) != 0);
-#endif
+	void *obj = NULL;
+	size_t mempool_size;
 
 	mempool_list = RTE_TAILQ_CAST(rte_mempool_tailq.head, rte_mempool_list);
 
 	/* asked cache too big */
 	if (cache_size > RTE_MEMPOOL_CACHE_MAX_SIZE ||
-	    CALC_CACHE_FLUSHTHRESH(cache_size) > n) {
+		CALC_CACHE_FLUSHTHRESH(cache_size) > num_elt) {
 		rte_errno = EINVAL;
 		return NULL;
 	}
 
-	/* check that we have both VA and PA */
-	if (vaddr != NULL && paddr == NULL) {
-		rte_errno = EINVAL;
-		return NULL;
-	}
-
-	/* Check that pg_num and pg_shift parameters are valid. */
-	if (pg_num < RTE_DIM(mp->elt_pa) || pg_shift > MEMPOOL_PG_SHIFT_MAX) {
-		rte_errno = EINVAL;
-		return NULL;
-	}
-
-	/* "no cache align" imply "no spread" */
-	if (flags & MEMPOOL_F_NO_CACHE_ALIGN)
-		flags |= MEMPOOL_F_NO_SPREAD;
+	if (flags && MEMPOOL_F_INT_HANDLER) {
+		/* Check that pg_num and pg_shift parameters are valid. */
+		if (pg_num < RTE_DIM(mp->elt_pa) ||
+				pg_shift > MEMPOOL_PG_SHIFT_MAX) {
+			rte_errno = EINVAL;
+			return NULL;
+		}
 
-	/* ring flags */
-	if (flags & MEMPOOL_F_SP_PUT)
-		rg_flags |= RING_F_SP_ENQ;
-	if (flags & MEMPOOL_F_SC_GET)
-		rg_flags |= RING_F_SC_DEQ;
+		/* "no cache align" imply "no spread" */
+		if (flags & MEMPOOL_F_NO_CACHE_ALIGN)
+			flags |= MEMPOOL_F_NO_SPREAD;
 
-	/* calculate mempool object sizes. */
-	if (!rte_mempool_calc_obj_size(elt_size, flags, &objsz)) {
-		rte_errno = EINVAL;
-		return NULL;
+		/* calculate mempool object sizes. */
+		if (!rte_mempool_calc_obj_size(elt_size, flags, &objsz)) {
+			rte_errno = EINVAL;
+			return NULL;
+		}
 	}
 
 	rte_rwlock_write_lock(RTE_EAL_MEMPOOL_RWLOCK);
 
-	/* allocate the ring that will be used to store objects */
-	/* Ring functions will return appropriate errors if we are
-	 * running as a secondary process etc., so no checks made
-	 * in this function for that condition */
-	snprintf(rg_name, sizeof(rg_name), RTE_MEMPOOL_MZ_FORMAT, name);
-	r = rte_ring_create(rg_name, rte_align32pow2(n+1), socket_id, rg_flags);
-	if (r == NULL)
-		goto exit;
-
 	/*
 	 * reserve a memory zone for this mempool: private data is
 	 * cache-aligned
 	 */
-	private_data_size = (private_data_size +
-			     RTE_MEMPOOL_ALIGN_MASK) & (~RTE_MEMPOOL_ALIGN_MASK);
+	private_data_size = RTE_ALIGN_CEIL(private_data_size,
+						RTE_MEMPOOL_ALIGN);
 
-	if (! rte_eal_has_hugepages()) {
-		/*
-		 * expand private data size to a whole page, so that the
-		 * first pool element will start on a new standard page
-		 */
-		int head = sizeof(struct rte_mempool);
-		int new_size = (private_data_size + head) % page_size;
-		if (new_size) {
-			private_data_size += page_size - new_size;
-		}
-	}
 
 	/* try to allocate tailq entry */
 	te = rte_zmalloc("MEMPOOL_TAILQ_ENTRY", sizeof(*te), 0);
@@ -539,23 +479,51 @@ rte_mempool_xmem_create(const char *name, unsigned n, unsigned elt_size,
 		goto exit;
 	}
 
-	/*
-	 * If user provided an external memory buffer, then use it to
-	 * store mempool objects. Otherwise reserve a memzone that is large
-	 * enough to hold mempool header and metadata plus mempool objects.
-	 */
-	mempool_size = MEMPOOL_HEADER_SIZE(mp, pg_num) + private_data_size;
-	mempool_size = RTE_ALIGN_CEIL(mempool_size, RTE_MEMPOOL_ALIGN);
-	if (vaddr == NULL)
-		mempool_size += (size_t)objsz.total_size * n;
+	if (flags && MEMPOOL_F_INT_HANDLER) {
 
-	if (! rte_eal_has_hugepages()) {
+		if (!rte_eal_has_hugepages()) {
+			/*
+			 * expand private data size to a whole page, so that the
+			 * first pool element will start on a new standard page
+			 */
+			int head = sizeof(struct rte_mempool);
+			int new_size = (private_data_size + head) % page_size;
+
+			if (new_size)
+				private_data_size += page_size - new_size;
+		}
+
+
+		/*
+		 * If user provided an external memory buffer, then use it to
+		 * store mempool objects. Otherwise reserve a memzone that is
+		 * large enough to hold mempool header and metadata plus
+		 * mempool objects
+		 */
+		mempool_size =
+			MEMPOOL_HEADER_SIZE(mp, pg_num) + private_data_size;
+		mempool_size =
+			RTE_ALIGN_CEIL(mempool_size, RTE_MEMPOOL_ALIGN);
+		if (vaddr == NULL)
+			mempool_size += (size_t)objsz.total_size * num_elt;
+
+		if (!rte_eal_has_hugepages()) {
+			/*
+			 * we want the memory pool to start on a page boundary,
+			 * because pool elements crossing page boundaries would
+			 * result in discontiguous physical addresses
+			 */
+			mempool_size += page_size;
+		}
+	} else {
 		/*
-		 * we want the memory pool to start on a page boundary,
-		 * because pool elements crossing page boundaries would
-		 * result in discontiguous physical addresses
+		 * If user provided an external memory buffer, then use it to
+		 * store mempool objects. Otherwise reserve a memzone that is
+		 * large enough to hold mempool header and metadata plus
+		 * mempool objects
 		 */
-		mempool_size += page_size;
+		mempool_size = sizeof(*mp) + private_data_size;
+		mempool_size = RTE_ALIGN_CEIL(mempool_size, RTE_MEMPOOL_ALIGN);
 	}
 
 	snprintf(mz_name, sizeof(mz_name), RTE_MEMPOOL_MZ_FORMAT, name);
@@ -563,24 +531,29 @@ rte_mempool_xmem_create(const char *name, unsigned n, unsigned elt_size,
 	mz = rte_memzone_reserve(mz_name, mempool_size, socket_id, mz_flags);
 
 	/*
-	 * no more memory: in this case we loose previously reserved
-	 * space for the ring as we cannot free it
+	 * no more memory
 	 */
 	if (mz == NULL) {
 		rte_free(te);
 		goto exit;
 	}
 
-	if (rte_eal_has_hugepages()) {
-		startaddr = (void*)mz->addr;
-	} else {
-		/* align memory pool start address on a page boundary */
-		unsigned long addr = (unsigned long)mz->addr;
-		if (addr & (page_size - 1)) {
-			addr += page_size;
-			addr &= ~(page_size - 1);
+	if (flags && MEMPOOL_F_INT_HANDLER) {
+
+		if (rte_eal_has_hugepages()) {
+			startaddr = (void *)mz->addr;
+		} else {
+			/* align memory pool start address on a page boundary */
+			unsigned long addr = (unsigned long)mz->addr;
+
+			if (addr & (page_size - 1)) {
+				addr += page_size;
+				addr &= ~(page_size - 1);
+			}
+			startaddr = (void *)addr;
 		}
-		startaddr = (void*)addr;
+	} else {
+		startaddr = (void *)mz->addr;
 	}
 
 	/* init the mempool structure */
@@ -588,8 +561,7 @@ rte_mempool_xmem_create(const char *name, unsigned n, unsigned elt_size,
 	memset(mp, 0, sizeof(*mp));
 	snprintf(mp->name, sizeof(mp->name), "%s", name);
 	mp->phys_addr = mz->phys_addr;
-	mp->ring = r;
-	mp->size = n;
+	mp->size = num_elt;
 	mp->flags = flags;
 	mp->elt_size = objsz.elt_size;
 	mp->header_size = objsz.header_size;
@@ -598,35 +570,54 @@ rte_mempool_xmem_create(const char *name, unsigned n, unsigned elt_size,
 	mp->cache_flushthresh = CALC_CACHE_FLUSHTHRESH(cache_size);
 	mp->private_data_size = private_data_size;
 
-	/* calculate address of the first element for continuous mempool. */
-	obj = (char *)mp + MEMPOOL_HEADER_SIZE(mp, pg_num) +
-		private_data_size;
-	obj = RTE_PTR_ALIGN_CEIL(obj, RTE_MEMPOOL_ALIGN);
-
-	/* populate address translation fields. */
-	mp->pg_num = pg_num;
-	mp->pg_shift = pg_shift;
-	mp->pg_mask = RTE_LEN2MASK(mp->pg_shift, typeof(mp->pg_mask));
+	mp->handler_idx = rte_get_mempool_handler_idx(handler_name);
+	if (mp->handler_idx < 0) {
+		RTE_LOG(ERR, MEMPOOL, "Cannot find mempool handler by name!\n");
+		rte_free(te);
+		goto exit;
+	}
 
-	/* mempool elements allocated together with mempool */
-	if (vaddr == NULL) {
-		mp->elt_va_start = (uintptr_t)obj;
-		mp->elt_pa[0] = mp->phys_addr +
-			(mp->elt_va_start - (uintptr_t)mp);
+	if (flags && MEMPOOL_F_INT_HANDLER) {
+		/* calculate address of first element for continuous mempool. */
+		obj = (char *)mp + MEMPOOL_HEADER_SIZE(mp, pg_num) +
+			private_data_size;
+		obj = RTE_PTR_ALIGN_CEIL(obj, RTE_MEMPOOL_ALIGN);
+
+		/* populate address translation fields. */
+		mp->pg_num = pg_num;
+		mp->pg_shift = pg_shift;
+		mp->pg_mask = RTE_LEN2MASK(mp->pg_shift, typeof(mp->pg_mask));
+
+		/* mempool elements allocated together with mempool */
+		if (vaddr == NULL) {
+			mp->elt_va_start = (uintptr_t)obj;
+			mp->elt_pa[0] = mp->phys_addr +
+				(mp->elt_va_start - (uintptr_t)mp);
+		/* mempool elements in a separate chunk of memory. */
+		} else {
+			mp->elt_va_start = (uintptr_t)vaddr;
+			memcpy(mp->elt_pa, paddr,
+				sizeof(mp->elt_pa[0]) * pg_num);
+		}
 
-	/* mempool elements in a separate chunk of memory. */
-	} else {
-		mp->elt_va_start = (uintptr_t)vaddr;
-		memcpy(mp->elt_pa, paddr, sizeof (mp->elt_pa[0]) * pg_num);
+		mp->elt_va_end = mp->elt_va_start;
 	}
 
-	mp->elt_va_end = mp->elt_va_start;
+	/* Parameters are setup. Call the mempool handler alloc */
+	mp->rt_pool =
+		rte_mempool_ext_alloc(mp, name, num_elt, socket_id, flags);
+	if (mp->rt_pool == NULL) {
+		RTE_LOG(ERR, MEMPOOL, "Failed to alloc mempool!\n");
+		rte_free(te);
+		goto exit;
+	}
 
 	/* call the initializer */
 	if (mp_init)
 		mp_init(mp, mp_init_arg);
 
-	mempool_populate(mp, n, 1, obj_init, obj_init_arg);
+	if (obj_init)
+		mempool_populate(mp, num_elt, 1, obj_init, obj_init_arg);
 
 	te->data = (void *) mp;
 
@@ -640,13 +631,79 @@ exit:
 	return mp;
 }
 
+/* Create the mempool over already allocated chunk of memory */
+struct rte_mempool *
+rte_mempool_xmem_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_ctor_t *obj_init, void *obj_init_arg,
+		int socket_id, unsigned flags, void *vaddr,
+		const phys_addr_t paddr[], uint32_t pg_num, uint32_t pg_shift)
+{
+	struct rte_mempool *mp = NULL;
+	char handler_name[RTE_MEMPOOL_NAMESIZE];
+
+
+	/* compilation-time checks */
+	RTE_BUILD_BUG_ON((sizeof(struct rte_mempool) &
+			  RTE_CACHE_LINE_MASK) != 0);
+#if RTE_MEMPOOL_CACHE_MAX_SIZE > 0
+	RTE_BUILD_BUG_ON((sizeof(struct rte_mempool_cache) &
+			  RTE_CACHE_LINE_MASK) != 0);
+	RTE_BUILD_BUG_ON((offsetof(struct rte_mempool, local_cache) &
+			  RTE_CACHE_LINE_MASK) != 0);
+#endif
+#ifdef RTE_LIBRTE_MEMPOOL_DEBUG
+	RTE_BUILD_BUG_ON((sizeof(struct rte_mempool_debug_stats) &
+			  RTE_CACHE_LINE_MASK) != 0);
+	RTE_BUILD_BUG_ON((offsetof(struct rte_mempool, stats) &
+			  RTE_CACHE_LINE_MASK) != 0);
+#endif
+
+
+	/* check that we have both VA and PA */
+	if (vaddr != NULL && paddr == NULL) {
+		rte_errno = EINVAL;
+		return NULL;
+	}
+
+	/*
+	 * Since we have 4 combinations of the SP/SC/MP/MC, and stack,
+	 * examine the
+	 * flags to set the correct index into the handler table.
+	 */
+	if (flags & (MEMPOOL_F_SP_PUT | MEMPOOL_F_SC_GET))
+		sprintf(handler_name, "%s", "ring_sp_sc");
+	else if (flags & MEMPOOL_F_SP_PUT)
+		sprintf(handler_name, "%s", "ring_sp_mc");
+	else if (flags & MEMPOOL_F_SC_GET)
+		sprintf(handler_name, "%s", "ring_mp_sc");
+	else
+		sprintf(handler_name, "%s", "ring_mp_mc");
+
+	flags |= MEMPOOL_F_INT_HANDLER;
+
+	mp = mempool_create(name,
+		n, elt_size,
+		cache_size, private_data_size,
+		mp_init, mp_init_arg,
+		obj_init, obj_init_arg,
+		socket_id,
+		flags,
+		vaddr, paddr,
+		pg_num, pg_shift,
+		handler_name);
+
+	return mp;
+}
+
 /* Return the number of entries in the mempool */
 unsigned
 rte_mempool_count(const struct rte_mempool *mp)
 {
 	unsigned count;
 
-	count = rte_ring_count(mp->ring);
+	count = rte_mempool_ext_get_count(mp);
 
 #if RTE_MEMPOOL_CACHE_MAX_SIZE > 0
 	{
@@ -802,7 +859,6 @@ rte_mempool_dump(FILE *f, const struct rte_mempool *mp)
 
 	fprintf(f, "mempool <%s>@%p\n", mp->name, mp);
 	fprintf(f, "  flags=%x\n", mp->flags);
-	fprintf(f, "  ring=<%s>@%p\n", mp->ring->name, mp->ring);
 	fprintf(f, "  phys_addr=0x%" PRIx64 "\n", mp->phys_addr);
 	fprintf(f, "  size=%"PRIu32"\n", mp->size);
 	fprintf(f, "  header_size=%"PRIu32"\n", mp->header_size);
@@ -825,7 +881,7 @@ rte_mempool_dump(FILE *f, const struct rte_mempool *mp)
 			mp->size);
 
 	cache_count = rte_mempool_dump_cache(f, mp);
-	common_count = rte_ring_count(mp->ring);
+	common_count = rte_mempool_ext_get_count(mp);
 	if ((cache_count + common_count) > mp->size)
 		common_count = mp->size - cache_count;
 	fprintf(f, "  common_pool_count=%u\n", common_count);
@@ -919,3 +975,30 @@ void rte_mempool_walk(void (*func)(const struct rte_mempool *, void *),
 
 	rte_rwlock_read_unlock(RTE_EAL_MEMPOOL_RWLOCK);
 }
+
+
+/* create the mempool using an external mempool manager */
+struct rte_mempool *
+rte_mempool_create_ext(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_ctor_t *obj_init, void *obj_init_arg,
+	int socket_id, unsigned flags,
+	const char *handler_name)
+{
+	struct rte_mempool *mp = NULL;
+
+	mp = mempool_create(name,
+		n, elt_size,
+		cache_size, private_data_size,
+		mp_init, mp_init_arg,
+		obj_init, obj_init_arg,
+		socket_id, flags,
+		NULL, NULL,              /* vaddr, paddr */
+		0, 0,                    /* pg_num, pg_shift, */
+		handler_name);
+
+	return mp;
+
+
+}
diff --git a/lib/librte_mempool/rte_mempool.h b/lib/librte_mempool/rte_mempool.h
index 9745bf0..3705fbd 100644
--- a/lib/librte_mempool/rte_mempool.h
+++ b/lib/librte_mempool/rte_mempool.h
@@ -88,6 +88,8 @@ extern "C" {
 struct rte_mempool_debug_stats {
 	uint64_t put_bulk;         /**< Number of puts. */
 	uint64_t put_objs;         /**< Number of objects successfully put. */
+	uint64_t put_pool_bulk;    /**< Number of puts into pool. */
+	uint64_t put_pool_objs;    /**< Number of objects into pool. */
 	uint64_t get_success_bulk; /**< Successful allocation number. */
 	uint64_t get_success_objs; /**< Objects successfully allocated. */
 	uint64_t get_fail_bulk;    /**< Failed allocation number. */
@@ -175,12 +177,85 @@ struct rte_mempool_objtlr {
 #endif
 };
 
+/* Handler functions for external mempool support */
+typedef void *(*rte_mempool_alloc_t)(struct rte_mempool *mp,
+		const char *name, unsigned n, int socket_id, unsigned flags);
+typedef int (*rte_mempool_put_t)(void *p,
+		void * const *obj_table, unsigned n);
+typedef int (*rte_mempool_get_t)(void *p, void **obj_table,
+		unsigned n);
+typedef unsigned (*rte_mempool_get_count)(void *p);
+typedef int (*rte_mempool_free_t)(struct rte_mempool *mp);
+
+/**
+ * @internal wrapper for external mempool manager alloc callback.
+ *
+ * @param mp
+ *   Pointer to the memory pool.
+ * @param name
+ *   Name of the memory pool.
+ * @param n
+ *   Number of objects in the mempool.
+ * @param socket_id
+ *   socket id on which to allocate.
+ * @param flags
+ *   general flags to allocate function (MEMPOOL_F_* flags)
+ */
+void *
+rte_mempool_ext_alloc(struct rte_mempool *mp,
+		const char *name, unsigned n, int socket_id, unsigned flags);
+
+/**
+ * @internal wrapper for external mempool manager get callback.
+ *
+ * @param mp
+ *   Pointer to the memory pool.
+ * @param obj_table
+ *   Pointer to a table of void * pointers (objects).
+ * @param n
+ *	 Number of objects to get
+ */
+int
+rte_mempool_ext_get_bulk(struct rte_mempool *mp, void **obj_table,
+		unsigned n);
+
+/**
+ * @internal wrapper for external mempool manager put callback.
+ *
+ * @param mp
+ *   Pointer to the memory pool.
+ * @param obj_table
+ *   Pointer to a table of void * pointers (objects).
+ * @param n
+ *   Number of objects to put
+ */
+int
+rte_mempool_ext_put_bulk(struct rte_mempool *mp, void * const *obj_table,
+		unsigned n);
+
+/**
+ * @internal wrapper for external mempool manager get_count callback.
+ *
+ * @param mp
+ *   Pointer to the memory pool.
+ */
+int
+rte_mempool_ext_get_count(const struct rte_mempool *mp);
+
+/**
+ * @internal wrapper for external mempool manager free callback.
+ *
+ * @param mp
+ *   Pointer to the memory pool.
+ */
+int
+rte_mempool_ext_free(struct rte_mempool *mp);
+
 /**
  * The RTE mempool structure.
  */
 struct rte_mempool {
 	char name[RTE_MEMPOOL_NAMESIZE]; /**< Name of mempool. */
-	struct rte_ring *ring;           /**< Ring to store objects. */
 	phys_addr_t phys_addr;           /**< Phys. addr. of mempool struct. */
 	int flags;                       /**< Flags of the mempool. */
 	uint32_t size;                   /**< Size of the mempool. */
@@ -194,6 +269,11 @@ struct rte_mempool {
 
 	unsigned private_data_size;      /**< Size of private data. */
 
+	/* Common pool data structure pointer */
+	void *rt_pool;
+
+	int16_t handler_idx;
+
 #if RTE_MEMPOOL_CACHE_MAX_SIZE > 0
 	/** Per-lcore local cache. */
 	struct rte_mempool_cache local_cache[RTE_MAX_LCORE];
@@ -223,6 +303,8 @@ struct rte_mempool {
 #define MEMPOOL_F_NO_CACHE_ALIGN 0x0002 /**< Do not align objs on cache lines.*/
 #define MEMPOOL_F_SP_PUT         0x0004 /**< Default put is "single-producer".*/
 #define MEMPOOL_F_SC_GET         0x0008 /**< Default get is "single-consumer".*/
+#define MEMPOOL_F_INT_HANDLER    0x0020 /**< Using internal mempool handler */
+
 
 /**
  * @internal When debug is enabled, store some statistics.
@@ -753,7 +835,7 @@ void rte_mempool_dump(FILE *f, const struct rte_mempool *mp);
  */
 static inline void __attribute__((always_inline))
 __mempool_put_bulk(struct rte_mempool *mp, void * const *obj_table,
-		    unsigned n, int is_mp)
+		    unsigned n, __attribute__((unused)) int is_mp)
 {
 #if RTE_MEMPOOL_CACHE_MAX_SIZE > 0
 	struct rte_mempool_cache *cache;
@@ -769,8 +851,7 @@ __mempool_put_bulk(struct rte_mempool *mp, void * const *obj_table,
 
 #if RTE_MEMPOOL_CACHE_MAX_SIZE > 0
 	/* cache is not enabled or single producer or non-EAL thread */
-	if (unlikely(cache_size == 0 || is_mp == 0 ||
-		     lcore_id >= RTE_MAX_LCORE))
+	if (unlikely(cache_size == 0 || lcore_id >= RTE_MAX_LCORE))
 		goto ring_enqueue;
 
 	/* Go straight to ring if put would overflow mem allocated for cache */
@@ -793,8 +874,8 @@ __mempool_put_bulk(struct rte_mempool *mp, void * const *obj_table,
 
 	cache->len += n;
 
-	if (cache->len >= flushthresh) {
-		rte_ring_mp_enqueue_bulk(mp->ring, &cache->objs[cache_size],
+	if (unlikely(cache->len >= flushthresh)) {
+		rte_mempool_ext_put_bulk(mp, &cache->objs[cache_size],
 				cache->len - cache_size);
 		cache->len = cache_size;
 	}
@@ -804,22 +885,10 @@ __mempool_put_bulk(struct rte_mempool *mp, void * const *obj_table,
 ring_enqueue:
 #endif /* RTE_MEMPOOL_CACHE_MAX_SIZE > 0 */
 
-	/* push remaining objects in ring */
-#ifdef RTE_LIBRTE_MEMPOOL_DEBUG
-	if (is_mp) {
-		if (rte_ring_mp_enqueue_bulk(mp->ring, obj_table, n) < 0)
-			rte_panic("cannot put objects in mempool\n");
-	}
-	else {
-		if (rte_ring_sp_enqueue_bulk(mp->ring, obj_table, n) < 0)
-			rte_panic("cannot put objects in mempool\n");
-	}
-#else
-	if (is_mp)
-		rte_ring_mp_enqueue_bulk(mp->ring, obj_table, n);
-	else
-		rte_ring_sp_enqueue_bulk(mp->ring, obj_table, n);
-#endif
+	/* Increment stats counter to tell us how many pool puts happened */
+	__MEMPOOL_STAT_ADD(mp, put_pool, n);
+
+	rte_mempool_ext_put_bulk(mp, obj_table, n);
 }
 
 
@@ -943,7 +1012,7 @@ rte_mempool_put(struct rte_mempool *mp, void *obj)
  */
 static inline int __attribute__((always_inline))
 __mempool_get_bulk(struct rte_mempool *mp, void **obj_table,
-		   unsigned n, int is_mc)
+		   unsigned n, __attribute__((unused))int is_mc)
 {
 	int ret;
 #if RTE_MEMPOOL_CACHE_MAX_SIZE > 0
@@ -954,8 +1023,8 @@ __mempool_get_bulk(struct rte_mempool *mp, void **obj_table,
 	uint32_t cache_size = mp->cache_size;
 
 	/* cache is not enabled or single consumer */
-	if (unlikely(cache_size == 0 || is_mc == 0 ||
-		     n >= cache_size || lcore_id >= RTE_MAX_LCORE))
+	if (unlikely(cache_size == 0 || n >= cache_size ||
+						lcore_id >= RTE_MAX_LCORE))
 		goto ring_dequeue;
 
 	cache = &mp->local_cache[lcore_id];
@@ -967,7 +1036,8 @@ __mempool_get_bulk(struct rte_mempool *mp, void **obj_table,
 		uint32_t req = n + (cache_size - cache->len);
 
 		/* How many do we require i.e. number to fill the cache + the request */
-		ret = rte_ring_mc_dequeue_bulk(mp->ring, &cache->objs[cache->len], req);
+		ret = rte_mempool_ext_get_bulk(mp,
+						&cache->objs[cache->len], req);
 		if (unlikely(ret < 0)) {
 			/*
 			 * In the offchance that we are buffer constrained,
@@ -995,10 +1065,7 @@ ring_dequeue:
 #endif /* RTE_MEMPOOL_CACHE_MAX_SIZE > 0 */
 
 	/* get remaining objects from ring */
-	if (is_mc)
-		ret = rte_ring_mc_dequeue_bulk(mp->ring, obj_table, n);
-	else
-		ret = rte_ring_sc_dequeue_bulk(mp->ring, obj_table, n);
+	ret = rte_mempool_ext_get_bulk(mp, obj_table, n);
 
 	if (ret < 0)
 		__MEMPOOL_STAT_ADD(mp, get_fail, n);
@@ -1401,6 +1468,79 @@ ssize_t rte_mempool_xmem_usage(void *vaddr, uint32_t elt_num, size_t elt_sz,
 void rte_mempool_walk(void (*func)(const struct rte_mempool *, void *arg),
 		      void *arg);
 
+/**
+ * Function to get the name of a mempool handler
+ *
+ * @param mp
+ *   A pointer to the mempool structure.
+ * @return
+ *   The name of the mempool handler
+ */
+char *rte_mempool_get_handler_name(struct rte_mempool *mp);
+
+/**
+ * Create a new mempool named *name* in memory.
+ *
+ * This function uses an externally defined alloc callback to allocate memory.
+ * Its size is set to n elements.
+ * All elements of the mempool are allocated separately to the mempool header.
+ *
+ * @param name
+ *   The name of the mempool.
+ * @param n
+ *   The number of elements in the mempool. The optimum size (in terms of
+ *   memory usage) for a mempool is when n is a power of two minus one:
+ *   n = (2^q - 1).
+ * @param cache_size
+ *   If cache_size is non-zero, the rte_mempool library will try to
+ *   limit the accesses to the common lockless pool, by maintaining a
+ *   per-lcore object cache. This argument must be lower or equal to
+ *   CONFIG_RTE_MEMPOOL_CACHE_MAX_SIZE and n / 1.5. It is advised to choose
+ *   cache_size to have "n modulo cache_size == 0": if this is
+ *   not the case, some elements will always stay in the pool and will
+ *   never be used. The access to the per-lcore table is of course
+ *   faster than the multi-producer/consumer pool. The cache can be
+ *   disabled if the cache_size argument is set to 0; it can be useful to
+ *   avoid losing objects in cache. Note that even if not used, the
+ *   memory space for cache is always reserved in a mempool structure,
+ *   except if CONFIG_RTE_MEMPOOL_CACHE_MAX_SIZE is set to 0.
+ * @param private_data_size
+ *   The size of the private data appended after the mempool
+ *   structure. This is useful for storing some private data after the
+ *   mempool structure, as is done for rte_mbuf_pool for example.
+ * @param mp_init
+ *   A function pointer that is called for initialization of the pool,
+ *   before object initialization. The user can initialize the private
+ *   data in this function if needed. This parameter can be NULL if
+ *   not needed.
+ * @param mp_init_arg
+ *   An opaque pointer to data that can be used in the mempool
+ *   constructor function.
+ * @param obj_init
+ *   A function pointer that is called for each object at
+ *   initialization of the pool. The user can set some meta data in
+ *   objects if needed. This parameter can be NULL if not needed.
+ *   The obj_init() function takes the mempool pointer, the init_arg,
+ *   the object pointer and the object number as parameters.
+ * @param obj_init_arg
+ *   An opaque pointer to data that can be used as an argument for
+ *   each call to the object constructor function.
+ * @param socket_id
+ *   The *socket_id* argument is the socket identifier in the case of
+ *   NUMA. The value can be *SOCKET_ID_ANY* if there is no NUMA
+ *   constraint for the reserved zone.
+ * @param flags
+ * @return
+ *   The pointer to the new allocated mempool, on success. NULL on error
+ */
+struct rte_mempool *
+rte_mempool_create_ext(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_ctor_t *obj_init, void *obj_init_arg,
+		int socket_id, unsigned flags,
+		const char *handler_name);
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/lib/librte_mempool/rte_mempool_default.c b/lib/librte_mempool/rte_mempool_default.c
new file mode 100644
index 0000000..ca3255e
--- /dev/null
+++ b/lib/librte_mempool/rte_mempool_default.c
@@ -0,0 +1,236 @@
+/*-
+ *   BSD LICENSE
+ *
+ *   Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
+ *   All rights reserved.
+ *
+ *   Redistribution and use in source and binary forms, with or without
+ *   modification, are permitted provided that the following conditions
+ *   are met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in
+ *       the documentation and/or other materials provided with the
+ *       distribution.
+ *     * Neither the name of Intel Corporation nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <stdio.h>
+#include <rte_mempool.h>
+#include <rte_malloc.h>
+#include <string.h>
+
+#include "rte_mempool.h"
+#include "rte_mempool_internal.h"
+
+/*
+ * Indirect jump table to support external memory pools
+ */
+struct rte_mempool_handler_list mempool_handler_list = {
+	.sl =  RTE_SPINLOCK_INITIALIZER ,
+	.num_handlers = 0
+};
+
+/*
+ * Returns the name of the mempool
+ */
+char *
+rte_mempool_get_handler_name(struct rte_mempool *mp) {
+	return mempool_handler_list.handler[mp->handler_idx].name;
+}
+
+int16_t
+rte_mempool_register_handler(struct rte_mempool_handler *h)
+{
+	int16_t handler_idx;
+
+	/*  */
+	rte_spinlock_lock(&mempool_handler_list.sl);
+
+	/* Check whether jump table has space */
+	if (mempool_handler_list.num_handlers >= RTE_MEMPOOL_MAX_HANDLER_IDX) {
+		rte_spinlock_unlock(&mempool_handler_list.sl);
+		RTE_LOG(ERR, MEMPOOL,
+				"Maximum number of mempool handlers exceeded\n");
+		return -1;
+	}
+
+	if ((h->put == NULL) || (h->get == NULL) ||
+		(h->get_count == NULL)) {
+		rte_spinlock_unlock(&mempool_handler_list.sl);
+		 RTE_LOG(ERR, MEMPOOL,
+					"Missing callback while registering mempool handler\n");
+		return -1;
+	}
+
+	/* add new handler index */
+	handler_idx = mempool_handler_list.num_handlers++;
+
+	snprintf(mempool_handler_list.handler[handler_idx].name,
+				RTE_MEMPOOL_NAMESIZE, "%s", h->name);
+	mempool_handler_list.handler[handler_idx].alloc = h->alloc;
+	mempool_handler_list.handler[handler_idx].put = h->put;
+	mempool_handler_list.handler[handler_idx].get = h->get;
+	mempool_handler_list.handler[handler_idx].get_count = h->get_count;
+
+	rte_spinlock_unlock(&mempool_handler_list.sl);
+
+	return handler_idx;
+}
+
+int16_t
+rte_get_mempool_handler_idx(const char *name)
+{
+	int16_t i;
+
+	for (i = 0; i < mempool_handler_list.num_handlers; i++) {
+		if (!strcmp(name, mempool_handler_list.handler[i].name))
+			return i;
+	}
+	return -1;
+}
+
+static int
+common_ring_mp_put(void *p, void * const *obj_table, unsigned n)
+{
+	return rte_ring_mp_enqueue_bulk((struct rte_ring *)p, obj_table, n);
+}
+
+static int
+common_ring_sp_put(void *p, void * const *obj_table, unsigned n)
+{
+	return rte_ring_sp_enqueue_bulk((struct rte_ring *)p, obj_table, n);
+}
+
+static int
+common_ring_mc_get(void *p, void **obj_table, unsigned n)
+{
+	return rte_ring_mc_dequeue_bulk((struct rte_ring *)p, obj_table, n);
+}
+
+static int
+common_ring_sc_get(void *p, void **obj_table, unsigned n)
+{
+	return rte_ring_sc_dequeue_bulk((struct rte_ring *)p, obj_table, n);
+}
+
+static unsigned
+common_ring_get_count(void *p)
+{
+	return rte_ring_count((struct rte_ring *)p);
+}
+
+
+static void *
+rte_mempool_common_ring_alloc(struct rte_mempool *mp,
+		const char *name, unsigned n, int socket_id, unsigned flags)
+{
+	struct rte_ring *r;
+	char rg_name[RTE_RING_NAMESIZE];
+	int rg_flags = 0;
+
+	if (flags & MEMPOOL_F_SP_PUT)
+		rg_flags |= RING_F_SP_ENQ;
+	if (flags & MEMPOOL_F_SC_GET)
+		rg_flags |= RING_F_SC_DEQ;
+
+	/* allocate the ring that will be used to store objects */
+	/* Ring functions will return appropriate errors if we are
+	 * running as a secondary process etc., so no checks made
+	 * in this function for that condition */
+	snprintf(rg_name, sizeof(rg_name), "%s-ring", name);
+	r = rte_ring_create(rg_name, rte_align32pow2(n+1), socket_id, rg_flags);
+	if (r == NULL)
+		return NULL;
+
+	mp->rt_pool = (void *)r;
+
+	return (void *) r;
+}
+
+void *
+rte_mempool_ext_alloc(struct rte_mempool *mp,
+		const char *name, unsigned n, int socket_id, unsigned flags)
+{
+	if (mempool_handler_list.handler[mp->handler_idx].alloc) {
+		return (mempool_handler_list.handler[mp->handler_idx].alloc)
+						(mp, name, n, socket_id, flags);
+	}
+	return NULL;
+}
+
+inline int __attribute__((always_inline))
+rte_mempool_ext_get_bulk(struct rte_mempool *mp, void **obj_table, unsigned n)
+{
+	return (mempool_handler_list.handler[mp->handler_idx].get)
+						(mp->rt_pool, obj_table, n);
+}
+
+inline int __attribute__((always_inline))
+rte_mempool_ext_put_bulk(struct rte_mempool *mp, void * const *obj_table,
+		unsigned n)
+{
+	return (mempool_handler_list.handler[mp->handler_idx].put)
+						(mp->rt_pool, obj_table, n);
+}
+
+int
+rte_mempool_ext_get_count(const struct rte_mempool *mp)
+{
+	return (mempool_handler_list.handler[mp->handler_idx].get_count)
+						(mp->rt_pool);
+}
+
+static struct rte_mempool_handler handler_mp_mc = {
+	.name = "ring_mp_mc",
+	.alloc = rte_mempool_common_ring_alloc,
+	.put = common_ring_mp_put,
+	.get = common_ring_mc_get,
+	.get_count = common_ring_get_count,
+	.free = NULL
+};
+static struct rte_mempool_handler handler_sp_sc = {
+	.name = "ring_sp_sc",
+	.alloc = rte_mempool_common_ring_alloc,
+	.put = common_ring_sp_put,
+	.get = common_ring_sc_get,
+	.get_count = common_ring_get_count,
+	.free = NULL
+};
+static struct rte_mempool_handler handler_mp_sc = {
+	.name = "ring_mp_sc",
+	.alloc = rte_mempool_common_ring_alloc,
+	.put = common_ring_mp_put,
+	.get = common_ring_sc_get,
+	.get_count = common_ring_get_count,
+	.free = NULL
+};
+static struct rte_mempool_handler handler_sp_mc = {
+	.name = "ring_sp_mc",
+	.alloc = rte_mempool_common_ring_alloc,
+	.put = common_ring_sp_put,
+	.get = common_ring_mc_get,
+	.get_count = common_ring_get_count,
+	.free = NULL
+};
+
+REGISTER_MEMPOOL_HANDLER(handler_mp_mc);
+REGISTER_MEMPOOL_HANDLER(handler_sp_sc);
+REGISTER_MEMPOOL_HANDLER(handler_mp_sc);
+REGISTER_MEMPOOL_HANDLER(handler_sp_mc);
diff --git a/lib/librte_mempool/rte_mempool_internal.h b/lib/librte_mempool/rte_mempool_internal.h
new file mode 100644
index 0000000..982396f
--- /dev/null
+++ b/lib/librte_mempool/rte_mempool_internal.h
@@ -0,0 +1,75 @@
+/*-
+ *   BSD LICENSE
+ *
+ *   Copyright(c) 2010-2015 Intel Corporation. All rights reserved.
+ *   All rights reserved.
+ *
+ *   Redistribution and use in source and binary forms, with or without
+ *   modification, are permitted provided that the following conditions
+ *   are met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in
+ *       the documentation and/or other materials provided with the
+ *       distribution.
+ *     * Neither the name of Intel Corporation nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _RTE_MEMPOOL_INTERNAL_H_
+#define _RTE_MEMPOOL_INTERNAL_H_
+
+#include <rte_spinlock.h>
+#include <rte_mempool.h>
+
+#define RTE_MEMPOOL_MAX_HANDLER_IDX 16
+
+struct rte_mempool_handler {
+	char name[RTE_MEMPOOL_NAMESIZE]; /**< Name of mempool handler */
+
+	rte_mempool_alloc_t alloc;
+
+	rte_mempool_get_count get_count;
+
+	rte_mempool_free_t free;
+
+	rte_mempool_put_t put;
+
+	rte_mempool_get_t get;
+} __rte_cache_aligned;
+
+struct rte_mempool_handler_list {
+	rte_spinlock_t sl;		  /**< Spinlock for add/delete. */
+
+	int32_t num_handlers;	  /**< Number of handlers that are valid. */
+
+	/* storage for all possible handlers */
+	struct rte_mempool_handler handler[RTE_MEMPOOL_MAX_HANDLER_IDX];
+};
+
+int16_t rte_mempool_register_handler(struct rte_mempool_handler *h);
+int16_t rte_get_mempool_handler_idx(const char *name);
+
+#define REGISTER_MEMPOOL_HANDLER(h) \
+static int16_t __attribute__((used)) testfn_##h(void);\
+int16_t __attribute__((constructor, used)) testfn_##h(void)\
+{\
+	return rte_mempool_register_handler(&h);\
+}
+
+#endif
diff --git a/lib/librte_mempool/rte_mempool_version.map b/lib/librte_mempool/rte_mempool_version.map
index 17151e0..589db27 100644
--- a/lib/librte_mempool/rte_mempool_version.map
+++ b/lib/librte_mempool/rte_mempool_version.map
@@ -6,6 +6,7 @@ DPDK_2.0 {
 	rte_mempool_calc_obj_size;
 	rte_mempool_count;
 	rte_mempool_create;
+	rte_mempool_create_ext;
 	rte_mempool_dump;
 	rte_mempool_list_dump;
 	rte_mempool_lookup;
-- 
2.5.0

  reply	other threads:[~2016-02-16 14:48 UTC|newest]

Thread overview: 238+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-01-26 17:25 [PATCH 0/5] add external mempool manager David Hunt
2016-01-26 17:25 ` [PATCH 1/5] mempool: add external mempool manager support David Hunt
2016-01-28 17:52   ` Jerin Jacob
2016-02-03 14:16     ` Hunt, David
2016-02-04 13:23       ` Jerin Jacob
2016-02-04 14:52   ` Olivier MATZ
2016-02-04 16:47     ` Hunt, David
2016-02-08 11:02       ` Olivier MATZ
2016-02-04 17:34     ` Hunt, David
2016-02-05  9:26       ` Olivier MATZ
2016-03-01 13:32     ` Hunt, David
2016-03-04  9:05       ` Olivier MATZ
2016-03-08 10:04         ` Hunt, David
2016-01-26 17:25 ` [PATCH 2/5] memool: add stack (lifo) based external mempool handler David Hunt
2016-02-04 15:02   ` Olivier MATZ
2016-01-26 17:25 ` [PATCH 3/5] mempool: add custom external mempool handler example David Hunt
2016-01-28 17:54   ` Jerin Jacob
2016-01-26 17:25 ` [PATCH 4/5] mempool: add autotest for external mempool custom example David Hunt
2016-01-26 17:25 ` [PATCH 5/5] mempool: allow rte_pktmbuf_pool_create switch between memool handlers David Hunt
2016-02-05 10:11   ` Olivier MATZ
2016-01-28 17:26 ` [PATCH 0/5] add external mempool manager Jerin Jacob
2016-01-29 13:40   ` Hunt, David
2016-01-29 17:16     ` Jerin Jacob
2016-02-16 14:48 ` [PATCH 0/6] " David Hunt
2016-02-16 14:48   ` David Hunt [this message]
2016-02-16 19:27     ` [dpdk-dev, 1/6] mempool: add external mempool manager support Jan Viktorin
2016-02-19 13:30     ` [PATCH " Olivier MATZ
2016-02-29 11:11       ` Hunt, David
2016-03-04  9:04         ` Olivier MATZ
2016-02-16 14:48   ` [PATCH 2/6] mempool: add stack (lifo) based external mempool handler David Hunt
2016-02-19 13:31     ` Olivier MATZ
2016-02-29 11:04       ` Hunt, David
2016-03-04  9:04         ` Olivier MATZ
2016-03-08 20:45       ` Venkatesan, Venky
2016-03-09 14:53         ` Olivier MATZ
2016-02-16 14:48   ` [PATCH 3/6] mempool: adds a simple ring-based mempool handler using mallocs for objects David Hunt
2016-02-16 14:48   ` [PATCH 4/6] mempool: add autotest for external mempool custom example David Hunt
2016-02-16 14:48   ` [PATCH 5/6] mempool: allow rte_pktmbuf_pool_create switch between memool handlers David Hunt
2016-02-16 14:48   ` [PATCH 6/6] mempool: add in the RTE_NEXT_ABI protection for ABI breakages David Hunt
2016-02-19 13:33     ` Olivier MATZ
2016-02-19 13:25   ` [PATCH 0/6] external mempool manager Olivier MATZ
2016-02-29 10:55     ` Hunt, David
2016-03-09  9:50   ` [PATCH v3 0/4] " David Hunt
2016-03-09  9:50     ` [PATCH v3 1/4] mempool: add external mempool manager support David Hunt
2016-04-11 22:52       ` Yuanhan Liu
2016-03-09  9:50     ` [PATCH v3 2/4] mempool: add custom mempool handler example David Hunt
2016-03-09  9:50     ` [PATCH v3 3/4] mempool: allow rte_pktmbuf_pool_create switch between memool handlers David Hunt
2016-03-09 10:54       ` Panu Matilainen
2016-03-09 11:38         ` Hunt, David
2016-03-09 11:44           ` Panu Matilainen
2016-03-09  9:50     ` [PATCH v3 4/4] mempool: add in the RTE_NEXT_ABI for ABI breakages David Hunt
2016-03-09 10:46       ` Panu Matilainen
2016-03-09 11:30         ` Hunt, David
2016-03-09 14:59           ` Olivier MATZ
2016-03-09 16:28             ` Hunt, David
2016-03-09 16:31               ` Olivier MATZ
2016-03-09 16:39                 ` Hunt, David
2016-03-09 11:10     ` [PATCH v3 0/4] external mempool manager Hunt, David
2016-04-11 22:46     ` Yuanhan Liu
2016-04-14 13:57     ` [PATCH v4 0/3] " Olivier Matz
2016-04-14 13:57       ` [PATCH v4 1/3] mempool: support external handler Olivier Matz
2016-04-14 13:57       ` [PATCH v4 2/3] app/test: test external mempool handler Olivier Matz
2016-04-14 13:57       ` [PATCH v4 3/3] mbuf: get default mempool handler from configuration Olivier Matz
2016-05-19 13:44       ` mempool: external mempool manager David Hunt
2016-05-19 13:44         ` [PATCH v5 1/3] mempool: support external handler David Hunt
2016-05-23 12:35           ` [dpdk-dev,v5,1/3] " Jan Viktorin
2016-05-24 14:04             ` Hunt, David
2016-05-31  9:09             ` Hunt, David
2016-05-31 12:06               ` Jan Viktorin
2016-05-31 13:47                 ` Hunt, David
2016-05-31 20:40                   ` Olivier MATZ
2016-06-01  9:39                     ` Hunt, David
2016-06-01 12:30                     ` Jan Viktorin
2016-05-24 15:35           ` [PATCH v5 1/3] " Jerin Jacob
2016-05-27  9:52             ` Hunt, David
2016-05-27 10:33               ` Jerin Jacob
2016-05-27 14:44                 ` Hunt, David
2016-05-30  9:41                   ` Jerin Jacob
2016-05-30 11:27                     ` Hunt, David
2016-05-31  8:53                       ` Jerin Jacob
2016-05-31 15:37                         ` Hunt, David
2016-05-31 16:03                           ` Jerin Jacob
2016-05-31 20:41                             ` Olivier MATZ
2016-05-31 21:11                               ` Jerin Jacob
2016-06-01 10:46                                 ` Hunt, David
2016-06-01 11:18                                   ` Jerin Jacob
2016-05-19 13:45         ` [PATCH v5 2/3] app/test: test external mempool handler David Hunt
2016-05-23 12:45           ` [dpdk-dev, v5, " Jan Viktorin
2016-05-31  9:17             ` Hunt, David
2016-05-31 12:14               ` Jan Viktorin
2016-05-31 20:40                 ` Olivier MATZ
2016-05-19 13:45         ` [PATCH v5 3/3] mbuf: get default mempool handler from configuration David Hunt
2016-05-23 12:40           ` [dpdk-dev, v5, " Jan Viktorin
2016-05-31  9:26             ` Hunt, David
2016-06-01 16:19         ` [PATCH v6 0/5] mempool: add external mempool manager David Hunt
2016-06-01 16:19           ` [PATCH v6 1/5] mempool: support external handler David Hunt
2016-06-01 16:29             ` Hunt, David
2016-06-01 17:54             ` Jan Viktorin
2016-06-02  9:11               ` Hunt, David
2016-06-02 11:23               ` Hunt, David
2016-06-02 13:43                 ` Jan Viktorin
2016-06-01 16:19           ` [PATCH v6 2/5] mempool: remove rte_ring from rte_mempool struct David Hunt
2016-06-01 16:19           ` [PATCH v6 3/5] mempool: add default external mempool handler David Hunt
2016-06-01 16:19           ` [PATCH v6 4/5] app/test: test " David Hunt
2016-06-01 16:19           ` [PATCH v6 5/5] mbuf: get default mempool handler from configuration David Hunt
2016-06-02 13:27           ` [PATCH v7 0/5] mempool: add external mempool manager David Hunt
2016-06-02 13:27             ` [PATCH v7 1/5] mempool: support external mempool operations David Hunt
2016-06-02 13:38               ` [PATCH v7 0/5] mempool: add external mempool manager Hunt, David
2016-06-03  6:38               ` [PATCH v7 1/5] mempool: support external mempool operations Jerin Jacob
2016-06-03 10:28                 ` Hunt, David
2016-06-03 10:49                   ` Jerin Jacob
2016-06-03 11:07                   ` Olivier MATZ
2016-06-03 11:42                     ` Jan Viktorin
2016-06-03 12:10                     ` Hunt, David
2016-06-03 12:28               ` Olivier MATZ
2016-06-02 13:27             ` [PATCH v7 2/5] mempool: remove rte_ring from rte_mempool struct David Hunt
2016-06-03 12:28               ` Olivier MATZ
2016-06-03 14:17                 ` Hunt, David
2016-06-02 13:27             ` [PATCH v7 3/5] mempool: add default external mempool ops David Hunt
2016-06-02 13:27             ` [PATCH v7 4/5] app/test: test external mempool manager David Hunt
2016-06-02 13:27             ` [PATCH v7 5/5] mbuf: allow apps to change default mempool ops David Hunt
2016-06-03 12:28               ` Olivier MATZ
2016-06-03 14:06                 ` Hunt, David
2016-06-03 14:10                   ` Olivier Matz
2016-06-03 14:14                     ` Hunt, David
2016-06-03 14:58             ` [PATCH v8 0/5] mempool: add external mempool manager David Hunt
2016-06-03 14:58               ` [PATCH v8 1/3] mempool: support external mempool operations David Hunt
2016-06-06 14:32                 ` Shreyansh Jain
2016-06-06 14:38                 ` Shreyansh Jain
2016-06-07  9:25                   ` Hunt, David
2016-06-08 13:48                     ` Shreyansh Jain
2016-06-09  9:39                       ` Hunt, David
2016-06-09 10:31                         ` Jerin Jacob
2016-06-09 11:06                           ` Hunt, David
2016-06-09 11:49                           ` Shreyansh Jain
2016-06-09 12:30                             ` Jerin Jacob
2016-06-09 13:03                               ` Shreyansh Jain
2016-06-09 13:18                               ` Hunt, David
2016-06-09 13:37                                 ` Jerin Jacob
2016-06-09 11:41                         ` Shreyansh Jain
2016-06-09 12:55                           ` Hunt, David
2016-06-09 13:09                         ` Jan Viktorin
2016-06-10  7:29                           ` Olivier Matz
2016-06-10  8:49                             ` Jan Viktorin
2016-06-10  9:02                               ` Hunt, David
2016-06-10  9:34                             ` Hunt, David
2016-06-10 11:29                               ` Shreyansh Jain
2016-06-10 11:13                             ` Jerin Jacob
2016-06-10 11:37                             ` Shreyansh Jain
2016-06-07  9:05                 ` Shreyansh Jain
2016-06-08 12:13                 ` Olivier Matz
2016-06-09 10:33                   ` Hunt, David
2016-06-08 14:28                 ` Shreyansh Jain
2016-06-03 14:58               ` [PATCH v8 2/3] app/test: test external mempool manager David Hunt
2016-06-03 14:58               ` [PATCH v8 3/3] mbuf: make default mempool ops configurable at build David Hunt
2016-06-10 15:16               ` [PATCH v9 0/3] mempool: add external mempool manager David Hunt
2016-06-10 15:16                 ` [PATCH v9 1/3] mempool: support external mempool operations David Hunt
2016-06-13 12:16                   ` Olivier Matz
2016-06-13 13:46                     ` Hunt, David
2016-06-10 15:16                 ` [PATCH v9 2/3] app/test: test external mempool manager David Hunt
2016-06-10 15:16                 ` [PATCH v9 3/3] mbuf: make default mempool ops configurable at build David Hunt
2016-06-14  9:46                 ` [PATCH v10 0/3] mempool: add external mempool manager David Hunt
2016-06-14  9:46                   ` [PATCH v10 1/3] mempool: support external mempool operations David Hunt
2016-06-14 11:38                     ` Shreyansh Jain
2016-06-14 12:55                     ` Thomas Monjalon
2016-06-14 13:20                       ` Hunt, David
2016-06-14 13:29                         ` Thomas Monjalon
2016-06-14  9:46                   ` [PATCH v10 2/3] app/test: test external mempool manager David Hunt
2016-06-14 11:39                     ` Shreyansh Jain
2016-06-14  9:46                   ` [PATCH v10 3/3] mbuf: make default mempool ops configurable at build David Hunt
2016-06-14 11:45                     ` Shreyansh Jain
2016-06-14 12:32                   ` [PATCH v10 0/3] mempool: add external mempool manager Olivier MATZ
2016-06-14 15:48                   ` [PATCH v11 " David Hunt
2016-06-14 15:48                     ` [PATCH v11 1/3] mempool: support external mempool operations David Hunt
2016-06-14 16:08                       ` Thomas Monjalon
2016-06-14 15:49                     ` [PATCH v11 2/3] app/test: test external mempool manager David Hunt
2016-06-14 15:49                     ` [PATCH v11 3/3] mbuf: make default mempool ops configurable at build David Hunt
2016-06-15  7:47                     ` [PATCH v12 0/3] mempool: add external mempool manager David Hunt
2016-06-15  7:47                       ` [PATCH v12 1/3] mempool: support external mempool operations David Hunt
2016-06-15 10:14                         ` Jan Viktorin
2016-06-15 10:29                           ` Hunt, David
2016-06-15 11:26                             ` Jan Viktorin
2016-06-15 11:38                             ` Thomas Monjalon
2016-06-15  7:47                       ` [PATCH v12 2/3] app/test: test external mempool manager David Hunt
2016-06-15  7:47                       ` [PATCH v12 3/3] mbuf: make default mempool ops configurable at build David Hunt
2016-06-15 10:13                       ` [PATCH v12 0/3] mempool: add external mempool manager Jan Viktorin
2016-06-15 11:47                         ` Hunt, David
2016-06-15 12:03                           ` Olivier MATZ
2016-06-15 12:38                             ` Hunt, David
2016-06-15 13:50                               ` Olivier MATZ
2016-06-15 14:02                                 ` Hunt, David
2016-06-15 14:10                                   ` Olivier MATZ
2016-06-15 14:47                                     ` Jan Viktorin
2016-06-15 16:03                                       ` Hunt, David
2016-06-15 16:34                             ` Hunt, David
2016-06-15 16:40                               ` Olivier MATZ
2016-06-16  4:35                                 ` Shreyansh Jain
2016-06-16  7:04                                   ` Hunt, David
2016-06-16  7:47                                 ` Hunt, David
2016-06-16  8:47                                   ` Olivier MATZ
2016-06-16  8:55                                     ` Hunt, David
2016-06-16  8:58                                       ` Olivier MATZ
2016-06-16 11:34                                         ` Hunt, David
2016-06-16 12:30                       ` [PATCH v13 " David Hunt
2016-06-16 12:30                         ` [PATCH v13 1/3] mempool: support external mempool operations David Hunt
2016-06-17  6:58                           ` Hunt, David
2016-06-17  8:08                             ` Olivier Matz
2016-06-17  8:42                               ` Hunt, David
2016-06-17  9:09                                 ` Thomas Monjalon
2016-06-17  9:24                                   ` Hunt, David
2016-06-17 10:19                                     ` Olivier Matz
2016-06-17 10:18                           ` Olivier Matz
2016-06-17 10:47                             ` Hunt, David
2016-06-16 12:30                         ` [PATCH v13 2/3] app/test: test external mempool manager David Hunt
2016-06-16 12:30                         ` [PATCH v13 3/3] mbuf: make default mempool ops configurable at build David Hunt
2016-06-17 13:53                         ` [PATCH v14 0/3] mempool: add mempool handler feature David Hunt
2016-06-17 13:53                           ` [PATCH v14 1/3] mempool: support mempool handler operations David Hunt
2016-06-17 14:35                             ` Jan Viktorin
2016-06-19 11:44                               ` Hunt, David
2016-06-17 13:53                           ` [PATCH v14 2/3] app/test: test mempool handler David Hunt
2016-06-17 14:37                             ` Jan Viktorin
2016-06-17 13:53                           ` [PATCH v14 3/3] mbuf: make default mempool ops configurable at build David Hunt
2016-06-17 14:41                             ` Jan Viktorin
2016-06-19 12:05                           ` [PATCH v15 0/3] mempool: add mempool handler feature David Hunt
2016-06-19 12:05                             ` [PATCH v15 1/3] mempool: support mempool handler operations David Hunt
2016-06-19 12:05                             ` [PATCH v15 2/3] app/test: test mempool handler David Hunt
2016-06-19 12:05                             ` [PATCH v15 3/3] mbuf: make default mempool ops configurable at build David Hunt
2016-06-22  7:56                             ` [PATCH v15 0/3] mempool: add mempool handler feature Thomas Monjalon
2016-06-22  8:02                               ` Thomas Monjalon
2016-06-22  9:27                             ` [PATCH v16 " David Hunt
2016-06-22  9:27                               ` [PATCH v16 1/3] mempool: support mempool handler operations David Hunt
2016-06-22  9:27                               ` [PATCH v16 2/3] app/test: test mempool handler David Hunt
2016-06-22  9:27                               ` [PATCH v16 3/3] mbuf: make default mempool ops configurable at build David Hunt
2016-06-23 21:22                               ` [PATCH v16 0/3] mempool: add mempool handler feature Thomas Monjalon
2016-06-24  4:55                                 ` Wiles, Keith
2016-06-24 11:20                                   ` Jan Viktorin
2016-06-24 11:24                                     ` Thomas Monjalon
2016-06-24 13:10                                       ` Jan Viktorin

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1455634095-4183-2-git-send-email-david.hunt@intel.com \
    --to=david.hunt@intel.com \
    --cc=dev@dpdk.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.