From: therbert@google.com (Tom Herbert)
To: davem@davemloft.net, netdev@vger.kernel.org
Subject: RFC [PATCH net-2.6 1/6] net: Scheduling softirqs between CPUSs
Date: Wed, 5 Mar 2008 12:51:16 -0800 (PST) [thread overview]
Message-ID: <20080305205116.5989A412541@localhost> (raw)
This patch implements kernel changes to allow scheduling of softirq's between processors.
Signed-off-by: Tom Herbert <therbert@google.com>
---
diff -uprN -X /tmp/donts/si_1 net-2.6/include/linux/interrupt.h net-2.6.patch/include/linux/interrupt.h
--- net-2.6/include/linux/interrupt.h 2008-03-05 09:03:21.033991000 -0800
+++ net-2.6.patch/include/linux/interrupt.h 2008-03-05 09:34:48.010014000 -0800
@@ -247,6 +247,9 @@ static inline void __deprecated save_and
enum
{
HI_SOFTIRQ=0,
+#ifdef CONFIG_SMP
+ SEND_CPU_SOFTIRQ,
+#endif
TIMER_SOFTIRQ,
NET_TX_SOFTIRQ,
NET_RX_SOFTIRQ,
@@ -276,6 +279,13 @@ extern void softirq_init(void);
extern void raise_softirq_irqoff(unsigned int nr);
extern void raise_softirq(unsigned int nr);
+#ifdef CONFIG_SMP
+DECLARE_PER_CPU(atomic_t, alt_softirqs);
+
+extern void raise_softirq_oncpu(int cpu, unsigned int nr);
+extern void or_alt_softirqs_pending_irqoff(void);
+extern void or_alt_softirqs_pending(void);
+#endif
/* Tasklets --- multithreaded analogue of BHs.
diff -uprN -X /tmp/donts/si_1 net-2.6/include/linux/smp.h net-2.6.patch/include/linux/smp.h
--- net-2.6/include/linux/smp.h 2008-03-05 09:03:23.150865000 -0800
+++ net-2.6.patch/include/linux/smp.h 2008-03-05 09:25:33.530753000 -0800
@@ -33,6 +33,21 @@ extern void smp_send_stop(void);
*/
extern void smp_send_reschedule(int cpu);
+/*
+ * sends a 'reschedule' event to multiple CPUs in mask:
+ */
+#ifdef ARCH_HAS_SEND_RESCHEDULE_MASK
+extern void smp_send_reschedule_mask(cpumask_t mask);
+#else
+static inline void smp_send_reschedule_mask(cpumask_t mask)
+{
+ int cpu;
+
+ for_each_cpu_mask(cpu, mask) {
+ smp_send_reschedule(cpu);
+ }
+}
+#endif
/*
* Prepare machine for booting other CPUs.
diff -uprN -X /tmp/donts/si_1 net-2.6/kernel/softirq.c net-2.6.patch/kernel/softirq.c
--- net-2.6/kernel/softirq.c 2008-03-05 09:03:26.407673000 -0800
+++ net-2.6.patch/kernel/softirq.c 2008-03-05 09:36:33.849334000 -0800
@@ -16,6 +16,7 @@
#include <linux/notifier.h>
#include <linux/percpu.h>
#include <linux/cpu.h>
+#include <linux/cpumask.h>
#include <linux/freezer.h>
#include <linux/kthread.h>
#include <linux/rcupdate.h>
@@ -352,6 +353,62 @@ void open_softirq(int nr, void (*action)
softirq_vec[nr].action = action;
}
+#ifdef CONFIG_SMP
+/*
+ * Functions and definitions to support scheduling of softirqs between CPU's.
+ */
+
+DEFINE_PER_CPU(atomic_t, alt_softirqs);
+static DEFINE_PER_CPU(cpumask_t, softirq_cpus);
+
+static void send_cpu_softirq_action(struct softirq_action *a)
+{
+ cpumask_t mask;
+ unsigned long flags;
+
+ local_irq_save(flags);
+ mask = __get_cpu_var(softirq_cpus);
+ cpus_clear(__get_cpu_var(softirq_cpus));
+ local_irq_restore(flags);
+
+ /*
+ * Wake up CPUs by sending them a reschedule event. This is
+ * usually implemented by an IPI.
+ */
+ if (!cpus_empty(mask))
+ smp_send_reschedule_mask(mask);
+}
+
+void raise_softirq_oncpu(int cpu, unsigned int nr)
+{
+ if (cpu == get_cpu())
+ raise_softirq(nr);
+ else if (!test_and_set_bit(nr, &per_cpu(alt_softirqs, cpu))) {
+ cpu_set(cpu, __get_cpu_var(softirq_cpus));
+ raise_softirq(SEND_CPU_SOFTIRQ);
+ }
+}
+
+
+inline void or_alt_softirqs_pending_irqoff(void)
+{
+ __u32 pending;
+
+ pending = atomic_xchg(&__get_cpu_var(alt_softirqs), 0);
+ or_softirq_pending(pending);
+}
+
+
+void or_alt_softirqs_pending(void)
+{
+ unsigned long flags;
+
+ local_irq_save(flags);
+ or_alt_softirqs_pending_irqoff();
+ local_irq_restore(flags);
+}
+#endif /* CONFIG_SMP */
+
/* Tasklets */
struct tasklet_head
{
@@ -488,6 +545,9 @@ void __init softirq_init(void)
{
open_softirq(TASKLET_SOFTIRQ, tasklet_action, NULL);
open_softirq(HI_SOFTIRQ, tasklet_hi_action, NULL);
+#ifdef CONFIG_SMP
+ open_softirq(SEND_CPU_SOFTIRQ, send_cpu_softirq_action, NULL);
+#endif
}
static int ksoftirqd(void * __bind_cpu)
next reply other threads:[~2008-03-05 20:51 UTC|newest]
Thread overview: 12+ messages / expand[flat|nested] mbox.gz Atom feed top
2008-03-05 20:51 Tom Herbert [this message]
2008-03-05 21:21 ` RFC [PATCH net-2.6 1/6] net: Scheduling softirqs between CPUSs David Miller
2008-03-07 19:02 ` Max Krasnyanskiy
2008-03-10 23:26 ` Tom Herbert
2008-03-11 1:06 ` Brandeburg, Jesse
2008-03-11 16:20 ` Tom Herbert
2008-03-11 16:52 ` Ben Hutchings
2008-03-11 23:48 ` Tom Herbert
2008-03-12 15:10 ` Ben Hutchings
2008-03-13 3:41 ` David Miller
2008-03-13 11:47 ` Ben Hutchings
2008-03-13 12:53 ` David Miller
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=20080305205116.5989A412541@localhost \
--to=therbert@google.com \
--cc=davem@davemloft.net \
--cc=netdev@vger.kernel.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).