All of lore.kernel.org
 help / color / mirror / Atom feed
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

             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 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.