aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMartin KaFai Lau <kafai@fb.com>2017-01-17 01:17:29 -0500
committerDavid S. Miller <davem@davemloft.net>2017-01-17 15:39:39 -0500
commit3fbfadce6012e7bb384b2e9ad47869d5177f7209 (patch)
treec768617d6b7949b5b4bb75c6b2e58b08b4e1f6ea
parentd5ff72d9af73bc3cbaa3edb541333a851f8c7295 (diff)
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: 5db58faf989f ("bpf: Add tests for the LRU bpf_htab") Reported-by: Daniel Borkmann <daniel@iogearbox.net> Signed-off-by: Martin KaFai Lau <kafai@fb.com> Acked-by: Daniel Borkmann <daniel@iogearbox.net> Acked-by: Alexei Starovoitov <ast@kernel.org> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--tools/testing/selftests/bpf/test_lru_map.c53
1 files changed, 27 insertions, 26 deletions
diff --git a/tools/testing/selftests/bpf/test_lru_map.c b/tools/testing/selftests/bpf/test_lru_map.c
index b13fed534d76..9f7bd1915c21 100644
--- a/tools/testing/selftests/bpf/test_lru_map.c
+++ b/tools/testing/selftests/bpf/test_lru_map.c
@@ -67,21 +67,23 @@ static int map_equal(int lru_map, int expected)
67 return map_subset(lru_map, expected) && map_subset(expected, lru_map); 67 return map_subset(lru_map, expected) && map_subset(expected, lru_map);
68} 68}
69 69
70static int sched_next_online(int pid, int next_to_try) 70static int sched_next_online(int pid, int *next_to_try)
71{ 71{
72 cpu_set_t cpuset; 72 cpu_set_t cpuset;
73 int next = *next_to_try;
74 int ret = -1;
73 75
74 if (next_to_try == nr_cpus) 76 while (next < nr_cpus) {
75 return -1;
76
77 while (next_to_try < nr_cpus) {
78 CPU_ZERO(&cpuset); 77 CPU_ZERO(&cpuset);
79 CPU_SET(next_to_try++, &cpuset); 78 CPU_SET(next++, &cpuset);
80 if (!sched_setaffinity(pid, sizeof(cpuset), &cpuset)) 79 if (!sched_setaffinity(pid, sizeof(cpuset), &cpuset)) {
80 ret = 0;
81 break; 81 break;
82 }
82 } 83 }
83 84
84 return next_to_try; 85 *next_to_try = next;
86 return ret;
85} 87}
86 88
87/* Size of the LRU amp is 2 89/* Size of the LRU amp is 2
@@ -96,11 +98,12 @@ static void test_lru_sanity0(int map_type, int map_flags)
96{ 98{
97 unsigned long long key, value[nr_cpus]; 99 unsigned long long key, value[nr_cpus];
98 int lru_map_fd, expected_map_fd; 100 int lru_map_fd, expected_map_fd;
101 int next_cpu = 0;
99 102
100 printf("%s (map_type:%d map_flags:0x%X): ", __func__, map_type, 103 printf("%s (map_type:%d map_flags:0x%X): ", __func__, map_type,
101 map_flags); 104 map_flags);
102 105
103 assert(sched_next_online(0, 0) != -1); 106 assert(sched_next_online(0, &next_cpu) != -1);
104 107
105 if (map_flags & BPF_F_NO_COMMON_LRU) 108 if (map_flags & BPF_F_NO_COMMON_LRU)
106 lru_map_fd = create_map(map_type, map_flags, 2 * nr_cpus); 109 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 int lru_map_fd, expected_map_fd; 186 int lru_map_fd, expected_map_fd;
184 unsigned int batch_size; 187 unsigned int batch_size;
185 unsigned int map_size; 188 unsigned int map_size;
189 int next_cpu = 0;
186 190
187 if (map_flags & BPF_F_NO_COMMON_LRU) 191 if (map_flags & BPF_F_NO_COMMON_LRU)
188 /* Ther percpu lru list (i.e each cpu has its own LRU 192 /* 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 printf("%s (map_type:%d map_flags:0x%X): ", __func__, map_type, 200 printf("%s (map_type:%d map_flags:0x%X): ", __func__, map_type,
197 map_flags); 201 map_flags);
198 202
199 assert(sched_next_online(0, 0) != -1); 203 assert(sched_next_online(0, &next_cpu) != -1);
200 204
201 batch_size = tgt_free / 2; 205 batch_size = tgt_free / 2;
202 assert(batch_size * 2 == tgt_free); 206 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 int lru_map_fd, expected_map_fd; 266 int lru_map_fd, expected_map_fd;
263 unsigned int batch_size; 267 unsigned int batch_size;
264 unsigned int map_size; 268 unsigned int map_size;
269 int next_cpu = 0;
265 270
266 if (map_flags & BPF_F_NO_COMMON_LRU) 271 if (map_flags & BPF_F_NO_COMMON_LRU)
267 /* Ther percpu lru list (i.e each cpu has its own LRU 272 /* 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 printf("%s (map_type:%d map_flags:0x%X): ", __func__, map_type, 280 printf("%s (map_type:%d map_flags:0x%X): ", __func__, map_type,
276 map_flags); 281 map_flags);
277 282
278 assert(sched_next_online(0, 0) != -1); 283 assert(sched_next_online(0, &next_cpu) != -1);
279 284
280 batch_size = tgt_free / 2; 285 batch_size = tgt_free / 2;
281 assert(batch_size * 2 == tgt_free); 286 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 int lru_map_fd, expected_map_fd; 375 int lru_map_fd, expected_map_fd;
371 unsigned int batch_size; 376 unsigned int batch_size;
372 unsigned int map_size; 377 unsigned int map_size;
378 int next_cpu = 0;
373 379
374 printf("%s (map_type:%d map_flags:0x%X): ", __func__, map_type, 380 printf("%s (map_type:%d map_flags:0x%X): ", __func__, map_type,
375 map_flags); 381 map_flags);
376 382
377 assert(sched_next_online(0, 0) != -1); 383 assert(sched_next_online(0, &next_cpu) != -1);
378 384
379 batch_size = tgt_free / 2; 385 batch_size = tgt_free / 2;
380 assert(batch_size * 2 == tgt_free); 386 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 int lru_map_fd, expected_map_fd; 436 int lru_map_fd, expected_map_fd;
431 unsigned long long key, value[nr_cpus]; 437 unsigned long long key, value[nr_cpus];
432 unsigned long long end_key; 438 unsigned long long end_key;
439 int next_cpu = 0;
433 440
434 printf("%s (map_type:%d map_flags:0x%X): ", __func__, map_type, 441 printf("%s (map_type:%d map_flags:0x%X): ", __func__, map_type,
435 map_flags); 442 map_flags);
436 443
437 assert(sched_next_online(0, 0) != -1); 444 assert(sched_next_online(0, &next_cpu) != -1);
438 445
439 if (map_flags & BPF_F_NO_COMMON_LRU) 446 if (map_flags & BPF_F_NO_COMMON_LRU)
440 lru_map_fd = create_map(map_type, map_flags, 447 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)
502static void test_lru_sanity5(int map_type, int map_flags) 509static void test_lru_sanity5(int map_type, int map_flags)
503{ 510{
504 unsigned long long key, value[nr_cpus]; 511 unsigned long long key, value[nr_cpus];
505 int next_sched_cpu = 0; 512 int next_cpu = 0;
506 int map_fd; 513 int map_fd;
507 int i;
508 514
509 if (map_flags & BPF_F_NO_COMMON_LRU) 515 if (map_flags & BPF_F_NO_COMMON_LRU)
510 return; 516 return;
@@ -519,27 +525,20 @@ static void test_lru_sanity5(int map_type, int map_flags)
519 key = 0; 525 key = 0;
520 assert(!bpf_map_update(map_fd, &key, value, BPF_NOEXIST)); 526 assert(!bpf_map_update(map_fd, &key, value, BPF_NOEXIST));
521 527
522 for (i = 0; i < nr_cpus; i++) { 528 while (sched_next_online(0, &next_cpu) != -1) {
523 pid_t pid; 529 pid_t pid;
524 530
525 pid = fork(); 531 pid = fork();
526 if (pid == 0) { 532 if (pid == 0) {
527 next_sched_cpu = sched_next_online(0, next_sched_cpu); 533 do_test_lru_sanity5(key, map_fd);
528 if (next_sched_cpu != -1)
529 do_test_lru_sanity5(key, map_fd);
530 exit(0); 534 exit(0);
531 } else if (pid == -1) { 535 } else if (pid == -1) {
532 printf("couldn't spawn #%d process\n", i); 536 printf("couldn't spawn process to test key:%llu\n",
537 key);
533 exit(1); 538 exit(1);
534 } else { 539 } else {
535 int status; 540 int status;
536 541
537 /* It is mostly redundant and just allow the parent
538 * process to update next_shced_cpu for the next child
539 * process
540 */
541 next_sched_cpu = sched_next_online(pid, next_sched_cpu);
542
543 assert(waitpid(pid, &status, 0) == pid); 542 assert(waitpid(pid, &status, 0) == pid);
544 assert(status == 0); 543 assert(status == 0);
545 key++; 544 key++;
@@ -547,6 +546,8 @@ static void test_lru_sanity5(int map_type, int map_flags)
547 } 546 }
548 547
549 close(map_fd); 548 close(map_fd);
549 /* At least one key should be tested */
550 assert(key > 0);
550 551
551 printf("Pass\n"); 552 printf("Pass\n");
552} 553}