On Fri, Sep 14, 2018 at 1:59 PM Willem de Bruijn <willemdebruijn.ker...@gmail.com> wrote: > > From: Willem de Bruijn <will...@google.com> > > Add net_offload flag NET_OFF_FLAG_GRO_OFF. If set, a net_offload will > not be used for gro receive processing. > > Also add sysctl helper proc_do_net_offload that toggles this flag and > register sysctls net.{core,ipv4,ipv6}.gro > > Signed-off-by: Willem de Bruijn <will...@google.com> > --- > diff --git a/net/core/dev.c b/net/core/dev.c > index 20d9552afd38..0fd5273bc931 100644 > --- a/net/core/dev.c > +++ b/net/core/dev.c > @@ -154,6 +154,7 @@ > #define GRO_MAX_HEAD (MAX_HEADER + 128) > > static DEFINE_SPINLOCK(ptype_lock); > +DEFINE_SPINLOCK(offload_lock); > struct list_head ptype_base[PTYPE_HASH_SIZE] __read_mostly; > struct list_head ptype_all __read_mostly; /* Taps */ > static struct list_head offload_base __read_mostly; > diff --git a/net/core/sysctl_net_core.c b/net/core/sysctl_net_core.c > index b1a2c5e38530..d2d72afdd9eb 100644 > --- a/net/core/sysctl_net_core.c > +++ b/net/core/sysctl_net_core.c > @@ -15,6 +15,7 @@ > #include <linux/vmalloc.h> > #include <linux/init.h> > #include <linux/slab.h> > +#include <linux/bitmap.h> > > #include <net/ip.h> > #include <net/sock.h> > @@ -34,6 +35,58 @@ static int net_msg_warn; /* Unused, but still a sysctl > */ > int sysctl_fb_tunnels_only_for_init_net __read_mostly = 0; > EXPORT_SYMBOL(sysctl_fb_tunnels_only_for_init_net); > > +extern spinlock_t offload_lock; > + > +#define NET_OFF_TBL_LEN 256 > + > +int proc_do_net_offload(struct ctl_table *ctl, int write, void __user > *buffer, > + size_t *lenp, loff_t *ppos) > +{ > + unsigned long bitmap[NET_OFF_TBL_LEN / (sizeof(unsigned long) << 3)]; > + struct ctl_table tbl = { .maxlen = NET_OFF_TBL_LEN, .data = bitmap }; > + unsigned long flag = (unsigned long) ctl->extra2; > + struct net_offload __rcu **offs = ctl->extra1; > + struct net_offload *off; > + int i, ret; > + > + memset(bitmap, 0, sizeof(bitmap)); > + > + spin_lock(&offload_lock); > + > + for (i = 0; i < tbl.maxlen; i++) { > + off = rcu_dereference_protected(offs[i], > lockdep_is_held(&offload_lock)); > + if (off && off->flags & flag) {
This does not actually work as is. No protocol will have this flag set out of the box. I was in the middle of rewriting some of this when it became topical, so I sent it out for discussion. It's bound not to be the only bug of the patchset as is. I'll work through them to get it back in shape.