Sophie

Sophie

distrib > Scientific%20Linux > 5x > x86_64 > by-pkgid > 27922b4260f65d317aabda37e42bbbff > files > 3054

kernel-2.6.18-238.el5.src.rpm

From: Jiri Olsa <jolsa@redhat.com>
Date: Mon, 22 Mar 2010 08:26:32 -0400
Subject: [net] route: fix BUG_ON in rt_secret_rebuild_oneshot
Message-id: <20100322082632.GB1851@jolsa.sde>
Patchwork-id: 23684
O-Subject: Re: [PATCH RHEL5] BZ#566104 - route: Fix caught BUG_ON during
	rt_secret_rebuild_oneshot()
Bugzilla: 566104
RH-Acked-by: Dean Nelson <dnelson@redhat.com>

Bugzilla: 566104
https://bugzilla.redhat.com/show_bug.cgi?id=566104

Description:
============
Call rt_secret_rebuild can cause BUG_ON(timer_pending(&net->ipv4.rt_secret_timer)) in
add_timer as there is not any synchronization for call rt_secret_rebuild_oneshot()
for the same net namespace.
Also this issue affects to rt_secret_reschedule().
Thus use mod_timer enstead.

Upstream status:
================
- route: Fix caught BUG_ON during rt_secret_rebuild_oneshot()
	commit 858a18a6a2f74e8f0e5b2e9671d4b74694aba708
	Author: Vitaliy Gusev<vgusev@openvz.org>

Brew:
=====
https://brewweb.devel.redhat.com/taskinfo?taskID=2328590

Tested:
=======
booted, I tried to stress setting of secret_interval, but did
not succeed to trigger the BUG

wbr,
jirka

Signed-off-by: Jarod Wilson <jarod@redhat.com>

diff --git a/net/ipv4/route.c b/net/ipv4/route.c
index 8251ce8..261c70f 100644
--- a/net/ipv4/route.c
+++ b/net/ipv4/route.c
@@ -822,11 +822,9 @@ static void rt_secret_rebuild(unsigned long dummy)
 static void rt_secret_rebuild_oneshot(void)
 {
 	del_timer_sync(&rt_secret_timer);
-       rt_cache_flush(0);
-       if (ip_rt_secret_interval) {
-               rt_secret_timer.expires += ip_rt_secret_interval;
-               add_timer(&rt_secret_timer);
-       }
+	rt_cache_flush(0);
+	if (ip_rt_secret_interval)
+		mod_timer(&rt_secret_timer, jiffies + ip_rt_secret_interval);
 }
 
 static void rt_emergency_hash_rebuild(void)
@@ -3134,6 +3132,7 @@ static void rt_secret_reschedule(int old)
 	int new = ip_rt_secret_interval;
 	int diff = new - old;
 	int deleted;
+	long time;
 
 	if (!diff)
 		return;
@@ -3145,17 +3144,14 @@ static void rt_secret_reschedule(int old)
 		goto unlock;
 
 	if (deleted) {
-		long time = rt_secret_timer.expires - jiffies;
+		time = rt_secret_timer.expires - jiffies;
 
 		if (time <= 0 || (time += diff) <= 0)
 			time = 0;
-
-		rt_secret_timer.expires = time;
 	} else
-		rt_secret_timer.expires = new;
+		time = new;
 
-	rt_secret_timer.expires += jiffies;
-	add_timer(&rt_secret_timer);
+	mod_timer(&rt_secret_timer, jiffies + time);
 unlock:
 	rtnl_unlock();
 }