[CLOUD-DEV,v1,2/2] linux-gen: pool: add generic pool module to mempool subsystem

Message ID 1502186408-2662-3-git-send-email-odpbot@yandex.ru
State New
Headers show
Series
  • Move pool to modular framework
Related show

Commit Message

Github ODP bot Aug. 8, 2017, 10 a.m.
From: Kevin Wang <kevin.wang@arm.com>


---
/** Email created from pull request 117 (kevinwangsk:cloud-dev)
 ** https://github.com/Linaro/odp/pull/117
 ** Patch: https://github.com/Linaro/odp/pull/117.patch
 ** Base sha: 370f93139e16633390cb28acda6296da8fee006d
 ** Merge commit sha: b2fdd36c723fee970da5c3bcd487cfd4b5eb18a9
 **/
 platform/linux-generic/Makefile.am                 |   4 +-
 platform/linux-generic/include/odp_pool_internal.h |  24 ++
 platform/linux-generic/odp_buffer.c                | 251 ++++++++++++++++
 .../linux-generic/{odp_pool.c => pool/generic.c}   | 315 +++------------------
 platform/linux-generic/pool/subsystem.c            | 220 ++++++++++++++
 5 files changed, 532 insertions(+), 282 deletions(-)
 rename platform/linux-generic/{odp_pool.c => pool/generic.c} (70%)

Patch

diff --git a/platform/linux-generic/Makefile.am b/platform/linux-generic/Makefile.am
index dec8a0f4..3360c0f1 100644
--- a/platform/linux-generic/Makefile.am
+++ b/platform/linux-generic/Makefile.am
@@ -240,9 +240,9 @@  __LIB__libodp_linux_la_SOURCES = \
 			   pktio/sysfs.c \
 			   pktio/tap.c \
 			   pktio/ring.c \
+			   pool/generic.c \
 			   pool/subsystem.c \
 			   odp_pkt_queue.c \
-			   odp_pool.c \
 			   odp_queue.c \
 			   odp_queue_if.c \
 			   odp_rwlock.c \
@@ -295,6 +295,8 @@  if HAVE_PCAP
 __LIB__libodp_linux_la_SOURCES += pktio/pcap.c
 endif
 
+pool/generic.lo: CFLAGS += -DIM_ACTIVE_MODULE
+
 # Build modular framework into odp-linux library
 modularframeworkdir = $(top_srcdir)/frameworks/modular
 noinst_HEADERS += $(modularframeworkdir)/list.h \
diff --git a/platform/linux-generic/include/odp_pool_internal.h b/platform/linux-generic/include/odp_pool_internal.h
index ebb779da..533abefc 100644
--- a/platform/linux-generic/include/odp_pool_internal.h
+++ b/platform/linux-generic/include/odp_pool_internal.h
@@ -21,11 +21,14 @@  extern "C" {
 #include <odp/api/shared_memory.h>
 #include <odp/api/ticketlock.h>
 
+#include <odp_pool_subsystem.h>
 #include <odp_buffer_internal.h>
 #include <odp_config_internal.h>
 #include <odp_ring_internal.h>
 #include <odp/api/plat/strong_types.h>
 
+#define CACHE_BURST    32
+
 typedef struct pool_cache_t {
 	uint32_t num;
 
@@ -82,6 +85,14 @@  typedef struct pool_table_t {
 
 extern pool_table_t *pool_tbl;
 
+/* Thread local variables */
+typedef struct pool_local_t {
+	pool_cache_t *cache[ODP_CONFIG_POOLS];
+	int thr_id;
+} pool_local_t;
+
+extern __thread pool_local_t local;
+
 static inline pool_t *pool_entry(uint32_t pool_idx)
 {
 	return &pool_tbl->pool[pool_idx];
@@ -109,6 +120,19 @@  static inline odp_buffer_hdr_t *pool_buf_hdl_to_hdr(pool_t *pool,
 	return buf_hdr;
 }
 
+static inline odp_pool_t pool_index_to_handle(uint32_t pool_idx)
+{
+	return _odp_cast_scalar(odp_pool_t, pool_idx);
+}
+
+static inline uint32_t pool_id_from_buf(odp_buffer_t buf)
+{
+	odp_buffer_bits_t handle;
+
+	handle.handle = buf;
+	return handle.pool_id;
+}
+
 static inline odp_buffer_hdr_t *buf_hdl_to_hdr(odp_buffer_t buf)
 {
 	odp_buffer_bits_t handle;
diff --git a/platform/linux-generic/odp_buffer.c b/platform/linux-generic/odp_buffer.c
index 88c8140b..d44ada6f 100644
--- a/platform/linux-generic/odp_buffer.c
+++ b/platform/linux-generic/odp_buffer.c
@@ -81,3 +81,254 @@  uint64_t odp_buffer_to_u64(odp_buffer_t hdl)
 {
 	return _odp_pri(hdl);
 }
+
+odp_event_type_t _odp_buffer_event_type(odp_buffer_t buf)
+{
+	return buf_hdl_to_hdr(buf)->event_type;
+}
+
+void _odp_buffer_event_type_set(odp_buffer_t buf, int ev)
+{
+	buf_hdl_to_hdr(buf)->event_type = ev;
+}
+
+int buffer_alloc_multi(pool_t *pool, odp_buffer_t buf[],
+		       odp_buffer_hdr_t *buf_hdr[], int max_num)
+{
+	ring_t *ring;
+	uint32_t mask, i;
+	pool_cache_t *cache;
+	uint32_t cache_num, num_ch, num_deq, burst;
+	odp_buffer_hdr_t *hdr;
+
+	cache = local.cache[pool->pool_idx];
+
+	cache_num = cache->num;
+	num_ch    = max_num;
+	num_deq   = 0;
+	burst     = CACHE_BURST;
+
+	if (odp_unlikely(cache_num < (uint32_t)max_num)) {
+		/* Cache does not have enough buffers */
+		num_ch  = cache_num;
+		num_deq = max_num - cache_num;
+
+		if (odp_unlikely(num_deq > CACHE_BURST))
+			burst = num_deq;
+	}
+
+	/* Get buffers from the cache */
+	for (i = 0; i < num_ch; i++) {
+		buf[i] = cache->buf[cache_num - num_ch + i];
+
+		if (odp_likely(buf_hdr != NULL))
+			buf_hdr[i] = pool_buf_hdl_to_hdr(pool, buf[i]);
+	}
+
+	/* If needed, get more from the global pool */
+	if (odp_unlikely(num_deq)) {
+		/* Temporary copy needed since odp_buffer_t is uintptr_t
+		 * and not uint32_t. */
+		uint32_t data[burst];
+
+		ring      = &pool->ring->hdr;
+		mask      = pool->ring_mask;
+		burst     = ring_deq_multi(ring, mask, data, burst);
+		cache_num = burst - num_deq;
+
+		if (odp_unlikely(burst < num_deq)) {
+			num_deq   = burst;
+			cache_num = 0;
+		}
+
+		for (i = 0; i < num_deq; i++) {
+			uint32_t idx = num_ch + i;
+
+			buf[idx] = (odp_buffer_t)(uintptr_t)data[i];
+			hdr      = pool_buf_hdl_to_hdr(pool, buf[idx]);
+			odp_prefetch(hdr);
+
+			if (odp_likely(buf_hdr != NULL))
+				buf_hdr[idx] = hdr;
+		}
+
+		/* Cache extra buffers. Cache is currently empty. */
+		for (i = 0; i < cache_num; i++)
+			cache->buf[i] = (odp_buffer_t)
+					(uintptr_t)data[num_deq + i];
+
+		cache->num = cache_num;
+	} else {
+		cache->num = cache_num - num_ch;
+	}
+
+	return num_ch + num_deq;
+}
+
+static inline void buffer_free_to_pool(uint32_t pool_id,
+				       const odp_buffer_t buf[], int num)
+{
+	pool_t *pool;
+	int i;
+	ring_t *ring;
+	uint32_t mask;
+	pool_cache_t *cache;
+	uint32_t cache_num;
+
+	cache = local.cache[pool_id];
+	pool  = pool_entry(pool_id);
+
+	/* Special case of a very large free. Move directly to
+	 * the global pool. */
+	if (odp_unlikely(num > CONFIG_POOL_CACHE_SIZE)) {
+		ring  = &pool->ring->hdr;
+		mask  = pool->ring_mask;
+		for (i = 0; i < num; i++)
+			ring_enq(ring, mask, (uint32_t)(uintptr_t)buf[i]);
+
+		return;
+	}
+
+	/* Make room into local cache if needed. Do at least burst size
+	 * transfer. */
+	cache_num = cache->num;
+
+	if (odp_unlikely((int)(CONFIG_POOL_CACHE_SIZE - cache_num) < num)) {
+		uint32_t index;
+		int burst = CACHE_BURST;
+
+		ring  = &pool->ring->hdr;
+		mask  = pool->ring_mask;
+
+		if (odp_unlikely(num > CACHE_BURST))
+			burst = num;
+
+		{
+			/* Temporary copy needed since odp_buffer_t is
+			 * uintptr_t and not uint32_t. */
+			uint32_t data[burst];
+
+			index = cache_num - burst;
+
+			for (i = 0; i < burst; i++)
+				data[i] = (uint32_t)
+					  (uintptr_t)cache->buf[index + i];
+
+			ring_enq_multi(ring, mask, data, burst);
+		}
+
+		cache_num -= burst;
+	}
+
+	for (i = 0; i < num; i++)
+		cache->buf[cache_num + i] = buf[i];
+
+	cache->num = cache_num + num;
+}
+
+void buffer_free_multi(const odp_buffer_t buf[], int num_total)
+{
+	uint32_t pool_id;
+	int num;
+	int i;
+	int first = 0;
+
+	while (1) {
+		num = 1;
+		i   = 1;
+		pool_id = pool_id_from_buf(buf[first]);
+
+		/* 'num' buffers are from the same pool */
+		if (num_total > 1) {
+			for (i = first; i < num_total; i++)
+				if (pool_id != pool_id_from_buf(buf[i]))
+					break;
+
+			num = i - first;
+		}
+
+		buffer_free_to_pool(pool_id, &buf[first], num);
+
+		if (i == num_total)
+			return;
+
+		first = i;
+	}
+}
+
+odp_buffer_t odp_buffer_alloc(odp_pool_t pool_hdl)
+{
+	odp_buffer_t buf;
+	pool_t *pool;
+	int ret;
+
+	ODP_ASSERT(ODP_POOL_INVALID != pool_hdl);
+
+	pool = pool_entry_from_hdl(pool_hdl);
+	ret = buffer_alloc_multi(pool, &buf, NULL, 1);
+
+	if (odp_likely(ret == 1))
+		return buf;
+
+	return ODP_BUFFER_INVALID;
+}
+
+int odp_buffer_alloc_multi(odp_pool_t pool_hdl, odp_buffer_t buf[], int num)
+{
+	pool_t *pool;
+
+	ODP_ASSERT(ODP_POOL_INVALID != pool_hdl);
+
+	pool = pool_entry_from_hdl(pool_hdl);
+
+	return buffer_alloc_multi(pool, buf, NULL, num);
+}
+
+void odp_buffer_free(odp_buffer_t buf)
+{
+	buffer_free_multi(&buf, 1);
+}
+
+void odp_buffer_free_multi(const odp_buffer_t buf[], int num)
+{
+	buffer_free_multi(buf, num);
+}
+
+odp_pool_t odp_buffer_pool(odp_buffer_t buf)
+{
+	uint32_t pool_id = pool_id_from_buf(buf);
+
+	return pool_index_to_handle(pool_id);
+}
+
+int seg_alloc_tail(odp_buffer_hdr_t *buf_hdr,  int segcount)
+{
+	(void)buf_hdr;
+	(void)segcount;
+	return 0;
+}
+
+void seg_free_tail(odp_buffer_hdr_t *buf_hdr, int segcount)
+{
+	(void)buf_hdr;
+	(void)segcount;
+}
+
+int odp_buffer_is_valid(odp_buffer_t buf)
+{
+	odp_buffer_bits_t handle;
+	pool_t *pool;
+
+	handle.handle = buf;
+
+	if (handle.pool_id >= ODP_CONFIG_POOLS)
+		return 0;
+
+	pool = pool_entry(handle.pool_id);
+
+	if (pool->reserved == 0)
+		return 0;
+
+	return 1;
+}
+
diff --git a/platform/linux-generic/odp_pool.c b/platform/linux-generic/pool/generic.c
similarity index 70%
rename from platform/linux-generic/odp_pool.c
rename to platform/linux-generic/pool/generic.c
index 9dba7341..0903a3bf 100644
--- a/platform/linux-generic/odp_pool.c
+++ b/platform/linux-generic/pool/generic.c
@@ -26,7 +26,6 @@ 
 #define UNLOCK(a)    _odp_ticketlock_unlock(a)
 #define LOCK_INIT(a) odp_ticketlock_init(a)
 
-#define CACHE_BURST    32
 #define RING_SIZE_MIN  (2 * CACHE_BURST)
 
 /* Define a practical limit for contiguous memory allocations */
@@ -38,29 +37,10 @@  ODP_STATIC_ASSERT(CONFIG_POOL_CACHE_SIZE > (2 * CACHE_BURST),
 ODP_STATIC_ASSERT(CONFIG_PACKET_SEG_LEN_MIN >= 256,
 		  "ODP Segment size must be a minimum of 256 bytes");
 
-/* Thread local variables */
-typedef struct pool_local_t {
-	pool_cache_t *cache[ODP_CONFIG_POOLS];
-	int thr_id;
-} pool_local_t;
-
 pool_table_t *pool_tbl;
-static __thread pool_local_t local;
-
-static inline odp_pool_t pool_index_to_handle(uint32_t pool_idx)
-{
-	return _odp_cast_scalar(odp_pool_t, pool_idx);
-}
-
-static inline uint32_t pool_id_from_buf(odp_buffer_t buf)
-{
-	odp_buffer_bits_t handle;
-
-	handle.handle = buf;
-	return handle.pool_id;
-}
+__thread pool_local_t local;
 
-int odp_pool_init_global(void)
+static int generic_pool_init_global(void)
 {
 	uint32_t i;
 	odp_shm_t shm;
@@ -92,7 +72,7 @@  int odp_pool_init_global(void)
 	return 0;
 }
 
-int odp_pool_term_global(void)
+static int generic_pool_term_global(void)
 {
 	int i;
 	pool_t *pool;
@@ -119,7 +99,7 @@  int odp_pool_term_global(void)
 	return rc;
 }
 
-int odp_pool_init_local(void)
+static int generic_pool_init_local(void)
 {
 	pool_t *pool;
 	int i;
@@ -155,7 +135,7 @@  static void flush_cache(pool_cache_t *cache, pool_t *pool)
 	cache->num = 0;
 }
 
-int odp_pool_term_local(void)
+static int generic_pool_term_local(void)
 {
 	int i;
 
@@ -508,7 +488,8 @@  static int check_params(odp_pool_param_t *params)
 	return 0;
 }
 
-odp_pool_t odp_pool_create(const char *name, odp_pool_param_t *params)
+static odp_pool_t generic_pool_create(const char *name,
+				      odp_pool_param_t *params)
 {
 	uint32_t shm_flags = 0;
 
@@ -523,7 +504,7 @@  odp_pool_t odp_pool_create(const char *name, odp_pool_param_t *params)
 	return pool_create(name, params, shm_flags);
 }
 
-int odp_pool_destroy(odp_pool_t pool_hdl)
+static int generic_pool_destroy(odp_pool_t pool_hdl)
 {
 	pool_t *pool = pool_entry_from_hdl(pool_hdl);
 	int i;
@@ -556,17 +537,7 @@  int odp_pool_destroy(odp_pool_t pool_hdl)
 	return 0;
 }
 
-odp_event_type_t _odp_buffer_event_type(odp_buffer_t buf)
-{
-	return buf_hdl_to_hdr(buf)->event_type;
-}
-
-void _odp_buffer_event_type_set(odp_buffer_t buf, int ev)
-{
-	buf_hdl_to_hdr(buf)->event_type = ev;
-}
-
-odp_pool_t odp_pool_lookup(const char *name)
+static odp_pool_t generic_pool_lookup(const char *name)
 {
 	uint32_t i;
 	pool_t *pool;
@@ -586,7 +557,7 @@  odp_pool_t odp_pool_lookup(const char *name)
 	return ODP_POOL_INVALID;
 }
 
-int odp_pool_info(odp_pool_t pool_hdl, odp_pool_info_t *info)
+static int generic_pool_info(odp_pool_t pool_hdl, odp_pool_info_t *info)
 {
 	pool_t *pool = pool_entry_from_hdl(pool_hdl);
 
@@ -599,209 +570,7 @@  int odp_pool_info(odp_pool_t pool_hdl, odp_pool_info_t *info)
 	return 0;
 }
 
-int buffer_alloc_multi(pool_t *pool, odp_buffer_t buf[],
-		       odp_buffer_hdr_t *buf_hdr[], int max_num)
-{
-	ring_t *ring;
-	uint32_t mask, i;
-	pool_cache_t *cache;
-	uint32_t cache_num, num_ch, num_deq, burst;
-	odp_buffer_hdr_t *hdr;
-
-	cache = local.cache[pool->pool_idx];
-
-	cache_num = cache->num;
-	num_ch    = max_num;
-	num_deq   = 0;
-	burst     = CACHE_BURST;
-
-	if (odp_unlikely(cache_num < (uint32_t)max_num)) {
-		/* Cache does not have enough buffers */
-		num_ch  = cache_num;
-		num_deq = max_num - cache_num;
-
-		if (odp_unlikely(num_deq > CACHE_BURST))
-			burst = num_deq;
-	}
-
-	/* Get buffers from the cache */
-	for (i = 0; i < num_ch; i++) {
-		buf[i] = cache->buf[cache_num - num_ch + i];
-
-		if (odp_likely(buf_hdr != NULL))
-			buf_hdr[i] = pool_buf_hdl_to_hdr(pool, buf[i]);
-	}
-
-	/* If needed, get more from the global pool */
-	if (odp_unlikely(num_deq)) {
-		/* Temporary copy needed since odp_buffer_t is uintptr_t
-		 * and not uint32_t. */
-		uint32_t data[burst];
-
-		ring      = &pool->ring->hdr;
-		mask      = pool->ring_mask;
-		burst     = ring_deq_multi(ring, mask, data, burst);
-		cache_num = burst - num_deq;
-
-		if (odp_unlikely(burst < num_deq)) {
-			num_deq   = burst;
-			cache_num = 0;
-		}
-
-		for (i = 0; i < num_deq; i++) {
-			uint32_t idx = num_ch + i;
-
-			buf[idx] = (odp_buffer_t)(uintptr_t)data[i];
-			hdr      = pool_buf_hdl_to_hdr(pool, buf[idx]);
-			odp_prefetch(hdr);
-
-			if (odp_likely(buf_hdr != NULL))
-				buf_hdr[idx] = hdr;
-		}
-
-		/* Cache extra buffers. Cache is currently empty. */
-		for (i = 0; i < cache_num; i++)
-			cache->buf[i] = (odp_buffer_t)
-					(uintptr_t)data[num_deq + i];
-
-		cache->num = cache_num;
-	} else {
-		cache->num = cache_num - num_ch;
-	}
-
-	return num_ch + num_deq;
-}
-
-static inline void buffer_free_to_pool(uint32_t pool_id,
-				       const odp_buffer_t buf[], int num)
-{
-	pool_t *pool;
-	int i;
-	ring_t *ring;
-	uint32_t mask;
-	pool_cache_t *cache;
-	uint32_t cache_num;
-
-	cache = local.cache[pool_id];
-	pool  = pool_entry(pool_id);
-
-	/* Special case of a very large free. Move directly to
-	 * the global pool. */
-	if (odp_unlikely(num > CONFIG_POOL_CACHE_SIZE)) {
-		ring  = &pool->ring->hdr;
-		mask  = pool->ring_mask;
-		for (i = 0; i < num; i++)
-			ring_enq(ring, mask, (uint32_t)(uintptr_t)buf[i]);
-
-		return;
-	}
-
-	/* Make room into local cache if needed. Do at least burst size
-	 * transfer. */
-	cache_num = cache->num;
-
-	if (odp_unlikely((int)(CONFIG_POOL_CACHE_SIZE - cache_num) < num)) {
-		uint32_t index;
-		int burst = CACHE_BURST;
-
-		ring  = &pool->ring->hdr;
-		mask  = pool->ring_mask;
-
-		if (odp_unlikely(num > CACHE_BURST))
-			burst = num;
-
-		{
-			/* Temporary copy needed since odp_buffer_t is
-			 * uintptr_t and not uint32_t. */
-			uint32_t data[burst];
-
-			index = cache_num - burst;
-
-			for (i = 0; i < burst; i++)
-				data[i] = (uint32_t)
-					  (uintptr_t)cache->buf[index + i];
-
-			ring_enq_multi(ring, mask, data, burst);
-		}
-
-		cache_num -= burst;
-	}
-
-	for (i = 0; i < num; i++)
-		cache->buf[cache_num + i] = buf[i];
-
-	cache->num = cache_num + num;
-}
-
-void buffer_free_multi(const odp_buffer_t buf[], int num_total)
-{
-	uint32_t pool_id;
-	int num;
-	int i;
-	int first = 0;
-
-	while (1) {
-		num = 1;
-		i   = 1;
-		pool_id = pool_id_from_buf(buf[first]);
-
-		/* 'num' buffers are from the same pool */
-		if (num_total > 1) {
-			for (i = first; i < num_total; i++)
-				if (pool_id != pool_id_from_buf(buf[i]))
-					break;
-
-			num = i - first;
-		}
-
-		buffer_free_to_pool(pool_id, &buf[first], num);
-
-		if (i == num_total)
-			return;
-
-		first = i;
-	}
-}
-
-odp_buffer_t odp_buffer_alloc(odp_pool_t pool_hdl)
-{
-	odp_buffer_t buf;
-	pool_t *pool;
-	int ret;
-
-	ODP_ASSERT(ODP_POOL_INVALID != pool_hdl);
-
-	pool = pool_entry_from_hdl(pool_hdl);
-	ret = buffer_alloc_multi(pool, &buf, NULL, 1);
-
-	if (odp_likely(ret == 1))
-		return buf;
-
-	return ODP_BUFFER_INVALID;
-}
-
-int odp_buffer_alloc_multi(odp_pool_t pool_hdl, odp_buffer_t buf[], int num)
-{
-	pool_t *pool;
-
-	ODP_ASSERT(ODP_POOL_INVALID != pool_hdl);
-
-	pool = pool_entry_from_hdl(pool_hdl);
-
-	return buffer_alloc_multi(pool, buf, NULL, num);
-}
-
-void odp_buffer_free(odp_buffer_t buf)
-{
-	buffer_free_multi(&buf, 1);
-}
-
-void odp_buffer_free_multi(const odp_buffer_t buf[], int num)
-{
-	buffer_free_multi(buf, num);
-}
-
-int odp_pool_capability(odp_pool_capability_t *capa)
+static int generic_pool_capability(odp_pool_capability_t *capa)
 {
 	uint32_t max_seg_len = CONFIG_PACKET_MAX_SEG_LEN;
 
@@ -833,7 +602,7 @@  int odp_pool_capability(odp_pool_capability_t *capa)
 	return 0;
 }
 
-void odp_pool_print(odp_pool_t pool_hdl)
+static void generic_pool_print(odp_pool_t pool_hdl)
 {
 	pool_t *pool;
 
@@ -869,50 +638,34 @@  void odp_pool_print(odp_pool_t pool_hdl)
 	printf("\n");
 }
 
-odp_pool_t odp_buffer_pool(odp_buffer_t buf)
-{
-	uint32_t pool_id = pool_id_from_buf(buf);
-
-	return pool_index_to_handle(pool_id);
-}
-
-void odp_pool_param_init(odp_pool_param_t *params)
+static void generic_pool_param_init(odp_pool_param_t *params)
 {
 	memset(params, 0, sizeof(odp_pool_param_t));
 }
 
-uint64_t odp_pool_to_u64(odp_pool_t hdl)
+static uint64_t generic_pool_to_u64(odp_pool_t hdl)
 {
 	return _odp_pri(hdl);
 }
 
-int seg_alloc_tail(odp_buffer_hdr_t *buf_hdr,  int segcount)
-{
-	(void)buf_hdr;
-	(void)segcount;
-	return 0;
-}
-
-void seg_free_tail(odp_buffer_hdr_t *buf_hdr, int segcount)
-{
-	(void)buf_hdr;
-	(void)segcount;
-}
-
-int odp_buffer_is_valid(odp_buffer_t buf)
-{
-	odp_buffer_bits_t handle;
-	pool_t *pool;
-
-	handle.handle = buf;
-
-	if (handle.pool_id >= ODP_CONFIG_POOLS)
-		return 0;
-
-	pool = pool_entry(handle.pool_id);
-
-	if (pool->reserved == 0)
-		return 0;
-
-	return 1;
+pool_module_t generic_pool = {
+	.base.name = "generic_pool",
+	.base.init_global = generic_pool_init_global,
+	.base.init_local = generic_pool_init_local,
+	.base.term_global = generic_pool_term_global,
+	.base.term_local = generic_pool_term_local,
+	.capability = generic_pool_capability,
+	.create = generic_pool_create,
+	.destroy = generic_pool_destroy,
+	.lookup = generic_pool_lookup,
+	.info = generic_pool_info,
+	.print = generic_pool_print,
+	.to_u64 = generic_pool_to_u64,
+	.param_init = generic_pool_param_init,
+};
+
+ODP_MODULE_CONSTRUCTOR(generic_pool)
+{
+	odp_module_constructor(&generic_pool);
+	odp_subsystem_register_module(pool, &generic_pool);
 }
diff --git a/platform/linux-generic/pool/subsystem.c b/platform/linux-generic/pool/subsystem.c
index 35600399..3a9fb275 100644
--- a/platform/linux-generic/pool/subsystem.c
+++ b/platform/linux-generic/pool/subsystem.c
@@ -5,6 +5,10 @@ 
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
+#include <odp/api/pool.h>
+#include <odp_internal.h>
+#include <odp_pool_subsystem.h>
+#include <odp_debug_internal.h>
 #include <odp_module.h>
 
 #define SUBSYSTEM_VERSION 0x00010000UL
@@ -14,3 +18,219 @@  ODP_SUBSYSTEM_CONSTRUCTOR(pool)
 {
 	odp_subsystem_constructor(pool);
 }
+
+int odp_pool_init_global(void)
+{
+	pool_module_t *mod;
+
+	mod = odp_subsystem_active_module(pool, mod);
+	if (mod == NULL) {
+		ODP_ERR("No active module in pool subsystem\n");
+		return -1;
+	}
+	if (mod->base.init_global == NULL) {
+		ODP_ERR("No defined init_global function "
+			"in module %s of pool subsystem\n", mod->base.name);
+		return -1;
+	}
+
+	return mod->base.init_global();
+}
+
+int odp_pool_term_global(void)
+{
+	pool_module_t *mod;
+
+	mod = odp_subsystem_active_module(pool, mod);
+	if (mod == NULL) {
+		ODP_ERR("No active module in pool subsystem\n");
+		return -1;
+	}
+	if (mod->base.term_global == NULL) {
+		ODP_ERR("No defined term_global function "
+			"in module %s of pool subsystem\n", mod->base.name);
+		return -1;
+	}
+
+	return mod->base.term_global();
+}
+
+int odp_pool_init_local(void)
+{
+	pool_module_t *mod;
+
+	mod = odp_subsystem_active_module(pool, mod);
+	if (mod == NULL) {
+		ODP_ERR("No active module in pool subsystem\n");
+		return -1;
+	}
+	if (mod->base.term_global == NULL) {
+		ODP_ERR("No defined init_local function "
+			"in module %s of pool subsystem\n", mod->base.name);
+		return -1;
+	}
+
+	return mod->base.init_local();
+}
+
+int odp_pool_term_local(void)
+{
+	pool_module_t *mod;
+
+	mod = odp_subsystem_active_module(pool, mod);
+	if (mod == NULL) {
+		ODP_ERR("No active module in pool subsystem\n");
+		return -1;
+	}
+	if (mod->base.term_local == NULL) {
+		ODP_ERR("No defined term_local function "
+			"in module %s of pool subsystem\n", mod->base.name);
+		return -1;
+	}
+
+	return mod->base.term_local();
+}
+
+int odp_pool_capability(odp_pool_capability_t *capa)
+{
+	pool_module_t *mod;
+
+	mod = odp_subsystem_active_module(pool, mod);
+	if (mod == NULL) {
+		ODP_ERR("No active module in pool subsystem\n");
+		return -1;
+	}
+	if (mod->capability == NULL) {
+		ODP_ERR("No defined capability function "
+			"in module %s of pool subsystem\n", mod->base.name);
+		return -1;
+	}
+
+	return mod->capability(capa);
+}
+
+odp_pool_t odp_pool_create(const char *name, odp_pool_param_t *params)
+{
+	pool_module_t *mod;
+
+	mod = odp_subsystem_active_module(pool, mod);
+	if (mod == NULL) {
+		ODP_ERR("No active module in pool subsystem\n");
+		return ODP_POOL_INVALID;
+	}
+	if (mod->create == NULL) {
+		ODP_ERR("No defined create function "
+			"in module %s of pool subsystem\n", mod->base.name);
+		return ODP_POOL_INVALID;
+	}
+
+	return mod->create(name, params);
+}
+
+int odp_pool_destroy(odp_pool_t pool_hdl)
+{
+	pool_module_t *mod;
+
+	mod = odp_subsystem_active_module(pool, mod);
+	if (mod == NULL) {
+		ODP_ERR("No active module in pool subsystem\n");
+		return -1;
+	}
+	if (mod->destroy == NULL) {
+		ODP_ERR("No defined destroy function "
+			"in module %s of pool subsystem\n", mod->base.name);
+		return -1;
+	}
+
+	return mod->destroy(pool_hdl);
+}
+
+odp_pool_t odp_pool_lookup(const char *name)
+{
+	pool_module_t *mod;
+
+	mod = odp_subsystem_active_module(pool, mod);
+	if (mod == NULL) {
+		ODP_ERR("No active module in pool subsystem\n");
+		return ODP_POOL_INVALID;
+	}
+	if (mod->lookup == NULL) {
+		ODP_ERR("No defined lookup function "
+			"in module %s of pool subsystem\n", mod->base.name);
+		return ODP_POOL_INVALID;
+	}
+
+	return mod->lookup(name);
+}
+
+int odp_pool_info(odp_pool_t pool_hdl, odp_pool_info_t *info)
+{
+	pool_module_t *mod;
+
+	mod = odp_subsystem_active_module(pool, mod);
+	if (mod == NULL) {
+		ODP_ERR("No active module in pool subsystem\n");
+		return -1;
+	}
+	if (mod->info == NULL) {
+		ODP_ERR("No defined info function "
+			"in module %s of pool subsystem\n", mod->base.name);
+		return -1;
+	}
+
+	return mod->info(pool_hdl, info);
+}
+
+void odp_pool_print(odp_pool_t pool_hdl)
+{
+	pool_module_t *mod;
+
+	mod = odp_subsystem_active_module(pool, mod);
+	if (mod == NULL) {
+		ODP_ERR("No active module in pool subsystem\n");
+		return;
+	}
+	if (mod->print == NULL) {
+		ODP_ERR("No defined print function "
+			"in module %s of pool subsystem\n", mod->base.name);
+		return;
+	}
+
+	mod->print(pool_hdl);
+}
+
+void odp_pool_param_init(odp_pool_param_t *params)
+{
+	pool_module_t *mod;
+
+	mod = odp_subsystem_active_module(pool, mod);
+	if (mod == NULL) {
+		ODP_ERR("No active module in pool subsystem\n");
+		return;
+	}
+	if (mod->param_init == NULL) {
+		ODP_ERR("No defined param_init function "
+			"in module %s of pool subsystem\n", mod->base.name);
+		return;
+	}
+
+	mod->param_init(params);
+}
+
+uint64_t odp_pool_to_u64(odp_pool_t hdl)
+{
+	pool_module_t *mod;
+
+	mod = odp_subsystem_active_module(pool, mod);
+	if (mod == NULL) {
+		ODP_ERR("No active module in pool subsystem\n");
+		return -1;
+	}
+	if (mod->to_u64 == NULL) {
+		ODP_ERR("No defined to_u64 function "
+			"in module %s of pool subsystem\n", mod->base.name);
+		return -1;
+	}
+
+	return mod->to_u64(hdl);
+}