public inbox for netdev@vger.kernel.org 
 help / color / mirror / Atom feed
From: Stephen Hemminger <shemminger@vyatta•com>
To: David Miller <davem@davemloft•net>,
	Patrick McHardy <kaber@trash•net>,
	Rick Jones <rick.jones2@hp•com>,
	Eric Dumazet <dada1@cosmosbay•com>
Cc: netdev@vger•kernel.org, netfilter-devel@vger•kernel.org,
	tglx@linutronix•de, Martin Josefsson <gandalf@wlug•westbo.se>
Subject: [RFT 2/4] Add mod_timer_noact
Date: Tue, 17 Feb 2009 21:19:08 -0800	[thread overview]
Message-ID: <20090218052747.437271195@vyatta.com> (raw)
In-Reply-To: 20090218051906.174295181@vyatta.com

[-- Attachment #1: mod_timer_noact.patch --]
[-- Type: text/plain, Size: 4828 bytes --]

Introduce mod_timer_noact() which for example is to replace the calls to
del_timer()/add_timer() in __nf_ct_refresh_acct(). It works like mod_timer()
but doesn't activate or modify the timeout of an inactive timer which is the
behaviour we want in order to be able to use timers as a means of
synchronization in nf_conntrack.

A later patch will modify __nf_ct_refresh_acct() to use mod_timer_noact()
which will then save one spin_lock_irqsave() / spin_lock_irqrestore() pair per
conntrack timer update. This will also get rid of the race we currently have
without adding more locking in nf_conntrack.

Signed-off-by: Martin Josefsson <gandalf@wlug•westbo.se>

---
 include/linux/timer.h |    8 ++++++--
 kernel/relay.c        |    2 +-
 kernel/timer.c        |   40 +++++++++++++++++++++++++++++++++++-----
 3 files changed, 42 insertions(+), 8 deletions(-)

--- a/include/linux/timer.h	2009-02-17 10:55:33.427785986 -0800
+++ b/include/linux/timer.h	2009-02-17 11:04:10.291844534 -0800
@@ -25,6 +25,9 @@ struct timer_list {
 
 extern struct tvec_base boot_tvec_bases;
 
+#define TIMER_ACT	1
+#define TIMER_NOACT	0
+
 #define TIMER_INITIALIZER(_function, _expires, _data) {		\
 		.entry = { .prev = TIMER_ENTRY_STATIC },	\
 		.function = (_function),			\
@@ -86,8 +89,9 @@ static inline int timer_pending(const st
 
 extern void add_timer_on(struct timer_list *timer, int cpu);
 extern int del_timer(struct timer_list * timer);
-extern int __mod_timer(struct timer_list *timer, unsigned long expires);
+extern int __mod_timer(struct timer_list *timer, unsigned long expires, int activate);
 extern int mod_timer(struct timer_list *timer, unsigned long expires);
+extern int mod_timer_noact(struct timer_list *timer, unsigned long expires);
 
 /*
  * The jiffies value which is added to now, when there is no timer
@@ -163,7 +167,7 @@ static inline void timer_stats_timer_cle
 static inline void add_timer(struct timer_list *timer)
 {
 	BUG_ON(timer_pending(timer));
-	__mod_timer(timer, timer->expires);
+	__mod_timer(timer, timer->expires, TIMER_ACT);
 }
 
 #ifdef CONFIG_SMP
--- a/kernel/timer.c	2009-02-17 10:55:33.403580297 -0800
+++ b/kernel/timer.c	2009-02-17 11:04:10.291844534 -0800
@@ -589,7 +589,7 @@ static struct tvec_base *lock_timer_base
 	}
 }
 
-int __mod_timer(struct timer_list *timer, unsigned long expires)
+int __mod_timer(struct timer_list *timer, unsigned long expires, int activate)
 {
 	struct tvec_base *base, *new_base;
 	unsigned long flags;
@@ -603,7 +603,8 @@ int __mod_timer(struct timer_list *timer
 	if (timer_pending(timer)) {
 		detach_timer(timer, 0);
 		ret = 1;
-	}
+	} else if (activate == TIMER_NOACT)
+		goto out_unlock;
 
 	debug_timer_activate(timer);
 
@@ -629,8 +630,9 @@ int __mod_timer(struct timer_list *timer
 
 	timer->expires = expires;
 	internal_add_timer(base, timer);
-	spin_unlock_irqrestore(&base->lock, flags);
 
+out_unlock:
+	spin_unlock_irqrestore(&base->lock, flags);
 	return ret;
 }
 
@@ -699,11 +701,39 @@ int mod_timer(struct timer_list *timer, 
 	if (timer->expires == expires && timer_pending(timer))
 		return 1;
 
-	return __mod_timer(timer, expires);
+	return __mod_timer(timer, expires, TIMER_ACT);
 }
 
 EXPORT_SYMBOL(mod_timer);
 
+/***
+ * mod_timer_noact - modify a timer's timeout
+ * @timer: the timer to be modified
+ *
+ * mod_timer_noact works like mod_timer except that it doesn't activate an
+ * inactive timer, instead it returns without updating timer->expires.
+ *
+ * The function returns whether it has modified a pending timer or not.
+ * (ie. mod_timer_noact() of an inactive timer returns 0, mod_timer_noact() of
+ * an active timer returns 1.)
+ */
+int mod_timer_noact(struct timer_list *timer, unsigned long expires)
+{
+	BUG_ON(!timer->function);
+
+	/*
+	 * This is a common optimization triggered by the
+	 * networking code - if the timer is re-modified
+	 * to be the same thing then just return:
+	 */
+	if (timer->expires == expires && timer_pending(timer))
+		return 1;
+
+	return __mod_timer(timer, expires, TIMER_NOACT);
+}
+
+EXPORT_SYMBOL(mod_timer_noact);
+
 /**
  * del_timer - deactive a timer.
  * @timer: the timer to be deactivated
@@ -1268,7 +1298,7 @@ signed long __sched schedule_timeout(sig
 	expire = timeout + jiffies;
 
 	setup_timer_on_stack(&timer, process_timeout, (unsigned long)current);
-	__mod_timer(&timer, expire);
+	__mod_timer(&timer, expire, TIMER_ACT);
 	schedule();
 	del_singleshot_timer_sync(&timer);
 
--- a/kernel/relay.c	2009-02-17 10:55:33.416279439 -0800
+++ b/kernel/relay.c	2009-02-17 11:04:10.291844534 -0800
@@ -750,7 +750,7 @@ size_t relay_switch_subbuf(struct rchan_
 			 * from the scheduler (trying to re-grab
 			 * rq->lock), so defer it.
 			 */
-			__mod_timer(&buf->timer, jiffies + 1);
+			__mod_timer(&buf->timer, jiffies + 1, TIMER_NOACT);
 	}
 
 	old = buf->data;

-- 


  parent reply	other threads:[~2009-02-18  5:19 UTC|newest]

Thread overview: 87+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2009-02-18  5:19 [RFT 0/4] Netfilter/iptables performance improvements Stephen Hemminger
2009-02-18  5:19 ` [RFT 1/4] iptables: lock free counters Stephen Hemminger
2009-02-18 10:02   ` Patrick McHardy
2009-02-19 19:47   ` [PATCH] " Stephen Hemminger
2009-02-19 23:46     ` Eric Dumazet
2009-02-19 23:56       ` Rick Jones
2009-02-20  1:03         ` Stephen Hemminger
2009-02-20  1:18           ` Rick Jones
2009-02-20  9:42             ` Patrick McHardy
2009-02-20 22:57               ` Rick Jones
2009-02-21  0:35                 ` Rick Jones
2009-02-20  9:37       ` Patrick McHardy
2009-02-20 18:10       ` [PATCH] iptables: xt_hashlimit fix Eric Dumazet
2009-02-20 18:33         ` Jan Engelhardt
2009-02-28  1:54           ` Jan Engelhardt
2009-02-28  6:56             ` Eric Dumazet
2009-02-28  8:22               ` Jan Engelhardt
2009-02-24 14:31         ` Patrick McHardy
2009-02-27 14:02       ` [PATCH] iptables: lock free counters Eric Dumazet
2009-02-27 16:08         ` [PATCH] rcu: increment quiescent state counter in ksoftirqd() Eric Dumazet
2009-02-27 16:34           ` Paul E. McKenney
2009-03-02 10:55         ` [PATCH] iptables: lock free counters Patrick McHardy
2009-03-02 17:47           ` Eric Dumazet
2009-03-02 21:56             ` Patrick McHardy
2009-03-02 22:02               ` Stephen Hemminger
2009-03-02 22:07                 ` Patrick McHardy
2009-03-02 22:17                   ` Paul E. McKenney
2009-03-02 22:27                 ` Eric Dumazet
2009-02-18  5:19 ` Stephen Hemminger [this message]
2009-02-18  9:20   ` [RFT 2/4] Add mod_timer_noact Ingo Molnar
2009-02-18  9:30     ` David Miller
2009-02-18 11:01       ` Ingo Molnar
2009-02-18 11:39         ` Jarek Poplawski
2009-02-18 12:37           ` Ingo Molnar
2009-02-18 12:33         ` Patrick McHardy
2009-02-18 21:39         ` David Miller
2009-02-18 21:51           ` Ingo Molnar
2009-02-18 22:04             ` David Miller
2009-02-18 22:42               ` Peter Zijlstra
2009-02-18 22:47                 ` David Miller
2009-02-18 22:56                   ` Stephen Hemminger
2009-02-18 10:07     ` Patrick McHardy
2009-02-18 12:05       ` [patch] timers: add mod_timer_pending() Ingo Molnar
2009-02-18 12:33         ` Patrick McHardy
2009-02-18 12:50           ` Ingo Molnar
2009-02-18 12:54             ` Patrick McHardy
2009-02-18 13:47               ` Ingo Molnar
2009-02-18 17:00         ` Oleg Nesterov
2009-02-18 18:23           ` Ingo Molnar
2009-02-18 18:58             ` Oleg Nesterov
2009-02-18 19:24               ` Ingo Molnar
2009-02-18 10:29   ` [RFT 2/4] Add mod_timer_noact Patrick McHardy
2009-02-18  5:19 ` [RFT 3/4] Use mod_timer_noact to remove nf_conntrack_lock Stephen Hemminger
2009-02-18  9:54   ` Patrick McHardy
2009-02-18 11:05   ` Jarek Poplawski
2009-02-18 11:08     ` Patrick McHardy
2009-02-18 14:01   ` Eric Dumazet
2009-02-18 14:04     ` Patrick McHardy
2009-02-18 14:22       ` Eric Dumazet
2009-02-18 14:27         ` Patrick McHardy
2009-02-18  5:19 ` [RFT 4/4] netfilter: Get rid of central rwlock in tcp conntracking Stephen Hemminger
2009-02-18  9:56   ` Patrick McHardy
2009-02-18 14:17     ` Eric Dumazet
2009-02-19 22:03       ` Stephen Hemminger
2009-03-28 16:55       ` [PATCH] netfilter: finer grained nf_conn locking Eric Dumazet
2009-03-29  0:48         ` Stephen Hemminger
2009-03-30 19:57           ` Eric Dumazet
2009-03-30 20:05             ` Stephen Hemminger
2009-04-06 12:07               ` Patrick McHardy
2009-04-06 12:32                 ` Jan Engelhardt
2009-04-06 17:25                   ` Stephen Hemminger
2009-03-30 18:57         ` Rick Jones
2009-03-30 19:20           ` Eric Dumazet
2009-03-30 19:38           ` Jesper Dangaard Brouer
2009-03-30 19:54             ` Eric Dumazet
2009-03-30 20:34               ` Jesper Dangaard Brouer
2009-03-30 20:41                 ` Eric Dumazet
2009-03-30 21:25                   ` Jesper Dangaard Brouer
2009-03-30 22:44                   ` Rick Jones
2009-03-31 19:52                   ` Jesper Dangaard Brouer
2009-03-31 20:23                     ` Eric Dumazet
2009-03-31 20:35                       ` Rick Jones
2009-03-31 20:52                       ` Jesper Dangaard Brouer
2009-02-18 21:55     ` [RFT 4/4] netfilter: Get rid of central rwlock in tcp conntracking David Miller
2009-02-18 23:23       ` Patrick McHardy
2009-02-18 23:35         ` Stephen Hemminger
2009-02-18  8:30 ` [RFT 0/4] Netfilter/iptables performance improvements Eric Dumazet

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=20090218052747.437271195@vyatta.com \
    --to=shemminger@vyatta$(echo .)com \
    --cc=dada1@cosmosbay$(echo .)com \
    --cc=davem@davemloft$(echo .)net \
    --cc=gandalf@wlug$(echo .)westbo.se \
    --cc=kaber@trash$(echo .)net \
    --cc=netdev@vger$(echo .)kernel.org \
    --cc=netfilter-devel@vger$(echo .)kernel.org \
    --cc=rick.jones2@hp$(echo .)com \
    --cc=tglx@linutronix$(echo .)de \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html
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