X-Git-Url: https://git.karo-electronics.de/?a=blobdiff_plain;f=net%2Fcore%2Fdst.c;h=13ba4a090c410e40853178df4ffca85f02b71b03;hb=f69d64deedc19ed1345d5e75176671a84e0cccdc;hp=6192f11beec9077de964e2aeff4f78547f08b8da;hpb=c531577bcdac51225f50033e0c89644873f4dc6d;p=karo-tx-linux.git diff --git a/net/core/dst.c b/net/core/dst.c index 6192f11beec9..13ba4a090c41 100644 --- a/net/core/dst.c +++ b/net/core/dst.c @@ -469,6 +469,20 @@ static int dst_dev_event(struct notifier_block *this, unsigned long event, spin_lock_bh(&dst_garbage.lock); dst = dst_garbage.list; dst_garbage.list = NULL; + /* The code in dst_ifdown places a hold on the loopback device. + * If the gc entry processing is set to expire after a lengthy + * interval, this hold can cause netdev_wait_allrefs() to hang + * out and wait for a long time -- until the the loopback + * interface is released. If we're really unlucky, it'll emit + * pr_emerg messages to console too. Reset the interval here, + * so dst cleanups occur in a more timely fashion. + */ + if (dst_garbage.timer_inc > DST_GC_INC) { + dst_garbage.timer_inc = DST_GC_INC; + dst_garbage.timer_expires = DST_GC_MIN; + mod_delayed_work(system_wq, &dst_gc_work, + dst_garbage.timer_expires); + } spin_unlock_bh(&dst_garbage.lock); if (last)