aboutsummaryrefslogtreecommitdiffstats
path: root/arch/mips/kernel/smtc.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/mips/kernel/smtc.c')
-rw-r--r--arch/mips/kernel/smtc.c64
1 files changed, 41 insertions, 23 deletions
diff --git a/arch/mips/kernel/smtc.c b/arch/mips/kernel/smtc.c
index a8b387197d5b..6a857bf030b0 100644
--- a/arch/mips/kernel/smtc.c
+++ b/arch/mips/kernel/smtc.c
@@ -4,6 +4,7 @@
4#include <linux/sched.h> 4#include <linux/sched.h>
5#include <linux/cpumask.h> 5#include <linux/cpumask.h>
6#include <linux/interrupt.h> 6#include <linux/interrupt.h>
7#include <linux/module.h>
7 8
8#include <asm/cpu.h> 9#include <asm/cpu.h>
9#include <asm/processor.h> 10#include <asm/processor.h>
@@ -270,9 +271,12 @@ void smtc_configure_tlb(void)
270 * of their initialization in smtc_cpu_setup(). 271 * of their initialization in smtc_cpu_setup().
271 */ 272 */
272 273
273 tlbsiz = tlbsiz & 0x3f; /* MIPS32 limits TLB indices to 64 */ 274 /* MIPS32 limits TLB indices to 64 */
274 cpu_data[0].tlbsize = tlbsiz; 275 if (tlbsiz > 64)
276 tlbsiz = 64;
277 cpu_data[0].tlbsize = current_cpu_data.tlbsize = tlbsiz;
275 smtc_status |= SMTC_TLB_SHARED; 278 smtc_status |= SMTC_TLB_SHARED;
279 local_flush_tlb_all();
276 280
277 printk("TLB of %d entry pairs shared by %d VPEs\n", 281 printk("TLB of %d entry pairs shared by %d VPEs\n",
278 tlbsiz, vpes); 282 tlbsiz, vpes);
@@ -1017,6 +1021,35 @@ void setup_cross_vpe_interrupts(void)
1017 * SMTC-specific hacks invoked from elsewhere in the kernel. 1021 * SMTC-specific hacks invoked from elsewhere in the kernel.
1018 */ 1022 */
1019 1023
1024void smtc_ipi_replay(void)
1025{
1026 /*
1027 * To the extent that we've ever turned interrupts off,
1028 * we may have accumulated deferred IPIs. This is subtle.
1029 * If we use the smtc_ipi_qdepth() macro, we'll get an
1030 * exact number - but we'll also disable interrupts
1031 * and create a window of failure where a new IPI gets
1032 * queued after we test the depth but before we re-enable
1033 * interrupts. So long as IXMT never gets set, however,
1034 * we should be OK: If we pick up something and dispatch
1035 * it here, that's great. If we see nothing, but concurrent
1036 * with this operation, another TC sends us an IPI, IXMT
1037 * is clear, and we'll handle it as a real pseudo-interrupt
1038 * and not a pseudo-pseudo interrupt.
1039 */
1040 if (IPIQ[smp_processor_id()].depth > 0) {
1041 struct smtc_ipi *pipi;
1042 extern void self_ipi(struct smtc_ipi *);
1043
1044 while ((pipi = smtc_ipi_dq(&IPIQ[smp_processor_id()]))) {
1045 self_ipi(pipi);
1046 smtc_cpu_stats[smp_processor_id()].selfipis++;
1047 }
1048 }
1049}
1050
1051EXPORT_SYMBOL(smtc_ipi_replay);
1052
1020void smtc_idle_loop_hook(void) 1053void smtc_idle_loop_hook(void)
1021{ 1054{
1022#ifdef SMTC_IDLE_HOOK_DEBUG 1055#ifdef SMTC_IDLE_HOOK_DEBUG
@@ -1113,29 +1146,14 @@ void smtc_idle_loop_hook(void)
1113 if (pdb_msg != &id_ho_db_msg[0]) 1146 if (pdb_msg != &id_ho_db_msg[0])
1114 printk("CPU%d: %s", smp_processor_id(), id_ho_db_msg); 1147 printk("CPU%d: %s", smp_processor_id(), id_ho_db_msg);
1115#endif /* SMTC_IDLE_HOOK_DEBUG */ 1148#endif /* SMTC_IDLE_HOOK_DEBUG */
1149
1116 /* 1150 /*
1117 * To the extent that we've ever turned interrupts off, 1151 * Replay any accumulated deferred IPIs. If "Instant Replay"
1118 * we may have accumulated deferred IPIs. This is subtle. 1152 * 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 */ 1153 */
1130 if (IPIQ[smp_processor_id()].depth > 0) { 1154#ifndef CONFIG_MIPS_MT_SMTC_INSTANT_REPLAY
1131 struct smtc_ipi *pipi; 1155 smtc_ipi_replay();
1132 extern void self_ipi(struct smtc_ipi *); 1156#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} 1157}
1140 1158
1141void smtc_soft_dump(void) 1159void smtc_soft_dump(void)