linux.h 6.92 KB
Newer Older
Nicolas Denoyelle's avatar
Nicolas Denoyelle committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
/*******************************************************************************
 * Copyright 2019 UChicago Argonne, LLC.
 * (c.f. AUTHORS, LICENSE)
 *
 * This file is part of the AML project.
 * For more info, see https://xgitlab.cels.anl.gov/argo/aml
 *
 * SPDX-License-Identifier: BSD-3-Clause
*******************************************************************************/

#ifndef AML_AREA_LINUX_NUMA_H
#define AML_AREA_LINUX_NUMA_H

#include <sys/mman.h>
#include <numa.h>
#include <numaif.h>

18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40
/**
 * @defgroup aml_area_linux "AML Linux Areas"
 * @brief Linux Implementation of Areas.
 *
 * Linux implementation of AML areas.
 * This building block relies on libnuma implementation and
 * linux mmap/munmap to provide mmap/munmap on NUMA host
 * host processor memory. New areas may be created
 * to allocate a specific subset of memories.
 * This building block also include a static declaration of
 * a default initialized area that can be used out of the box with
 * abstract area API.
 *
 * #include <aml/area/linux.h>
 * @{
 **/

/**
 * Allowed binding flag for area creation.
 * This flag will apply strict binding to the selected bitmask.
 * If subsequent allocation will failt if they cannot enforce binding
 * on bitmask.
 **/
Nicolas Denoyelle's avatar
Nicolas Denoyelle committed
41
#define AML_AREA_LINUX_BINDING_FLAG_BIND       (MPOL_BIND)
42 43 44 45 46 47

/**
 * Allowed binding flag for area creation.
 * This flag will make subsequent allocations to interleave
 * pages on memories of the bitmask.
 **/
Nicolas Denoyelle's avatar
Nicolas Denoyelle committed
48
#define AML_AREA_LINUX_BINDING_FLAG_INTERLEAVE (MPOL_INTERLEAVE)
49 50 51 52 53 54

/**
 * Allowed binding flag for area creation.
 * This flag will make subsequent allocations to bound to the
 * nodes of bitmask if possible, else to some other node.
 **/
Nicolas Denoyelle's avatar
Nicolas Denoyelle committed
55 56
#define AML_AREA_LINUX_BINDING_FLAG_PREFERRED  (MPOL_PREFERRED)

57 58 59 60 61
/**
 * Allowed mapping flag for area creation.
 * This flag will make subsequent allocations to be private
 * to the process making them.
 **/
62
#define AML_AREA_LINUX_MMAP_FLAG_PRIVATE (MAP_PRIVATE | MAP_ANONYMOUS)
Nicolas Denoyelle's avatar
Nicolas Denoyelle committed
63

64
/**
65 66 67
 * Allowed mapping flag for area creation.
 * This flag will make subsequent allocations to be visible to
 * other processes of the system.
68
 **/
69
#define AML_AREA_LINUX_MMAP_FLAG_SHARED  (MAP_SHARED | MAP_ANONYMOUS)
70

71
/**
72 73
 * This contains area operations implementation
 * for linux area.
74
 **/
75
extern struct aml_area_ops aml_area_linux_ops;
Nicolas Denoyelle's avatar
Nicolas Denoyelle committed
76

77
/**
78 79
 * Default linux area with private mapping and no binding.
 * Can be used out of the box with aml_area_*() functions.
80
 **/
81
extern struct aml_area aml_area_linux;
Nicolas Denoyelle's avatar
Nicolas Denoyelle committed
82

83
/**
84
 * Implementation of aml_area_data for linux areas.
85
 **/
86 87 88 89 90 91 92 93
struct aml_area_linux_data {
	/** numanodes to use when allocating data **/
	struct bitmask *nodeset;
	/** binding policy **/
	int             binding_flags;
	/** mmap flags **/
	int             mmap_flags;
};
94

95 96 97
/**
 * Static declaration of an aml area with linux ops.
 **/
98 99 100 101 102 103 104
#define AML_AREA_LINUX_DECL(name) \
	struct aml_area_linux_data __ ##name## _inner_data; \
	struct aml_area name = { \
		&aml_area_linux_ops, \
		(struct aml_area_data *)&__ ## name ## _inner_data, \
	}

105 106 107
/**
 * Static declaration of the size of a linux aml area.
 **/
108 109 110 111 112
#define AML_AREA_LINUX_ALLOCSIZE \
	(sizeof(struct aml_area_linux_data) + \
	 sizeof(struct aml_area))

/**
113 114
 * \brief Linux area creation.
 *
115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132
 * Allocate and initialize a struct aml_area implemented by aml_area_linux
 * operations.
 * @param[out] area pointer to an uninitialized struct aml_area pointer to
 * receive the new area.
 * @param[in] mmap_flags flags to use when retrieving virtual memory with mmap
 * @param[in] binding_flags, flags to use when binding memory.
 * @param[in] nodemask list of memory nodes to use. Default to allowed memory
 * nodes if NULL.
 * @return On success, returns 0 and area points to the new aml_area.
 * @return On failure, sets area to NULL and returns one of AML error codes:
 * - AML_ENOMEM if there wasn't enough memory available.
 * - AML_EINVAL if inputs flags were invalid.
 * - AML_EDOM the nodemask provided is out of bounds (allowed nodeset).
 **/
int aml_area_linux_create(struct aml_area **area, const int mmap_flags,
			  const struct aml_bitmap *nodemask,
			  const int binding_flags);

133 134 135 136 137 138 139 140 141 142 143

/**
 * \brief Linux area destruction.
 *
 * Destroy (finalize and free resources) a struct aml_area created by
 * aml_area_linux_create().
 *
 * @param area is NULL after this call.
 **/
void aml_area_linux_destroy(struct aml_area **area);

144 145
/**
 * Initialize a struct aml_area declared using the AML_AREA_LINUX_DECL macro.
146
 * @see aml_area_linux_create() for details on arguments.
147 148 149 150
 */
int aml_area_linux_init(struct aml_area *area, const int mmap_flags,
			const struct aml_bitmap *nodemask,
			const int binding_flags);
151

152 153 154 155 156 157
/**
 * Finalize a struct aml_area initialized with aml_area_linux_init.
 */
void aml_area_linux_fini(struct aml_area *area);

/**
158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186
 * Bind memory of size "size" pointed by "ptr" to binding set in "bind".
 * If mbind call was not successfull, i.e AML_FAILURE is returned, then errno
 * should be inspected for further error checking.
 * @param bind: The binding settings. mmap_flags is actually unused.
 * @param ptr: The data to bind.
 * @param size: The size of the data pointed by ptr.
 * @return an AML error code.
 **/
int
aml_area_linux_mbind(struct aml_area_linux_data    *bind,
		     void                          *ptr,
		     size_t                         size);

/**
 * Function to check whether binding of a ptr obtained with
 * aml_area_linux_mmap() then aml_area_linux_mbind() match area settings.
 * @param area_data: The expected binding settings.
 * @param ptr: The data supposely bound.
 * @param size: The data size.
 * @return 1 if mapped memory binding in ptr match area_data binding settings,
 * else 0.
 **/
int
aml_area_linux_check_binding(struct aml_area_linux_data *area_data,
			     void                       *ptr,
			     size_t                      size);

/**
 * \brief mmap block for aml area.
187
 *
188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220
 * This function is a wrapper on mmap function using arguments set in
 * mmap_flags of area_data.
 * This function does not perform binding, unlike it is done in areas created
 * with aml_area_linux_create().
 * @param area_data: The structure containing mmap_flags for mmap call.
 *        nodemask and bind_flags fields are ignored.
 * @param ptr: A hint provided to mmap function.
 * @param size: The size to allocate.
 * @return NULL on failure, else a valid pointer to memory.
 * Upon failure, errno should be checked for further error investigations.
 **/
void*
aml_area_linux_mmap(const struct aml_area_data  *area_data,
		    void                        *ptr,
		    size_t                       size);

/**
 * \brief munmap hook for aml area.
 *
 * unmap memory mapped with aml_area_linux_mmap().
 * @param area_data: unused
 * @param ptr: The virtual memory to unmap.
 * @param size: The size of virtual memory to unmap.
 * @return AML_FAILURE on error, AML_SUCCESS.
 * Upon failure errno should be checked for further error investigations.
 **/
int
aml_area_linux_munmap(const struct aml_area_data *area_data,
		      void *ptr,
		      const size_t size);

/**
 * @}
221 222
 **/

223
#endif //AML_AREA_LINUX_NUMA_H