netdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Patrick McHardy <kaber@trash.net>
To: David Miller <davem@davemloft.net>
Cc: Jarek Poplawski <jarkao2@o2.pl>,
	Andrew Morton <akpm@linux-foundation.org>,
	netdev@vger.kernel.org,
	"bugme-daemon@kernel-bugs.osdl.org"
	<bugme-daemon@kernel-bugs.osdl.org>,
	ranko@spidernet.net
Subject: [NET]: gen_estimator: fix locking and timer related bugs [Re: [Bugme-new] [Bug 8668] New: HTB Deadlock]
Date: Wed, 27 Jun 2007 17:09:37 +0200	[thread overview]
Message-ID: <46827DB1.3060509@trash.net> (raw)
In-Reply-To: <468279FC.3070502@trash.net>

[-- Attachment #1: Type: text/plain, Size: 490 bytes --]

Patrick McHardy wrote:
> Jarek Poplawski wrote:
>> I look at this just now, and maybe it's enough for asking,
>> but definitely not enough for patch. I'll try to check this
>> more in the evening, so I could send something tomorrow.
>>
>> So if it's not only about kindness, feel free to do it
>> sooner and I've no doubts  - better.
>
> I can take care of it, no problem. 


OK, this patch should fix the Jarek noticed (and a few more).
It does not fix the original HTB problem though.




[-- Attachment #2: x --]
[-- Type: text/plain, Size: 3180 bytes --]

[NET]: gen_estimator: fix locking and timer related bugs

As noticed by Jarek Poplawski <jarkao2@o2.pl>, the timer removal in
gen_kill_estimator races with the timer function rearming the timer.

Additionally there are a few more related problems that seem to be
relicts from the time when the estimator was qdisc specific and
could rely on the rtnl or dev->qdisc_lock:

- the check whether the list is empty and a timer needs to be started
  when adding a new estimator doesn't take the lock, so it races
  against concurrent additions, which can result in the timer getting
  added twice or getting reinitialized after getting added.

- the new estimator's next pointer is also set without holding the
  lock, again racing against concurrent additions with possible
  list corruption as a result.

- the timer deletion when killing an estimator is also not under
  the lock and races against timer arming when adding a new estimator.

Fix by holding the lock around the entire list addition and initial
timer arming. Timer removal is not done explicitly anymore, instead
the timer function only rearms the timer when there are still
estimators present.

Signed-off-by: Patrick McHardy <kaber@trash.net>

---
commit 59b5997f78c3cf3366886969ac8e6b38100b30e9
tree 9b43ce1af21ad1c8817f1f2bc8291c0f60457a4e
parent 48d8d7ee5dd17c64833e0343ab4ae8ef01cc2648
author Patrick McHardy <kaber@trash.net> Wed, 27 Jun 2007 17:06:02 +0200
committer Patrick McHardy <kaber@trash.net> Wed, 27 Jun 2007 17:06:02 +0200

 net/core/gen_estimator.c |   10 +++-------
 1 files changed, 3 insertions(+), 7 deletions(-)

diff --git a/net/core/gen_estimator.c b/net/core/gen_estimator.c
index 17daf4c..49a0bd3 100644
--- a/net/core/gen_estimator.c
+++ b/net/core/gen_estimator.c
@@ -127,8 +127,8 @@ static void est_timer(unsigned long arg)
 		e->rate_est->pps = (e->avpps+0x1FF)>>10;
 		spin_unlock(e->stats_lock);
 	}
-
-	mod_timer(&elist[idx].timer, jiffies + ((HZ<<idx)/4));
+	if (elist[idx].list != NULL)
+		mod_timer(&elist[idx].timer, jiffies + ((HZ<<idx)/4));
 	read_unlock(&est_lock);
 }
 
@@ -173,6 +173,7 @@ int gen_new_estimator(struct gnet_stats_basic *bstats,
 	est->last_packets = bstats->packets;
 	est->avpps = rate_est->pps<<10;
 
+	write_lock_bh(&est_lock);
 	est->next = elist[est->interval].list;
 	if (est->next == NULL) {
 		init_timer(&elist[est->interval].timer);
@@ -181,7 +182,6 @@ int gen_new_estimator(struct gnet_stats_basic *bstats,
 		elist[est->interval].timer.function = est_timer;
 		add_timer(&elist[est->interval].timer);
 	}
-	write_lock_bh(&est_lock);
 	elist[est->interval].list = est;
 	write_unlock_bh(&est_lock);
 	return 0;
@@ -202,7 +202,6 @@ void gen_kill_estimator(struct gnet_stats_basic *bstats,
 	struct gen_estimator *est, **pest;
 
 	for (idx=0; idx <= EST_MAX_INTERVAL; idx++) {
-		int killed = 0;
 		pest = &elist[idx].list;
 		while ((est=*pest) != NULL) {
 			if (est->rate_est != rate_est || est->bstats != bstats) {
@@ -215,10 +214,7 @@ void gen_kill_estimator(struct gnet_stats_basic *bstats,
 			write_unlock_bh(&est_lock);
 
 			kfree(est);
-			killed++;
 		}
-		if (killed && elist[idx].list == NULL)
-			del_timer(&elist[idx].timer);
 	}
 }
 

  reply	other threads:[~2007-06-27 15:10 UTC|newest]

Thread overview: 24+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
     [not found] <bug-8668-10286@http.bugzilla.kernel.org/>
2007-06-25  5:24 ` [Bugme-new] [Bug 8668] New: HTB Deadlock Andrew Morton
2007-06-25  9:28   ` Patrick McHardy
2007-06-25  9:30     ` Patrick McHardy
2007-06-25 11:37       ` Ranko Zivojnovic
2007-06-27 11:45     ` Jarek Poplawski
2007-06-27 11:44       ` Patrick McHardy
2007-06-27 12:10         ` Jarek Poplawski
2007-06-27 12:30           ` Jarek Poplawski
2007-06-27 14:53           ` Patrick McHardy
2007-06-27 15:09             ` Patrick McHardy [this message]
2007-06-27 15:25               ` [NET]: gen_estimator: fix locking and timer related bugs [Re: [Bugme-new] [Bug 8668] New: HTB Deadlock] Patrick McHardy
2007-06-28  6:54                 ` Jarek Poplawski
2007-06-28  9:56                   ` Jarek Poplawski
2007-06-28  9:13                 ` Jarek Poplawski
2007-06-28 12:23                   ` Patrick McHardy
2007-06-28 13:03                     ` Jarek Poplawski
2007-06-28 12:55                       ` Patrick McHardy
2007-06-28 13:27                         ` Jarek Poplawski
2007-06-29  7:02                         ` Jarek Poplawski
2007-06-29  7:56                           ` Jarek Poplawski
2007-06-28  7:52             ` [Bugme-new] [Bug 8668] New: HTB Deadlock Jarek Poplawski
2007-06-28 12:24               ` Patrick McHardy
2007-06-28 13:18                 ` Jarek Poplawski
2007-06-28 13:16                   ` Patrick McHardy

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=46827DB1.3060509@trash.net \
    --to=kaber@trash.net \
    --cc=akpm@linux-foundation.org \
    --cc=bugme-daemon@kernel-bugs.osdl.org \
    --cc=davem@davemloft.net \
    --cc=jarkao2@o2.pl \
    --cc=netdev@vger.kernel.org \
    --cc=ranko@spidernet.net \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).