From: Suresh Siddha on
From: Venkatesh Pallipadi <venki(a)google.com>
Subject: softirq: Add a no local fallback option to send_remote_softirq
send_remote_softirq and __send_remote_softirq fallback to triggering
the softirq on local CPU when __try_remote_softirq fails. In certain
circumstances (like the SCHED_SOFTIRQ usage in following patch), the
softirq should only run on target CPUs if it runs. This new option helps
such callers.

As there seem to be no current users of send_remote_softirq in tree
today, added this option to current API instead of introducing a new
API.

Signed-off-by: Venkatesh Pallipadi <venki(a)google.com>
Signed-off-by: Suresh Siddha <suresh.b.siddha(a)intel.com>
---
include/linux/interrupt.h | 5 +++--
kernel/softirq.c | 12 ++++++++----
2 files changed, 11 insertions(+), 6 deletions(-)

Index: tip/include/linux/interrupt.h
===================================================================
--- tip.orig/include/linux/interrupt.h
+++ tip/include/linux/interrupt.h
@@ -419,13 +419,14 @@ DECLARE_PER_CPU(struct list_head [NR_SOF
/* Try to send a softirq to a remote cpu. If this cannot be done, the
* work will be queued to the local cpu.
*/
-extern void send_remote_softirq(struct call_single_data *cp, int cpu, int softirq);
+extern void send_remote_softirq(struct call_single_data *cp, int cpu,
+ int softirq, int fallback);

/* Like send_remote_softirq(), but the caller must disable local cpu interrupts
* and compute the current cpu, passed in as 'this_cpu'.
*/
extern void __send_remote_softirq(struct call_single_data *cp, int cpu,
- int this_cpu, int softirq);
+ int this_cpu, int softirq, int fallback);

/* Tasklets --- multithreaded analogue of BHs.

Index: tip/kernel/softirq.c
===================================================================
--- tip.orig/kernel/softirq.c
+++ tip/kernel/softirq.c
@@ -610,9 +610,12 @@ static int __try_remote_softirq(struct c
*
* Interrupts must be disabled.
*/
-void __send_remote_softirq(struct call_single_data *cp, int cpu, int this_cpu, int softirq)
+void __send_remote_softirq(struct call_single_data *cp, int cpu, int this_cpu,
+ int softirq, int fallback)
{
- if (cpu == this_cpu || __try_remote_softirq(cp, cpu, softirq))
+ if (cpu == this_cpu)
+ __local_trigger(cp, softirq);
+ else if (__try_remote_softirq(cp, cpu, softirq) && fallback)
__local_trigger(cp, softirq);
}
EXPORT_SYMBOL(__send_remote_softirq);
@@ -626,14 +629,15 @@ EXPORT_SYMBOL(__send_remote_softirq);
* Like __send_remote_softirq except that disabling interrupts and
* computing the current cpu is done for the caller.
*/
-void send_remote_softirq(struct call_single_data *cp, int cpu, int softirq)
+void send_remote_softirq(struct call_single_data *cp, int cpu, int softirq,
+ int fallback)
{
unsigned long flags;
int this_cpu;

local_irq_save(flags);
this_cpu = smp_processor_id();
- __send_remote_softirq(cp, cpu, this_cpu, softirq);
+ __send_remote_softirq(cp, cpu, this_cpu, softirq, fallback);
local_irq_restore(flags);
}
EXPORT_SYMBOL(send_remote_softirq);


--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo(a)vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/