ipv4: make sure that dst garbage collector is run and finished

when called from device event notifier.

Signed-off-by: Denis V. Lunev <den@parallels.com>
=================================================
--- ./net/core/dst.c.dst1	2008-09-15 10:38:46.000000000 +0400
+++ ./net/core/dst.c	2008-09-29 12:22:36.000000000 +0400
@@ -41,16 +41,20 @@ static void ___dst_free(struct dst_entry
 
 static DEFINE_TIMER(dst_gc_timer, dst_run_gc, DST_GC_MIN, 0);
 
-static void dst_run_gc(unsigned long dummy)
+static void dst_run_gc(unsigned long lock_hard)
 {
 	int    delayed = 0;
 	int    work_performed;
 	struct dst_entry * dst, **dstp;
 
-	if (!spin_trylock(&dst_lock)) {
-		mod_timer(&dst_gc_timer, jiffies + HZ/10);
-		return;
-	}
+	if (!lock_hard)	{
+		if (!spin_trylock(&dst_lock)) {
+			mod_timer(&dst_gc_timer, jiffies + HZ/10);
+			return;
+		}
+	} else
+		/* Device is stopping. No need to hurry */
+		spin_lock(&dst_lock);
 
 	del_timer(&dst_gc_timer);
 	dstp = &dst_garbage_list;
@@ -260,7 +264,7 @@ static int dst_dev_event(struct notifier
 	case NETDEV_UNREGISTER:
 	case NETDEV_DOWN:
 		local_bh_disable();
-		dst_run_gc(0);
+		dst_run_gc(1);
 		spin_lock(&dst_lock);
 		for (dst = dst_garbage_list; dst; dst = dst->next) {
 			dst_ifdown(dst, dev, event != NETDEV_DOWN);
