aboutsummaryrefslogtreecommitdiffstats
path: root/arch/blackfin/mach-bf561/smp.c
diff options
context:
space:
mode:
authorYi Li <yi.li@analog.com>2009-12-17 03:20:32 -0500
committerMike Frysinger <vapier@gentoo.org>2011-01-10 07:18:15 -0500
commit73a400646b8e26615f3ef1a0a4bc0cd0d5bd284c (patch)
tree331002731d5aac594bb99a5a9cc61f5c0933ca69 /arch/blackfin/mach-bf561/smp.c
parent2c1657c29f810d0ba32cde54cba1e916815493e5 (diff)
Blackfin: SMP: rewrite IPI handling to avoid memory allocation
Currently, sending an interprocessor interrupt (IPI) requires building up a message dynamically which means memory allocation. But often times, we will want to send an IPI in low level contexts where allocation is not possible which may lead to a panic(). So create a per-cpu static array for the message queue and use that instead. Further, while we have two supplemental interrupts, we are currently only using one of them. So use the second one for the most common IPI message of all -- smp_send_reschedule(). This avoids ugly contention for locks which in turn would require an IPI message ... In general, this improves SMP performance, and in some cases allows the SMP port to work in places it wouldn't before. Such as the PREEMPT_RT state where the slab is protected by a per-cpu spin lock. If the slab kmalloc/kfree were to put the task to sleep, and that task was actually the IPI handler, then the system falls down yet again. After running some various stress tests on the system, the static limit of 5 messages seems to work. On the off chance even this overflows, we simply panic(), and we can review that scenario to see if the limit needs to be increased a bit more. Signed-off-by: Yi Li <yi.li@analog.com> Signed-off-by: Mike Frysinger <vapier@gentoo.org>
Diffstat (limited to 'arch/blackfin/mach-bf561/smp.c')
-rw-r--r--arch/blackfin/mach-bf561/smp.c25
1 files changed, 15 insertions, 10 deletions
diff --git a/arch/blackfin/mach-bf561/smp.c b/arch/blackfin/mach-bf561/smp.c
index 1a19fad63f4e..1074a7ef81c7 100644
--- a/arch/blackfin/mach-bf561/smp.c
+++ b/arch/blackfin/mach-bf561/smp.c
@@ -111,41 +111,46 @@ int __cpuinit platform_boot_secondary(unsigned int cpu, struct task_struct *idle
111 panic("CPU%u: processor failed to boot\n", cpu); 111 panic("CPU%u: processor failed to boot\n", cpu);
112} 112}
113 113
114void __init platform_request_ipi(void *handler) 114static const char supple0[] = "IRQ_SUPPLE_0";
115static const char supple1[] = "IRQ_SUPPLE_1";
116void __init platform_request_ipi(int irq, void *handler)
115{ 117{
116 int ret; 118 int ret;
119 const char *name = (irq == IRQ_SUPPLE_0) ? supple0 : supple1;
117 120
118 ret = request_irq(IRQ_SUPPLE_0, handler, IRQF_DISABLED, 121 ret = request_irq(irq, handler, IRQF_DISABLED | IRQF_PERCPU, name, handler);
119 "Supplemental Interrupt0", handler);
120 if (ret) 122 if (ret)
121 panic("Cannot request supplemental interrupt 0 for IPI service"); 123 panic("Cannot request %s for IPI service", name);
122} 124}
123 125
124void platform_send_ipi(cpumask_t callmap) 126void platform_send_ipi(cpumask_t callmap, int irq)
125{ 127{
126 unsigned int cpu; 128 unsigned int cpu;
129 int offset = (irq == IRQ_SUPPLE_0) ? 6 : 8;
127 130
128 for_each_cpu_mask(cpu, callmap) { 131 for_each_cpu_mask(cpu, callmap) {
129 BUG_ON(cpu >= 2); 132 BUG_ON(cpu >= 2);
130 SSYNC(); 133 SSYNC();
131 bfin_write_SICB_SYSCR(bfin_read_SICB_SYSCR() | (1 << (6 + cpu))); 134 bfin_write_SICB_SYSCR(bfin_read_SICB_SYSCR() | (1 << (offset + cpu)));
132 SSYNC(); 135 SSYNC();
133 } 136 }
134} 137}
135 138
136void platform_send_ipi_cpu(unsigned int cpu) 139void platform_send_ipi_cpu(unsigned int cpu, int irq)
137{ 140{
141 int offset = (irq == IRQ_SUPPLE_0) ? 6 : 8;
138 BUG_ON(cpu >= 2); 142 BUG_ON(cpu >= 2);
139 SSYNC(); 143 SSYNC();
140 bfin_write_SICB_SYSCR(bfin_read_SICB_SYSCR() | (1 << (6 + cpu))); 144 bfin_write_SICB_SYSCR(bfin_read_SICB_SYSCR() | (1 << (offset + cpu)));
141 SSYNC(); 145 SSYNC();
142} 146}
143 147
144void platform_clear_ipi(unsigned int cpu) 148void platform_clear_ipi(unsigned int cpu, int irq)
145{ 149{
150 int offset = (irq == IRQ_SUPPLE_0) ? 10 : 12;
146 BUG_ON(cpu >= 2); 151 BUG_ON(cpu >= 2);
147 SSYNC(); 152 SSYNC();
148 bfin_write_SICB_SYSCR(bfin_read_SICB_SYSCR() | (1 << (10 + cpu))); 153 bfin_write_SICB_SYSCR(bfin_read_SICB_SYSCR() | (1 << (offset + cpu)));
149 SSYNC(); 154 SSYNC();
150} 155}
151 156