diff options
Diffstat (limited to 'arch/mips/kernel/smtc.c')
-rw-r--r-- | arch/mips/kernel/smtc.c | 55 |
1 files changed, 34 insertions, 21 deletions
diff --git a/arch/mips/kernel/smtc.c b/arch/mips/kernel/smtc.c index 802febed7df5..44238ab2fc99 100644 --- a/arch/mips/kernel/smtc.c +++ b/arch/mips/kernel/smtc.c | |||
@@ -261,6 +261,7 @@ void smtc_configure_tlb(void) | |||
261 | } | 261 | } |
262 | } | 262 | } |
263 | write_c0_mvpcontrol(read_c0_mvpcontrol() | MVPCONTROL_STLB); | 263 | write_c0_mvpcontrol(read_c0_mvpcontrol() | MVPCONTROL_STLB); |
264 | ehb(); | ||
264 | 265 | ||
265 | /* | 266 | /* |
266 | * Setup kernel data structures to use software total, | 267 | * Setup kernel data structures to use software total, |
@@ -1016,6 +1017,33 @@ void setup_cross_vpe_interrupts(void) | |||
1016 | * SMTC-specific hacks invoked from elsewhere in the kernel. | 1017 | * SMTC-specific hacks invoked from elsewhere in the kernel. |
1017 | */ | 1018 | */ |
1018 | 1019 | ||
1020 | void 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 | |||
1019 | void smtc_idle_loop_hook(void) | 1047 | void smtc_idle_loop_hook(void) |
1020 | { | 1048 | { |
1021 | #ifdef SMTC_IDLE_HOOK_DEBUG | 1049 | #ifdef SMTC_IDLE_HOOK_DEBUG |
@@ -1112,29 +1140,14 @@ void smtc_idle_loop_hook(void) | |||
1112 | if (pdb_msg != &id_ho_db_msg[0]) | 1140 | if (pdb_msg != &id_ho_db_msg[0]) |
1113 | printk("CPU%d: %s", smp_processor_id(), id_ho_db_msg); | 1141 | printk("CPU%d: %s", smp_processor_id(), id_ho_db_msg); |
1114 | #endif /* SMTC_IDLE_HOOK_DEBUG */ | 1142 | #endif /* SMTC_IDLE_HOOK_DEBUG */ |
1143 | |||
1115 | /* | 1144 | /* |
1116 | * To the extent that we've ever turned interrupts off, | 1145 | * Replay any accumulated deferred IPIs. If "Instant Replay" |
1117 | * we may have accumulated deferred IPIs. This is subtle. | 1146 | * is in use, there should never be any. |
1118 | * If we use the smtc_ipi_qdepth() macro, we'll get an | ||
1119 | * exact number - but we'll also disable interrupts | ||
1120 | * and create a window of failure where a new IPI gets | ||
1121 | * queued after we test the depth but before we re-enable | ||
1122 | * interrupts. So long as IXMT never gets set, however, | ||
1123 | * we should be OK: If we pick up something and dispatch | ||
1124 | * it here, that's great. If we see nothing, but concurrent | ||
1125 | * with this operation, another TC sends us an IPI, IXMT | ||
1126 | * is clear, and we'll handle it as a real pseudo-interrupt | ||
1127 | * and not a pseudo-pseudo interrupt. | ||
1128 | */ | 1147 | */ |
1129 | if (IPIQ[smp_processor_id()].depth > 0) { | 1148 | #ifndef CONFIG_MIPS_MT_SMTC_INSTANT_REPLAY |
1130 | struct smtc_ipi *pipi; | 1149 | smtc_ipi_replay(); |
1131 | extern void self_ipi(struct smtc_ipi *); | 1150 | #endif /* CONFIG_MIPS_MT_SMTC_INSTANT_REPLAY */ |
1132 | |||
1133 | if ((pipi = smtc_ipi_dq(&IPIQ[smp_processor_id()])) != NULL) { | ||
1134 | self_ipi(pipi); | ||
1135 | smtc_cpu_stats[smp_processor_id()].selfipis++; | ||
1136 | } | ||
1137 | } | ||
1138 | } | 1151 | } |
1139 | 1152 | ||
1140 | void smtc_soft_dump(void) | 1153 | void smtc_soft_dump(void) |