samples/bpf: xdp_redirect_cpu_user: Do not update bpf maps in option loop
authorLorenzo Bianconi <lorenzo@kernel.org>
Tue, 14 Jul 2020 13:56:36 +0000 (15:56 +0200)
committerDaniel Borkmann <daniel@iogearbox.net>
Thu, 16 Jul 2020 15:00:31 +0000 (17:00 +0200)
Do not update xdp_redirect_cpu maps running while option loop but
defer it after all available options have been parsed. This is a
preliminary patch to pass the program name we want to attach to the
map entries as a user option

Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
Acked-by: Jesper Dangaard Brouer <brouer@redhat.com>
Link: https://lore.kernel.org/bpf/95dc46286fd2c609042948e04bb7ae1f5b425538.1594734381.git.lorenzo@kernel.org
samples/bpf/xdp_redirect_cpu_user.c

index f4e755e..6bb2d95 100644 (file)
@@ -681,6 +681,7 @@ int main(int argc, char **argv)
        int add_cpu = -1;
        int opt, err;
        int prog_fd;
+       int *cpu, i;
        __u32 qsize;
 
        n_cpus = get_nprocs_conf();
@@ -716,6 +717,13 @@ int main(int argc, char **argv)
        }
        mark_cpus_unavailable();
 
+       cpu = malloc(n_cpus * sizeof(int));
+       if (!cpu) {
+               fprintf(stderr, "failed to allocate cpu array\n");
+               return EXIT_FAIL;
+       }
+       memset(cpu, 0, n_cpus * sizeof(int));
+
        /* Parse commands line args */
        while ((opt = getopt_long(argc, argv, "hSd:s:p:q:c:xzF",
                                  long_options, &longindex)) != -1) {
@@ -760,8 +768,7 @@ int main(int argc, char **argv)
                                        errno, strerror(errno));
                                goto error;
                        }
-                       create_cpu_entry(add_cpu, qsize, added_cpus, true);
-                       added_cpus++;
+                       cpu[added_cpus++] = add_cpu;
                        break;
                case 'q':
                        qsize = atoi(optarg);
@@ -772,6 +779,7 @@ int main(int argc, char **argv)
                case 'h':
                error:
                default:
+                       free(cpu);
                        usage(argv, obj);
                        return EXIT_FAIL_OPTION;
                }
@@ -784,16 +792,21 @@ int main(int argc, char **argv)
        if (ifindex == -1) {
                fprintf(stderr, "ERR: required option --dev missing\n");
                usage(argv, obj);
-               return EXIT_FAIL_OPTION;
+               err = EXIT_FAIL_OPTION;
+               goto out;
        }
        /* Required option */
        if (add_cpu == -1) {
                fprintf(stderr, "ERR: required option --cpu missing\n");
                fprintf(stderr, " Specify multiple --cpu option to add more\n");
                usage(argv, obj);
-               return EXIT_FAIL_OPTION;
+               err = EXIT_FAIL_OPTION;
+               goto out;
        }
 
+       for (i = 0; i < added_cpus; i++)
+               create_cpu_entry(cpu[i], qsize, i, true);
+
        /* Remove XDP program when program is interrupted or killed */
        signal(SIGINT, int_exit);
        signal(SIGTERM, int_exit);
@@ -801,27 +814,32 @@ int main(int argc, char **argv)
        prog = bpf_object__find_program_by_title(obj, prog_name);
        if (!prog) {
                fprintf(stderr, "bpf_object__find_program_by_title failed\n");
-               return EXIT_FAIL;
+               err = EXIT_FAIL;
+               goto out;
        }
 
        prog_fd = bpf_program__fd(prog);
        if (prog_fd < 0) {
                fprintf(stderr, "bpf_program__fd failed\n");
-               return EXIT_FAIL;
+               err = EXIT_FAIL;
+               goto out;
        }
 
        if (bpf_set_link_xdp_fd(ifindex, prog_fd, xdp_flags) < 0) {
                fprintf(stderr, "link set xdp fd failed\n");
-               return EXIT_FAIL_XDP;
+               err = EXIT_FAIL_XDP;
+               goto out;
        }
 
        err = bpf_obj_get_info_by_fd(prog_fd, &info, &info_len);
        if (err) {
                printf("can't get prog info - %s\n", strerror(errno));
-               return err;
+               goto out;
        }
        prog_id = info.id;
 
        stats_poll(interval, use_separators, prog_name, stress_mode);
-       return EXIT_OK;
+out:
+       free(cpu);
+       return err;
 }