On Mon, Mar 22, 2021 at 09:55:50AM +0100, Antoine Tenart wrote: > I only had a quick look at this, but I think the issue should be fixed > with: > > diff --git a/net/core/net-sysfs.c b/net/core/net-sysfs.c > index e16d54aabd4c..3ae3c20eb64c 100644 > --- a/net/core/net-sysfs.c > +++ b/net/core/net-sysfs.c > @@ -1378,7 +1378,7 @@ static ssize_t xps_queue_show(struct net_device *dev, unsigned int index, > nr_ids = dev_maps ? dev_maps->nr_ids : > (type == XPS_CPUS ? nr_cpu_ids : dev->num_rx_queues); > > - mask = bitmap_zalloc(nr_ids, GFP_KERNEL); > + mask = bitmap_zalloc(nr_ids, GFP_ATOMIC); > if (!mask) { > rcu_read_unlock(); > return -ENOMEM; sysfs isn't a good reason to use GFP_ATOMIC. try something like this: - mask = bitmap_zalloc(nr_ids, GFP_KERNEL); + mask = bitmap_zalloc(nr_ids, GFP_NOWAIT); if (!mask) { + int new_nr_ids; + rcu_read_unlock(); - return -ENOMEM; + mask = bitmap_zalloc(nr_ids, GFP_KERNEL); + if (!mask) + return -ENOMEM; + rcu_read_lock(); + dev_maps = rcu_dereference(dev->xps_maps[type]); + /* if nr_ids shrank while we slept, do not overrun array. + * if it increased, we just won't show the new ones + */ + new_nr_ids = dev_maps ? dev_maps->nr_ids : + (type == XPS_CPUS ? nr_cpu_ids : dev->num_rx_queues); + if (new_nr_ids < nr_ids) + nr_ids = new_nr_ids;