hc
2024-05-10 23fa18eaa71266feff7ba8d83022d9e1cc83c65a
kernel/samples/bpf/map_perf_test_user.c
....@@ -1,8 +1,5 @@
1
+// SPDX-License-Identifier: GPL-2.0-only
12 /* Copyright (c) 2016 Facebook
2
- *
3
- * This program is free software; you can redistribute it and/or
4
- * modify it under the terms of version 2 of the GNU General Public
5
- * License as published by the Free Software Foundation.
63 */
74 #define _GNU_SOURCE
85 #include <sched.h>
....@@ -14,7 +11,6 @@
1411 #include <sys/wait.h>
1512 #include <stdlib.h>
1613 #include <signal.h>
17
-#include <linux/bpf.h>
1814 #include <string.h>
1915 #include <time.h>
2016 #include <sys/resource.h>
....@@ -22,7 +18,7 @@
2218 #include <errno.h>
2319
2420 #include <bpf/bpf.h>
25
-#include "bpf_load.h"
21
+#include <bpf/libbpf.h>
2622
2723 #define TEST_BIT(t) (1U << (t))
2824 #define MAX_NR_CPUS 1024
....@@ -64,12 +60,18 @@
6460 [LRU_HASH_LOOKUP] = "lru_hash_lookup_map",
6561 };
6662
63
+enum map_idx {
64
+ array_of_lru_hashs_idx,
65
+ hash_map_alloc_idx,
66
+ lru_hash_lookup_idx,
67
+ NR_IDXES,
68
+};
69
+
70
+static int map_fd[NR_IDXES];
71
+
6772 static int test_flags = ~0;
6873 static uint32_t num_map_entries;
6974 static uint32_t inner_lru_hash_size;
70
-static int inner_lru_hash_idx = -1;
71
-static int array_of_lru_hashs_idx = -1;
72
-static int lru_hash_lookup_idx = -1;
7375 static int lru_hash_lookup_test_entries = 32;
7476 static uint32_t max_cnt = 1000000;
7577
....@@ -125,30 +127,30 @@
125127 __u64 start_time;
126128 int i, ret;
127129
128
- if (test == INNER_LRU_HASH_PREALLOC) {
130
+ if (test == INNER_LRU_HASH_PREALLOC && cpu) {
131
+ /* If CPU is not 0, create inner_lru hash map and insert the fd
132
+ * value into the array_of_lru_hash map. In case of CPU 0,
133
+ * 'inner_lru_hash_map' was statically inserted on the map init
134
+ */
129135 int outer_fd = map_fd[array_of_lru_hashs_idx];
130136 unsigned int mycpu, mynode;
131137
132138 assert(cpu < MAX_NR_CPUS);
133139
134
- if (cpu) {
135
- ret = syscall(__NR_getcpu, &mycpu, &mynode, NULL);
136
- assert(!ret);
140
+ ret = syscall(__NR_getcpu, &mycpu, &mynode, NULL);
141
+ assert(!ret);
137142
138
- inner_lru_map_fds[cpu] =
139
- bpf_create_map_node(BPF_MAP_TYPE_LRU_HASH,
140
- test_map_names[INNER_LRU_HASH_PREALLOC],
141
- sizeof(uint32_t),
142
- sizeof(long),
143
- inner_lru_hash_size, 0,
144
- mynode);
145
- if (inner_lru_map_fds[cpu] == -1) {
146
- printf("cannot create BPF_MAP_TYPE_LRU_HASH %s(%d)\n",
147
- strerror(errno), errno);
148
- exit(1);
149
- }
150
- } else {
151
- inner_lru_map_fds[cpu] = map_fd[inner_lru_hash_idx];
143
+ inner_lru_map_fds[cpu] =
144
+ bpf_create_map_node(BPF_MAP_TYPE_LRU_HASH,
145
+ test_map_names[INNER_LRU_HASH_PREALLOC],
146
+ sizeof(uint32_t),
147
+ sizeof(long),
148
+ inner_lru_hash_size, 0,
149
+ mynode);
150
+ if (inner_lru_map_fds[cpu] == -1) {
151
+ printf("cannot create BPF_MAP_TYPE_LRU_HASH %s(%d)\n",
152
+ strerror(errno), errno);
153
+ exit(1);
152154 }
153155
154156 ret = bpf_map_update_elem(outer_fd, &cpu,
....@@ -380,7 +382,8 @@
380382 key->data[1] = rand() & 0xff;
381383 key->data[2] = rand() & 0xff;
382384 key->data[3] = rand() & 0xff;
383
- r = bpf_map_update_elem(map_fd[6], key, &value, 0);
385
+ r = bpf_map_update_elem(map_fd[hash_map_alloc_idx],
386
+ key, &value, 0);
384387 assert(!r);
385388 }
386389
....@@ -391,59 +394,52 @@
391394 key->data[3] = 1;
392395 value = 128;
393396
394
- r = bpf_map_update_elem(map_fd[6], key, &value, 0);
397
+ r = bpf_map_update_elem(map_fd[hash_map_alloc_idx], key, &value, 0);
395398 assert(!r);
396399 }
397400
398
-static void fixup_map(struct bpf_map_data *map, int idx)
401
+static void fixup_map(struct bpf_object *obj)
399402 {
403
+ struct bpf_map *map;
400404 int i;
401405
402
- if (!strcmp("inner_lru_hash_map", map->name)) {
403
- inner_lru_hash_idx = idx;
404
- inner_lru_hash_size = map->def.max_entries;
405
- }
406
+ bpf_object__for_each_map(map, obj) {
407
+ const char *name = bpf_map__name(map);
406408
407
- if (!strcmp("array_of_lru_hashs", map->name)) {
408
- if (inner_lru_hash_idx == -1) {
409
- printf("inner_lru_hash_map must be defined before array_of_lru_hashs\n");
410
- exit(1);
409
+ /* Only change the max_entries for the enabled test(s) */
410
+ for (i = 0; i < NR_TESTS; i++) {
411
+ if (!strcmp(test_map_names[i], name) &&
412
+ (check_test_flags(i))) {
413
+ bpf_map__resize(map, num_map_entries);
414
+ continue;
415
+ }
411416 }
412
- map->def.inner_map_idx = inner_lru_hash_idx;
413
- array_of_lru_hashs_idx = idx;
414417 }
415
-
416
- if (!strcmp("lru_hash_lookup_map", map->name))
417
- lru_hash_lookup_idx = idx;
418
-
419
- if (num_map_entries <= 0)
420
- return;
421418
422419 inner_lru_hash_size = num_map_entries;
423
-
424
- /* Only change the max_entries for the enabled test(s) */
425
- for (i = 0; i < NR_TESTS; i++) {
426
- if (!strcmp(test_map_names[i], map->name) &&
427
- (check_test_flags(i))) {
428
- map->def.max_entries = num_map_entries;
429
- }
430
- }
431420 }
432421
433422 int main(int argc, char **argv)
434423 {
435424 struct rlimit r = {RLIM_INFINITY, RLIM_INFINITY};
425
+ int nr_cpus = sysconf(_SC_NPROCESSORS_ONLN);
426
+ struct bpf_link *links[8];
427
+ struct bpf_program *prog;
428
+ struct bpf_object *obj;
429
+ struct bpf_map *map;
436430 char filename[256];
437
- int num_cpu = 8;
431
+ int i = 0;
438432
439
- snprintf(filename, sizeof(filename), "%s_kern.o", argv[0]);
440
- setrlimit(RLIMIT_MEMLOCK, &r);
433
+ if (setrlimit(RLIMIT_MEMLOCK, &r)) {
434
+ perror("setrlimit(RLIMIT_MEMLOCK)");
435
+ return 1;
436
+ }
441437
442438 if (argc > 1)
443439 test_flags = atoi(argv[1]) ? : test_flags;
444440
445441 if (argc > 2)
446
- num_cpu = atoi(argv[2]) ? : num_cpu;
442
+ nr_cpus = atoi(argv[2]) ? : nr_cpus;
447443
448444 if (argc > 3)
449445 num_map_entries = atoi(argv[3]);
....@@ -451,14 +447,61 @@
451447 if (argc > 4)
452448 max_cnt = atoi(argv[4]);
453449
454
- if (load_bpf_file_fixup_map(filename, fixup_map)) {
455
- printf("%s", bpf_log_buf);
456
- return 1;
450
+ snprintf(filename, sizeof(filename), "%s_kern.o", argv[0]);
451
+ obj = bpf_object__open_file(filename, NULL);
452
+ if (libbpf_get_error(obj)) {
453
+ fprintf(stderr, "ERROR: opening BPF object file failed\n");
454
+ return 0;
455
+ }
456
+
457
+ map = bpf_object__find_map_by_name(obj, "inner_lru_hash_map");
458
+ if (libbpf_get_error(map)) {
459
+ fprintf(stderr, "ERROR: finding a map in obj file failed\n");
460
+ goto cleanup;
461
+ }
462
+
463
+ inner_lru_hash_size = bpf_map__max_entries(map);
464
+ if (!inner_lru_hash_size) {
465
+ fprintf(stderr, "ERROR: failed to get map attribute\n");
466
+ goto cleanup;
467
+ }
468
+
469
+ /* resize BPF map prior to loading */
470
+ if (num_map_entries > 0)
471
+ fixup_map(obj);
472
+
473
+ /* load BPF program */
474
+ if (bpf_object__load(obj)) {
475
+ fprintf(stderr, "ERROR: loading BPF object file failed\n");
476
+ goto cleanup;
477
+ }
478
+
479
+ map_fd[0] = bpf_object__find_map_fd_by_name(obj, "array_of_lru_hashs");
480
+ map_fd[1] = bpf_object__find_map_fd_by_name(obj, "hash_map_alloc");
481
+ map_fd[2] = bpf_object__find_map_fd_by_name(obj, "lru_hash_lookup_map");
482
+ if (map_fd[0] < 0 || map_fd[1] < 0 || map_fd[2] < 0) {
483
+ fprintf(stderr, "ERROR: finding a map in obj file failed\n");
484
+ goto cleanup;
485
+ }
486
+
487
+ bpf_object__for_each_program(prog, obj) {
488
+ links[i] = bpf_program__attach(prog);
489
+ if (libbpf_get_error(links[i])) {
490
+ fprintf(stderr, "ERROR: bpf_program__attach failed\n");
491
+ links[i] = NULL;
492
+ goto cleanup;
493
+ }
494
+ i++;
457495 }
458496
459497 fill_lpm_trie();
460498
461
- run_perf_test(num_cpu);
499
+ run_perf_test(nr_cpus);
462500
501
+cleanup:
502
+ for (i--; i >= 0; i--)
503
+ bpf_link__destroy(links[i]);
504
+
505
+ bpf_object__close(obj);
463506 return 0;
464507 }