> On 6/30/20 2:49 PM, Lorenzo Bianconi wrote: > [...] [...] > > + prog = READ_ONCE(rcpu->prog); > > What purpose does the READ_ONCE() have here, also given you don't use it in above check? > Since upon map update you realloc, repopulate and then xchg() the rcpu entry itself, there > is never the case where you xchg() or WRITE_ONCE() the rcpu->prog, so what does READ_ONCE() > serve in this context? Imho, it should probably just be deleted and plain rcpu->prog used > to avoid confusion. Hi Daniel, ack, I will fix it in v6 > > > + for (i = 0; i < n; i++) { > > + struct xdp_frame *xdpf = 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 { > > + frames[nframes++] = xdpf; > > + stats->pass++; > > + } > > + break; > > + default: > > + bpf_warn_invalid_xdp_action(act); > > + /* fallthrough */ > > + case XDP_DROP: > > + xdp_return_frame(xdpf); > > + stats->drop++; > > + break; > > + } > > + } > > + > > + xdp_clear_return_frame_no_direct(); > > + > > + rcu_read_unlock(); > > + > > + return nframes; > > +} > [...] > > +bool cpu_map_prog_allowed(struct bpf_map *map) > > +{ > > + return map->map_type == BPF_MAP_TYPE_CPUMAP && > > + map->value_size != offsetofend(struct bpf_cpumap_val, qsize); > > +} > > + > > +static int __cpu_map_load_bpf_program(struct bpf_cpu_map_entry *rcpu, int fd) > > +{ > > + struct bpf_prog *prog; > > + > > + prog = bpf_prog_get_type_dev(fd, BPF_PROG_TYPE_XDP, false); > > Nit: why the _dev variant; just use bpf_prog_get_type()? ack, I will fix in v6 Regards, Lorenzo > > > + if (IS_ERR(prog)) > > + return PTR_ERR(prog); > > + > > + if (prog->expected_attach_type != BPF_XDP_CPUMAP) { > > + bpf_prog_put(prog); > > + return -EINVAL; > > + } > > + > > + rcpu->value.bpf_prog.id = prog->aux->id; > > + rcpu->prog = prog; > > + > > + return 0; > > +} > > +