From: Oleg Nesterov <oleg@tv-sign.ru>
To: Christoph Lameter <christoph@lameter.com>
Cc: linux-kernel@vger.kernel.org, Shai Fultheim <Shai@Scalex86.org>,
Andrew Morton <akpm@osdl.org>, Ingo Molnar <mingo@elte.hu>
Subject: [PATCH 2/2] del_timer_sync: proof of concept
Date: Tue, 15 Mar 2005 20:20:01 +0300 [thread overview]
Message-ID: <42371941.CCBAB134@tv-sign.ru> (raw)
In-Reply-To: Pine.LNX.4.58.0503111254270.25992@server.graphe.net
New rules:
->_base & 1 : is timer pending
->_base & ~1 : timer's base
If ->_base == NULL, this timer is not running on any cpu.
Cleared only in del_timer_sync().
Note that now we don't need del_singleshot_timer_sync().
Here is the code of del_timer_sync:
int del_timer_sync(struct timer_list *timer)
{
int ret = 0;
for (;;) {
unsigned long flags;
tvec_base_t *_base, *base;
_base = timer->_base;
if (!_base)
return ret;
base = __timer_base(_base);
spin_lock_irqsave(&base->lock, flags);
if (timer->_base != _base)
goto unlock;
if (base->running_timer == timer)
goto unlock;
if (__timer_pending(_base)) {
list_del(&timer->entry);
ret = 1;
}
smp_wmb();
timer->_base = NULL;
unlock:
spin_unlock_irqrestore(&base->lock, flags);
}
}
Signed-off-by: Oleg Nesterov <oleg@tv-sign.ru>
--- 2.6.11/include/linux/timer.h~2_PEND 2005-03-15 17:49:19.000000000 +0300
+++ 2.6.11/include/linux/timer.h 2005-03-15 18:09:06.000000000 +0300
@@ -21,9 +21,11 @@ struct timer_list {
struct tvec_t_base_s *_base;
};
+#define __TIMER_PENDING 1
+
static inline int __timer_pending(struct tvec_t_base_s *base)
{
- return base != NULL;
+ return ((unsigned long)base & __TIMER_PENDING) != 0;
}
#define TIMER_MAGIC 0x4b87ad6e
--- 2.6.11/kernel/timer.c~2_PEND 2005-03-15 17:55:00.000000000 +0300
+++ 2.6.11/kernel/timer.c 2005-03-15 19:52:48.000000000 +0300
@@ -86,16 +86,26 @@ static inline void set_running_timer(tve
static inline tvec_base_t *__get_base(struct timer_list *timer)
{
- return timer->_base;
+ tvec_base_t *base = timer->_base;
+
+ if (__timer_pending(base))
+ return (void*)base - __TIMER_PENDING;
+ else
+ return NULL;
}
static inline void __set_base(struct timer_list *timer,
tvec_base_t *base, int pending)
{
if (pending)
- timer->_base = base;
+ timer->_base = (void*)base + __TIMER_PENDING;
else
- timer->_base = NULL;
+ timer->_base = base;
+}
+
+static inline tvec_base_t *__timer_base(tvec_base_t *base)
+{
+ return (tvec_base_t*)((unsigned long)base & ~__TIMER_PENDING);
}
/* Fake initialization */
@@ -356,29 +366,39 @@ EXPORT_SYMBOL(del_timer);
*/
int del_timer_sync(struct timer_list *timer)
{
- tvec_base_t *base;
- int i, ret = 0;
+ int ret;
check_timer(timer);
-del_again:
- ret += del_timer(timer);
+ ret = 0;
+ for (;;) {
+ unsigned long flags;
+ tvec_base_t *_base, *base;
+
+ _base = timer->_base;
+ if (!_base)
+ return ret;
- for_each_online_cpu(i) {
- base = &per_cpu(tvec_bases, i);
- if (base->running_timer == timer) {
- while (base->running_timer == timer) {
- cpu_relax();
- preempt_check_resched();
- }
- break;
+ base = __timer_base(_base);
+ spin_lock_irqsave(&base->lock, flags);
+
+ if (timer->_base != _base)
+ goto unlock;
+
+ if (base->running_timer == timer)
+ goto unlock;
+
+ if (__timer_pending(_base)) {
+ list_del(&timer->entry);
+ ret = 1;
}
+ /* Need to make sure that anybody who sees a NULL base
+ * also sees the list ops */
+ smp_wmb();
+ timer->_base = NULL;
+unlock:
+ spin_unlock_irqrestore(&base->lock, flags);
}
- smp_rmb();
- if (timer_pending(timer))
- goto del_again;
-
- return ret;
}
EXPORT_SYMBOL(del_timer_sync);
next prev parent reply other threads:[~2005-03-15 16:17 UTC|newest]
Thread overview: 18+ messages / expand[flat|nested] mbox.gz Atom feed top
2005-03-11 18:54 [patch] del_timer_sync scalability patch Oleg Nesterov
2005-03-11 20:57 ` Christoph Lameter
2005-03-15 17:19 ` [PATCH 0/2] del_timer_sync: proof of concept Oleg Nesterov
2005-03-15 18:15 ` Christoph Lameter
2005-03-15 19:41 ` Oleg Nesterov
2005-03-15 19:02 ` Christoph Lameter
2005-03-16 16:55 ` Oleg Nesterov
2005-03-15 17:19 ` [PATCH 1/2] " Oleg Nesterov
2005-03-15 17:20 ` Oleg Nesterov [this message]
2005-03-16 9:00 ` [PATCH 2/2] " Ingo Molnar
2005-03-16 12:09 ` Oleg Nesterov
2005-03-16 13:52 ` Ingo Molnar
2005-03-13 13:13 ` [patch] del_timer_sync scalability patch Oleg Nesterov
2005-03-14 19:40 ` Christoph Lameter
2005-03-15 9:12 ` Oleg Nesterov
2005-03-15 8:06 ` Christoph Lameter
2005-03-15 9:28 ` Ingo Molnar
2005-03-15 10:28 ` Oleg Nesterov
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=42371941.CCBAB134@tv-sign.ru \
--to=oleg@tv-sign.ru \
--cc=Shai@Scalex86.org \
--cc=akpm@osdl.org \
--cc=christoph@lameter.com \
--cc=linux-kernel@vger.kernel.org \
--cc=mingo@elte.hu \
/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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.