提交 3fbfadce 编写于 作者: M Martin KaFai Lau 提交者: David S. Miller

bpf: Fix test_lru_sanity5() in test_lru_map.c

test_lru_sanity5() fails when the number of online cpus
is fewer than the number of possible cpus.  It can be
reproduced with qemu by using cmd args "--smp cpus=2,maxcpus=8".

The problem is the loop in test_lru_sanity5() is testing
'i' which is incorrect.

This patch:
1. Make sched_next_online() always return -1 if it cannot
   find a next cpu to schedule the process.
2. In test_lru_sanity5(), the parent process does
   sched_setaffinity() first (through sched_next_online())
   and the forked process will inherit it according to
   the 'man sched_setaffinity'.

Fixes: 5db58faf ("bpf: Add tests for the LRU bpf_htab")
Reported-by: NDaniel Borkmann <daniel@iogearbox.net>
Signed-off-by: NMartin KaFai Lau <kafai@fb.com>
Acked-by: NDaniel Borkmann <daniel@iogearbox.net>
Acked-by: NAlexei Starovoitov <ast@kernel.org>
Signed-off-by: NDavid S. Miller <davem@davemloft.net>
上级 d5ff72d9
...@@ -67,21 +67,23 @@ static int map_equal(int lru_map, int expected) ...@@ -67,21 +67,23 @@ static int map_equal(int lru_map, int expected)
return map_subset(lru_map, expected) && map_subset(expected, lru_map); return map_subset(lru_map, expected) && map_subset(expected, lru_map);
} }
static int sched_next_online(int pid, int next_to_try) static int sched_next_online(int pid, int *next_to_try)
{ {
cpu_set_t cpuset; cpu_set_t cpuset;
int next = *next_to_try;
int ret = -1;
if (next_to_try == nr_cpus) while (next < nr_cpus) {
return -1;
while (next_to_try < nr_cpus) {
CPU_ZERO(&cpuset); CPU_ZERO(&cpuset);
CPU_SET(next_to_try++, &cpuset); CPU_SET(next++, &cpuset);
if (!sched_setaffinity(pid, sizeof(cpuset), &cpuset)) if (!sched_setaffinity(pid, sizeof(cpuset), &cpuset)) {
ret = 0;
break; break;
} }
}
return next_to_try; *next_to_try = next;
return ret;
} }
/* Size of the LRU amp is 2 /* Size of the LRU amp is 2
...@@ -96,11 +98,12 @@ static void test_lru_sanity0(int map_type, int map_flags) ...@@ -96,11 +98,12 @@ static void test_lru_sanity0(int map_type, int map_flags)
{ {
unsigned long long key, value[nr_cpus]; unsigned long long key, value[nr_cpus];
int lru_map_fd, expected_map_fd; int lru_map_fd, expected_map_fd;
int next_cpu = 0;
printf("%s (map_type:%d map_flags:0x%X): ", __func__, map_type, printf("%s (map_type:%d map_flags:0x%X): ", __func__, map_type,
map_flags); map_flags);
assert(sched_next_online(0, 0) != -1); assert(sched_next_online(0, &next_cpu) != -1);
if (map_flags & BPF_F_NO_COMMON_LRU) if (map_flags & BPF_F_NO_COMMON_LRU)
lru_map_fd = create_map(map_type, map_flags, 2 * nr_cpus); lru_map_fd = create_map(map_type, map_flags, 2 * nr_cpus);
...@@ -183,6 +186,7 @@ static void test_lru_sanity1(int map_type, int map_flags, unsigned int tgt_free) ...@@ -183,6 +186,7 @@ static void test_lru_sanity1(int map_type, int map_flags, unsigned int tgt_free)
int lru_map_fd, expected_map_fd; int lru_map_fd, expected_map_fd;
unsigned int batch_size; unsigned int batch_size;
unsigned int map_size; unsigned int map_size;
int next_cpu = 0;
if (map_flags & BPF_F_NO_COMMON_LRU) if (map_flags & BPF_F_NO_COMMON_LRU)
/* Ther percpu lru list (i.e each cpu has its own LRU /* Ther percpu lru list (i.e each cpu has its own LRU
...@@ -196,7 +200,7 @@ static void test_lru_sanity1(int map_type, int map_flags, unsigned int tgt_free) ...@@ -196,7 +200,7 @@ static void test_lru_sanity1(int map_type, int map_flags, unsigned int tgt_free)
printf("%s (map_type:%d map_flags:0x%X): ", __func__, map_type, printf("%s (map_type:%d map_flags:0x%X): ", __func__, map_type,
map_flags); map_flags);
assert(sched_next_online(0, 0) != -1); assert(sched_next_online(0, &next_cpu) != -1);
batch_size = tgt_free / 2; batch_size = tgt_free / 2;
assert(batch_size * 2 == tgt_free); assert(batch_size * 2 == tgt_free);
...@@ -262,6 +266,7 @@ static void test_lru_sanity2(int map_type, int map_flags, unsigned int tgt_free) ...@@ -262,6 +266,7 @@ static void test_lru_sanity2(int map_type, int map_flags, unsigned int tgt_free)
int lru_map_fd, expected_map_fd; int lru_map_fd, expected_map_fd;
unsigned int batch_size; unsigned int batch_size;
unsigned int map_size; unsigned int map_size;
int next_cpu = 0;
if (map_flags & BPF_F_NO_COMMON_LRU) if (map_flags & BPF_F_NO_COMMON_LRU)
/* Ther percpu lru list (i.e each cpu has its own LRU /* Ther percpu lru list (i.e each cpu has its own LRU
...@@ -275,7 +280,7 @@ static void test_lru_sanity2(int map_type, int map_flags, unsigned int tgt_free) ...@@ -275,7 +280,7 @@ static void test_lru_sanity2(int map_type, int map_flags, unsigned int tgt_free)
printf("%s (map_type:%d map_flags:0x%X): ", __func__, map_type, printf("%s (map_type:%d map_flags:0x%X): ", __func__, map_type,
map_flags); map_flags);
assert(sched_next_online(0, 0) != -1); assert(sched_next_online(0, &next_cpu) != -1);
batch_size = tgt_free / 2; batch_size = tgt_free / 2;
assert(batch_size * 2 == tgt_free); assert(batch_size * 2 == tgt_free);
...@@ -370,11 +375,12 @@ static void test_lru_sanity3(int map_type, int map_flags, unsigned int tgt_free) ...@@ -370,11 +375,12 @@ static void test_lru_sanity3(int map_type, int map_flags, unsigned int tgt_free)
int lru_map_fd, expected_map_fd; int lru_map_fd, expected_map_fd;
unsigned int batch_size; unsigned int batch_size;
unsigned int map_size; unsigned int map_size;
int next_cpu = 0;
printf("%s (map_type:%d map_flags:0x%X): ", __func__, map_type, printf("%s (map_type:%d map_flags:0x%X): ", __func__, map_type,
map_flags); map_flags);
assert(sched_next_online(0, 0) != -1); assert(sched_next_online(0, &next_cpu) != -1);
batch_size = tgt_free / 2; batch_size = tgt_free / 2;
assert(batch_size * 2 == tgt_free); assert(batch_size * 2 == tgt_free);
...@@ -430,11 +436,12 @@ static void test_lru_sanity4(int map_type, int map_flags, unsigned int tgt_free) ...@@ -430,11 +436,12 @@ static void test_lru_sanity4(int map_type, int map_flags, unsigned int tgt_free)
int lru_map_fd, expected_map_fd; int lru_map_fd, expected_map_fd;
unsigned long long key, value[nr_cpus]; unsigned long long key, value[nr_cpus];
unsigned long long end_key; unsigned long long end_key;
int next_cpu = 0;
printf("%s (map_type:%d map_flags:0x%X): ", __func__, map_type, printf("%s (map_type:%d map_flags:0x%X): ", __func__, map_type,
map_flags); map_flags);
assert(sched_next_online(0, 0) != -1); assert(sched_next_online(0, &next_cpu) != -1);
if (map_flags & BPF_F_NO_COMMON_LRU) if (map_flags & BPF_F_NO_COMMON_LRU)
lru_map_fd = create_map(map_type, map_flags, lru_map_fd = create_map(map_type, map_flags,
...@@ -502,9 +509,8 @@ static void do_test_lru_sanity5(unsigned long long last_key, int map_fd) ...@@ -502,9 +509,8 @@ static void do_test_lru_sanity5(unsigned long long last_key, int map_fd)
static void test_lru_sanity5(int map_type, int map_flags) static void test_lru_sanity5(int map_type, int map_flags)
{ {
unsigned long long key, value[nr_cpus]; unsigned long long key, value[nr_cpus];
int next_sched_cpu = 0; int next_cpu = 0;
int map_fd; int map_fd;
int i;
if (map_flags & BPF_F_NO_COMMON_LRU) if (map_flags & BPF_F_NO_COMMON_LRU)
return; return;
...@@ -519,27 +525,20 @@ static void test_lru_sanity5(int map_type, int map_flags) ...@@ -519,27 +525,20 @@ static void test_lru_sanity5(int map_type, int map_flags)
key = 0; key = 0;
assert(!bpf_map_update(map_fd, &key, value, BPF_NOEXIST)); assert(!bpf_map_update(map_fd, &key, value, BPF_NOEXIST));
for (i = 0; i < nr_cpus; i++) { while (sched_next_online(0, &next_cpu) != -1) {
pid_t pid; pid_t pid;
pid = fork(); pid = fork();
if (pid == 0) { if (pid == 0) {
next_sched_cpu = sched_next_online(0, next_sched_cpu);
if (next_sched_cpu != -1)
do_test_lru_sanity5(key, map_fd); do_test_lru_sanity5(key, map_fd);
exit(0); exit(0);
} else if (pid == -1) { } else if (pid == -1) {
printf("couldn't spawn #%d process\n", i); printf("couldn't spawn process to test key:%llu\n",
key);
exit(1); exit(1);
} else { } else {
int status; int status;
/* It is mostly redundant and just allow the parent
* process to update next_shced_cpu for the next child
* process
*/
next_sched_cpu = sched_next_online(pid, next_sched_cpu);
assert(waitpid(pid, &status, 0) == pid); assert(waitpid(pid, &status, 0) == pid);
assert(status == 0); assert(status == 0);
key++; key++;
...@@ -547,6 +546,8 @@ static void test_lru_sanity5(int map_type, int map_flags) ...@@ -547,6 +546,8 @@ static void test_lru_sanity5(int map_type, int map_flags)
} }
close(map_fd); close(map_fd);
/* At least one key should be tested */
assert(key > 0);
printf("Pass\n"); printf("Pass\n");
} }
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册