On Sat, 20 Jun 2020 00:57:20 +0200 Lorenzo Bianconi <lorenzo@xxxxxxxxxx> wrote: > +static int cpu_map_bpf_prog_run_xdp(struct bpf_cpu_map_entry *rcpu, > + void **xdp_frames, int n, > + struct xdp_cpumap_stats *stats) > +{ > + struct xdp_rxq_info rxq; I do think we can merge this code as-is (and I actually re-factored this code offlist), but I have some optimizations I would like to try out. E.g. as I've tried to explain over IRC, it will be possible to avoid having to reconstruct xdp_rxq_info here, as we can use the expected_attach_type and remap the BPF instructions to use info from xdp_frame. I want to benchmark it first, to see if it is worth it (we will only save 2 store operations in a likely cache-hot area). > + struct bpf_prog *prog; > + struct xdp_buff xdp; > + int i, nframes = 0; > + > + if (!rcpu->prog) > + return n; > + > + xdp_set_return_frame_no_direct(); > + xdp.rxq = &rxq; > + > + rcu_read_lock(); > + > + prog = READ_ONCE(rcpu->prog); > + for (i = 0; i < n; i++) { > + struct xdp_frame *xdpf = xdp_frames[i]; > + u32 act; > + int err; > + > + rxq.dev = xdpf->dev_rx; > + rxq.mem = xdpf->mem; > + /* TODO: report queue_index to xdp_rxq_info */ > + > + xdp_convert_frame_to_buff(xdpf, &xdp); > + > + act = bpf_prog_run_xdp(prog, &xdp); > + switch (act) { > + case XDP_PASS: > + err = xdp_update_frame_from_buff(&xdp, xdpf); > + if (err < 0) { > + xdp_return_frame(xdpf); > + stats->drop++; > + } else { > + xdp_frames[nframes++] = xdpf; > + stats->pass++; > + } > + break; > + default: > + bpf_warn_invalid_xdp_action(act); > + /* fallthrough */ > + case XDP_DROP: > + xdp_return_frame(xdpf); > + stats->drop++; > + break; > + } > + } > + > + rcu_read_unlock(); > + xdp_clear_return_frame_no_direct(); > + > + return nframes; > +} -- Best regards, Jesper Dangaard Brouer MSc.CS, Principal Kernel Engineer at Red Hat LinkedIn: http://www.linkedin.com/in/brouer