diff --git a/lib/librte_mempool/rte_mempool.h b/lib/librte_mempool/rte_mempool.h
index c90cf31..2709b9e 100644
--- a/lib/librte_mempool/rte_mempool.h
+++ b/lib/librte_mempool/rte_mempool.h
@@ -50,6 +50,7 @@
 #include <rte_ring.h>
 #include <rte_memcpy.h>
 #include <rte_common.h>
+#include <rte_init.h>
 
 #ifdef __cplusplus
 extern "C" {
@@ -678,7 +679,6 @@ struct rte_mempool_ops {
  */
 struct rte_mempool_ops_table {
 	rte_spinlock_t sl;     /**< Spinlock for add/delete. */
-	uint32_t num_ops;      /**< Number of used ops structs in the table. */
 	/**
 	 * Storage for all possible ops structs.
 	 */
@@ -910,6 +910,30 @@ int rte_mempool_ops_get_info(const struct rte_mempool *mp,
  */
 int rte_mempool_register_ops(const struct rte_mempool_ops *ops);
 
+struct rte_mempool_shared_ops {
+	size_t num_mempool_ops;
+	struct {
+		char name[RTE_MEMPOOL_OPS_NAMESIZE];
+	} mempool_ops[RTE_MEMPOOL_MAX_OPS_IDX];
+
+	rte_spinlock_t mempool;
+};
+
+static inline int
+mempool_ops_register_cb(const void *arg)
+{
+	const struct rte_mempool_ops *h = (const struct rte_mempool_ops *)arg;
+
+	return rte_mempool_register_ops(h);
+}
+
+static inline void
+mempool_ops_register(const struct rte_mempool_ops *ops)
+{
+	rte_init_register(mempool_ops_register_cb, (const void *)ops,
+			  RTE_INIT_PRE);
+}
+
 /**
  * Macro to statically register the ops of a mempool handler.
  * Note that the rte_mempool_register_ops fails silently here when
@@ -918,7 +942,7 @@ int rte_mempool_ops_get_info(const struct rte_mempool *mp,
 #define MEMPOOL_REGISTER_OPS(ops)				\
 	RTE_INIT(mp_hdlr_init_##ops)				\
 	{							\
-		rte_mempool_register_ops(&ops);			\
+		mempool_ops_register(&ops);			\
 	}
 
 /**
diff --git a/lib/librte_mempool/rte_mempool_ops.c b/lib/librte_mempool/rte_mempool_ops.c
index 22c5251..bc01964 100644
--- a/lib/librte_mempool/rte_mempool_ops.c
+++ b/lib/librte_mempool/rte_mempool_ops.c
@@ -14,43 +14,95 @@
 /* indirect jump table to support external memory pools. */
 struct rte_mempool_ops_table rte_mempool_ops_table = {
 	.sl =  RTE_SPINLOCK_INITIALIZER,
-	.num_ops = 0
 };
 
-/* add a new ops struct in rte_mempool_ops_table, return its index. */
-int
-rte_mempool_register_ops(const struct rte_mempool_ops *h)
+static int
+rte_mempool_register_shared_ops(const char *name)
 {
-	struct rte_mempool_ops *ops;
-	int16_t ops_index;
+	static bool mempool_shared_ops_inited = false;
+	struct rte_mempool_shared_ops *shared_ops;
+	const struct rte_memzone *mz;
+	uint32_t ops_index = 0;
+
+	if (rte_eal_process_type() == RTE_PROC_PRIMARY &&
+	    !mempool_shared_ops_inited) {
+
+		mz = rte_memzone_reserve("mempool_ops_shared",
+					 sizeof(*shared_ops), 0, 0);
+		if (mz == NULL)
+			return -ENOMEM;
+
+		shared_ops = mz->addr;
+		shared_ops->num_mempool_ops = 0;
+		rte_spinlock_init(&shared_ops->mempool);
+
+		mempool_shared_ops_inited = true;
+	} else {
+		mz = rte_memzone_lookup("mempool_ops_shared");
+		if (mz == NULL)
+			return -ENOMEM;
+
+		shared_ops = mz->addr;
+	}
 
-	rte_spinlock_lock(&rte_mempool_ops_table.sl);
+	rte_spinlock_lock(&shared_ops->mempool);
 
-	if (rte_mempool_ops_table.num_ops >=
-			RTE_MEMPOOL_MAX_OPS_IDX) {
-		rte_spinlock_unlock(&rte_mempool_ops_table.sl);
+	if (shared_ops->num_mempool_ops >= RTE_MEMPOOL_MAX_OPS_IDX) {
+		rte_spinlock_unlock(&shared_ops->mempool);
 		RTE_LOG(ERR, MEMPOOL,
 			"Maximum number of mempool ops structs exceeded\n");
 		return -ENOSPC;
 	}
 
+	while (shared_ops->mempool_ops[ops_index].name[0]) {
+		if (!strcmp(name, shared_ops->mempool_ops[ops_index].name)) {
+			rte_spinlock_unlock(&shared_ops->mempool);
+			return ops_index;
+		}
+
+		ops_index++;
+	}
+
+	strlcpy(shared_ops->mempool_ops[ops_index].name, name,
+		sizeof(shared_ops->mempool_ops[0].name));
+
+	shared_ops->num_mempool_ops++;
+
+	rte_spinlock_unlock(&shared_ops->mempool);
+	return ops_index;
+}
+
+/* add a new ops struct in rte_mempool_ops_table, return its index. */
+int
+rte_mempool_register_ops(const struct rte_mempool_ops *h)
+{
+	struct rte_mempool_ops *ops;
+	int16_t ops_index;
+
 	if (h->alloc == NULL || h->enqueue == NULL ||
-			h->dequeue == NULL || h->get_count == NULL) {
-		rte_spinlock_unlock(&rte_mempool_ops_table.sl);
+	    h->dequeue == NULL || h->get_count == NULL) {
 		RTE_LOG(ERR, MEMPOOL,
 			"Missing callback while registering mempool ops\n");
+		rte_errno = EINVAL;
 		return -EINVAL;
 	}
 
 	if (strlen(h->name) >= sizeof(ops->name) - 1) {
-		rte_spinlock_unlock(&rte_mempool_ops_table.sl);
-		RTE_LOG(DEBUG, EAL, "%s(): mempool_ops <%s>: name too long\n",
-				__func__, h->name);
+		RTE_LOG(ERR, MEMPOOL,
+			"The registering  mempool_ops <%s>: name too long\n",
+			h->name);
 		rte_errno = EEXIST;
 		return -EEXIST;
 	}
 
-	ops_index = rte_mempool_ops_table.num_ops++;
+	ops_index = rte_mempool_register_shared_ops(h->name);
+	if (ops_index < 0) {
+		rte_errno = -ops_index;
+		return ops_index;
+	}
+
+	rte_spinlock_lock(&rte_mempool_ops_table.sl);
+
 	ops = &rte_mempool_ops_table.ops[ops_index];
 	strlcpy(ops->name, h->name, sizeof(ops->name));
 	ops->alloc = h->alloc;
@@ -165,9 +217,8 @@ struct rte_mempool_ops_table rte_mempool_ops_table = {
 	if (mp->flags & MEMPOOL_F_POOL_CREATED)
 		return -EEXIST;
 
-	for (i = 0; i < rte_mempool_ops_table.num_ops; i++) {
-		if (!strcmp(name,
-				rte_mempool_ops_table.ops[i].name)) {
+	for (i = 0; i < RTE_MEMPOOL_MAX_OPS_IDX; i++) {
+		if (!strcmp(name, rte_mempool_ops_table.ops[i].name)) {
 			ops = &rte_mempool_ops_table.ops[i];
 			break;
 		}
