area_linux_mbind.c 3.18 KB
Newer Older
Swann Perarnau's avatar
Swann Perarnau committed
1 2 3 4 5 6 7 8 9 10
/*******************************************************************************
 * 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
*******************************************************************************/

11
#include <assert.h>
12
#include "aml.h"
13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
#include <sys/mman.h>
#include <numaif.h>

/*******************************************************************************
 * mbind methods for Linux systems
 * Only handles the actual mbind/mempolicy calls
 ******************************************************************************/

int aml_area_linux_mbind_regular_pre_bind(struct aml_area_linux_mbind_data *data)
{
	assert(data != NULL);
	return 0;
}

int aml_area_linux_mbind_regular_post_bind(struct aml_area_linux_mbind_data *data,
					   void *ptr, size_t sz)
{
	assert(data != NULL);
31 32 33
	/* realign ptr to match mbind requirement that it is aligned on a page */
	intptr_t aligned = (intptr_t)ptr & (intptr_t)(~(PAGE_SIZE -1));
	size_t end = sz + ((intptr_t)ptr - aligned);
34
	return mbind((void*)aligned, sz, data->policy, data->nodemask.mask, AML_BITMAP_MAX, 0);
35 36 37 38 39 40 41 42
}

struct aml_area_linux_mbind_ops aml_area_linux_mbind_regular_ops = {
	aml_area_linux_mbind_regular_pre_bind,
	aml_area_linux_mbind_regular_post_bind,
};

int aml_area_linux_mbind_setdata(struct aml_area_linux_mbind_data *data,
43
				 int policy, const struct aml_bitmap *nodemask)
44 45 46
{
	assert(data != NULL);
	data->policy = policy;
47
	aml_bitmap_copy(&data->nodemask, nodemask);
48 49 50 51 52 53 54 55 56 57 58
	return 0;
}

int aml_area_linux_mbind_mempolicy_pre_bind(struct aml_area_linux_mbind_data *data)
{
	assert(data != NULL);
	/* function is called before mmap, we save the "generic" mempolicy into
	 * our data, and apply the one the user actually want
	 */
	int policy;
	int err;
59 60 61 62 63 64
	struct aml_bitmap bitmap;
	get_mempolicy(&policy, (unsigned long *)&bitmap.mask,
		      AML_BITMAP_MAX, NULL, 0);
	err = set_mempolicy(data->policy, (unsigned long *)&data->nodemask.mask,
			    AML_BITMAP_MAX);
	aml_area_linux_mbind_setdata(data, policy, &bitmap);
65 66 67 68 69 70 71 72 73 74 75 76
	return err;
}

int aml_area_linux_mbind_mempolicy_post_bind(struct aml_area_linux_mbind_data *data,
					     void *ptr, size_t sz)
{
	assert(data != NULL);
	/* function is called after mmap, we retrieve the mempolicy we applied
	 * to it, and restore the generic mempolicy we saved earlier.
	 */
	int policy;
	int err;
77 78 79 80 81 82
	struct aml_bitmap bitmap;
	get_mempolicy(&policy, (unsigned long *)&bitmap.mask,
		      AML_BITMAP_MAX, NULL, 0);
	err = set_mempolicy(data->policy, (unsigned long *)data->nodemask.mask,
			    AML_BITMAP_MAX);
	aml_area_linux_mbind_setdata(data, policy, &bitmap);
83 84 85 86 87 88 89 90 91
	return err;
}

struct aml_area_linux_mbind_ops aml_area_linux_mbind_mempolicy_ops = {
	aml_area_linux_mbind_mempolicy_pre_bind,
	aml_area_linux_mbind_mempolicy_post_bind,
};

int aml_area_linux_mbind_init(struct aml_area_linux_mbind_data *data,
92
			      int policy, const struct aml_bitmap *nodemask)
93 94 95 96 97 98 99 100 101 102 103
{
	assert(data != NULL);
	aml_area_linux_mbind_setdata(data, policy, nodemask);
	return 0;
}

int aml_area_linux_mbind_destroy(struct aml_area_linux_mbind_data *data)
{
	assert(data != NULL);
	return 0;
}