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;
--
next prev 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