From: Venkatesh Pallipadi 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 Signed-off-by: Suresh Siddha --- 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@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/