1/*-
2 *   BSD LICENSE
3 *
4 *   Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
5 *   All rights reserved.
6 *
7 *   Redistribution and use in source and binary forms, with or without
8 *   modification, are permitted provided that the following conditions
9 *   are met:
10 *
11 *     * Redistributions of source code must retain the above copyright
12 *       notice, this list of conditions and the following disclaimer.
13 *     * Redistributions in binary form must reproduce the above copyright
14 *       notice, this list of conditions and the following disclaimer in
15 *       the documentation and/or other materials provided with the
16 *       distribution.
17 *     * Neither the name of Intel Corporation nor the names of its
18 *       contributors may be used to endorse or promote products derived
19 *       from this software without specific prior written permission.
20 *
21 *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22 *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23 *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24 *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
25 *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26 *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
27 *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28 *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29 *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30 *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31 *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 */
33
34#ifndef _RTE_MEMZONE_H_
35#define _RTE_MEMZONE_H_
36
37/**
38 * @file
39 * RTE Memzone
40 *
41 * The goal of the memzone allocator is to reserve contiguous
42 * portions of physical memory. These zones are identified by a name.
43 *
44 * The memzone descriptors are shared by all partitions and are
45 * located in a known place of physical memory. This zone is accessed
46 * using rte_eal_get_configuration(). The lookup (by name) of a
47 * memory zone can be done in any partition and returns the same
48 * physical address.
49 *
50 * A reserved memory zone cannot be unreserved. The reservation shall
51 * be done at initialization time only.
52 */
53
54#include <stdio.h>
55#include <rte_memory.h>
56#include <rte_common.h>
57
58#ifdef __cplusplus
59extern "C" {
60#endif
61
62#define RTE_MEMZONE_2MB            0x00000001   /**< Use 2MB pages. */
63#define RTE_MEMZONE_1GB            0x00000002   /**< Use 1GB pages. */
64#define RTE_MEMZONE_16MB           0x00000100   /**< Use 16MB pages. */
65#define RTE_MEMZONE_16GB           0x00000200   /**< Use 16GB pages. */
66#define RTE_MEMZONE_256KB          0x00010000   /**< Use 256KB pages. */
67#define RTE_MEMZONE_256MB          0x00020000   /**< Use 256MB pages. */
68#define RTE_MEMZONE_512MB          0x00040000   /**< Use 512MB pages. */
69#define RTE_MEMZONE_4GB            0x00080000   /**< Use 4GB pages. */
70#define RTE_MEMZONE_SIZE_HINT_ONLY 0x00000004   /**< Use available page size */
71
72/**
73 * A structure describing a memzone, which is a contiguous portion of
74 * physical memory identified by a name.
75 */
76struct rte_memzone {
77
78#define RTE_MEMZONE_NAMESIZE 32       /**< Maximum length of memory zone name.*/
79	char name[RTE_MEMZONE_NAMESIZE];  /**< Name of the memory zone. */
80
81	phys_addr_t phys_addr;            /**< Start physical address. */
82	RTE_STD_C11
83	union {
84		void *addr;                   /**< Start virtual address. */
85		uint64_t addr_64;             /**< Makes sure addr is always 64-bits */
86	};
87	size_t len;                       /**< Length of the memzone. */
88
89	uint64_t hugepage_sz;             /**< The page size of underlying memory */
90
91	int32_t socket_id;                /**< NUMA socket ID. */
92
93	uint32_t flags;                   /**< Characteristics of this memzone. */
94	uint32_t memseg_id;               /**< Memseg it belongs. */
95} __attribute__((__packed__));
96
97/**
98 * Reserve a portion of physical memory.
99 *
100 * This function reserves some memory and returns a pointer to a
101 * correctly filled memzone descriptor. If the allocation cannot be
102 * done, return NULL.
103 *
104 * @param name
105 *   The name of the memzone. If it already exists, the function will
106 *   fail and return NULL.
107 * @param len
108 *   The size of the memory to be reserved. If it
109 *   is 0, the biggest contiguous zone will be reserved.
110 * @param socket_id
111 *   The socket identifier in the case of
112 *   NUMA. The value can be SOCKET_ID_ANY if there is no NUMA
113 *   constraint for the reserved zone.
114 * @param flags
115 *   The flags parameter is used to request memzones to be
116 *   taken from specifically sized hugepages.
117 *   - RTE_MEMZONE_2MB - Reserved from 2MB pages
118 *   - RTE_MEMZONE_1GB - Reserved from 1GB pages
119 *   - RTE_MEMZONE_16MB - Reserved from 16MB pages
120 *   - RTE_MEMZONE_16GB - Reserved from 16GB pages
121 *   - RTE_MEMZONE_256KB - Reserved from 256KB pages
122 *   - RTE_MEMZONE_256MB - Reserved from 256MB pages
123 *   - RTE_MEMZONE_512MB - Reserved from 512MB pages
124 *   - RTE_MEMZONE_4GB - Reserved from 4GB pages
125 *   - RTE_MEMZONE_SIZE_HINT_ONLY - Allow alternative page size to be used if
126 *                                  the requested page size is unavailable.
127 *                                  If this flag is not set, the function
128 *                                  will return error on an unavailable size
129 *                                  request.
130 * @return
131 *   A pointer to a correctly-filled read-only memzone descriptor, or NULL
132 *   on error.
133 *   On error case, rte_errno will be set appropriately:
134 *    - E_RTE_NO_CONFIG - function could not get pointer to rte_config structure
135 *    - E_RTE_SECONDARY - function was called from a secondary process instance
136 *    - ENOSPC - the maximum number of memzones has already been allocated
137 *    - EEXIST - a memzone with the same name already exists
138 *    - ENOMEM - no appropriate memory area found in which to create memzone
139 *    - EINVAL - invalid parameters
140 */
141const struct rte_memzone *rte_memzone_reserve(const char *name,
142					      size_t len, int socket_id,
143					      unsigned flags);
144
145/**
146 * Reserve a portion of physical memory with alignment on a specified
147 * boundary.
148 *
149 * This function reserves some memory with alignment on a specified
150 * boundary, and returns a pointer to a correctly filled memzone
151 * descriptor. If the allocation cannot be done or if the alignment
152 * is not a power of 2, returns NULL.
153 *
154 * @param name
155 *   The name of the memzone. If it already exists, the function will
156 *   fail and return NULL.
157 * @param len
158 *   The size of the memory to be reserved. If it
159 *   is 0, the biggest contiguous zone will be reserved.
160 * @param socket_id
161 *   The socket identifier in the case of
162 *   NUMA. The value can be SOCKET_ID_ANY if there is no NUMA
163 *   constraint for the reserved zone.
164 * @param flags
165 *   The flags parameter is used to request memzones to be
166 *   taken from specifically sized hugepages.
167 *   - RTE_MEMZONE_2MB - Reserved from 2MB pages
168 *   - RTE_MEMZONE_1GB - Reserved from 1GB pages
169 *   - RTE_MEMZONE_16MB - Reserved from 16MB pages
170 *   - RTE_MEMZONE_16GB - Reserved from 16GB pages
171 *   - RTE_MEMZONE_256KB - Reserved from 256KB pages
172 *   - RTE_MEMZONE_256MB - Reserved from 256MB pages
173 *   - RTE_MEMZONE_512MB - Reserved from 512MB pages
174 *   - RTE_MEMZONE_4GB - Reserved from 4GB pages
175 *   - RTE_MEMZONE_SIZE_HINT_ONLY - Allow alternative page size to be used if
176 *                                  the requested page size is unavailable.
177 *                                  If this flag is not set, the function
178 *                                  will return error on an unavailable size
179 *                                  request.
180 * @param align
181 *   Alignment for resulting memzone. Must be a power of 2.
182 * @return
183 *   A pointer to a correctly-filled read-only memzone descriptor, or NULL
184 *   on error.
185 *   On error case, rte_errno will be set appropriately:
186 *    - E_RTE_NO_CONFIG - function could not get pointer to rte_config structure
187 *    - E_RTE_SECONDARY - function was called from a secondary process instance
188 *    - ENOSPC - the maximum number of memzones has already been allocated
189 *    - EEXIST - a memzone with the same name already exists
190 *    - ENOMEM - no appropriate memory area found in which to create memzone
191 *    - EINVAL - invalid parameters
192 */
193const struct rte_memzone *rte_memzone_reserve_aligned(const char *name,
194			size_t len, int socket_id,
195			unsigned flags, unsigned align);
196
197/**
198 * Reserve a portion of physical memory with specified alignment and
199 * boundary.
200 *
201 * This function reserves some memory with specified alignment and
202 * boundary, and returns a pointer to a correctly filled memzone
203 * descriptor. If the allocation cannot be done or if the alignment
204 * or boundary are not a power of 2, returns NULL.
205 * Memory buffer is reserved in a way, that it wouldn't cross specified
206 * boundary. That implies that requested length should be less or equal
207 * then boundary.
208 *
209 * @param name
210 *   The name of the memzone. If it already exists, the function will
211 *   fail and return NULL.
212 * @param len
213 *   The size of the memory to be reserved. If it
214 *   is 0, the biggest contiguous zone will be reserved.
215 * @param socket_id
216 *   The socket identifier in the case of
217 *   NUMA. The value can be SOCKET_ID_ANY if there is no NUMA
218 *   constraint for the reserved zone.
219 * @param flags
220 *   The flags parameter is used to request memzones to be
221 *   taken from specifically sized hugepages.
222 *   - RTE_MEMZONE_2MB - Reserved from 2MB pages
223 *   - RTE_MEMZONE_1GB - Reserved from 1GB pages
224 *   - RTE_MEMZONE_16MB - Reserved from 16MB pages
225 *   - RTE_MEMZONE_16GB - Reserved from 16GB pages
226 *   - RTE_MEMZONE_256KB - Reserved from 256KB pages
227 *   - RTE_MEMZONE_256MB - Reserved from 256MB pages
228 *   - RTE_MEMZONE_512MB - Reserved from 512MB pages
229 *   - RTE_MEMZONE_4GB - Reserved from 4GB pages
230 *   - RTE_MEMZONE_SIZE_HINT_ONLY - Allow alternative page size to be used if
231 *                                  the requested page size is unavailable.
232 *                                  If this flag is not set, the function
233 *                                  will return error on an unavailable size
234 *                                  request.
235 * @param align
236 *   Alignment for resulting memzone. Must be a power of 2.
237 * @param bound
238 *   Boundary for resulting memzone. Must be a power of 2 or zero.
239 *   Zero value implies no boundary condition.
240 * @return
241 *   A pointer to a correctly-filled read-only memzone descriptor, or NULL
242 *   on error.
243 *   On error case, rte_errno will be set appropriately:
244 *    - E_RTE_NO_CONFIG - function could not get pointer to rte_config structure
245 *    - E_RTE_SECONDARY - function was called from a secondary process instance
246 *    - ENOSPC - the maximum number of memzones has already been allocated
247 *    - EEXIST - a memzone with the same name already exists
248 *    - ENOMEM - no appropriate memory area found in which to create memzone
249 *    - EINVAL - invalid parameters
250 */
251const struct rte_memzone *rte_memzone_reserve_bounded(const char *name,
252			size_t len, int socket_id,
253			unsigned flags, unsigned align, unsigned bound);
254
255/**
256 * Free a memzone.
257 *
258 * @param mz
259 *   A pointer to the memzone
260 * @return
261 *  -EINVAL - invalid parameter.
262 *  0 - success
263 */
264int rte_memzone_free(const struct rte_memzone *mz);
265
266/**
267 * Lookup for a memzone.
268 *
269 * Get a pointer to a descriptor of an already reserved memory
270 * zone identified by the name given as an argument.
271 *
272 * @param name
273 *   The name of the memzone.
274 * @return
275 *   A pointer to a read-only memzone descriptor.
276 */
277const struct rte_memzone *rte_memzone_lookup(const char *name);
278
279/**
280 * Dump all reserved memzones to a file.
281 *
282 * @param f
283 *   A pointer to a file for output
284 */
285void rte_memzone_dump(FILE *f);
286
287/**
288 * Walk list of all memzones
289 *
290 * @param func
291 *   Iterator function
292 * @param arg
293 *   Argument passed to iterator
294 */
295void rte_memzone_walk(void (*func)(const struct rte_memzone *, void *arg),
296		      void *arg);
297
298#ifdef __cplusplus
299}
300#endif
301
302#endif /* _RTE_MEMZONE_H_ */
303