From ac8be955049dab828a68b9c68a75144832f8289f Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Sat, 20 Jan 2007 00:18:01 +0000 Subject: [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 --- arch/mips/kernel/smtc.c | 54 ++++++++++++++++++++++++++++++------------------- 1 file changed, 33 insertions(+), 21 deletions(-) (limited to 'arch/mips/kernel') diff --git a/arch/mips/kernel/smtc.c b/arch/mips/kernel/smtc.c index a8b387197d5..44238ab2fc9 100644 --- a/arch/mips/kernel/smtc.c +++ b/arch/mips/kernel/smtc.c @@ -1017,6 +1017,33 @@ void setup_cross_vpe_interrupts(void) * SMTC-specific hacks invoked from elsewhere in the kernel. */ +void smtc_ipi_replay(void) +{ + /* + * To the extent that we've ever turned interrupts off, + * we may have accumulated deferred IPIs. This is subtle. + * If we use the smtc_ipi_qdepth() macro, we'll get an + * exact number - but we'll also disable interrupts + * and create a window of failure where a new IPI gets + * queued after we test the depth but before we re-enable + * interrupts. So long as IXMT never gets set, however, + * we should be OK: If we pick up something and dispatch + * it here, that's great. If we see nothing, but concurrent + * with this operation, another TC sends us an IPI, IXMT + * is clear, and we'll handle it as a real pseudo-interrupt + * and not a pseudo-pseudo interrupt. + */ + if (IPIQ[smp_processor_id()].depth > 0) { + struct smtc_ipi *pipi; + extern void self_ipi(struct smtc_ipi *); + + while ((pipi = smtc_ipi_dq(&IPIQ[smp_processor_id()]))) { + self_ipi(pipi); + smtc_cpu_stats[smp_processor_id()].selfipis++; + } + } +} + void smtc_idle_loop_hook(void) { #ifdef SMTC_IDLE_HOOK_DEBUG @@ -1113,29 +1140,14 @@ void smtc_idle_loop_hook(void) if (pdb_msg != &id_ho_db_msg[0]) printk("CPU%d: %s", smp_processor_id(), id_ho_db_msg); #endif /* SMTC_IDLE_HOOK_DEBUG */ + /* - * To the extent that we've ever turned interrupts off, - * we may have accumulated deferred IPIs. This is subtle. - * If we use the smtc_ipi_qdepth() macro, we'll get an - * exact number - but we'll also disable interrupts - * and create a window of failure where a new IPI gets - * queued after we test the depth but before we re-enable - * interrupts. So long as IXMT never gets set, however, - * we should be OK: If we pick up something and dispatch - * it here, that's great. If we see nothing, but concurrent - * with this operation, another TC sends us an IPI, IXMT - * is clear, and we'll handle it as a real pseudo-interrupt - * and not a pseudo-pseudo interrupt. + * Replay any accumulated deferred IPIs. If "Instant Replay" + * is in use, there should never be any. */ - if (IPIQ[smp_processor_id()].depth > 0) { - struct smtc_ipi *pipi; - extern void self_ipi(struct smtc_ipi *); - - if ((pipi = smtc_ipi_dq(&IPIQ[smp_processor_id()])) != NULL) { - self_ipi(pipi); - smtc_cpu_stats[smp_processor_id()].selfipis++; - } - } +#ifndef CONFIG_MIPS_MT_SMTC_INSTANT_REPLAY + smtc_ipi_replay(); +#endif /* CONFIG_MIPS_MT_SMTC_INSTANT_REPLAY */ } void smtc_soft_dump(void) -- cgit v1.2.3 From a0b6218037b5cf50737a7dc0fc5464ea3f8781cd Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Fri, 19 Jan 2007 14:35:14 +0000 Subject: [MIPS] SMTC: Fix TLB sizing bug for TLB of 64 >= entries Signed-off-by: Ralf Baechle --- arch/mips/kernel/smtc.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'arch/mips/kernel') diff --git a/arch/mips/kernel/smtc.c b/arch/mips/kernel/smtc.c index 44238ab2fc9..c37e83b173e 100644 --- a/arch/mips/kernel/smtc.c +++ b/arch/mips/kernel/smtc.c @@ -270,9 +270,12 @@ void smtc_configure_tlb(void) * of their initialization in smtc_cpu_setup(). */ - tlbsiz = tlbsiz & 0x3f; /* MIPS32 limits TLB indices to 64 */ - cpu_data[0].tlbsize = tlbsiz; + /* MIPS32 limits TLB indices to 64 */ + if (tlbsiz > 64) + tlbsiz = 64; + cpu_data[0].tlbsize = current_cpu_data.tlbsize = tlbsiz; smtc_status |= SMTC_TLB_SHARED; + local_flush_tlb_all(); printk("TLB of %d entry pairs shared by %d VPEs\n", tlbsiz, vpes); -- cgit v1.2.3 From ec43c01420fc1da8bf0b19f0ceb24d7d3c7f47f3 Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Wed, 24 Jan 2007 19:23:21 +0000 Subject: [MIPS] SMTC: Fix module build by exporting symbol Signed-off-by: Ralf Baechle --- arch/mips/kernel/smtc.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'arch/mips/kernel') diff --git a/arch/mips/kernel/smtc.c b/arch/mips/kernel/smtc.c index c37e83b173e..6a857bf030b 100644 --- a/arch/mips/kernel/smtc.c +++ b/arch/mips/kernel/smtc.c @@ -4,6 +4,7 @@ #include #include #include +#include #include #include @@ -1047,6 +1048,8 @@ void smtc_ipi_replay(void) } } +EXPORT_SYMBOL(smtc_ipi_replay); + void smtc_idle_loop_hook(void) { #ifdef SMTC_IDLE_HOOK_DEBUG -- cgit v1.2.3 From 9cfdf6f15a2a462b6b328b4c60b252cfc04ec03e Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Wed, 24 Jan 2007 19:13:08 +0000 Subject: [MIPS] VPE loader: Initialize lists before they're actually being used ... kspd which due to makefile order happens to be initialized before the vpe loader causes references to vpecontrol lists before they're actually been initialized. Signed-off-by: Ralf Baechle --- arch/mips/kernel/vpe.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'arch/mips/kernel') diff --git a/arch/mips/kernel/vpe.c b/arch/mips/kernel/vpe.c index 666bef484dc..458fccf87c5 100644 --- a/arch/mips/kernel/vpe.c +++ b/arch/mips/kernel/vpe.c @@ -139,13 +139,16 @@ struct tc { struct list_head list; }; -struct vpecontrol_ { +struct { /* Virtual processing elements */ struct list_head vpe_list; /* Thread contexts */ struct list_head tc_list; -} vpecontrol; +} vpecontrol = { + .vpe_list = LIST_HEAD_INIT(vpecontrol.vpe_list), + .tc_list = LIST_HEAD_INIT(vpecontrol.tc_list) +}; static void release_progmem(void *ptr); /* static __attribute_used__ void dump_vpe(struct vpe * v); */ @@ -1388,8 +1391,6 @@ static int __init vpe_module_init(void) /* dump_mtregs(); */ - INIT_LIST_HEAD(&vpecontrol.vpe_list); - INIT_LIST_HEAD(&vpecontrol.tc_list); val = read_c0_mvpconf0(); for (i = 0; i < ((val & MVPCONF0_PTC) + 1); i++) { -- cgit v1.2.3