This adds a new set of _contig API's to rte_memzone. For now, hugepage memory is always contiguous, but we need to prepare the drivers for the switch.
Signed-off-by: Anatoly Burakov <anatoly.bura...@intel.com> --- Notes: v3: - Moved this patch earlier lib/librte_eal/common/eal_common_memzone.c | 44 ++++++++ lib/librte_eal/common/include/rte_memzone.h | 158 ++++++++++++++++++++++++++++ lib/librte_eal/rte_eal_version.map | 3 + 3 files changed, 205 insertions(+) diff --git a/lib/librte_eal/common/eal_common_memzone.c b/lib/librte_eal/common/eal_common_memzone.c index 16a2e7a..36d2553 100644 --- a/lib/librte_eal/common/eal_common_memzone.c +++ b/lib/librte_eal/common/eal_common_memzone.c @@ -171,6 +171,12 @@ memzone_reserve_aligned_thread_unsafe(const char *name, size_t len, socket_id = SOCKET_ID_ANY; if (len == 0) { + /* len == 0 is only allowed for non-contiguous zones */ + if (contig) { + RTE_LOG(DEBUG, EAL, "Reserving zero-length contiguous memzones is not supported\n"); + rte_errno = EINVAL; + return NULL; + } if (bound != 0) requested_len = bound; else { @@ -272,6 +278,19 @@ rte_memzone_reserve_bounded(const char *name, size_t len, int socket_id, /* * Return a pointer to a correctly filled memzone descriptor (with a + * specified alignment and boundary). If the allocation cannot be done, + * return NULL. + */ +__rte_experimental const struct rte_memzone * +rte_memzone_reserve_bounded_contig(const char *name, size_t len, int socket_id, + unsigned int flags, unsigned int align, unsigned int bound) +{ + return rte_memzone_reserve_thread_safe(name, len, socket_id, flags, + align, bound, true); +} + +/* + * Return a pointer to a correctly filled memzone descriptor (with a * specified alignment). If the allocation cannot be done, return NULL. */ const struct rte_memzone * @@ -283,6 +302,18 @@ rte_memzone_reserve_aligned(const char *name, size_t len, int socket_id, } /* + * Return a pointer to a correctly filled memzone descriptor (with a + * specified alignment). If the allocation cannot be done, return NULL. + */ +__rte_experimental const struct rte_memzone * +rte_memzone_reserve_aligned_contig(const char *name, size_t len, int socket_id, + unsigned int flags, unsigned int align) +{ + return rte_memzone_reserve_thread_safe(name, len, socket_id, flags, + align, 0, true); +} + +/* * Return a pointer to a correctly filled memzone descriptor. If the * allocation cannot be done, return NULL. */ @@ -295,6 +326,19 @@ rte_memzone_reserve(const char *name, size_t len, int socket_id, false); } +/* + * Return a pointer to a correctly filled memzone descriptor. If the + * allocation cannot be done, return NULL. + */ +__rte_experimental const struct rte_memzone * +rte_memzone_reserve_contig(const char *name, size_t len, int socket_id, + unsigned int flags) +{ + return rte_memzone_reserve_thread_safe(name, len, socket_id, + flags, RTE_CACHE_LINE_SIZE, 0, + true); +} + int rte_memzone_free(const struct rte_memzone *mz) { diff --git a/lib/librte_eal/common/include/rte_memzone.h b/lib/librte_eal/common/include/rte_memzone.h index 2bfb273..ef3a4dd 100644 --- a/lib/librte_eal/common/include/rte_memzone.h +++ b/lib/librte_eal/common/include/rte_memzone.h @@ -23,6 +23,7 @@ */ #include <stdio.h> +#include <rte_compat.h> #include <rte_memory.h> #include <rte_common.h> @@ -228,6 +229,163 @@ const struct rte_memzone *rte_memzone_reserve_bounded(const char *name, unsigned flags, unsigned align, unsigned bound); /** + * Reserve an IOVA-contiguous portion of physical memory. + * + * This function reserves some IOVA-contiguous memory and returns a pointer to a + * correctly filled memzone descriptor. If the allocation cannot be + * done, return NULL. + * + * @param name + * The name of the memzone. If it already exists, the function will + * fail and return NULL. + * @param len + * The size of the memory to be reserved. + * @param socket_id + * 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 + * The flags parameter is used to request memzones to be + * taken from specifically sized hugepages. + * - RTE_MEMZONE_2MB - Reserved from 2MB pages + * - RTE_MEMZONE_1GB - Reserved from 1GB pages + * - RTE_MEMZONE_16MB - Reserved from 16MB pages + * - RTE_MEMZONE_16GB - Reserved from 16GB pages + * - RTE_MEMZONE_256KB - Reserved from 256KB pages + * - RTE_MEMZONE_256MB - Reserved from 256MB pages + * - RTE_MEMZONE_512MB - Reserved from 512MB pages + * - RTE_MEMZONE_4GB - Reserved from 4GB pages + * - RTE_MEMZONE_SIZE_HINT_ONLY - Allow alternative page size to be used if + * the requested page size is unavailable. + * If this flag is not set, the function + * will return error on an unavailable size + * request. + * @return + * A pointer to a correctly-filled read-only memzone descriptor, or NULL + * on error. + * On error case, rte_errno will be set appropriately: + * - E_RTE_NO_CONFIG - function could not get pointer to rte_config structure + * - E_RTE_SECONDARY - function was called from a secondary process instance + * - ENOSPC - the maximum number of memzones has already been allocated + * - EEXIST - a memzone with the same name already exists + * - ENOMEM - no appropriate memory area found in which to create memzone + * - EINVAL - invalid parameters + */ +__rte_experimental const struct rte_memzone * +rte_memzone_reserve_contig(const char *name, + size_t len, int socket_id, unsigned int flags); + +/** + * Reserve an IOVA-contiguous portion of physical memory with alignment on a + * specified boundary. + * + * This function reserves some IOVA-contiguous memory with alignment on a + * specified boundary, and returns a pointer to a correctly filled memzone + * descriptor. If the allocation cannot be done or if the alignment + * is not a power of 2, returns NULL. + * + * @param name + * The name of the memzone. If it already exists, the function will + * fail and return NULL. + * @param len + * The size of the memory to be reserved. + * @param socket_id + * 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 + * The flags parameter is used to request memzones to be + * taken from specifically sized hugepages. + * - RTE_MEMZONE_2MB - Reserved from 2MB pages + * - RTE_MEMZONE_1GB - Reserved from 1GB pages + * - RTE_MEMZONE_16MB - Reserved from 16MB pages + * - RTE_MEMZONE_16GB - Reserved from 16GB pages + * - RTE_MEMZONE_256KB - Reserved from 256KB pages + * - RTE_MEMZONE_256MB - Reserved from 256MB pages + * - RTE_MEMZONE_512MB - Reserved from 512MB pages + * - RTE_MEMZONE_4GB - Reserved from 4GB pages + * - RTE_MEMZONE_SIZE_HINT_ONLY - Allow alternative page size to be used if + * the requested page size is unavailable. + * If this flag is not set, the function + * will return error on an unavailable size + * request. + * @param align + * Alignment for resulting memzone. Must be a power of 2. + * @return + * A pointer to a correctly-filled read-only memzone descriptor, or NULL + * on error. + * On error case, rte_errno will be set appropriately: + * - E_RTE_NO_CONFIG - function could not get pointer to rte_config structure + * - E_RTE_SECONDARY - function was called from a secondary process instance + * - ENOSPC - the maximum number of memzones has already been allocated + * - EEXIST - a memzone with the same name already exists + * - ENOMEM - no appropriate memory area found in which to create memzone + * - EINVAL - invalid parameters + */ +__rte_experimental const struct rte_memzone * +rte_memzone_reserve_aligned_contig(const char *name, + size_t len, int socket_id, unsigned int flags, + unsigned int align); + +/** + * Reserve an IOVA-contiguous portion of physical memory with specified + * alignment and boundary. + * + * This function reserves some IOVA-contiguous memory with specified alignment + * and boundary, and returns a pointer to a correctly filled memzone + * descriptor. If the allocation cannot be done or if the alignment + * or boundary are not a power of 2, returns NULL. + * Memory buffer is reserved in a way, that it wouldn't cross specified + * boundary. That implies that requested length should be less or equal + * then boundary. + * + * @param name + * The name of the memzone. If it already exists, the function will + * fail and return NULL. + * @param len + * The size of the memory to be reserved. + * @param socket_id + * 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 + * The flags parameter is used to request memzones to be + * taken from specifically sized hugepages. + * - RTE_MEMZONE_2MB - Reserved from 2MB pages + * - RTE_MEMZONE_1GB - Reserved from 1GB pages + * - RTE_MEMZONE_16MB - Reserved from 16MB pages + * - RTE_MEMZONE_16GB - Reserved from 16GB pages + * - RTE_MEMZONE_256KB - Reserved from 256KB pages + * - RTE_MEMZONE_256MB - Reserved from 256MB pages + * - RTE_MEMZONE_512MB - Reserved from 512MB pages + * - RTE_MEMZONE_4GB - Reserved from 4GB pages + * - RTE_MEMZONE_SIZE_HINT_ONLY - Allow alternative page size to be used if + * the requested page size is unavailable. + * If this flag is not set, the function + * will return error on an unavailable size + * request. + * @param align + * Alignment for resulting memzone. Must be a power of 2. + * @param bound + * Boundary for resulting memzone. Must be a power of 2 or zero. + * Zero value implies no boundary condition. + * @return + * A pointer to a correctly-filled read-only memzone descriptor, or NULL + * on error. + * On error case, rte_errno will be set appropriately: + * - E_RTE_NO_CONFIG - function could not get pointer to rte_config structure + * - E_RTE_SECONDARY - function was called from a secondary process instance + * - ENOSPC - the maximum number of memzones has already been allocated + * - EEXIST - a memzone with the same name already exists + * - ENOMEM - no appropriate memory area found in which to create memzone + * - EINVAL - invalid parameters + */ +__rte_experimental const struct rte_memzone * +rte_memzone_reserve_bounded_contig(const char *name, + size_t len, int socket_id, unsigned int flags, + unsigned int align, unsigned int bound); + +/** * Free a memzone. * * @param mz diff --git a/lib/librte_eal/rte_eal_version.map b/lib/librte_eal/rte_eal_version.map index d9fc458..25e00de 100644 --- a/lib/librte_eal/rte_eal_version.map +++ b/lib/librte_eal/rte_eal_version.map @@ -223,6 +223,9 @@ EXPERIMENTAL { rte_eal_mbuf_user_pool_ops; rte_log_register_type_and_pick_level; rte_malloc_dump_heaps; + rte_memzone_reserve_contig; + rte_memzone_reserve_aligned_contig; + rte_memzone_reserve_bounded_contig; rte_mp_action_register; rte_mp_action_unregister; rte_mp_reply; -- 2.7.4