199a2dd95SBruce Richardson /* SPDX-License-Identifier: BSD-3-Clause 299a2dd95SBruce Richardson * Copyright(c) 2010-2014 Intel Corporation 399a2dd95SBruce Richardson */ 499a2dd95SBruce Richardson 599a2dd95SBruce Richardson #ifndef _RTE_MEMZONE_H_ 699a2dd95SBruce Richardson #define _RTE_MEMZONE_H_ 799a2dd95SBruce Richardson 899a2dd95SBruce Richardson /** 999a2dd95SBruce Richardson * @file 1099a2dd95SBruce Richardson * RTE Memzone 1199a2dd95SBruce Richardson * 1299a2dd95SBruce Richardson * The goal of the memzone allocator is to reserve contiguous 1399a2dd95SBruce Richardson * portions of physical memory. These zones are identified by a name. 1499a2dd95SBruce Richardson * 1599a2dd95SBruce Richardson * The memzone descriptors are shared by all partitions and are 1699a2dd95SBruce Richardson * located in a known place of physical memory. This zone is accessed 1799a2dd95SBruce Richardson * using rte_eal_get_configuration(). The lookup (by name) of a 1899a2dd95SBruce Richardson * memory zone can be done in any partition and returns the same 1999a2dd95SBruce Richardson * physical address. 2099a2dd95SBruce Richardson * 2199a2dd95SBruce Richardson * A reserved memory zone cannot be unreserved. The reservation shall 2299a2dd95SBruce Richardson * be done at initialization time only. 2399a2dd95SBruce Richardson */ 2499a2dd95SBruce Richardson 2599a2dd95SBruce Richardson #include <stdio.h> 2699a2dd95SBruce Richardson #include <rte_memory.h> 2799a2dd95SBruce Richardson #include <rte_common.h> 2899a2dd95SBruce Richardson 2999a2dd95SBruce Richardson #ifdef __cplusplus 3099a2dd95SBruce Richardson extern "C" { 3199a2dd95SBruce Richardson #endif 3299a2dd95SBruce Richardson 3399a2dd95SBruce Richardson #define RTE_MEMZONE_2MB 0x00000001 /**< Use 2MB pages. */ 3499a2dd95SBruce Richardson #define RTE_MEMZONE_1GB 0x00000002 /**< Use 1GB pages. */ 3599a2dd95SBruce Richardson #define RTE_MEMZONE_16MB 0x00000100 /**< Use 16MB pages. */ 3699a2dd95SBruce Richardson #define RTE_MEMZONE_16GB 0x00000200 /**< Use 16GB pages. */ 3799a2dd95SBruce Richardson #define RTE_MEMZONE_256KB 0x00010000 /**< Use 256KB pages. */ 3899a2dd95SBruce Richardson #define RTE_MEMZONE_256MB 0x00020000 /**< Use 256MB pages. */ 3999a2dd95SBruce Richardson #define RTE_MEMZONE_512MB 0x00040000 /**< Use 512MB pages. */ 4099a2dd95SBruce Richardson #define RTE_MEMZONE_4GB 0x00080000 /**< Use 4GB pages. */ 4199a2dd95SBruce Richardson #define RTE_MEMZONE_SIZE_HINT_ONLY 0x00000004 /**< Use available page size */ 4299a2dd95SBruce Richardson #define RTE_MEMZONE_IOVA_CONTIG 0x00100000 /**< Ask for IOVA-contiguous memzone. */ 4399a2dd95SBruce Richardson 4499a2dd95SBruce Richardson /** 4599a2dd95SBruce Richardson * A structure describing a memzone, which is a contiguous portion of 4699a2dd95SBruce Richardson * physical memory identified by a name. 4799a2dd95SBruce Richardson */ 48*fba98755SAndre Muezerie struct __rte_packed_begin rte_memzone { 4999a2dd95SBruce Richardson 5099a2dd95SBruce Richardson #define RTE_MEMZONE_NAMESIZE 32 /**< Maximum length of memory zone name.*/ 5199a2dd95SBruce Richardson char name[RTE_MEMZONE_NAMESIZE]; /**< Name of the memory zone. */ 5299a2dd95SBruce Richardson 5399a2dd95SBruce Richardson rte_iova_t iova; /**< Start IO address. */ 5499a2dd95SBruce Richardson union { 5599a2dd95SBruce Richardson void *addr; /**< Start virtual address. */ 5699a2dd95SBruce Richardson uint64_t addr_64; /**< Makes sure addr is always 64-bits */ 5799a2dd95SBruce Richardson }; 5899a2dd95SBruce Richardson size_t len; /**< Length of the memzone. */ 5999a2dd95SBruce Richardson 6099a2dd95SBruce Richardson uint64_t hugepage_sz; /**< The page size of underlying memory */ 6199a2dd95SBruce Richardson 6299a2dd95SBruce Richardson int32_t socket_id; /**< NUMA socket ID. */ 6399a2dd95SBruce Richardson 6499a2dd95SBruce Richardson uint32_t flags; /**< Characteristics of this memzone. */ 65*fba98755SAndre Muezerie } __rte_packed_end; 6699a2dd95SBruce Richardson 6799a2dd95SBruce Richardson /** 6838689022SOphir Munk * Set the maximum number of memzones. 6938689022SOphir Munk * 7038689022SOphir Munk * This function can only be called prior to rte_eal_init(). 7138689022SOphir Munk * 7238689022SOphir Munk * @param max 7338689022SOphir Munk * Maximum number of memzones. 7438689022SOphir Munk * @return 7538689022SOphir Munk * 0 on success, -1 otherwise. 7638689022SOphir Munk */ 7738689022SOphir Munk int rte_memzone_max_set(size_t max); 7838689022SOphir Munk 7938689022SOphir Munk /** 8038689022SOphir Munk * Get the maximum number of memzones. 8138689022SOphir Munk * 8238689022SOphir Munk * @note: The maximum value will not change after calling rte_eal_init(). 8338689022SOphir Munk * 8438689022SOphir Munk * @return 8538689022SOphir Munk * Maximum number of memzones. 8638689022SOphir Munk */ 8738689022SOphir Munk size_t rte_memzone_max_get(void); 8838689022SOphir Munk 8938689022SOphir Munk /** 9099a2dd95SBruce Richardson * Reserve a portion of physical memory. 9199a2dd95SBruce Richardson * 9299a2dd95SBruce Richardson * This function reserves some memory and returns a pointer to a 9399a2dd95SBruce Richardson * correctly filled memzone descriptor. If the allocation cannot be 9499a2dd95SBruce Richardson * done, return NULL. 9599a2dd95SBruce Richardson * 9699a2dd95SBruce Richardson * @note Reserving memzones with len set to 0 will only attempt to allocate 9799a2dd95SBruce Richardson * memzones from memory that is already available. It will not trigger any 9899a2dd95SBruce Richardson * new allocations. 9999a2dd95SBruce Richardson * 10099a2dd95SBruce Richardson * @note: When reserving memzones with len set to 0, it is preferable to also 10199a2dd95SBruce Richardson * set a valid socket_id. Setting socket_id to SOCKET_ID_ANY is supported, but 10299a2dd95SBruce Richardson * will likely not yield expected results. Specifically, the resulting memzone 10399a2dd95SBruce Richardson * may not necessarily be the biggest memzone available, but rather biggest 10499a2dd95SBruce Richardson * memzone available on socket id corresponding to an lcore from which 10599a2dd95SBruce Richardson * reservation was called. 10699a2dd95SBruce Richardson * 10799a2dd95SBruce Richardson * @param name 10899a2dd95SBruce Richardson * The name of the memzone. If it already exists, the function will 10999a2dd95SBruce Richardson * fail and return NULL. 11099a2dd95SBruce Richardson * @param len 11199a2dd95SBruce Richardson * The size of the memory to be reserved. If it 11299a2dd95SBruce Richardson * is 0, the biggest contiguous zone will be reserved. 11399a2dd95SBruce Richardson * @param socket_id 11499a2dd95SBruce Richardson * The socket identifier in the case of 11599a2dd95SBruce Richardson * NUMA. The value can be SOCKET_ID_ANY if there is no NUMA 11699a2dd95SBruce Richardson * constraint for the reserved zone. 11799a2dd95SBruce Richardson * @param flags 11899a2dd95SBruce Richardson * The flags parameter is used to request memzones to be 11999a2dd95SBruce Richardson * taken from specifically sized hugepages. 12099a2dd95SBruce Richardson * - RTE_MEMZONE_2MB - Reserved from 2MB pages 12199a2dd95SBruce Richardson * - RTE_MEMZONE_1GB - Reserved from 1GB pages 12299a2dd95SBruce Richardson * - RTE_MEMZONE_16MB - Reserved from 16MB pages 12399a2dd95SBruce Richardson * - RTE_MEMZONE_16GB - Reserved from 16GB pages 12499a2dd95SBruce Richardson * - RTE_MEMZONE_256KB - Reserved from 256KB pages 12599a2dd95SBruce Richardson * - RTE_MEMZONE_256MB - Reserved from 256MB pages 12699a2dd95SBruce Richardson * - RTE_MEMZONE_512MB - Reserved from 512MB pages 12799a2dd95SBruce Richardson * - RTE_MEMZONE_4GB - Reserved from 4GB pages 12899a2dd95SBruce Richardson * - RTE_MEMZONE_SIZE_HINT_ONLY - Allow alternative page size to be used if 12999a2dd95SBruce Richardson * the requested page size is unavailable. 13099a2dd95SBruce Richardson * If this flag is not set, the function 13199a2dd95SBruce Richardson * will return error on an unavailable size 13299a2dd95SBruce Richardson * request. 13399a2dd95SBruce Richardson * - RTE_MEMZONE_IOVA_CONTIG - Ensure reserved memzone is IOVA-contiguous. 13499a2dd95SBruce Richardson * This option should be used when allocating 13599a2dd95SBruce Richardson * memory intended for hardware rings etc. 13699a2dd95SBruce Richardson * @return 13799a2dd95SBruce Richardson * A pointer to a correctly-filled read-only memzone descriptor, or NULL 13899a2dd95SBruce Richardson * on error. 13999a2dd95SBruce Richardson * On error case, rte_errno will be set appropriately: 14099a2dd95SBruce Richardson * - E_RTE_NO_CONFIG - function could not get pointer to rte_config structure 14199a2dd95SBruce Richardson * - ENOSPC - the maximum number of memzones has already been allocated 14299a2dd95SBruce Richardson * - EEXIST - a memzone with the same name already exists 14399a2dd95SBruce Richardson * - ENOMEM - no appropriate memory area found in which to create memzone 14499a2dd95SBruce Richardson * - EINVAL - invalid parameters 14599a2dd95SBruce Richardson */ 14699a2dd95SBruce Richardson const struct rte_memzone *rte_memzone_reserve(const char *name, 14799a2dd95SBruce Richardson size_t len, int socket_id, 14899a2dd95SBruce Richardson unsigned flags); 14999a2dd95SBruce Richardson 15099a2dd95SBruce Richardson /** 15199a2dd95SBruce Richardson * Reserve a portion of physical memory with alignment on a specified 15299a2dd95SBruce Richardson * boundary. 15399a2dd95SBruce Richardson * 15499a2dd95SBruce Richardson * This function reserves some memory with alignment on a specified 15599a2dd95SBruce Richardson * boundary, and returns a pointer to a correctly filled memzone 15699a2dd95SBruce Richardson * descriptor. If the allocation cannot be done or if the alignment 15799a2dd95SBruce Richardson * is not a power of 2, returns NULL. 15899a2dd95SBruce Richardson * 15999a2dd95SBruce Richardson * @note Reserving memzones with len set to 0 will only attempt to allocate 16099a2dd95SBruce Richardson * memzones from memory that is already available. It will not trigger any 16199a2dd95SBruce Richardson * new allocations. 16299a2dd95SBruce Richardson * 16399a2dd95SBruce Richardson * @note: When reserving memzones with len set to 0, it is preferable to also 16499a2dd95SBruce Richardson * set a valid socket_id. Setting socket_id to SOCKET_ID_ANY is supported, but 16599a2dd95SBruce Richardson * will likely not yield expected results. Specifically, the resulting memzone 16699a2dd95SBruce Richardson * may not necessarily be the biggest memzone available, but rather biggest 16799a2dd95SBruce Richardson * memzone available on socket id corresponding to an lcore from which 16899a2dd95SBruce Richardson * reservation was called. 16999a2dd95SBruce Richardson * 17099a2dd95SBruce Richardson * @param name 17199a2dd95SBruce Richardson * The name of the memzone. If it already exists, the function will 17299a2dd95SBruce Richardson * fail and return NULL. 17399a2dd95SBruce Richardson * @param len 17499a2dd95SBruce Richardson * The size of the memory to be reserved. If it 17599a2dd95SBruce Richardson * is 0, the biggest contiguous zone will be reserved. 17699a2dd95SBruce Richardson * @param socket_id 17799a2dd95SBruce Richardson * The socket identifier in the case of 17899a2dd95SBruce Richardson * NUMA. The value can be SOCKET_ID_ANY if there is no NUMA 17999a2dd95SBruce Richardson * constraint for the reserved zone. 18099a2dd95SBruce Richardson * @param flags 18199a2dd95SBruce Richardson * The flags parameter is used to request memzones to be 18299a2dd95SBruce Richardson * taken from specifically sized hugepages. 18399a2dd95SBruce Richardson * - RTE_MEMZONE_2MB - Reserved from 2MB pages 18499a2dd95SBruce Richardson * - RTE_MEMZONE_1GB - Reserved from 1GB pages 18599a2dd95SBruce Richardson * - RTE_MEMZONE_16MB - Reserved from 16MB pages 18699a2dd95SBruce Richardson * - RTE_MEMZONE_16GB - Reserved from 16GB pages 18799a2dd95SBruce Richardson * - RTE_MEMZONE_256KB - Reserved from 256KB pages 18899a2dd95SBruce Richardson * - RTE_MEMZONE_256MB - Reserved from 256MB pages 18999a2dd95SBruce Richardson * - RTE_MEMZONE_512MB - Reserved from 512MB pages 19099a2dd95SBruce Richardson * - RTE_MEMZONE_4GB - Reserved from 4GB pages 19199a2dd95SBruce Richardson * - RTE_MEMZONE_SIZE_HINT_ONLY - Allow alternative page size to be used if 19299a2dd95SBruce Richardson * the requested page size is unavailable. 19399a2dd95SBruce Richardson * If this flag is not set, the function 19499a2dd95SBruce Richardson * will return error on an unavailable size 19599a2dd95SBruce Richardson * request. 19699a2dd95SBruce Richardson * - RTE_MEMZONE_IOVA_CONTIG - Ensure reserved memzone is IOVA-contiguous. 19799a2dd95SBruce Richardson * This option should be used when allocating 19899a2dd95SBruce Richardson * memory intended for hardware rings etc. 19999a2dd95SBruce Richardson * @param align 20099a2dd95SBruce Richardson * Alignment for resulting memzone. Must be a power of 2. 20199a2dd95SBruce Richardson * @return 20299a2dd95SBruce Richardson * A pointer to a correctly-filled read-only memzone descriptor, or NULL 20399a2dd95SBruce Richardson * on error. 20499a2dd95SBruce Richardson * On error case, rte_errno will be set appropriately: 20599a2dd95SBruce Richardson * - E_RTE_NO_CONFIG - function could not get pointer to rte_config structure 20699a2dd95SBruce Richardson * - ENOSPC - the maximum number of memzones has already been allocated 20799a2dd95SBruce Richardson * - EEXIST - a memzone with the same name already exists 20899a2dd95SBruce Richardson * - ENOMEM - no appropriate memory area found in which to create memzone 20999a2dd95SBruce Richardson * - EINVAL - invalid parameters 21099a2dd95SBruce Richardson */ 21199a2dd95SBruce Richardson const struct rte_memzone *rte_memzone_reserve_aligned(const char *name, 21299a2dd95SBruce Richardson size_t len, int socket_id, 21399a2dd95SBruce Richardson unsigned flags, unsigned align); 21499a2dd95SBruce Richardson 21599a2dd95SBruce Richardson /** 21699a2dd95SBruce Richardson * Reserve a portion of physical memory with specified alignment and 21799a2dd95SBruce Richardson * boundary. 21899a2dd95SBruce Richardson * 21999a2dd95SBruce Richardson * This function reserves some memory with specified alignment and 22099a2dd95SBruce Richardson * boundary, and returns a pointer to a correctly filled memzone 22199a2dd95SBruce Richardson * descriptor. If the allocation cannot be done or if the alignment 22299a2dd95SBruce Richardson * or boundary are not a power of 2, returns NULL. 22399a2dd95SBruce Richardson * Memory buffer is reserved in a way, that it wouldn't cross specified 22499a2dd95SBruce Richardson * boundary. That implies that requested length should be less or equal 22599a2dd95SBruce Richardson * then boundary. 22699a2dd95SBruce Richardson * 22799a2dd95SBruce Richardson * @note Reserving memzones with len set to 0 will only attempt to allocate 22899a2dd95SBruce Richardson * memzones from memory that is already available. It will not trigger any 22999a2dd95SBruce Richardson * new allocations. 23099a2dd95SBruce Richardson * 23199a2dd95SBruce Richardson * @note: When reserving memzones with len set to 0, it is preferable to also 23299a2dd95SBruce Richardson * set a valid socket_id. Setting socket_id to SOCKET_ID_ANY is supported, but 23399a2dd95SBruce Richardson * will likely not yield expected results. Specifically, the resulting memzone 23499a2dd95SBruce Richardson * may not necessarily be the biggest memzone available, but rather biggest 23599a2dd95SBruce Richardson * memzone available on socket id corresponding to an lcore from which 23699a2dd95SBruce Richardson * reservation was called. 23799a2dd95SBruce Richardson * 23899a2dd95SBruce Richardson * @param name 23999a2dd95SBruce Richardson * The name of the memzone. If it already exists, the function will 24099a2dd95SBruce Richardson * fail and return NULL. 24199a2dd95SBruce Richardson * @param len 24299a2dd95SBruce Richardson * The size of the memory to be reserved. If it 24399a2dd95SBruce Richardson * is 0, the biggest contiguous zone will be reserved. 24499a2dd95SBruce Richardson * @param socket_id 24599a2dd95SBruce Richardson * The socket identifier in the case of 24699a2dd95SBruce Richardson * NUMA. The value can be SOCKET_ID_ANY if there is no NUMA 24799a2dd95SBruce Richardson * constraint for the reserved zone. 24899a2dd95SBruce Richardson * @param flags 24999a2dd95SBruce Richardson * The flags parameter is used to request memzones to be 25099a2dd95SBruce Richardson * taken from specifically sized hugepages. 25199a2dd95SBruce Richardson * - RTE_MEMZONE_2MB - Reserved from 2MB pages 25299a2dd95SBruce Richardson * - RTE_MEMZONE_1GB - Reserved from 1GB pages 25399a2dd95SBruce Richardson * - RTE_MEMZONE_16MB - Reserved from 16MB pages 25499a2dd95SBruce Richardson * - RTE_MEMZONE_16GB - Reserved from 16GB pages 25599a2dd95SBruce Richardson * - RTE_MEMZONE_256KB - Reserved from 256KB pages 25699a2dd95SBruce Richardson * - RTE_MEMZONE_256MB - Reserved from 256MB pages 25799a2dd95SBruce Richardson * - RTE_MEMZONE_512MB - Reserved from 512MB pages 25899a2dd95SBruce Richardson * - RTE_MEMZONE_4GB - Reserved from 4GB pages 25999a2dd95SBruce Richardson * - RTE_MEMZONE_SIZE_HINT_ONLY - Allow alternative page size to be used if 26099a2dd95SBruce Richardson * the requested page size is unavailable. 26199a2dd95SBruce Richardson * If this flag is not set, the function 26299a2dd95SBruce Richardson * will return error on an unavailable size 26399a2dd95SBruce Richardson * request. 26499a2dd95SBruce Richardson * - RTE_MEMZONE_IOVA_CONTIG - Ensure reserved memzone is IOVA-contiguous. 26599a2dd95SBruce Richardson * This option should be used when allocating 26699a2dd95SBruce Richardson * memory intended for hardware rings etc. 26799a2dd95SBruce Richardson * @param align 26899a2dd95SBruce Richardson * Alignment for resulting memzone. Must be a power of 2. 26999a2dd95SBruce Richardson * @param bound 27099a2dd95SBruce Richardson * Boundary for resulting memzone. Must be a power of 2 or zero. 27199a2dd95SBruce Richardson * Zero value implies no boundary condition. 27299a2dd95SBruce Richardson * @return 27399a2dd95SBruce Richardson * A pointer to a correctly-filled read-only memzone descriptor, or NULL 27499a2dd95SBruce Richardson * on error. 27599a2dd95SBruce Richardson * On error case, rte_errno will be set appropriately: 27699a2dd95SBruce Richardson * - E_RTE_NO_CONFIG - function could not get pointer to rte_config structure 27799a2dd95SBruce Richardson * - ENOSPC - the maximum number of memzones has already been allocated 27899a2dd95SBruce Richardson * - EEXIST - a memzone with the same name already exists 27999a2dd95SBruce Richardson * - ENOMEM - no appropriate memory area found in which to create memzone 28099a2dd95SBruce Richardson * - EINVAL - invalid parameters 28199a2dd95SBruce Richardson */ 28299a2dd95SBruce Richardson const struct rte_memzone *rte_memzone_reserve_bounded(const char *name, 28399a2dd95SBruce Richardson size_t len, int socket_id, 28499a2dd95SBruce Richardson unsigned flags, unsigned align, unsigned bound); 28599a2dd95SBruce Richardson 28699a2dd95SBruce Richardson /** 28799a2dd95SBruce Richardson * Free a memzone. 28899a2dd95SBruce Richardson * 28999a2dd95SBruce Richardson * @param mz 29099a2dd95SBruce Richardson * A pointer to the memzone 29199a2dd95SBruce Richardson * @return 29299a2dd95SBruce Richardson * -EINVAL - invalid parameter. 29399a2dd95SBruce Richardson * 0 - success 29499a2dd95SBruce Richardson */ 29599a2dd95SBruce Richardson int rte_memzone_free(const struct rte_memzone *mz); 29699a2dd95SBruce Richardson 29799a2dd95SBruce Richardson /** 29899a2dd95SBruce Richardson * Lookup for a memzone. 29999a2dd95SBruce Richardson * 30099a2dd95SBruce Richardson * Get a pointer to a descriptor of an already reserved memory 30199a2dd95SBruce Richardson * zone identified by the name given as an argument. 30299a2dd95SBruce Richardson * 30399a2dd95SBruce Richardson * @param name 30499a2dd95SBruce Richardson * The name of the memzone. 30599a2dd95SBruce Richardson * @return 30699a2dd95SBruce Richardson * A pointer to a read-only memzone descriptor. 30799a2dd95SBruce Richardson */ 30899a2dd95SBruce Richardson const struct rte_memzone *rte_memzone_lookup(const char *name); 30999a2dd95SBruce Richardson 31099a2dd95SBruce Richardson /** 31199a2dd95SBruce Richardson * Dump all reserved memzones to a file. 31299a2dd95SBruce Richardson * 31399a2dd95SBruce Richardson * @param f 31499a2dd95SBruce Richardson * A pointer to a file for output 31599a2dd95SBruce Richardson */ 31699a2dd95SBruce Richardson void rte_memzone_dump(FILE *f); 31799a2dd95SBruce Richardson 31899a2dd95SBruce Richardson /** 31999a2dd95SBruce Richardson * Walk list of all memzones 32099a2dd95SBruce Richardson * 32199a2dd95SBruce Richardson * @param func 32299a2dd95SBruce Richardson * Iterator function 32399a2dd95SBruce Richardson * @param arg 32499a2dd95SBruce Richardson * Argument passed to iterator 32599a2dd95SBruce Richardson */ 32699a2dd95SBruce Richardson void rte_memzone_walk(void (*func)(const struct rte_memzone *, void *arg), 32799a2dd95SBruce Richardson void *arg); 32899a2dd95SBruce Richardson 32999a2dd95SBruce Richardson #ifdef __cplusplus 33099a2dd95SBruce Richardson } 33199a2dd95SBruce Richardson #endif 33299a2dd95SBruce Richardson 33399a2dd95SBruce Richardson #endif /* _RTE_MEMZONE_H_ */ 334