aboutsummaryrefslogtreecommitdiffstats
path: root/arch/mips/kernel/smtc.c
diff options
context:
space:
mode:
authorRalf Baechle <ralf@linux-mips.org>2007-01-19 19:18:01 -0500
committerRalf Baechle <ralf@linux-mips.org>2007-01-23 13:26:47 -0500
commitac8be955049dab828a68b9c68a75144832f8289f (patch)
treec9992cccbc6bcb2f099395ef614ebc96b91a2598 /arch/mips/kernel/smtc.c
parent9ee79a3d372fcb6729893437f4923c5efd1f85db (diff)
[MIPS] SMTC: Instant IPI replay.
SMTC pseudo-interrupts between TCs are deferred and queued if the target TC is interrupt-inhibited (IXMT). In the first SMTC prototypes, these queued IPIs were serviced on return to user mode, or on entry into the kernel idle loop. The INSTANT_REPLAY option dispatches them as part of local_irq_restore() processing, which adds runtime overhead (hence the option to turn it off), but ensures that IPIs are handled promptly even under heavy I/O interrupt load. Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
Diffstat (limited to 'arch/mips/kernel/smtc.c')
-rw-r--r--arch/mips/kernel/smtc.c54
1 files changed, 33 insertions, 21 deletions
diff --git a/arch/mips/kernel/smtc.c b/arch/mips/kernel/smtc.c
index a8b387197d5b..44238ab2fc99 100644
--- a/arch/mips/kernel/smtc.c
+++ b/arch/mips/kernel/smtc.c
@@ -1017,6 +1017,33 @@ void setup_cross_vpe_interrupts(void)
1017 * SMTC-specific hacks invoked from elsewhere in the kernel. 1017 * SMTC-specific hacks invoked from elsewhere in the kernel.
1018 */ 1018 */
1019 1019
1020void smtc_ipi_replay(void)
1021{
1022 /*
1023 * To the extent that we've ever turned interrupts off,
1024 * we may have accumulated deferred IPIs. This is subtle.
1025 * If we use the smtc_ipi_qdepth() macro, we'll get an
1026 * exact number - but we'll also disable interrupts
1027 * and create a window of failure where a new IPI gets
1028 * queued after we test the depth but before we re-enable
1029 * interrupts. So long as IXMT never gets set, however,
1030 * we should be OK: If we pick up something and dispatch
1031 * it here, that's great. If we see nothing, but concurrent
1032 * with this operation, another TC sends us an IPI, IXMT
1033 * is clear, and we'll handle it as a real pseudo-interrupt
1034 * and not a pseudo-pseudo interrupt.
1035 */
1036 if (IPIQ[smp_processor_id()].depth > 0) {
1037 struct smtc_ipi *pipi;
1038 extern void self_ipi(struct smtc_ipi *);
1039
1040 while ((pipi = smtc_ipi_dq(&IPIQ[smp_processor_id()]))) {
1041 self_ipi(pipi);
1042 smtc_cpu_stats[smp_processor_id()].selfipis++;
1043 }
1044 }
1045}
1046
1020void smtc_idle_loop_hook(void) 1047void smtc_idle_loop_hook(void)
1021{ 1048{
1022#ifdef SMTC_IDLE_HOOK_DEBUG 1049#ifdef SMTC_IDLE_HOOK_DEBUG
@@ -1113,29 +1140,14 @@ void smtc_idle_loop_hook(void)
1113 if (pdb_msg != &id_ho_db_msg[0]) 1140 if (pdb_msg != &id_ho_db_msg[0])
1114 printk("CPU%d: %s", smp_processor_id(), id_ho_db_msg); 1141 printk("CPU%d: %s", smp_processor_id(), id_ho_db_msg);
1115#endif /* SMTC_IDLE_HOOK_DEBUG */ 1142#endif /* SMTC_IDLE_HOOK_DEBUG */
1143
1116 /* 1144 /*
1117 * To the extent that we've ever turned interrupts off, 1145 * Replay any accumulated deferred IPIs. If "Instant Replay"
1118 * we may have accumulated deferred IPIs. This is subtle. 1146 * is in use, there should never be any.
1119 * If we use the smtc_ipi_qdepth() macro, we'll get an
1120 * exact number - but we'll also disable interrupts
1121 * and create a window of failure where a new IPI gets
1122 * queued after we test the depth but before we re-enable
1123 * interrupts. So long as IXMT never gets set, however,
1124 * we should be OK: If we pick up something and dispatch
1125 * it here, that's great. If we see nothing, but concurrent
1126 * with this operation, another TC sends us an IPI, IXMT
1127 * is clear, and we'll handle it as a real pseudo-interrupt
1128 * and not a pseudo-pseudo interrupt.
1129 */ 1147 */
1130 if (IPIQ[smp_processor_id()].depth > 0) { 1148#ifndef CONFIG_MIPS_MT_SMTC_INSTANT_REPLAY
1131 struct smtc_ipi *pipi; 1149 smtc_ipi_replay();
1132 extern void self_ipi(struct smtc_ipi *); 1150#endif /* CONFIG_MIPS_MT_SMTC_INSTANT_REPLAY */
1133
1134 if ((pipi = smtc_ipi_dq(&IPIQ[smp_processor_id()])) != NULL) {
1135 self_ipi(pipi);
1136 smtc_cpu_stats[smp_processor_id()].selfipis++;
1137 }
1138 }
1139} 1151}
1140 1152
1141void smtc_soft_dump(void) 1153void smtc_soft_dump(void)