1 /*
2  * SPDX-License-Identifier: GPL-2.0-or-later
3  *
4  * Copyright (c) 2018 Cyril Hrubis <chrubis@suse.cz>
5  */
6 
7 #ifndef TST_NUMA_H__
8 #define TST_NUMA_H__
9 
10 #include <string.h>
11 
12 /**
13  * Numa nodemap.
14  */
15 struct tst_nodemap {
16         /** Number of nodes in map */
17 	unsigned int cnt;
18 	/** Page allocation counters */
19 	unsigned int *counters;
20 	/** Array of numa ids */
21 	unsigned int map[];
22 };
23 
24 /**
25  * Clears numa counters. The counters are lazy-allocated on first call of this function.
26  *
27  * @nodes Numa nodemap.
28  */
29 void tst_nodemap_reset_counters(struct tst_nodemap *nodes);
30 
31 /**
32  * Prints pages allocated per each node.
33  *
34  * @nodes Numa nodemap.
35  */
36 void tst_nodemap_print_counters(struct tst_nodemap *nodes);
37 
38 /**
39  * Returns a name for a mempolicy/mbind mode.
40  *
41  * @mode Numa mempolicy mode.
42  */
43 const char *tst_numa_mode_name(int mode);
44 
45 /**
46  * Maps pages into memory, if path is NULL the mapping is anonymous otherwise is backed by the file.
47  *
48  * @path Path to a file, if not NULL mapping is file based.
49  * @size Mapping size.
50  */
51 void *tst_numa_map(const char *path, size_t size);
52 
53 /*
54  * Writes to memory in order to get the pages faulted.
55  *
56  * @ptr Start of the mapping.
57  * @size Size of the mapping.
58  */
tst_numa_fault(void * ptr,size_t size)59 static inline void tst_numa_fault(void *ptr, size_t size)
60 {
61 	memset(ptr, 'a', size);
62 }
63 
64 /*
65  * Frees the memory.
66  *
67  * @ptr Start of the mapping.
68  * @size Size of the mapping.
69  */
tst_numa_unmap(void * ptr,size_t size)70 static inline void tst_numa_unmap(void *ptr, size_t size)
71 {
72 	SAFE_MUNMAP(ptr, size);
73 }
74 
75 /**
76  * Check on which numa node resides each page of the mapping starting at ptr
77  * and continuing pages long and increases nodemap counters accordingly.
78  *
79  * @nodes Nodemap with initialized counters.
80  * @ptr   Pointer to start of a mapping.
81  * @size  Size of the mapping.
82  */
83 void tst_nodemap_count_pages(struct tst_nodemap *nodes, void *ptr, size_t size);
84 
85 /**
86  * Frees nodemap.
87  *
88  * @nodes Numa nodemap to be freed.
89  */
90 void tst_nodemap_free(struct tst_nodemap *nodes);
91 
92 /**
93  * Bitflags for tst_get_nodemap() function.
94  */
95 enum tst_numa_types {
96 	TST_NUMA_ANY = 0x00,
97 	TST_NUMA_MEM = 0x01,
98 };
99 
100 /**
101  * Allocates and returns numa node map, which is an array of numa nodes which
102  * contain desired resources e.g. memory.
103  *
104  * @type       Bitflags of enum tst_numa_types specifying desired resources.
105  * @min_mem_kb Minimal free RAM on memory nodes, if given node has less than
106  *             requested amount of free+buffers memory it's not included in
107  *             the resulting list of nodes.
108  *
109  * @return On success returns allocated and initialized struct tst_nodemap which contains
110  *         array of numa node ids that contains desired resources.
111  */
112 struct tst_nodemap *tst_get_nodemap(int type, size_t min_mem_kb);
113 
114 #endif /* TST_NUMA_H__ */
115