move_pages: just use calloc
[trinity.git] / syscalls / move_pages.c
blob10055605ade77651c3ddc13651f5b5c21000ee5f
1 /*
2 * SYSCALL_DEFINE6(move_pages, pid_t, pid, unsigned long, nr_pages,
3 const void __user * __user *, pages,
4 const int __user *, nodes,
5 int __user *, status, int, flags)
6 */
8 #define MPOL_MF_MOVE (1<<1) /* Move pages owned by this process to conform to mapping */
9 #define MPOL_MF_MOVE_ALL (1<<2) /* Move every page to conform to mapping */
11 #include <malloc.h>
12 #include <string.h>
13 #include <stdlib.h>
14 #include <unistd.h>
15 #include <sys/types.h>
16 #include "arch.h"
17 #include "maps.h"
18 #include "random.h"
19 #include "sanitise.h"
20 #include "shm.h"
21 #include "utils.h"
23 static unsigned int count;
25 #define NOT_SET 0
26 #define WAS_MALLOC 1
27 #define WAS_MAP 2
28 static unsigned char *pagetypes;
30 /* After a succesful run, ->post calls this, which frees up
31 * the allocations done by ->sanitise */
32 static void free_all_pageallocs(unsigned long *page_alloc)
34 unsigned int i = 0;
36 if (pagetypes == NULL)
37 return;
39 while (pagetypes[i] != NOT_SET) {
40 /* we only care about freeing mallocs, ignore the mmaps. */
41 if (pagetypes[i] == WAS_MALLOC) {
42 free((void *)page_alloc[i]);
43 page_alloc[i] = 0;
44 pagetypes[i] = NOT_SET;
46 i++;
48 free(page_alloc);
51 static void sanitise_move_pages(int childno)
53 struct map *map;
54 int *nodes;
55 unsigned long *page_alloc;
56 unsigned int i;
58 if (pagetypes == NULL)
59 pagetypes = zmalloc(page_size); // The implied memset(0) == NOT_SET
61 /* number of pages to move */
62 count = rand() % (page_size / sizeof(void *));
63 count = max(1, count);
64 shm->syscall[childno].a2 = count;
66 /* setup array of ptrs to pages to move */
67 page_alloc = (unsigned long *) zmalloc(page_size);
68 shm->scratch[childno] = (unsigned long) page_alloc;
70 for (i = 0; i < count; i++) {
71 if (rand_bool()) {
72 /* malloc */
73 page_alloc[i] = (unsigned long) memalign(page_size, page_size);
74 if (!page_alloc[i]) {
75 free_all_pageallocs(page_alloc);
76 return;
78 pagetypes[i] = WAS_MALLOC;
79 } else {
80 /* mapping. */
81 map = get_map();
82 page_alloc[i] = (unsigned long) map->ptr;
83 pagetypes[i] = WAS_MAP;
86 shm->syscall[childno].a3 = (unsigned long) page_alloc;
88 /* nodes = array of ints specifying desired location for each page */
89 nodes = malloc(count * sizeof(int));
90 for (i = 0; i < count; i++)
91 nodes[i] = (int) rand() % 2;
92 shm->syscall[childno].a4 = (unsigned long) nodes;
94 /* status = array of ints returning status of each page.*/
95 shm->syscall[childno].a5 = (unsigned long) calloc(count, sizeof(int));
97 /* Needs CAP_SYS_NICE */
98 if (getuid() != 0)
99 shm->syscall[childno].a6 &= ~MPOL_MF_MOVE_ALL;
102 static void post_move_pages(int childno)
104 unsigned long *page;
106 page = (void *) shm->scratch[childno];
107 if (page == NULL)
108 return;
110 free_all_pageallocs(page);
112 shm->scratch[childno] = 0;
115 struct syscallentry syscall_move_pages = {
116 .name = "move_pages",
117 .num_args = 6,
118 .arg1name = "pid",
119 .arg1type = ARG_PID,
120 .arg2name = "nr_pages",
121 .arg3name = "pages",
122 .arg4name = "nodes",
123 .arg5name = "status",
124 .arg6name = "flags",
125 .arg6type = ARG_LIST,
126 .arg6list = {
127 .num = 2,
128 .values = { MPOL_MF_MOVE, MPOL_MF_MOVE_ALL },
130 .group = GROUP_VM,
131 .sanitise = sanitise_move_pages,
132 .post = post_move_pages,