1*49cdfc7eSAndroid Build Coastguard Worker /*
2*49cdfc7eSAndroid Build Coastguard Worker * Copyright (C) 2010-2017 Red Hat, Inc.
3*49cdfc7eSAndroid Build Coastguard Worker *
4*49cdfc7eSAndroid Build Coastguard Worker * This program is free software; you can redistribute it and/or modify
5*49cdfc7eSAndroid Build Coastguard Worker * it under the terms of the GNU General Public License as published by
6*49cdfc7eSAndroid Build Coastguard Worker * the Free Software Foundation; either version 2 of the License, or
7*49cdfc7eSAndroid Build Coastguard Worker * (at your option) any later version.
8*49cdfc7eSAndroid Build Coastguard Worker *
9*49cdfc7eSAndroid Build Coastguard Worker * This program is distributed in the hope that it will be useful,
10*49cdfc7eSAndroid Build Coastguard Worker * but WITHOUT ANY WARRANTY; without even the implied warranty of
11*49cdfc7eSAndroid Build Coastguard Worker * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
12*49cdfc7eSAndroid Build Coastguard Worker * the GNU General Public License for more details.
13*49cdfc7eSAndroid Build Coastguard Worker *
14*49cdfc7eSAndroid Build Coastguard Worker * Out Of Memory when changing cpuset's mems on NUMA. There was a
15*49cdfc7eSAndroid Build Coastguard Worker * problem reported upstream that the allocator may see an empty
16*49cdfc7eSAndroid Build Coastguard Worker * nodemask when changing cpuset's mems.
17*49cdfc7eSAndroid Build Coastguard Worker * http://lkml.org/lkml/2010/5/4/77
18*49cdfc7eSAndroid Build Coastguard Worker * http://lkml.org/lkml/2010/5/4/79
19*49cdfc7eSAndroid Build Coastguard Worker * http://lkml.org/lkml/2010/5/4/80
20*49cdfc7eSAndroid Build Coastguard Worker * This test is based on the reproducers for the above issue.
21*49cdfc7eSAndroid Build Coastguard Worker */
22*49cdfc7eSAndroid Build Coastguard Worker
23*49cdfc7eSAndroid Build Coastguard Worker #include "config.h"
24*49cdfc7eSAndroid Build Coastguard Worker #include <stdio.h>
25*49cdfc7eSAndroid Build Coastguard Worker #include <sys/wait.h>
26*49cdfc7eSAndroid Build Coastguard Worker #if HAVE_NUMA_H
27*49cdfc7eSAndroid Build Coastguard Worker #include <numa.h>
28*49cdfc7eSAndroid Build Coastguard Worker #endif
29*49cdfc7eSAndroid Build Coastguard Worker #if HAVE_NUMAIF_H
30*49cdfc7eSAndroid Build Coastguard Worker #include <numaif.h>
31*49cdfc7eSAndroid Build Coastguard Worker #endif
32*49cdfc7eSAndroid Build Coastguard Worker
33*49cdfc7eSAndroid Build Coastguard Worker #include "mem.h"
34*49cdfc7eSAndroid Build Coastguard Worker #include "numa_helper.h"
35*49cdfc7eSAndroid Build Coastguard Worker
36*49cdfc7eSAndroid Build Coastguard Worker #ifdef HAVE_NUMA_V2
37*49cdfc7eSAndroid Build Coastguard Worker
38*49cdfc7eSAndroid Build Coastguard Worker volatile int end;
39*49cdfc7eSAndroid Build Coastguard Worker static int *nodes;
40*49cdfc7eSAndroid Build Coastguard Worker static int nnodes;
41*49cdfc7eSAndroid Build Coastguard Worker static long ncpus;
42*49cdfc7eSAndroid Build Coastguard Worker
43*49cdfc7eSAndroid Build Coastguard Worker static void sighandler(int signo LTP_ATTRIBUTE_UNUSED);
44*49cdfc7eSAndroid Build Coastguard Worker static int mem_hog(void);
45*49cdfc7eSAndroid Build Coastguard Worker static int mem_hog_cpuset(int ntasks);
46*49cdfc7eSAndroid Build Coastguard Worker static long count_cpu(void);
47*49cdfc7eSAndroid Build Coastguard Worker
test_cpuset(void)48*49cdfc7eSAndroid Build Coastguard Worker static void test_cpuset(void)
49*49cdfc7eSAndroid Build Coastguard Worker {
50*49cdfc7eSAndroid Build Coastguard Worker int child, i;
51*49cdfc7eSAndroid Build Coastguard Worker unsigned long nmask[MAXNODES / BITS_PER_LONG] = { 0 };
52*49cdfc7eSAndroid Build Coastguard Worker char buf[BUFSIZ];
53*49cdfc7eSAndroid Build Coastguard Worker
54*49cdfc7eSAndroid Build Coastguard Worker SAFE_CG_READ(tst_cg, "cpuset.cpus", buf, sizeof(buf));
55*49cdfc7eSAndroid Build Coastguard Worker SAFE_CG_PRINT(tst_cg, "cpuset.cpus", buf);
56*49cdfc7eSAndroid Build Coastguard Worker SAFE_CG_READ(tst_cg, "cpuset.mems", buf, sizeof(buf));
57*49cdfc7eSAndroid Build Coastguard Worker SAFE_CG_PRINT(tst_cg, "cpuset.mems", buf);
58*49cdfc7eSAndroid Build Coastguard Worker
59*49cdfc7eSAndroid Build Coastguard Worker child = SAFE_FORK();
60*49cdfc7eSAndroid Build Coastguard Worker if (child == 0) {
61*49cdfc7eSAndroid Build Coastguard Worker for (i = 0; i < nnodes; i++) {
62*49cdfc7eSAndroid Build Coastguard Worker if (nodes[i] >= MAXNODES)
63*49cdfc7eSAndroid Build Coastguard Worker continue;
64*49cdfc7eSAndroid Build Coastguard Worker set_node(nmask, nodes[i]);
65*49cdfc7eSAndroid Build Coastguard Worker }
66*49cdfc7eSAndroid Build Coastguard Worker if (set_mempolicy(MPOL_BIND, nmask, MAXNODES) == -1)
67*49cdfc7eSAndroid Build Coastguard Worker tst_brk(TBROK | TERRNO, "set_mempolicy");
68*49cdfc7eSAndroid Build Coastguard Worker exit(mem_hog_cpuset(ncpus > 1 ? ncpus : 1));
69*49cdfc7eSAndroid Build Coastguard Worker }
70*49cdfc7eSAndroid Build Coastguard Worker
71*49cdfc7eSAndroid Build Coastguard Worker SAFE_CG_PRINTF(tst_cg, "cpuset.mems", "%d", nodes[0]);
72*49cdfc7eSAndroid Build Coastguard Worker SAFE_CG_PRINTF(tst_cg, "cpuset.mems", "%d", nodes[1]);
73*49cdfc7eSAndroid Build Coastguard Worker
74*49cdfc7eSAndroid Build Coastguard Worker tst_reap_children();
75*49cdfc7eSAndroid Build Coastguard Worker
76*49cdfc7eSAndroid Build Coastguard Worker tst_res(TPASS, "cpuset test pass");
77*49cdfc7eSAndroid Build Coastguard Worker }
78*49cdfc7eSAndroid Build Coastguard Worker
setup(void)79*49cdfc7eSAndroid Build Coastguard Worker static void setup(void)
80*49cdfc7eSAndroid Build Coastguard Worker {
81*49cdfc7eSAndroid Build Coastguard Worker ncpus = count_cpu();
82*49cdfc7eSAndroid Build Coastguard Worker if (get_allowed_nodes_arr(NH_MEMS | NH_CPUS, &nnodes, &nodes) < 0)
83*49cdfc7eSAndroid Build Coastguard Worker tst_brk(TBROK | TERRNO, "get_allowed_nodes_arr");
84*49cdfc7eSAndroid Build Coastguard Worker if (nnodes <= 1)
85*49cdfc7eSAndroid Build Coastguard Worker tst_brk(TCONF, "requires a NUMA system.");
86*49cdfc7eSAndroid Build Coastguard Worker
87*49cdfc7eSAndroid Build Coastguard Worker SAFE_CG_PRINTF(tst_cg, "cgroup.procs", "%d", getpid());
88*49cdfc7eSAndroid Build Coastguard Worker }
89*49cdfc7eSAndroid Build Coastguard Worker
sighandler(int signo LTP_ATTRIBUTE_UNUSED)90*49cdfc7eSAndroid Build Coastguard Worker static void sighandler(int signo LTP_ATTRIBUTE_UNUSED)
91*49cdfc7eSAndroid Build Coastguard Worker {
92*49cdfc7eSAndroid Build Coastguard Worker end = 1;
93*49cdfc7eSAndroid Build Coastguard Worker }
94*49cdfc7eSAndroid Build Coastguard Worker
mem_hog(void)95*49cdfc7eSAndroid Build Coastguard Worker static int mem_hog(void)
96*49cdfc7eSAndroid Build Coastguard Worker {
97*49cdfc7eSAndroid Build Coastguard Worker long pagesize;
98*49cdfc7eSAndroid Build Coastguard Worker unsigned long *addr;
99*49cdfc7eSAndroid Build Coastguard Worker int ret = 0;
100*49cdfc7eSAndroid Build Coastguard Worker
101*49cdfc7eSAndroid Build Coastguard Worker pagesize = getpagesize();
102*49cdfc7eSAndroid Build Coastguard Worker while (!end) {
103*49cdfc7eSAndroid Build Coastguard Worker addr = SAFE_MMAP(NULL, pagesize * 10, PROT_READ | PROT_WRITE,
104*49cdfc7eSAndroid Build Coastguard Worker MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
105*49cdfc7eSAndroid Build Coastguard Worker memset(addr, 0xF7, pagesize * 10);
106*49cdfc7eSAndroid Build Coastguard Worker SAFE_MUNMAP(addr, pagesize * 10);
107*49cdfc7eSAndroid Build Coastguard Worker }
108*49cdfc7eSAndroid Build Coastguard Worker return ret;
109*49cdfc7eSAndroid Build Coastguard Worker }
110*49cdfc7eSAndroid Build Coastguard Worker
mem_hog_cpuset(int ntasks)111*49cdfc7eSAndroid Build Coastguard Worker static int mem_hog_cpuset(int ntasks)
112*49cdfc7eSAndroid Build Coastguard Worker {
113*49cdfc7eSAndroid Build Coastguard Worker int i, status, ret = 0;
114*49cdfc7eSAndroid Build Coastguard Worker struct sigaction sa;
115*49cdfc7eSAndroid Build Coastguard Worker pid_t *pids;
116*49cdfc7eSAndroid Build Coastguard Worker
117*49cdfc7eSAndroid Build Coastguard Worker if (ntasks <= 0)
118*49cdfc7eSAndroid Build Coastguard Worker tst_brk(TBROK | TERRNO, "ntasks is small.");
119*49cdfc7eSAndroid Build Coastguard Worker sa.sa_handler = sighandler;
120*49cdfc7eSAndroid Build Coastguard Worker if (sigemptyset(&sa.sa_mask) < 0)
121*49cdfc7eSAndroid Build Coastguard Worker tst_brk(TBROK | TERRNO, "sigemptyset");
122*49cdfc7eSAndroid Build Coastguard Worker sa.sa_flags = 0;
123*49cdfc7eSAndroid Build Coastguard Worker if (sigaction(SIGUSR1, &sa, NULL) < 0)
124*49cdfc7eSAndroid Build Coastguard Worker tst_brk(TBROK | TERRNO, "sigaction");
125*49cdfc7eSAndroid Build Coastguard Worker
126*49cdfc7eSAndroid Build Coastguard Worker pids = SAFE_MALLOC(sizeof(pid_t) * ntasks);
127*49cdfc7eSAndroid Build Coastguard Worker for (i = 0; i < ntasks; i++) {
128*49cdfc7eSAndroid Build Coastguard Worker switch (pids[i] = fork()) {
129*49cdfc7eSAndroid Build Coastguard Worker case -1:
130*49cdfc7eSAndroid Build Coastguard Worker tst_res(TFAIL | TERRNO, "fork %d", pids[i]);
131*49cdfc7eSAndroid Build Coastguard Worker ret = 1;
132*49cdfc7eSAndroid Build Coastguard Worker break;
133*49cdfc7eSAndroid Build Coastguard Worker case 0:
134*49cdfc7eSAndroid Build Coastguard Worker ret = mem_hog();
135*49cdfc7eSAndroid Build Coastguard Worker exit(ret);
136*49cdfc7eSAndroid Build Coastguard Worker default:
137*49cdfc7eSAndroid Build Coastguard Worker break;
138*49cdfc7eSAndroid Build Coastguard Worker }
139*49cdfc7eSAndroid Build Coastguard Worker }
140*49cdfc7eSAndroid Build Coastguard Worker
141*49cdfc7eSAndroid Build Coastguard Worker while (i--) {
142*49cdfc7eSAndroid Build Coastguard Worker if (kill(pids[i], SIGUSR1) == -1) {
143*49cdfc7eSAndroid Build Coastguard Worker tst_res(TFAIL | TERRNO, "kill %d", pids[i]);
144*49cdfc7eSAndroid Build Coastguard Worker ret = 1;
145*49cdfc7eSAndroid Build Coastguard Worker }
146*49cdfc7eSAndroid Build Coastguard Worker }
147*49cdfc7eSAndroid Build Coastguard Worker while (waitpid(-1, &status, WUNTRACED | WCONTINUED) > 0) {
148*49cdfc7eSAndroid Build Coastguard Worker if (WIFEXITED(status)) {
149*49cdfc7eSAndroid Build Coastguard Worker if (WEXITSTATUS(status) != 0) {
150*49cdfc7eSAndroid Build Coastguard Worker tst_res(TFAIL, "child exit status is %d",
151*49cdfc7eSAndroid Build Coastguard Worker WEXITSTATUS(status));
152*49cdfc7eSAndroid Build Coastguard Worker ret = 1;
153*49cdfc7eSAndroid Build Coastguard Worker }
154*49cdfc7eSAndroid Build Coastguard Worker } else if (WIFSIGNALED(status)) {
155*49cdfc7eSAndroid Build Coastguard Worker tst_res(TFAIL, "child caught signal %d",
156*49cdfc7eSAndroid Build Coastguard Worker WTERMSIG(status));
157*49cdfc7eSAndroid Build Coastguard Worker ret = 1;
158*49cdfc7eSAndroid Build Coastguard Worker }
159*49cdfc7eSAndroid Build Coastguard Worker }
160*49cdfc7eSAndroid Build Coastguard Worker return ret;
161*49cdfc7eSAndroid Build Coastguard Worker }
162*49cdfc7eSAndroid Build Coastguard Worker
count_cpu(void)163*49cdfc7eSAndroid Build Coastguard Worker static long count_cpu(void)
164*49cdfc7eSAndroid Build Coastguard Worker {
165*49cdfc7eSAndroid Build Coastguard Worker int ncpus = 0;
166*49cdfc7eSAndroid Build Coastguard Worker
167*49cdfc7eSAndroid Build Coastguard Worker while (path_exist(PATH_SYS_SYSTEM "/cpu/cpu%d", ncpus))
168*49cdfc7eSAndroid Build Coastguard Worker ncpus++;
169*49cdfc7eSAndroid Build Coastguard Worker
170*49cdfc7eSAndroid Build Coastguard Worker return ncpus;
171*49cdfc7eSAndroid Build Coastguard Worker }
172*49cdfc7eSAndroid Build Coastguard Worker
173*49cdfc7eSAndroid Build Coastguard Worker static struct tst_test test = {
174*49cdfc7eSAndroid Build Coastguard Worker .needs_root = 1,
175*49cdfc7eSAndroid Build Coastguard Worker .forks_child = 1,
176*49cdfc7eSAndroid Build Coastguard Worker .setup = setup,
177*49cdfc7eSAndroid Build Coastguard Worker .test_all = test_cpuset,
178*49cdfc7eSAndroid Build Coastguard Worker .needs_cgroup_ctrls = (const char *const []){ "cpuset", NULL },
179*49cdfc7eSAndroid Build Coastguard Worker };
180*49cdfc7eSAndroid Build Coastguard Worker
181*49cdfc7eSAndroid Build Coastguard Worker #else
182*49cdfc7eSAndroid Build Coastguard Worker TST_TEST_TCONF(NUMA_ERROR_MSG);
183*49cdfc7eSAndroid Build Coastguard Worker #endif
184