Message ID | 20191126100744.5083-8-prashantbhole.linux@gmail.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | virtio_net XDP offload | expand |
On 11/26/19 4:07 AM, Prashant Bhole wrote: > From: Jason Wang <jasowang@redhat.com> > > This patch introduces an ioctl way to set an offloaded XDP program > to tun driver. This ioctl will be used by qemu to offload XDP program > from virtio_net in the guest. > > Signed-off-by: Jason Wang <jasowang@redhat.com> > Signed-off-by: Prashant Bhole <prashantbhole.linux@gmail.com> > --- > drivers/net/tun.c | 19 ++++++++++++++----- > include/uapi/linux/if_tun.h | 1 + > 2 files changed, 15 insertions(+), 5 deletions(-) > > diff --git a/drivers/net/tun.c b/drivers/net/tun.c > index d078b4659897..ecb49101b0b5 100644 > --- a/drivers/net/tun.c > +++ b/drivers/net/tun.c > @@ -241,6 +241,7 @@ struct tun_struct { > struct bpf_prog __rcu *xdp_prog; > struct tun_prog __rcu *steering_prog; > struct tun_prog __rcu *filter_prog; > + struct tun_prog __rcu *offloaded_xdp_prog; I have been looking into running XDP pograms in the TX path of a tap device [1] where the program is installed and managed by a process in the host. The code paths are the same as what you are doing with XDP offload, so how about calling this xdp_prog_tx? [1] https://github.com/dsahern/linux/commit/f2303d05187c8a604cdb70b288338e9b1d1b0db6
On 11/26/19 4:07 AM, Prashant Bhole wrote: > From: Jason Wang <jasowang@redhat.com> > > This patch introduces an ioctl way to set an offloaded XDP program > to tun driver. This ioctl will be used by qemu to offload XDP program > from virtio_net in the guest. > Seems like you need to set / reset the SOCK_XDP flag on tfile->sk since this is an XDP program. Also, why not add this program using netlink instead of ioctl? e.g., as part of a generic XDP in the egress path like I am looking into for the host side.
On 2019/12/2 上午12:35, David Ahern wrote: > On 11/26/19 4:07 AM, Prashant Bhole wrote: >> From: Jason Wang <jasowang@redhat.com> >> >> This patch introduces an ioctl way to set an offloaded XDP program >> to tun driver. This ioctl will be used by qemu to offload XDP program >> from virtio_net in the guest. >> >> Signed-off-by: Jason Wang <jasowang@redhat.com> >> Signed-off-by: Prashant Bhole <prashantbhole.linux@gmail.com> >> --- >> drivers/net/tun.c | 19 ++++++++++++++----- >> include/uapi/linux/if_tun.h | 1 + >> 2 files changed, 15 insertions(+), 5 deletions(-) >> >> diff --git a/drivers/net/tun.c b/drivers/net/tun.c >> index d078b4659897..ecb49101b0b5 100644 >> --- a/drivers/net/tun.c >> +++ b/drivers/net/tun.c >> @@ -241,6 +241,7 @@ struct tun_struct { >> struct bpf_prog __rcu *xdp_prog; >> struct tun_prog __rcu *steering_prog; >> struct tun_prog __rcu *filter_prog; >> + struct tun_prog __rcu *offloaded_xdp_prog; > I have been looking into running XDP pograms in the TX path of a tap > device [1] where the program is installed and managed by a process in > the host. The code paths are the same as what you are doing with XDP > offload, so how about calling this xdp_prog_tx? > > [1] > https://github.com/dsahern/linux/commit/f2303d05187c8a604cdb70b288338e9b1d1b0db6 > I think it's fine, btw, except for the netlink part there should be no much difference. Thanks
On 2019/12/2 上午12:45, David Ahern wrote: > On 11/26/19 4:07 AM, Prashant Bhole wrote: >> From: Jason Wang <jasowang@redhat.com> >> >> This patch introduces an ioctl way to set an offloaded XDP program >> to tun driver. This ioctl will be used by qemu to offload XDP program >> from virtio_net in the guest. >> > Seems like you need to set / reset the SOCK_XDP flag on tfile->sk since > this is an XDP program. > > Also, why not add this program using netlink instead of ioctl? e.g., as > part of a generic XDP in the egress path like I am looking into for the > host side. Maybe both, otherwise, qemu may need netlink as a dependency. Thanks >
On 12/2/19 11:47 AM, Jason Wang wrote: > > On 2019/12/2 上午12:45, David Ahern wrote: >> On 11/26/19 4:07 AM, Prashant Bhole wrote: >>> From: Jason Wang <jasowang@redhat.com> >>> >>> This patch introduces an ioctl way to set an offloaded XDP program >>> to tun driver. This ioctl will be used by qemu to offload XDP program >>> from virtio_net in the guest. >>> >> Seems like you need to set / reset the SOCK_XDP flag on tfile->sk since >> this is an XDP program. >> >> Also, why not add this program using netlink instead of ioctl? e.g., as >> part of a generic XDP in the egress path like I am looking into for the >> host side. > > > Maybe both, otherwise, qemu may need netlink as a dependency. > > Thanks > Thank you all for reviewing. We will continue to improve this set. If we split this work, Tx path XDP is one of the necessary part which can be developed first. As suggested by David Ahern it will be a netlink way but we will still need ioctl way for tap. I will try to come up with Tx path XDP set next time. Thanks.
diff --git a/drivers/net/tun.c b/drivers/net/tun.c index d078b4659897..ecb49101b0b5 100644 --- a/drivers/net/tun.c +++ b/drivers/net/tun.c @@ -241,6 +241,7 @@ struct tun_struct { struct bpf_prog __rcu *xdp_prog; struct tun_prog __rcu *steering_prog; struct tun_prog __rcu *filter_prog; + struct tun_prog __rcu *offloaded_xdp_prog; struct ethtool_link_ksettings link_ksettings; }; @@ -2256,7 +2257,7 @@ static void tun_prog_free(struct rcu_head *rcu) { struct tun_prog *prog = container_of(rcu, struct tun_prog, rcu); - bpf_prog_destroy(prog->prog); + bpf_prog_put(prog->prog); kfree(prog); } @@ -2301,6 +2302,7 @@ static void tun_free_netdev(struct net_device *dev) security_tun_dev_free_security(tun->security); __tun_set_ebpf(tun, &tun->steering_prog, NULL); __tun_set_ebpf(tun, &tun->filter_prog, NULL); + __tun_set_ebpf(tun, &tun->offloaded_xdp_prog, NULL); } static void tun_setup(struct net_device *dev) @@ -3036,7 +3038,7 @@ static int tun_set_queue(struct file *file, struct ifreq *ifr) } static int tun_set_ebpf(struct tun_struct *tun, struct tun_prog **prog_p, - void __user *data) + void __user *data, int type) { struct bpf_prog *prog; int fd; @@ -3047,7 +3049,7 @@ static int tun_set_ebpf(struct tun_struct *tun, struct tun_prog **prog_p, if (fd == -1) { prog = NULL; } else { - prog = bpf_prog_get_type(fd, BPF_PROG_TYPE_SOCKET_FILTER); + prog = bpf_prog_get_type(fd, type); if (IS_ERR(prog)) return PTR_ERR(prog); } @@ -3345,11 +3347,18 @@ static long __tun_chr_ioctl(struct file *file, unsigned int cmd, break; case TUNSETSTEERINGEBPF: - ret = tun_set_ebpf(tun, &tun->steering_prog, argp); + ret = tun_set_ebpf(tun, &tun->steering_prog, argp, + BPF_PROG_TYPE_SOCKET_FILTER); break; case TUNSETFILTEREBPF: - ret = tun_set_ebpf(tun, &tun->filter_prog, argp); + ret = tun_set_ebpf(tun, &tun->filter_prog, argp, + BPF_PROG_TYPE_SOCKET_FILTER); + break; + + case TUNSETOFFLOADEDXDP: + ret = tun_set_ebpf(tun, &tun->offloaded_xdp_prog, argp, + BPF_PROG_TYPE_XDP); break; case TUNSETCARRIER: diff --git a/include/uapi/linux/if_tun.h b/include/uapi/linux/if_tun.h index 454ae31b93c7..21dbd8db2401 100644 --- a/include/uapi/linux/if_tun.h +++ b/include/uapi/linux/if_tun.h @@ -61,6 +61,7 @@ #define TUNSETFILTEREBPF _IOR('T', 225, int) #define TUNSETCARRIER _IOW('T', 226, int) #define TUNGETDEVNETNS _IO('T', 227) +#define TUNSETOFFLOADEDXDP _IOW('T', 228, int) /* TUNSETIFF ifr flags */ #define IFF_TUN 0x0001