On Mon, Mar 22, 2021 at 2:26 AM Antoine Tenart <atenart@xxxxxxxxxx> wrote: > > Quoting Matthew Wilcox (2021-03-22 10:05:36) > > 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; > > Thanks for the suggestion, I'll look into that. We could also just > return -ENOMEM if the first allocation fails, retrying adds a lot of > complexity. > > Antoine I agree that the retry logic is probably unneeded. In addition we probably don't need GFP_ATOMIC as GFP_NOWAIT will probably be good enough as the allocation can fail and just return an -ENOMEM in the case of low memory. Thanks. - Alex