summaryrefslogtreecommitdiffstats
path: root/recipes-core/numad/numad-0.6/test.patch
blob: 762790cbcd7fc3877a4ef87bdd147261e88f7c9c (plain)
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
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
Test output format: ptest style (PASS, FAIL, SKIP)
Description: Allocate memory from a node other than
the current CPU is running on. Wait for numad to modify
memory and CPU policy binding the process to run and allocate on
the same node.
Dependencies: libnuma

Signed-off-by: Radu Patriu <radu.patriu@enea.com>
Upstream-Status: Pending

Index: numa-test/test.c
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ numa-test/test.c	2014-02-18 17:22:49.952290472 +0200
@@ -0,0 +1,160 @@
+#define _GNU_SOURCE
+#include <sched.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <ctype.h>
+#include <sys/time.h>
+#include <sched.h>
+#include <numa.h>
+
+#define TIMEOUT (1000 * 60) /*60 seconds*/
+#define LOOP_TIME (1000 * 5) /*5 seconds*/
+#define MEM_POLICY_CHANGED  1
+#define NODE_POLICY_CHANGED 2
+#define TEST_DONE           (MEM_POLICY_CHANGED | NODE_POLICY_CHANGED)
+
+#define TEST_PASS 0
+#define TEST_FAIL 1
+#define TEST_SKIP 2
+
+#define MEM_SIZE 0.3 /* 30 % node memory */
+
+unsigned int numa_bitmask_weight(const struct bitmask *bmp);
+
+void print_bitmask(struct bitmask *mask)
+{
+    /*assume 32 max nodes*/
+    printf("0x%08lx", *(mask->maskp));
+}
+
+int test()
+{
+    int i, j, total_nodes, total_mem_nodes, total_cpus, prefered_node;
+    struct bitmask *allowed_mem_nodes, *allowed_nodes, *cpu_mask, *mem_bind, *bit_mask;
+    long long mem_size, page_size;
+    unsigned char *mem;
+    struct timeval start, end, res;
+    int local_node, local_cpu, other_node, test_complete;
+
+    allowed_mem_nodes = numa_allocate_nodemask();
+    allowed_nodes = numa_allocate_nodemask();
+    mem_bind = numa_allocate_nodemask();
+    cpu_mask = numa_allocate_cpumask();
+    if (!(allowed_mem_nodes && allowed_nodes && mem_bind && cpu_mask)) {
+        printf("Error: numa_allocate failed\n");
+        return TEST_FAIL;
+    }
+
+    total_nodes = numa_max_node() + 1;
+    printf("total_nodes %d\n", total_nodes);
+
+    total_mem_nodes = numa_num_configured_nodes();
+    printf("total_mem_nodes %d\n", total_mem_nodes);
+
+    total_cpus = numa_num_configured_cpus();
+    printf("total_cpus %d\n", total_cpus);
+
+    page_size = numa_pagesize();
+    printf("page_size %llu\n", page_size);
+
+    i = 0;
+    test_complete = 0;
+    gettimeofday(&start, NULL);
+    do {
+        printf("\n\n\nLoop %d\n", i);
+
+        bit_mask = numa_get_mems_allowed();
+        if (i && !numa_bitmask_equal(bit_mask, allowed_mem_nodes)) {
+            printf("\nInfo: memory policy modified\n\n");
+            test_complete |= MEM_POLICY_CHANGED;
+        }
+        copy_bitmask_to_bitmask(bit_mask, allowed_mem_nodes);
+        printf("allowed_mem_nodes "); print_bitmask(allowed_mem_nodes); printf("\n");
+        if ((0 == i) && (1 == numa_bitmask_weight(allowed_mem_nodes))) {
+            printf("Error: need at least two memory nodes\n");
+            return TEST_SKIP;
+        }
+
+        bit_mask = numa_get_run_node_mask();
+        if (i && !numa_bitmask_equal(bit_mask, allowed_nodes)) {
+            printf("\nInfo: node/cpu policy modified\n\n");
+            test_complete |= NODE_POLICY_CHANGED;
+        }
+        copy_bitmask_to_bitmask(bit_mask, allowed_nodes);
+        printf("allowed_nodes "); print_bitmask(allowed_nodes); printf("\n");
+
+        prefered_node = numa_preferred();
+        printf("prefered_node %d\n", prefered_node);
+
+        bit_mask = numa_get_membind();
+        copy_bitmask_to_bitmask(bit_mask, mem_bind);
+        printf("mem_bind "); print_bitmask(mem_bind); printf("\n");
+
+        if (numa_sched_getaffinity(0, cpu_mask) < 0) {
+            printf("Error: numa_sched_getaffinity failed\n");
+            return TEST_FAIL;
+        }
+        printf("sched_affinity "); print_bitmask(cpu_mask); printf("\n");
+
+        other_node = -1;
+        local_cpu = sched_getcpu();
+        local_node = numa_node_of_cpu(local_cpu);
+        for (j = 0; j < total_mem_nodes; ++j)
+            if (numa_bitmask_isbitset(allowed_mem_nodes, j) && (j != local_node))
+                other_node = j;
+
+        printf("running on node %d, cpu %d\n", local_node, local_cpu);
+        printf("alloc memory from node %d\n", other_node);
+
+        mem_size = numa_node_size64(other_node, NULL) * MEM_SIZE;
+        printf("test_mem_size %llu\n", mem_size);
+
+        /* avoid mbind: Invalid argument */
+        if (TEST_DONE == test_complete)
+            return TEST_PASS;
+
+        mem = numa_alloc_onnode(mem_size, other_node);
+        if (!mem) {
+            printf("Error: numa_alloc_onnode failed for node %d\n", other_node);
+            return TEST_FAIL;
+        }
+
+        gettimeofday(&end, NULL);
+        /* do some work */
+        do {
+            struct timeval now;
+            memcpy(mem, mem + mem_size/2, mem_size/2);
+            gettimeofday(&now, NULL);
+            timersub(&now, &end, &res);
+        } while((res.tv_sec * 1000 + res.tv_usec / 1000) < LOOP_TIME);
+
+        numa_free(mem, mem_size);
+        ++i;
+        gettimeofday(&end, NULL);
+        timersub(&end, &start, &res);
+    } while((res.tv_sec * 1000 + res.tv_usec / 1000) < TIMEOUT);
+
+    return TEST_FAIL;
+}
+
+int main()
+{
+    if (numa_available() < 0) {
+        printf("Error: numa not available\n");
+        printf("SKIP: numad\n");
+        return 0;
+    }
+
+    switch(test()) {
+    case TEST_PASS:
+        printf("PASS: numad\n");
+        break;
+    case TEST_SKIP:
+        printf("FAIL: numad\n");
+        break;
+    default:
+        printf("FAIL: numad\n");
+    }
+
+    return 0;
+}