From a77cd3f75c0f348da1a4387b655e7efadc404b15 Mon Sep 17 00:00:00 2001 From: zkhatami88 Date: Fri, 23 Feb 2018 14:43:28 +0800 Subject: [PATCH] env: add malloc variants with DMA/shareable flags This will allow environment abstraction layers to provide different types of memory depending on whether it needs to be DMA-able and/or shared across multi-process boundaries. For the DPDK environment, the flags can be ignored, since rte_malloc() supports both DMA-able and shared memory. Change-Id: I5ee894337dd9d6e24418848c0a35f131184383c8 Signed-off-by: zkhatami88 Reviewed-on: https://review.gerrithub.io/402334 Reviewed-by: Daniel Verkamp Reviewed-by: Dariusz Stojaczyk Tested-by: Ben Walker Reviewed-by: Ben Walker --- CHANGELOG.md | 6 +++++ include/spdk/env.h | 56 ++++++++++++++++++++++++++++++++++++++++++++++ lib/env_dpdk/env.c | 26 +++++++++++++++++---- 3 files changed, 84 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b140ce556..bc660e553 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,6 +13,12 @@ for additional information on the DPDK vulnerability. Add wrapper for DPDK rte_mempool_get_bulk() via spdk_mempool_get_bulk(). +New memory management functions spdk_malloc(), spdk_zmalloc(), and spdk_free() have been added. +These new functions have a `flags` parameter that allows the user to specify whether the allocated +memory needs to be suitable for DMA and whether it should be shared across processes with the same +shm_id. The new functions are intended to replace spdk_dma_malloc() and related functions, which will +eventually be deprecated and removed. + ### Bdev Add new optional bdev module interface function, init_complete, to notify bdev modules diff --git a/include/spdk/env.h b/include/spdk/env.h index 81bfd29ab..bf6ba459c 100644 --- a/include/spdk/env.h +++ b/include/spdk/env.h @@ -48,6 +48,16 @@ extern "C" { #define SPDK_ENV_SOCKET_ID_ANY (-1) #define SPDK_ENV_LCORE_ID_ANY (UINT32_MAX) +/** + * Memory is dma-safe. + */ +#define SPDK_MALLOC_DMA 0x01 + +/** + * Memory is sharable across process boundries. + */ +#define SPDK_MALLOC_SHARE 0x02 + struct spdk_pci_device; /** @@ -67,6 +77,52 @@ struct spdk_env_opts { void *env_context; }; +/** + * Allocate dma/sharable memory based on a given dma_flg. It is a physically + * contiguous memory buffer with the given size, alignment and socket id. + * + * \param size Size in bytes. + * \param align Alignment value for the allocated memory. If '0', the allocated + * buffer is suitably aligned (in the same manner as malloc()). Otherwise, the + * allocated buffer is aligned to the multiple of align. In this case, it must + * be a power of two. + * \param phys_addr A pointer to the variable to hold the physical address of + * the allocated buffer is passed. If NULL, the physical address is not returned. + * \param socket_id Socket ID to allocate memory on, or SPDK_ENV_SOCKET_ID_ANY + * for any socket. + * \param flags Combination of SPDK_MALLOC flags (\ref SPDK_MALLOC_DMA, \ref SPDK_MALLOC_SHARE). + * + * \return a pointer to the allocated memory buffer. + */ +void *spdk_malloc(size_t size, size_t align, uint64_t *phys_addr, int socket_id, uint32_t flags); + +/** + * Allocate dma/sharable memory based on a given dma_flg. It is a physically + * contiguous memory buffer with the given size, alignment and socket id. + * Also, the buffer will be zeroed. + * + * \param size Size in bytes. + * \param align Alignment value for the allocated memory. If '0', the allocated + * buffer is suitably aligned (in the same manner as malloc()). Otherwise, the + * allocated buffer is aligned to the multiple of align. In this case, it must + * be a power of two. + * \param phys_addr A pointer to the variable to hold the physical address of + * the allocated buffer is passed. If NULL, the physical address is not returned. + * \param socket_id Socket ID to allocate memory on, or SPDK_ENV_SOCKET_ID_ANY + * for any socket. + * \param flags Combination of SPDK_MALLOC flags (\ref SPDK_MALLOC_DMA, \ref SPDK_MALLOC_SHARE). + * + * \return a pointer to the allocated memory buffer. + */ +void *spdk_zmalloc(size_t size, size_t align, uint64_t *phys_addr, int socket_id, uint32_t flags); + +/** + * Free buffer memory that was previously allocated with spdk_malloc() or spdk_zmalloc(). + * + * \param buf Buffer to free. + */ +void spdk_free(void *buf); + /** * Initialize the default value of opts. * diff --git a/lib/env_dpdk/env.c b/lib/env_dpdk/env.c index da7696900..93f627294 100644 --- a/lib/env_dpdk/env.c +++ b/lib/env_dpdk/env.c @@ -63,7 +63,7 @@ virt_to_phys(void *vaddr) } void * -spdk_dma_malloc_socket(size_t size, size_t align, uint64_t *phys_addr, int socket_id) +spdk_malloc(size_t size, size_t align, uint64_t *phys_addr, int socket_id, uint32_t flags) { void *buf = rte_malloc_socket(NULL, size, align, socket_id); if (buf && phys_addr) { @@ -73,15 +73,33 @@ spdk_dma_malloc_socket(size_t size, size_t align, uint64_t *phys_addr, int socke } void * -spdk_dma_zmalloc_socket(size_t size, size_t align, uint64_t *phys_addr, int socket_id) +spdk_zmalloc(size_t size, size_t align, uint64_t *phys_addr, int socket_id, uint32_t flags) { - void *buf = spdk_dma_malloc_socket(size, align, phys_addr, socket_id); + void *buf = spdk_malloc(size, align, phys_addr, socket_id, flags); if (buf) { memset(buf, 0, size); } return buf; } +void +spdk_free(void *buf) +{ + rte_free(buf); +} + +void * +spdk_dma_malloc_socket(size_t size, size_t align, uint64_t *phys_addr, int socket_id) +{ + return spdk_malloc(size, align, phys_addr, socket_id, (SPDK_MALLOC_DMA | SPDK_MALLOC_SHARE)); +} + +void * +spdk_dma_zmalloc_socket(size_t size, size_t align, uint64_t *phys_addr, int socket_id) +{ + return spdk_zmalloc(size, align, phys_addr, socket_id, (SPDK_MALLOC_DMA | SPDK_MALLOC_SHARE)); +} + void * spdk_dma_malloc(size_t size, size_t align, uint64_t *phys_addr) { @@ -107,7 +125,7 @@ spdk_dma_realloc(void *buf, size_t size, size_t align, uint64_t *phys_addr) void spdk_dma_free(void *buf) { - rte_free(buf); + spdk_free(buf); } void *