From: george anzinger <george@mvista.com>
To: Matthew Wilcox <willy@debian.org>, Robert Love <rml@mvista.com>,
Linus Torvalds <torvalds@transmeta.com>,
"linux-kernel@vger.kernel.org" <linux-kernel@vger.kernel.org>
Subject: [PATCH] Replace timer_bh with tasklet
Date: Mon, 17 Jun 2002 20:45:14 -0700 [thread overview]
Message-ID: <3D0EACCA.3290139@mvista.com> (raw)
This patch replaces the timer_bh with a tasklet. It also
introduces
a way to flag a tasklet as a must run (i.e. do NOT kick up
to ksoftirqd).
It make NO sense to pass timer work to a task.
Comments...
diff -urN linux-2.5.22/include/linux/interrupt.h
linux/include/linux/interrupt.h
--- linux-2.5.22/include/linux/interrupt.h Sun Jun 16
19:31:22 2002
+++ linux/include/linux/interrupt.h Mon Jun 17 15:58:59 2002
@@ -57,12 +57,19 @@
enum
{
- HI_SOFTIRQ=0,
+ RUN_TIMER_LIST=0,
+ HI_SOFTIRQ,
NET_TX_SOFTIRQ,
NET_RX_SOFTIRQ,
TASKLET_SOFTIRQ
};
+/*
+ * The ALWAYS_SOFTIRQ tasks will always be called
repeatedly (until
+ * the pending bit stays cleared) each time do_softirq is
called.
+ */
+#define ALWAYS_SOFTIRQ (1 << RUN_TIMER_LIST)
+
/* softirq mask and active fields moved to irq_cpustat_t in
* asm/hardirq.h to get better cache usage. KAO
*/
@@ -74,6 +81,7 @@
};
asmlinkage void do_softirq(void);
+extern void timer_softirq(struct softirq_action* a);
extern void open_softirq(int nr, void (*action)(struct
softirq_action*), void *data);
extern void softirq_init(void);
#define __cpu_raise_softirq(cpu, nr) do {
softirq_pending(cpu) |= 1UL << (nr); } while (0)
diff -urN linux-2.5.22/kernel/sched.c linux/kernel/sched.c
--- linux-2.5.22/kernel/sched.c Sun Jun 16 19:31:27 2002
+++ linux/kernel/sched.c Mon Jun 17 15:57:06 2002
@@ -1633,7 +1633,6 @@
}
extern void init_timervecs(void);
-extern void timer_bh(void);
extern void tqueue_bh(void);
extern void immediate_bh(void);
@@ -1671,7 +1670,6 @@
wake_up_process(current);
init_timervecs();
- init_bh(TIMER_BH, timer_bh);
init_bh(TQUEUE_BH, tqueue_bh);
init_bh(IMMEDIATE_BH, immediate_bh);
diff -urN linux-2.5.22/kernel/softirq.c
linux/kernel/softirq.c
--- linux-2.5.22/kernel/softirq.c Sun Jun 16 19:31:27 2002
+++ linux/kernel/softirq.c Mon Jun 17 16:00:03 2002
@@ -96,7 +96,7 @@
local_irq_disable();
pending = softirq_pending(cpu);
- if (pending & mask) {
+ if (pending & (mask | ALWAYS_SOFTIRQ)) {
mask &= ~pending;
goto restart;
}
@@ -332,6 +332,7 @@
open_softirq(TASKLET_SOFTIRQ, tasklet_action, NULL);
open_softirq(HI_SOFTIRQ, tasklet_hi_action, NULL);
+ open_softirq(RUN_TIMER_LIST,timer_softirq, NULL);
}
void __run_task_queue(task_queue *list)
diff -urN linux-2.5.22/kernel/timer.c linux/kernel/timer.c
--- linux-2.5.22/kernel/timer.c Sun Jun 16 19:31:28 2002
+++ linux/kernel/timer.c Mon Jun 17 16:02:54 2002
@@ -14,6 +14,7 @@
* Copyright (C) 1998 Andrea
Arcangeli
* 1999-03-10 Improved NTP compatibility by Ulrich Windl
* 2002-05-31 Move sys_sysinfo here and make its locking
sane, Robert Love
+ * 2002-06-17 Run timers off a tasklet and remove TIMER_BH
*/
#include <linux/config.h>
@@ -37,6 +38,12 @@
/* The current time */
struct timeval xtime __attribute__ ((aligned (16)));
+/*
+ * This atomic prevents re-entry of the run_timer_list and
has the side
+ * effect of shifting conflict runs to the "owning" cpu.
+ */
+static atomic_t timer_tasklet_lock = ATOMIC_INIT(-1);
+
/* Don't completely fail for HZ > 500. */
int tickadj = 500/HZ ? : 1; /* microsecs */
@@ -645,7 +652,7 @@
unsigned long ticks;
/*
- * update_times() is run from the raw timer_bh handler so
we
+ * update_times() is run from the raw timer_tasklet so we
* just know that the irqs are locally enabled and so we
don't
* need to save/restore the flags of the local CPU here.
-arca
*/
@@ -661,10 +668,24 @@
write_unlock_irq(&xtime_lock);
}
-void timer_bh(void)
+
+/*
+ * timer_tasklet_lock starts at -1. 0 then means it is
cool to
+ * continue. If another cpu bumps it while the first is
still in
+ * run_timer_list, it will be detected on exit and we will
run it
+ * again. But multiple entries are not needed, just once
for all the
+ * "hits" while we are in run_timer_list.
+ */
+void timer_softirq(struct softirq_action* a)
{
- update_times();
- run_timer_list();
+ if (!atomic_inc_and_test(&timer_tasklet_lock))
+ return;
+
+ do {
+ atomic_set(&timer_tasklet_lock, 0);
+ update_times();
+ run_timer_list();
+ } while (!atomic_add_negative(-1,
&timer_tasklet_lock));
}
void do_timer(struct pt_regs *regs)
@@ -675,7 +696,7 @@
update_process_times(user_mode(regs));
#endif
- mark_bh(TIMER_BH);
+ raise_softirq( RUN_TIMER_LIST );
if (TQ_ACTIVE(tq_timer))
mark_bh(TQUEUE_BH);
}
--
George Anzinger george@mvista.com
High-res-timers:
http://sourceforge.net/projects/high-res-timers/
Real time sched: http://sourceforge.net/projects/rtsched/
Preemption patch:
http://www.kernel.org/pub/linux/kernel/people/rml
next reply other threads:[~2002-06-18 3:45 UTC|newest]
Thread overview: 30+ messages / expand[flat|nested] mbox.gz Atom feed top
2002-06-18 3:45 george anzinger [this message]
2002-06-18 4:06 ` [PATCH] Replace timer_bh with tasklet Linus Torvalds
2002-06-18 18:07 ` george anzinger
2002-06-18 22:46 ` Richard Zidlicky
2002-06-18 23:17 ` george anzinger
2002-06-19 11:43 ` Richard Zidlicky
2002-06-18 4:15 ` David S. Miller
2002-06-18 17:01 ` george anzinger
2002-06-18 17:12 ` Matthew Wilcox
2002-06-18 18:14 ` george anzinger
2002-06-18 5:16 ` kuznet
2002-06-18 18:19 ` george anzinger
2002-06-18 18:29 ` kuznet
2002-06-20 0:39 ` george anzinger
2002-06-20 1:34 ` David S. Miller
2002-06-20 1:53 ` Robert Love
2002-06-20 1:55 ` David S. Miller
2002-06-20 2:05 ` Robert Love
2002-06-20 2:01 ` David S. Miller
2002-06-20 2:15 ` Robert Love
2002-06-20 2:23 ` David S. Miller
2002-06-20 23:54 ` george anzinger
2002-06-21 1:03 ` David S. Miller
2002-06-21 14:04 ` george anzinger
2002-06-21 14:08 ` David S. Miller
2002-06-20 8:11 ` Russell King
2002-06-20 8:09 ` David S. Miller
2002-06-20 8:16 ` Russell King
2002-06-20 8:13 ` Russell King
2002-06-20 14:33 ` kuznet
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=3D0EACCA.3290139@mvista.com \
--to=george@mvista.com \
--cc=linux-kernel@vger.kernel.org \
--cc=rml@mvista.com \
--cc=torvalds@transmeta.com \
--cc=willy@debian.org \
/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).