On Fri, Sep 18, 2020 at 10:48 AM Eric Dumazet <eduma...@google.com> wrote:
> > > Also, I would try using synchronize_rcu() instead of the first s/synchronize_rcu/rcu_barrier/ of course :/ > msleep(), this might avoid all msleep() calls in your case. > > Patch without the macros to see the general idea : > > diff --git a/net/core/dev.c b/net/core/dev.c > index > 266073e300b5fc21440ea8f8ffc9306a1fc9f370..2d3b65034bc0dd99017dea846e6c0a966f1207ee > 100644 > --- a/net/core/dev.c > +++ b/net/core/dev.c > @@ -9989,7 +9989,7 @@ EXPORT_SYMBOL(netdev_refcnt_read); > static void netdev_wait_allrefs(struct net_device *dev) > { > unsigned long rebroadcast_time, warning_time; > - int refcnt; > + int wait = 0, refcnt; > > linkwatch_forget_dev(dev); > > @@ -10023,8 +10023,13 @@ static void netdev_wait_allrefs(struct net_device > *dev) > rebroadcast_time = jiffies; > } > > - msleep(250); > - > + if (!wait) { > + synchronize_rcu(); rcu_barrier(); > + wait = 1; > + } else { > + msleep(wait); > + wait = min(wait << 1, 250); > + } > refcnt = netdev_refcnt_read(dev); > > if (refcnt && time_after(jiffies, warning_time + 10 * HZ)) {