aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arc/kernel/smp.c
diff options
context:
space:
mode:
authorVineet Gupta <vgupta@synopsys.com>2014-11-07 10:45:28 +0530
committerVineet Gupta <vgupta@synopsys.com>2015-06-22 14:06:57 +0530
commitaa6083ed50957f699596999affbb6eb9d7a8b72e (patch)
tree67a2cb49a3514680cb1b4d59e4a9be5694f86146 /arch/arc/kernel/smp.c
parentARCv2: SMP: Support ARConnect (MCIP) for Inter-Core-Interrupts et al (diff)
downloadlinux-dev-aa6083ed50957f699596999affbb6eb9d7a8b72e.tar.xz
linux-dev-aa6083ed50957f699596999affbb6eb9d7a8b72e.zip
ARCv2: SMP: ARConnect debug/robustness
- Handle possible interrupt coalescing from MCIP - chk if prev IPI ack before sending new Signed-off-by: Vineet Gupta <vgupta@synopsys.com>
Diffstat (limited to 'arch/arc/kernel/smp.c')
-rw-r--r--arch/arc/kernel/smp.c20
1 files changed, 16 insertions, 4 deletions
diff --git a/arch/arc/kernel/smp.c b/arch/arc/kernel/smp.c
index d07cb53d7641..be13d12420ba 100644
--- a/arch/arc/kernel/smp.c
+++ b/arch/arc/kernel/smp.c
@@ -278,8 +278,10 @@ static void ipi_cpu_stop(void)
machine_halt();
}
-static inline void __do_IPI(unsigned long msg)
+static inline int __do_IPI(unsigned long msg)
{
+ int rc = 0;
+
switch (msg) {
case IPI_RESCHEDULE:
scheduler_ipi();
@@ -294,8 +296,10 @@ static inline void __do_IPI(unsigned long msg)
break;
default:
- pr_warn("IPI with unexpected msg %ld\n", msg);
+ rc = 1;
}
+
+ return rc;
}
/*
@@ -305,6 +309,7 @@ static inline void __do_IPI(unsigned long msg)
irqreturn_t do_IPI(int irq, void *dev_id)
{
unsigned long pending;
+ unsigned long __maybe_unused copy;
pr_debug("IPI [%ld] received on cpu %d\n",
*this_cpu_ptr(&ipi_data), smp_processor_id());
@@ -316,11 +321,18 @@ irqreturn_t do_IPI(int irq, void *dev_id)
* "dequeue" the msg corresponding to this IPI (and possibly other
* piggybacked msg from elided IPIs: see ipi_send_msg_one() above)
*/
- pending = xchg(this_cpu_ptr(&ipi_data), 0);
+ copy = pending = xchg(this_cpu_ptr(&ipi_data), 0);
do {
unsigned long msg = __ffs(pending);
- __do_IPI(msg);
+ int rc;
+
+ rc = __do_IPI(msg);
+#ifdef CONFIG_ARC_IPI_DBG
+ /* IPI received but no valid @msg */
+ if (rc)
+ pr_info("IPI with bogus msg %ld in %ld\n", msg, copy);
+#endif
pending &= ~(1U << msg);
} while (pending);