]> git.proxmox.com Git - mirror_ubuntu-eoan-kernel.git/commitdiff
selftests/bpf: extend the storage test to test per-cpu cgroup storage
authorRoman Gushchin <guro@fb.com>
Fri, 28 Sep 2018 14:45:55 +0000 (14:45 +0000)
committerDaniel Borkmann <daniel@iogearbox.net>
Mon, 1 Oct 2018 14:18:33 +0000 (16:18 +0200)
This test extends the cgroup storage test to use per-cpu flavor
of the cgroup storage as well.

The test initializes a per-cpu cgroup storage to some non-zero initial
value (1000), and then simple bumps a per-cpu counter each time
the shared counter is atomically incremented. Then it reads all
per-cpu areas from the userspace side, and checks that the sum
of values adds to the expected sum.

Expected output:
  $ ./test_cgroup_storage
  test_cgroup_storage:PASS

Signed-off-by: Roman Gushchin <guro@fb.com>
Acked-by: Song Liu <songliubraving@fb.com>
Cc: Daniel Borkmann <daniel@iogearbox.net>
Cc: Alexei Starovoitov <ast@kernel.org>
Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
tools/testing/selftests/bpf/test_cgroup_storage.c

index 4e196e3bfecfddf478800ffbfaa00094fd27be8d..f44834155f25e420270f28a49ece2376c1a95b5a 100644 (file)
@@ -4,6 +4,7 @@
 #include <linux/filter.h>
 #include <stdio.h>
 #include <stdlib.h>
+#include <sys/sysinfo.h>
 
 #include "bpf_rlimit.h"
 #include "cgroup_helpers.h"
@@ -15,6 +16,14 @@ char bpf_log_buf[BPF_LOG_BUF_SIZE];
 int main(int argc, char **argv)
 {
        struct bpf_insn prog[] = {
+               BPF_LD_MAP_FD(BPF_REG_1, 0), /* percpu map fd */
+               BPF_MOV64_IMM(BPF_REG_2, 0), /* flags, not used */
+               BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
+                            BPF_FUNC_get_local_storage),
+               BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_0, 0),
+               BPF_ALU64_IMM(BPF_ADD, BPF_REG_3, 0x1),
+               BPF_STX_MEM(BPF_W, BPF_REG_0, BPF_REG_3, 0),
+
                BPF_LD_MAP_FD(BPF_REG_1, 0), /* map fd */
                BPF_MOV64_IMM(BPF_REG_2, 0), /* flags, not used */
                BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
@@ -28,9 +37,18 @@ int main(int argc, char **argv)
        };
        size_t insns_cnt = sizeof(prog) / sizeof(struct bpf_insn);
        int error = EXIT_FAILURE;
-       int map_fd, prog_fd, cgroup_fd;
+       int map_fd, percpu_map_fd, prog_fd, cgroup_fd;
        struct bpf_cgroup_storage_key key;
        unsigned long long value;
+       unsigned long long *percpu_value;
+       int cpu, nproc;
+
+       nproc = get_nprocs_conf();
+       percpu_value = malloc(sizeof(*percpu_value) * nproc);
+       if (!percpu_value) {
+               printf("Not enough memory for per-cpu area (%d cpus)\n", nproc);
+               goto err;
+       }
 
        map_fd = bpf_create_map(BPF_MAP_TYPE_CGROUP_STORAGE, sizeof(key),
                                sizeof(value), 0, 0);
@@ -39,7 +57,15 @@ int main(int argc, char **argv)
                goto out;
        }
 
-       prog[0].imm = map_fd;
+       percpu_map_fd = bpf_create_map(BPF_MAP_TYPE_PERCPU_CGROUP_STORAGE,
+                                      sizeof(key), sizeof(value), 0, 0);
+       if (percpu_map_fd < 0) {
+               printf("Failed to create map: %s\n", strerror(errno));
+               goto out;
+       }
+
+       prog[0].imm = percpu_map_fd;
+       prog[7].imm = map_fd;
        prog_fd = bpf_load_program(BPF_PROG_TYPE_CGROUP_SKB,
                                   prog, insns_cnt, "GPL", 0,
                                   bpf_log_buf, BPF_LOG_BUF_SIZE);
@@ -77,7 +103,15 @@ int main(int argc, char **argv)
        }
 
        if (bpf_map_lookup_elem(map_fd, &key, &value)) {
-               printf("Failed to lookup cgroup storage\n");
+               printf("Failed to lookup cgroup storage 0\n");
+               goto err;
+       }
+
+       for (cpu = 0; cpu < nproc; cpu++)
+               percpu_value[cpu] = 1000;
+
+       if (bpf_map_update_elem(percpu_map_fd, &key, percpu_value, 0)) {
+               printf("Failed to update the data in the cgroup storage\n");
                goto err;
        }
 
@@ -120,11 +154,31 @@ int main(int argc, char **argv)
                goto err;
        }
 
+       /* Check the final value of the counter in the percpu local storage */
+
+       for (cpu = 0; cpu < nproc; cpu++)
+               percpu_value[cpu] = 0;
+
+       if (bpf_map_lookup_elem(percpu_map_fd, &key, percpu_value)) {
+               printf("Failed to lookup the per-cpu cgroup storage\n");
+               goto err;
+       }
+
+       value = 0;
+       for (cpu = 0; cpu < nproc; cpu++)
+               value += percpu_value[cpu];
+
+       if (value != nproc * 1000 + 6) {
+               printf("Unexpected data in the per-cpu cgroup storage\n");
+               goto err;
+       }
+
        error = 0;
        printf("test_cgroup_storage:PASS\n");
 
 err:
        cleanup_cgroup_environment();
+       free(percpu_value);
 
 out:
        return error;