File: move_pages.c

package info (click to toggle)
trinity 1.3-1
  • links: PTS, VCS
  • area: main
  • in suites: jessie, jessie-kfreebsd
  • size: 3,252 kB
  • ctags: 2,738
  • sloc: ansic: 24,011; sh: 322; makefile: 141
file content (100 lines) | stat: -rw-r--r-- 2,199 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
/*
 * SYSCALL_DEFINE6(move_pages, pid_t, pid, unsigned long, nr_pages,
	const void __user * __user *, pages,
	const int __user *, nodes,
	int __user *, status, int, flags)
 */

#define MPOL_MF_MOVE    (1<<1)  /* Move pages owned by this process to conform to mapping */
#define MPOL_MF_MOVE_ALL (1<<2) /* Move every page to conform to mapping */

#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include "utils.h"	// page_size
#include "sanitise.h"
#include "arch.h"
#include "shm.h"

static unsigned int count;

static void sanitise_move_pages(int childno)
{
	int *nodes;
	unsigned long *page_alloc;
	unsigned int i, j;

	// Needs CAP_SYS_NICE to move pages in another process
	if (getuid() != 0) {
		shm->a1[childno] = 0;
		shm->a6[childno] &= ~MPOL_MF_MOVE_ALL;
	}

	page_alloc = (unsigned long *) malloc(page_size);
	shm->scratch[childno] = (unsigned long) page_alloc;
	if (page_alloc == NULL)
		return;

	count = rand() % (page_size / sizeof(void *));
	count = max(1, count);

	shm->a2[childno] = count;

	for (i = 0; i < count; i++) {
		page_alloc[i] = (unsigned long) malloc(page_size);
		if (!page_alloc[i]) {
			for (j = 0; j < i; j++)
				free((void *)page_alloc[j]);
			free(page_alloc);
			return;
		}
		page_alloc[i] &= PAGE_MASK;
	}

	shm->a3[childno] = (unsigned long) page_alloc;

	nodes = malloc(count * sizeof(int));
	for (i = 0; i < count; i++)
		nodes[i] = (int) rand() % 2;
	shm->a4[childno] = (unsigned long) nodes;

	shm->a5[childno] = (unsigned long) malloc(count * sizeof(int));
}

static void post_move_pages(int childno)
{
	unsigned long *page;
	void *ptr;
	unsigned int i;

	page = (void *) shm->scratch[childno];
	if (page == NULL)
		return;

	for (i = 0; i < count; i++) {
		ptr = (void *) page[i];
		free(ptr);
	}

	free(page);
}

struct syscall syscall_move_pages = {
	.name = "move_pages",
	.num_args = 6,
	.arg1name = "pid",
	.arg2name = "nr_pages",
	.arg3name = "pages",
	.arg4name = "nodes",
	.arg5name = "status",
	.arg5type = ARG_ADDRESS,
	.arg6name = "flags",
	.arg6type = ARG_LIST,
	.arg6list = {
		.num = 2,
		.values = { MPOL_MF_MOVE, MPOL_MF_MOVE_ALL },
	},
	.group = GROUP_VM,
	.sanitise = sanitise_move_pages,
	.post = post_move_pages,
};