Message ID | 20201118191009.3406652-3-weiwan@google.com (mailing list archive) |
---|---|
State | Changes Requested |
Delegated to: | Netdev Maintainers |
Headers | show |
Series | implement kthread based napi poll | expand |
Context | Check | Description |
---|---|---|
netdev/cover_letter | success | Link |
netdev/fixes_present | success | Link |
netdev/patch_count | success | Link |
netdev/tree_selection | success | Clearly marked for net-next |
netdev/subject_prefix | success | Link |
netdev/source_inline | success | Was 0 now: 0 |
netdev/verify_signedoff | success | Link |
netdev/module_param | success | Was 0 now: 0 |
netdev/build_32bit | success | Errors and warnings before: 1 this patch: 1 |
netdev/kdoc | success | Errors and warnings before: 0 this patch: 0 |
netdev/verify_fixes | success | Link |
netdev/checkpatch | success | total: 0 errors, 0 warnings, 0 checks, 115 lines checked |
netdev/build_allmodconfig_warn | success | Errors and warnings before: 1 this patch: 1 |
netdev/header_inline | success | Link |
netdev/stable | success | Stable not CCed |
On 11/18/20 11:10 AM, Wei Wang wrote: > From: Paolo Abeni <pabeni@redhat.com> > > this patch adds a new sysfs attribute to the network > device class. Said attribute is a bitmask that allows controlling > the threaded mode for all the napi instances of the given > network device. > > The threaded mode can be switched only if related network device > is down. > > Signed-off-by: Paolo Abeni <pabeni@redhat.com> > Signed-off-by: Hannes Frederic Sowa <hannes@stressinduktion.org> > Signed-off-by: Wei Wang <weiwan@google.com> > Reviewed-by: Eric Dumazet <edumazet@google.com> Hi, Could someone describe the bitmask (is it a bit per instance of the network device?). And how to use the sysfs interface, please? > --- > net/core/net-sysfs.c | 103 +++++++++++++++++++++++++++++++++++++++++++ > 1 file changed, 103 insertions(+) > > diff --git a/net/core/net-sysfs.c b/net/core/net-sysfs.c > index 94fff0700bdd..df8dd25e5e4b 100644 > --- a/net/core/net-sysfs.c > +++ b/net/core/net-sysfs.c thanks.
On Wed, Nov 18, 2020 at 12:36 PM Randy Dunlap <rdunlap@infradead.org> wrote: > > On 11/18/20 11:10 AM, Wei Wang wrote: > > From: Paolo Abeni <pabeni@redhat.com> > > > > this patch adds a new sysfs attribute to the network > > device class. Said attribute is a bitmask that allows controlling > > the threaded mode for all the napi instances of the given > > network device. > > > > The threaded mode can be switched only if related network device > > is down. > > > > Signed-off-by: Paolo Abeni <pabeni@redhat.com> > > Signed-off-by: Hannes Frederic Sowa <hannes@stressinduktion.org> > > Signed-off-by: Wei Wang <weiwan@google.com> > > Reviewed-by: Eric Dumazet <edumazet@google.com> > > Hi, > > Could someone describe the bitmask (is it a bit per instance of the > network device?). > And how to use the sysfs interface, please? > It is 1 bit per napi. Depending on the driver implementation, 1 napi could correspond to 1 tx queue, or 1 rx queue, or 1 pair of tx/rx queues. To set bits in the bit mask, you could do: echo 0-14 > /sys/class/net/<dev>/threaded to set consecutive bits. or: echo 0,2,4,6,8 > /sys/class/net/<dev>/threaded to set individual bits. To clear the bit mask, you could do: echo > /sys/class/net/<dev>/threaded > > --- > > net/core/net-sysfs.c | 103 +++++++++++++++++++++++++++++++++++++++++++ > > 1 file changed, 103 insertions(+) > > > > diff --git a/net/core/net-sysfs.c b/net/core/net-sysfs.c > > index 94fff0700bdd..df8dd25e5e4b 100644 > > --- a/net/core/net-sysfs.c > > +++ b/net/core/net-sysfs.c > > > thanks. > -- > ~Randy >
diff --git a/net/core/net-sysfs.c b/net/core/net-sysfs.c index 94fff0700bdd..df8dd25e5e4b 100644 --- a/net/core/net-sysfs.c +++ b/net/core/net-sysfs.c @@ -538,6 +538,108 @@ static ssize_t phys_switch_id_show(struct device *dev, } static DEVICE_ATTR_RO(phys_switch_id); +static unsigned long *__alloc_thread_bitmap(struct net_device *netdev, + int *bits) +{ + struct napi_struct *n; + + *bits = 0; + list_for_each_entry(n, &netdev->napi_list, dev_list) + (*bits)++; + + return kmalloc_array(BITS_TO_LONGS(*bits), sizeof(unsigned long), + GFP_ATOMIC | __GFP_ZERO); +} + +static ssize_t threaded_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct net_device *netdev = to_net_dev(dev); + struct napi_struct *n; + unsigned long *bmap; + size_t count = 0; + int i, bits; + + if (!rtnl_trylock()) + return restart_syscall(); + + if (!dev_isalive(netdev)) + goto unlock; + + bmap = __alloc_thread_bitmap(netdev, &bits); + if (!bmap) { + count = -ENOMEM; + goto unlock; + } + + i = 0; + list_for_each_entry(n, &netdev->napi_list, dev_list) { + if (test_bit(NAPI_STATE_THREADED, &n->state)) + set_bit(i, bmap); + i++; + } + + count = bitmap_print_to_pagebuf(true, buf, bmap, bits); + kfree(bmap); + +unlock: + rtnl_unlock(); + + return count; +} + +static ssize_t threaded_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t len) +{ + struct net_device *netdev = to_net_dev(dev); + struct napi_struct *n; + unsigned long *bmap; + int i, bits; + size_t ret; + + if (!capable(CAP_NET_ADMIN)) + return -EPERM; + + if (!rtnl_trylock()) + return restart_syscall(); + + if (!dev_isalive(netdev)) { + ret = len; + goto unlock; + } + + if (netdev->flags & IFF_UP) { + ret = -EBUSY; + goto unlock; + } + + bmap = __alloc_thread_bitmap(netdev, &bits); + if (!bmap) { + ret = -ENOMEM; + goto unlock; + } + + ret = bitmap_parselist(buf, bmap, bits); + if (ret) + goto free_unlock; + + i = 0; + list_for_each_entry(n, &netdev->napi_list, dev_list) { + napi_set_threaded(n, test_bit(i, bmap)); + i++; + } + ret = len; + +free_unlock: + kfree(bmap); + +unlock: + rtnl_unlock(); + return ret; +} +static DEVICE_ATTR_RW(threaded); + static struct attribute *net_class_attrs[] __ro_after_init = { &dev_attr_netdev_group.attr, &dev_attr_type.attr, @@ -570,6 +672,7 @@ static struct attribute *net_class_attrs[] __ro_after_init = { &dev_attr_proto_down.attr, &dev_attr_carrier_up_count.attr, &dev_attr_carrier_down_count.attr, + &dev_attr_threaded.attr, NULL, }; ATTRIBUTE_GROUPS(net_class);