xdp-project / xdp-tutorial

XDP tutorial
2.51k stars 583 forks source link

basic04 reuse pinned map failed. #402

Open daiminglong opened 9 months ago

daiminglong commented 9 months ago

I have tried something below try to reuse a pinned map: step 1) load a prog to my test dev: $ ./xdp_loader --dev test

step 2) do ping ops inside the custom NS with: $ ./testenv.sh ping Running ping from inside test environment:

PING fc00:dead:cafe:1::1(fc00:dead:cafe:1::1) 56 data bytes 64 bytes from fc00:dead:cafe:1::1: icmp_seq=1 ttl=64 time=0.026 ms 64 bytes from fc00:dead:cafe:1::1: icmp_seq=2 ttl=64 time=0.040 ms 64 bytes from fc00:dead:cafe:1::1: icmp_seq=3 ttl=64 time=0.037 ms 64 bytes from fc00:dead:cafe:1::1: icmp_seq=4 ttl=64 time=0.038 ms 64 bytes from fc00:dead:cafe:1::1: icmp_seq=5 ttl=64 time=0.038 ms 64 bytes from fc00:dead:cafe:1::1: icmp_seq=6 ttl=64 time=0.037 ms 64 bytes from fc00:dead:cafe:1::1: icmp_seq=7 ttl=64 time=0.040 ms

step3) start a stat process, and it start print XDP-action stats(XDP_PASS has increased step by step like below): $ ./xdp_stats --dev test XDP-action XDP_ABORTED 0 pkts ( 0 pps) 0 Kbytes ( 0 Mbits/s) period:2.000120 XDP_DROP 0 pkts ( 0 pps) 0 Kbytes ( 0 Mbits/s) period:2.000120 XDP_PASS 1 pkts ( 0 pps) 0 Kbytes ( 0 Mbits/s) period:2.000120 XDP_TX 0 pkts ( 0 pps) 0 Kbytes ( 0 Mbits/s) period:2.000120 XDP_REDIRECT 0 pkts ( 0 pps) 0 Kbytes ( 0 Mbits/s) period:2.000120

XDP-action XDP_ABORTED 0 pkts ( 0 pps) 0 Kbytes ( 0 Mbits/s) period:2.000124 XDP_DROP 0 pkts ( 0 pps) 0 Kbytes ( 0 Mbits/s) period:2.000124 XDP_PASS 3 pkts ( 1 pps) 0 Kbytes ( 0 Mbits/s) period:2.000124 XDP_TX 0 pkts ( 0 pps) 0 Kbytes ( 0 Mbits/s) period:2.000124 XDP_REDIRECT 0 pkts ( 0 pps) 0 Kbytes ( 0 Mbits/s) period:2.000124 ...

step4) I unloaded the xdp prog with: $ ./xdp_loader --dev test --unload-all

step5) I reload the xdp prog with resuse map logic like below: $ ./xdp_loader --dev test

reuse logic is refered to assigment: WeChatWorkScreenshot_f708dec0-cab5-4dff-9c95-4b43081def5e

but the statistics value of XDP_PASS stopped, even that PING ops just going on: XDP-action XDP_ABORTED 0 pkts ( 0 pps) 0 Kbytes ( 0 Mbits/s) period:2.000135 XDP_DROP 0 pkts ( 0 pps) 0 Kbytes ( 0 Mbits/s) period:2.000135 XDP_PASS 65 pkts ( 0 pps) 7 Kbytes ( 0 Mbits/s) period:2.000135 XDP_TX 0 pkts ( 0 pps) 0 Kbytes ( 0 Mbits/s) period:2.000135 XDP_REDIRECT 0 pkts ( 0 pps) 0 Kbytes ( 0 Mbits/s) period:2.000134

XDP-action XDP_ABORTED 0 pkts ( 0 pps) 0 Kbytes ( 0 Mbits/s) period:2.000112 XDP_DROP 0 pkts ( 0 pps) 0 Kbytes ( 0 Mbits/s) period:2.000112 XDP_PASS 65 pkts ( 0 pps) 7 Kbytes ( 0 Mbits/s) period:2.000112 XDP_TX 0 pkts ( 0 pps) 0 Kbytes ( 0 Mbits/s) period:2.000112 XDP_REDIRECT 0 pkts ( 0 pps) 0 Kbytes ( 0 Mbits/s) period:2.000112

XDP-action XDP_ABORTED 0 pkts ( 0 pps) 0 Kbytes ( 0 Mbits/s) period:2.000139 XDP_DROP 0 pkts ( 0 pps) 0 Kbytes ( 0 Mbits/s) period:2.000139 XDP_PASS 65 pkts ( 0 pps) 7 Kbytes ( 0 Mbits/s) period:2.000139 XDP_TX 0 pkts ( 0 pps) 0 Kbytes ( 0 Mbits/s) period:2.000139 XDP_REDIRECT 0 pkts ( 0 pps) 0 Kbytes ( 0 Mbits/s) period:2.000139

It seems I failed, what's wrong and what should I do. Thks for help, plz:) @tohojo

tohojo commented 8 months ago

Well, things to check:

You can use bpftool to check if there's more than one map loaded into the kernel, which could be an indication that the XDP program and the userspace program don't agree on which one they are using...

daiminglong commented 8 months ago

Well, things to check:

  • Are the maps still pinned after you unload the program?
  • Is bpf_map__reuse_fd() succeeding?
  • Is the XDP program using the same map ID on first and second load (check with bpftool)?
  • Is the userspace program that's printing the stats polling the right map (the pinned one)?

You can use bpftool to check if there's more than one map loaded into the kernel, which could be an indication that the XDP program and the userspace program don't agree on which one they are using...

thks for you help. the key point is I did not do reuse map ops between load the prog ops & attach prog ops as the assignment hints described, the solution guide did not give the right answer, I have figured out the way just like below:

static int reuse_maps(struct bpf_object *obj, const char *path)
{
    struct bpf_map *map;

    if (!obj)
        return -ENOENT;

    if (!path)
        return -EINVAL;

    bpf_object__for_each_map(map, obj) {
        int len, err;
        int pinned_map_fd;
        char buf[PATH_MAX];

        len = snprintf(buf, PATH_MAX, "%s/%s", path, bpf_map__name(map));
        printf("try to reuse map: %s\n", buf);
        if (len < 0) {
            return -EINVAL;
        } else if (len >= PATH_MAX) {
            return -ENAMETOOLONG;
        }

        pinned_map_fd = bpf_obj_get(buf);
        if (pinned_map_fd < 0)
            return pinned_map_fd;

        err = bpf_map__reuse_fd(map, pinned_map_fd);
        if (err)
            return err;
    }

    return 0;
}

struct bpf_object *load_bpf_object_file_reuse_maps(const char *file,
                           const char *pin_dir)
{
    int err;
    struct bpf_object *obj;

    obj = bpf_object__open(file);
    if (!obj) {
        fprintf(stderr, "ERR: failed to open object %s\n", file);
        return NULL;
    }

    err = reuse_maps(obj, pin_dir);
    if (err) {
        fprintf(stderr, "ERR: failed to reuse maps for object %s, pin_dir=%s\n",
                file, pin_dir);
        return NULL;
    }

    err = bpf_object__load(obj);
    if (err) {
        fprintf(stderr, "ERR: loading BPF-OBJ file(%s) (%d): %s\n",
            file, err, strerror(-err));
        return NULL;
    }

    return obj;
}

// code in xdp_loader.c
if (cfg.reuse_maps) {
    struct bpf_object *objx = NULL;
    // 1) do load & map reuse
    objx = load_bpf_object_file_reuse_maps(cfg.filename, cfg.pin_dir);
    if (objx == NULL) {
        fprintf(stderr, "ERR, failed to load object with reuse map");
        return EXIT_FAIL_BPF;
    }
    // 2) create xdp prog from bpf object & do attach
    program = xdp_program__from_bpf_obj(objx, "xdp");
    if (program == NULL)  {
        fprintf(stderr, "ERR, failed to find program with reuse map");
        return EXIT_FAIL_BPF;
    }
    err = xdp_program__attach(program, cfg.ifindex, cfg.attach_mode, 0);
    if (err) {
        fprintf(stderr, "ERR, failed to attach program with reuse map");
        return EXIT_FAIL_BPF;
    }
    return EXIT_OK;
}