diff options
Diffstat (limited to 'net/core/dst.c')
| -rw-r--r-- | net/core/dst.c | 14 | 
1 files changed, 14 insertions, 0 deletions
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)  |