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

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