diff --git a/include/spdk/env.h b/include/spdk/env.h index 4ce5dc138..dd2c97d07 100644 --- a/include/spdk/env.h +++ b/include/spdk/env.h @@ -85,6 +85,36 @@ spdk_memzone_lookup(const char *name); int spdk_memzone_free(const char *name); +struct spdk_mempool; + +/** + * Create a thread-safe memory pool. Cache size is the number of + * elements in a thread-local cache. Can be 0 for no caching, or -1 + * for unspecified. + */ +struct spdk_mempool * +spdk_mempool_create(const char *name, size_t count, + size_t ele_size, size_t cache_size); + +/** + * Free a memory pool. + */ +void +spdk_mempool_free(struct spdk_mempool *mp); + +/** + * Get an element from a memory pool. If no elements remain, return NULL. + */ +void * +spdk_mempool_get(struct spdk_mempool *mp); + +/** + * Put an element back into the memory pool. + */ +void +spdk_mempool_put(struct spdk_mempool *mp, void *ele); + + /** * Return true if the calling process is primary process */ diff --git a/lib/env/env.c b/lib/env/env.c index 21bfd7f8d..2ba21f1b6 100644 --- a/lib/env/env.c +++ b/lib/env/env.c @@ -40,6 +40,7 @@ #include #include #include +#include void * spdk_zmalloc(size_t size, size_t align, uint64_t *phys_addr) @@ -94,6 +95,54 @@ spdk_memzone_free(const char *name) return -1; } +struct spdk_mempool * +spdk_mempool_create(const char *name, size_t count, + size_t ele_size, size_t cache_size) +{ + struct rte_mempool *mp; + size_t tmp; + + /* No more than half of all elements can be in cache */ + tmp = (count / 2) / rte_lcore_count(); + if (cache_size > tmp) { + cache_size = tmp; + } + + if (cache_size > RTE_MEMPOOL_CACHE_MAX_SIZE) { + cache_size = RTE_MEMPOOL_CACHE_MAX_SIZE; + } + + mp = rte_mempool_create(name, count, ele_size, cache_size, + 0, NULL, NULL, NULL, NULL, + SOCKET_ID_ANY, 0); + + return (struct spdk_mempool *)mp; +} + +void +spdk_mempool_free(struct spdk_mempool *mp) +{ +#if RTE_VERSION >= RTE_VERSION_NUM(16, 7, 0, 1) + rte_mempool_free((struct rte_mempool *)mp); +#endif +} + +void * +spdk_mempool_get(struct spdk_mempool *mp) +{ + void *ele = NULL; + + rte_mempool_get((struct rte_mempool *)mp, &ele); + + return ele; +} + +void +spdk_mempool_put(struct spdk_mempool *mp, void *ele) +{ + rte_mempool_put((struct rte_mempool *)mp, ele); +} + bool spdk_process_is_primary(void) { diff --git a/lib/nvme/nvme.c b/lib/nvme/nvme.c index 900bcf92d..238b99083 100644 --- a/lib/nvme/nvme.c +++ b/lib/nvme/nvme.c @@ -100,7 +100,7 @@ nvme_allocate_request(const struct nvme_payload *payload, uint32_t payload_size, { struct nvme_request *req = NULL; - nvme_mempool_get(g_spdk_nvme_driver->request_mempool, (void **)&req); + req = nvme_mempool_get(g_spdk_nvme_driver->request_mempool); if (req == NULL) { return req; } @@ -280,7 +280,7 @@ spdk_nvme_probe(void *cb_ctx, spdk_nvme_probe_cb probe_cb, spdk_nvme_attach_cb a if (g_spdk_nvme_driver->request_mempool == NULL) { g_spdk_nvme_driver->request_mempool = nvme_mempool_create("nvme_request", 8192, - sizeof(struct nvme_request), 128); + sizeof(struct nvme_request), -1); if (g_spdk_nvme_driver->request_mempool == NULL) { SPDK_ERRLOG("Unable to allocate pool of requests\n"); pthread_mutex_unlock(&g_spdk_nvme_driver->lock); diff --git a/lib/nvme/nvme_impl.h b/lib/nvme/nvme_impl.h index 2135bd7e0..79b10454e 100644 --- a/lib/nvme/nvme_impl.h +++ b/lib/nvme/nvme_impl.h @@ -115,41 +115,17 @@ #define nvme_vtophys(buf) spdk_vtophys(buf) #define NVME_VTOPHYS_ERROR SPDK_VTOPHYS_ERROR -typedef struct rte_mempool nvme_mempool_t; +typedef struct spdk_mempool nvme_mempool_t; /** * Create a mempool with the given configuration. * Return a pointer to the allocated memory address. If the allocation * cannot be done, return NULL. */ -static inline nvme_mempool_t * -nvme_mempool_create(const char *name, unsigned n, unsigned elt_size, - unsigned cache_size) -{ - struct rte_mempool *mp; - - mp = rte_mempool_create(name, n, elt_size, cache_size, - 0, NULL, NULL, NULL, NULL, - SOCKET_ID_ANY, 0); - - if (mp == NULL) { - return NULL; - } - - return (nvme_mempool_t *)mp; -} - -static inline void -nvme_mempool_get(nvme_mempool_t *mp, void **buf) -{ - rte_mempool_get(mp, buf); -} - -static inline void -nvme_mempool_put(nvme_mempool_t *mp, void *buf) -{ - rte_mempool_put(mp, buf); -} +#define nvme_mempool_create spdk_mempool_create +#define nvme_mempool_free spdk_mempool_free +#define nvme_mempool_get spdk_mempool_get +#define nvme_mempool_put spdk_mempool_put /** * Get a monotonic timestamp counter (used for measuring timeouts during initialization). diff --git a/test/lib/nvme/unit/nvme_ctrlr_c/nvme_ctrlr_ut.c b/test/lib/nvme/unit/nvme_ctrlr_c/nvme_ctrlr_ut.c index c52fc0251..e503bde74 100644 --- a/test/lib/nvme/unit/nvme_ctrlr_c/nvme_ctrlr_ut.c +++ b/test/lib/nvme/unit/nvme_ctrlr_c/nvme_ctrlr_ut.c @@ -321,7 +321,7 @@ nvme_allocate_request(const struct nvme_payload *payload, uint32_t payload_size, void *cb_arg) { struct nvme_request *req = NULL; - nvme_mempool_get(_g_nvme_driver.request_mempool, (void **)&req); + req = nvme_mempool_get(_g_nvme_driver.request_mempool); if (req != NULL) { memset(req, 0, offsetof(struct nvme_request, children)); diff --git a/test/lib/nvme/unit/nvme_impl.h b/test/lib/nvme/unit/nvme_impl.h index 3a3d0ae56..0d3331d2f 100644 --- a/test/lib/nvme/unit/nvme_impl.h +++ b/test/lib/nvme/unit/nvme_impl.h @@ -98,20 +98,24 @@ nvme_process_is_primary(void) typedef unsigned nvme_mempool_t; static inline nvme_mempool_t * -nvme_mempool_create(const char *name, unsigned n, unsigned elt_size, - unsigned cache_size) +nvme_mempool_create(const char *name, size_t n, + size_t elt_size, size_t cache_size) { static int mp; return ∓ } -static inline void -nvme_mempool_get(nvme_mempool_t *mp, void **buf) +static inline void * +nvme_mempool_get(nvme_mempool_t *mp) { - if (posix_memalign(buf, 64, 0x1000)) { - *buf = NULL; + void *buf; + + if (posix_memalign(&buf, 64, 0x1000)) { + buf = NULL; } + + return buf; } static inline void diff --git a/test/lib/nvme/unit/nvme_qpair_c/nvme_qpair_ut.c b/test/lib/nvme/unit/nvme_qpair_c/nvme_qpair_ut.c index d30ac6176..16f0647d6 100644 --- a/test/lib/nvme/unit/nvme_qpair_c/nvme_qpair_ut.c +++ b/test/lib/nvme/unit/nvme_qpair_c/nvme_qpair_ut.c @@ -132,7 +132,7 @@ nvme_allocate_request(const struct nvme_payload *payload, uint32_t payload_size, { struct nvme_request *req = NULL; - nvme_mempool_get(_g_nvme_driver.request_mempool, (void **)&req); + req = nvme_mempool_get(_g_nvme_driver.request_mempool); if (req == NULL) { return req; @@ -224,7 +224,7 @@ ut_insert_cq_entry(struct spdk_nvme_qpair *qpair, uint32_t slot) struct nvme_tracker *tr; struct spdk_nvme_cpl *cpl; - nvme_mempool_get(_g_nvme_driver.request_mempool, (void **)&req); + req = nvme_mempool_get(_g_nvme_driver.request_mempool); SPDK_CU_ASSERT_FATAL(req != NULL); memset(req, 0, sizeof(*req));