Merge branch 'upstream' of git://ftp.linux-mips.org/pub/scm/upstream-linus

* 'upstream' of git://ftp.linux-mips.org/pub/scm/upstream-linus:
[MIPS] SMTC: Fix SMTC dyntick support.
[MIPS] SMTC: Close tiny holes in the SMTC IPI replay system.
[MIPS] SMTC: Fix holes in SMTC and FPU affinity support.
[MIPS] SMTC: Build fix: Fix filename in Makefile
[MIPS] Build fix: Fix irq flags type

+685 -316
+4 -22
arch/mips/Kconfig
··· 1403 1403 depends on CPU_MIPS32_R2 1404 1404 #depends on CPU_MIPS64_R2 # once there is hardware ... 1405 1405 depends on SYS_SUPPORTS_MULTITHREADING 1406 - select GENERIC_CLOCKEVENTS_BROADCAST 1407 1406 select CPU_MIPSR2_IRQ_VI 1408 1407 select CPU_MIPSR2_IRQ_EI 1409 1408 select MIPS_MT ··· 1450 1451 Includes a loader for loading an elf relocatable object 1451 1452 onto another VPE and running it. 1452 1453 1453 - config MIPS_MT_SMTC_INSTANT_REPLAY 1454 - bool "Low-latency Dispatch of Deferred SMTC IPIs" 1455 - depends on MIPS_MT_SMTC && !PREEMPT 1456 - default y 1457 - help 1458 - SMTC pseudo-interrupts between TCs are deferred and queued 1459 - if the target TC is interrupt-inhibited (IXMT). In the first 1460 - SMTC prototypes, these queued IPIs were serviced on return 1461 - to user mode, or on entry into the kernel idle loop. The 1462 - INSTANT_REPLAY option dispatches them as part of local_irq_restore() 1463 - processing, which adds runtime overhead (hence the option to turn 1464 - it off), but ensures that IPIs are handled promptly even under 1465 - heavy I/O interrupt load. 1466 - 1467 1454 config MIPS_MT_SMTC_IM_BACKSTOP 1468 1455 bool "Use per-TC register bits as backstop for inhibited IM bits" 1469 1456 depends on MIPS_MT_SMTC 1470 - default y 1457 + default n 1471 1458 help 1472 1459 To support multiple TC microthreads acting as "CPUs" within 1473 1460 a VPE, VPE-wide interrupt mask bits must be specially manipulated 1474 1461 during interrupt handling. To support legacy drivers and interrupt 1475 1462 controller management code, SMTC has a "backstop" to track and 1476 1463 if necessary restore the interrupt mask. This has some performance 1477 - impact on interrupt service overhead. Disable it only if you know 1478 - what you are doing. 1464 + impact on interrupt service overhead. 1479 1465 1480 1466 config MIPS_MT_SMTC_IRQAFF 1481 1467 bool "Support IRQ affinity API" ··· 1470 1486 Enables SMP IRQ affinity API (/proc/irq/*/smp_affinity, etc.) 1471 1487 for SMTC Linux kernel. Requires platform support, of which 1472 1488 an example can be found in the MIPS kernel i8259 and Malta 1473 - platform code. It is recommended that MIPS_MT_SMTC_INSTANT_REPLAY 1474 - be enabled if MIPS_MT_SMTC_IRQAFF is used. Adds overhead to 1475 - interrupt dispatch, and should be used only if you know what 1476 - you are doing. 1489 + platform code. Adds some overhead to interrupt dispatch, and 1490 + should be used only if you know what you are doing. 1477 1491 1478 1492 config MIPS_VPE_LOADER_TOM 1479 1493 bool "Load VPE program into memory hidden from linux"
+1
arch/mips/kernel/Makefile
··· 10 10 11 11 obj-$(CONFIG_CEVT_BCM1480) += cevt-bcm1480.o 12 12 obj-$(CONFIG_CEVT_R4K) += cevt-r4k.o 13 + obj-$(CONFIG_MIPS_MT_SMTC) += cevt-smtc.o 13 14 obj-$(CONFIG_CEVT_DS1287) += cevt-ds1287.o 14 15 obj-$(CONFIG_CEVT_GT641XX) += cevt-gt641xx.o 15 16 obj-$(CONFIG_CEVT_SB1250) += cevt-sb1250.o
+48 -125
arch/mips/kernel/cevt-r4k.c
··· 12 12 13 13 #include <asm/smtc_ipi.h> 14 14 #include <asm/time.h> 15 + #include <asm/cevt-r4k.h> 16 + 17 + /* 18 + * The SMTC Kernel for the 34K, 1004K, et. al. replaces several 19 + * of these routines with SMTC-specific variants. 20 + */ 21 + 22 + #ifndef CONFIG_MIPS_MT_SMTC 15 23 16 24 static int mips_next_event(unsigned long delta, 17 25 struct clock_event_device *evt) ··· 27 19 unsigned int cnt; 28 20 int res; 29 21 30 - #ifdef CONFIG_MIPS_MT_SMTC 31 - { 32 - unsigned long flags, vpflags; 33 - local_irq_save(flags); 34 - vpflags = dvpe(); 35 - #endif 36 22 cnt = read_c0_count(); 37 23 cnt += delta; 38 24 write_c0_compare(cnt); 39 25 res = ((int)(read_c0_count() - cnt) > 0) ? -ETIME : 0; 40 - #ifdef CONFIG_MIPS_MT_SMTC 41 - evpe(vpflags); 42 - local_irq_restore(flags); 43 - } 44 - #endif 45 26 return res; 46 27 } 47 28 48 - static void mips_set_mode(enum clock_event_mode mode, 49 - struct clock_event_device *evt) 29 + #endif /* CONFIG_MIPS_MT_SMTC */ 30 + 31 + void mips_set_clock_mode(enum clock_event_mode mode, 32 + struct clock_event_device *evt) 50 33 { 51 34 /* Nothing to do ... */ 52 35 } 53 36 54 - static DEFINE_PER_CPU(struct clock_event_device, mips_clockevent_device); 55 - static int cp0_timer_irq_installed; 37 + DEFINE_PER_CPU(struct clock_event_device, mips_clockevent_device); 38 + int cp0_timer_irq_installed; 56 39 57 - /* 58 - * Timer ack for an R4k-compatible timer of a known frequency. 59 - */ 60 - static void c0_timer_ack(void) 61 - { 62 - write_c0_compare(read_c0_compare()); 63 - } 40 + #ifndef CONFIG_MIPS_MT_SMTC 64 41 65 - /* 66 - * Possibly handle a performance counter interrupt. 67 - * Return true if the timer interrupt should not be checked 68 - */ 69 - static inline int handle_perf_irq(int r2) 70 - { 71 - /* 72 - * The performance counter overflow interrupt may be shared with the 73 - * timer interrupt (cp0_perfcount_irq < 0). If it is and a 74 - * performance counter has overflowed (perf_irq() == IRQ_HANDLED) 75 - * and we can't reliably determine if a counter interrupt has also 76 - * happened (!r2) then don't check for a timer interrupt. 77 - */ 78 - return (cp0_perfcount_irq < 0) && 79 - perf_irq() == IRQ_HANDLED && 80 - !r2; 81 - } 82 - 83 - static irqreturn_t c0_compare_interrupt(int irq, void *dev_id) 42 + irqreturn_t c0_compare_interrupt(int irq, void *dev_id) 84 43 { 85 44 const int r2 = cpu_has_mips_r2; 86 45 struct clock_event_device *cd; ··· 68 93 * interrupt. Being the paranoiacs we are we check anyway. 69 94 */ 70 95 if (!r2 || (read_c0_cause() & (1 << 30))) { 71 - c0_timer_ack(); 72 - #ifdef CONFIG_MIPS_MT_SMTC 73 - if (cpu_data[cpu].vpe_id) 74 - goto out; 75 - cpu = 0; 76 - #endif 96 + /* Clear Count/Compare Interrupt */ 97 + write_c0_compare(read_c0_compare()); 77 98 cd = &per_cpu(mips_clockevent_device, cpu); 78 99 cd->event_handler(cd); 79 100 } ··· 78 107 return IRQ_HANDLED; 79 108 } 80 109 81 - static struct irqaction c0_compare_irqaction = { 110 + #endif /* Not CONFIG_MIPS_MT_SMTC */ 111 + 112 + struct irqaction c0_compare_irqaction = { 82 113 .handler = c0_compare_interrupt, 83 - #ifdef CONFIG_MIPS_MT_SMTC 84 - .flags = IRQF_DISABLED, 85 - #else 86 114 .flags = IRQF_DISABLED | IRQF_PERCPU, 87 - #endif 88 115 .name = "timer", 89 116 }; 90 117 91 - #ifdef CONFIG_MIPS_MT_SMTC 92 - DEFINE_PER_CPU(struct clock_event_device, smtc_dummy_clockevent_device); 93 118 94 - static void smtc_set_mode(enum clock_event_mode mode, 95 - struct clock_event_device *evt) 96 - { 97 - } 98 - 99 - static void mips_broadcast(cpumask_t mask) 100 - { 101 - unsigned int cpu; 102 - 103 - for_each_cpu_mask(cpu, mask) 104 - smtc_send_ipi(cpu, SMTC_CLOCK_TICK, 0); 105 - } 106 - 107 - static void setup_smtc_dummy_clockevent_device(void) 108 - { 109 - //uint64_t mips_freq = mips_hpt_^frequency; 110 - unsigned int cpu = smp_processor_id(); 111 - struct clock_event_device *cd; 112 - 113 - cd = &per_cpu(smtc_dummy_clockevent_device, cpu); 114 - 115 - cd->name = "SMTC"; 116 - cd->features = CLOCK_EVT_FEAT_DUMMY; 117 - 118 - /* Calculate the min / max delta */ 119 - cd->mult = 0; //div_sc((unsigned long) mips_freq, NSEC_PER_SEC, 32); 120 - cd->shift = 0; //32; 121 - cd->max_delta_ns = 0; //clockevent_delta2ns(0x7fffffff, cd); 122 - cd->min_delta_ns = 0; //clockevent_delta2ns(0x30, cd); 123 - 124 - cd->rating = 200; 125 - cd->irq = 17; //-1; 126 - // if (cpu) 127 - // cd->cpumask = CPU_MASK_ALL; // cpumask_of_cpu(cpu); 128 - // else 129 - cd->cpumask = cpumask_of_cpu(cpu); 130 - 131 - cd->set_mode = smtc_set_mode; 132 - 133 - cd->broadcast = mips_broadcast; 134 - 135 - clockevents_register_device(cd); 136 - } 137 - #endif 138 - 139 - static void mips_event_handler(struct clock_event_device *dev) 119 + void mips_event_handler(struct clock_event_device *dev) 140 120 { 141 121 } 142 122 ··· 99 177 return (read_c0_cause() >> cp0_compare_irq) & 0x100; 100 178 } 101 179 102 - static int c0_compare_int_usable(void) 180 + /* 181 + * Compare interrupt can be routed and latched outside the core, 182 + * so a single execution hazard barrier may not be enough to give 183 + * it time to clear as seen in the Cause register. 4 time the 184 + * pipeline depth seems reasonably conservative, and empirically 185 + * works better in configurations with high CPU/bus clock ratios. 186 + */ 187 + 188 + #define compare_change_hazard() \ 189 + do { \ 190 + irq_disable_hazard(); \ 191 + irq_disable_hazard(); \ 192 + irq_disable_hazard(); \ 193 + irq_disable_hazard(); \ 194 + } while (0) 195 + 196 + int c0_compare_int_usable(void) 103 197 { 104 198 unsigned int delta; 105 199 unsigned int cnt; ··· 125 187 */ 126 188 if (c0_compare_int_pending()) { 127 189 write_c0_compare(read_c0_count()); 128 - irq_disable_hazard(); 190 + compare_change_hazard(); 129 191 if (c0_compare_int_pending()) 130 192 return 0; 131 193 } ··· 134 196 cnt = read_c0_count(); 135 197 cnt += delta; 136 198 write_c0_compare(cnt); 137 - irq_disable_hazard(); 199 + compare_change_hazard(); 138 200 if ((int)(read_c0_count() - cnt) < 0) 139 201 break; 140 202 /* increase delta if the timer was already expired */ ··· 143 205 while ((int)(read_c0_count() - cnt) <= 0) 144 206 ; /* Wait for expiry */ 145 207 208 + compare_change_hazard(); 146 209 if (!c0_compare_int_pending()) 147 210 return 0; 148 211 149 212 write_c0_compare(read_c0_count()); 150 - irq_disable_hazard(); 213 + compare_change_hazard(); 151 214 if (c0_compare_int_pending()) 152 215 return 0; 153 216 ··· 157 218 */ 158 219 return 1; 159 220 } 221 + 222 + #ifndef CONFIG_MIPS_MT_SMTC 160 223 161 224 int __cpuinit mips_clockevent_init(void) 162 225 { ··· 169 228 170 229 if (!cpu_has_counter || !mips_hpt_frequency) 171 230 return -ENXIO; 172 - 173 - #ifdef CONFIG_MIPS_MT_SMTC 174 - setup_smtc_dummy_clockevent_device(); 175 - 176 - /* 177 - * On SMTC we only register VPE0's compare interrupt as clockevent 178 - * device. 179 - */ 180 - if (cpu) 181 - return 0; 182 - #endif 183 231 184 232 if (!c0_compare_int_usable()) 185 233 return -ENXIO; ··· 195 265 196 266 cd->rating = 300; 197 267 cd->irq = irq; 198 - #ifdef CONFIG_MIPS_MT_SMTC 199 - cd->cpumask = CPU_MASK_ALL; 200 - #else 201 268 cd->cpumask = cpumask_of_cpu(cpu); 202 - #endif 203 269 cd->set_next_event = mips_next_event; 204 - cd->set_mode = mips_set_mode; 270 + cd->set_mode = mips_set_clock_mode; 205 271 cd->event_handler = mips_event_handler; 206 272 207 273 clockevents_register_device(cd); ··· 207 281 208 282 cp0_timer_irq_installed = 1; 209 283 210 - #ifdef CONFIG_MIPS_MT_SMTC 211 - #define CPUCTR_IMASKBIT (0x100 << cp0_compare_irq) 212 - setup_irq_smtc(irq, &c0_compare_irqaction, CPUCTR_IMASKBIT); 213 - #else 214 284 setup_irq(irq, &c0_compare_irqaction); 215 - #endif 216 285 217 286 return 0; 218 287 } 288 + 289 + #endif /* Not CONFIG_MIPS_MT_SMTC */
+321
arch/mips/kernel/cevt-smtc.c
··· 1 + /* 2 + * This file is subject to the terms and conditions of the GNU General Public 3 + * License. See the file "COPYING" in the main directory of this archive 4 + * for more details. 5 + * 6 + * Copyright (C) 2007 MIPS Technologies, Inc. 7 + * Copyright (C) 2007 Ralf Baechle <ralf@linux-mips.org> 8 + * Copyright (C) 2008 Kevin D. Kissell, Paralogos sarl 9 + */ 10 + #include <linux/clockchips.h> 11 + #include <linux/interrupt.h> 12 + #include <linux/percpu.h> 13 + 14 + #include <asm/smtc_ipi.h> 15 + #include <asm/time.h> 16 + #include <asm/cevt-r4k.h> 17 + 18 + /* 19 + * Variant clock event timer support for SMTC on MIPS 34K, 1004K 20 + * or other MIPS MT cores. 21 + * 22 + * Notes on SMTC Support: 23 + * 24 + * SMTC has multiple microthread TCs pretending to be Linux CPUs. 25 + * But there's only one Count/Compare pair per VPE, and Compare 26 + * interrupts are taken opportunisitically by available TCs 27 + * bound to the VPE with the Count register. The new timer 28 + * framework provides for global broadcasts, but we really 29 + * want VPE-level multicasts for best behavior. So instead 30 + * of invoking the high-level clock-event broadcast code, 31 + * this version of SMTC support uses the historical SMTC 32 + * multicast mechanisms "under the hood", appearing to the 33 + * generic clock layer as if the interrupts are per-CPU. 34 + * 35 + * The approach taken here is to maintain a set of NR_CPUS 36 + * virtual timers, and track which "CPU" needs to be alerted 37 + * at each event. 38 + * 39 + * It's unlikely that we'll see a MIPS MT core with more than 40 + * 2 VPEs, but we *know* that we won't need to handle more 41 + * VPEs than we have "CPUs". So NCPUs arrays of NCPUs elements 42 + * is always going to be overkill, but always going to be enough. 43 + */ 44 + 45 + unsigned long smtc_nexttime[NR_CPUS][NR_CPUS]; 46 + static int smtc_nextinvpe[NR_CPUS]; 47 + 48 + /* 49 + * Timestamps stored are absolute values to be programmed 50 + * into Count register. Valid timestamps will never be zero. 51 + * If a Zero Count value is actually calculated, it is converted 52 + * to be a 1, which will introduce 1 or two CPU cycles of error 53 + * roughly once every four billion events, which at 1000 HZ means 54 + * about once every 50 days. If that's actually a problem, one 55 + * could alternate squashing 0 to 1 and to -1. 56 + */ 57 + 58 + #define MAKEVALID(x) (((x) == 0L) ? 1L : (x)) 59 + #define ISVALID(x) ((x) != 0L) 60 + 61 + /* 62 + * Time comparison is subtle, as it's really truncated 63 + * modular arithmetic. 64 + */ 65 + 66 + #define IS_SOONER(a, b, reference) \ 67 + (((a) - (unsigned long)(reference)) < ((b) - (unsigned long)(reference))) 68 + 69 + /* 70 + * CATCHUP_INCREMENT, used when the function falls behind the counter. 71 + * Could be an increasing function instead of a constant; 72 + */ 73 + 74 + #define CATCHUP_INCREMENT 64 75 + 76 + static int mips_next_event(unsigned long delta, 77 + struct clock_event_device *evt) 78 + { 79 + unsigned long flags; 80 + unsigned int mtflags; 81 + unsigned long timestamp, reference, previous; 82 + unsigned long nextcomp = 0L; 83 + int vpe = current_cpu_data.vpe_id; 84 + int cpu = smp_processor_id(); 85 + local_irq_save(flags); 86 + mtflags = dmt(); 87 + 88 + /* 89 + * Maintain the per-TC virtual timer 90 + * and program the per-VPE shared Count register 91 + * as appropriate here... 92 + */ 93 + reference = (unsigned long)read_c0_count(); 94 + timestamp = MAKEVALID(reference + delta); 95 + /* 96 + * To really model the clock, we have to catch the case 97 + * where the current next-in-VPE timestamp is the old 98 + * timestamp for the calling CPE, but the new value is 99 + * in fact later. In that case, we have to do a full 100 + * scan and discover the new next-in-VPE CPU id and 101 + * timestamp. 102 + */ 103 + previous = smtc_nexttime[vpe][cpu]; 104 + if (cpu == smtc_nextinvpe[vpe] && ISVALID(previous) 105 + && IS_SOONER(previous, timestamp, reference)) { 106 + int i; 107 + int soonest = cpu; 108 + 109 + /* 110 + * Update timestamp array here, so that new 111 + * value gets considered along with those of 112 + * other virtual CPUs on the VPE. 113 + */ 114 + smtc_nexttime[vpe][cpu] = timestamp; 115 + for_each_online_cpu(i) { 116 + if (ISVALID(smtc_nexttime[vpe][i]) 117 + && IS_SOONER(smtc_nexttime[vpe][i], 118 + smtc_nexttime[vpe][soonest], reference)) { 119 + soonest = i; 120 + } 121 + } 122 + smtc_nextinvpe[vpe] = soonest; 123 + nextcomp = smtc_nexttime[vpe][soonest]; 124 + /* 125 + * Otherwise, we don't have to process the whole array rank, 126 + * we just have to see if the event horizon has gotten closer. 127 + */ 128 + } else { 129 + if (!ISVALID(smtc_nexttime[vpe][smtc_nextinvpe[vpe]]) || 130 + IS_SOONER(timestamp, 131 + smtc_nexttime[vpe][smtc_nextinvpe[vpe]], reference)) { 132 + smtc_nextinvpe[vpe] = cpu; 133 + nextcomp = timestamp; 134 + } 135 + /* 136 + * Since next-in-VPE may me the same as the executing 137 + * virtual CPU, we update the array *after* checking 138 + * its value. 139 + */ 140 + smtc_nexttime[vpe][cpu] = timestamp; 141 + } 142 + 143 + /* 144 + * It may be that, in fact, we don't need to update Compare, 145 + * but if we do, we want to make sure we didn't fall into 146 + * a crack just behind Count. 147 + */ 148 + if (ISVALID(nextcomp)) { 149 + write_c0_compare(nextcomp); 150 + ehb(); 151 + /* 152 + * We never return an error, we just make sure 153 + * that we trigger the handlers as quickly as 154 + * we can if we fell behind. 155 + */ 156 + while ((nextcomp - (unsigned long)read_c0_count()) 157 + > (unsigned long)LONG_MAX) { 158 + nextcomp += CATCHUP_INCREMENT; 159 + write_c0_compare(nextcomp); 160 + ehb(); 161 + } 162 + } 163 + emt(mtflags); 164 + local_irq_restore(flags); 165 + return 0; 166 + } 167 + 168 + 169 + void smtc_distribute_timer(int vpe) 170 + { 171 + unsigned long flags; 172 + unsigned int mtflags; 173 + int cpu; 174 + struct clock_event_device *cd; 175 + unsigned long nextstamp = 0L; 176 + unsigned long reference; 177 + 178 + 179 + repeat: 180 + for_each_online_cpu(cpu) { 181 + /* 182 + * Find virtual CPUs within the current VPE who have 183 + * unserviced timer requests whose time is now past. 184 + */ 185 + local_irq_save(flags); 186 + mtflags = dmt(); 187 + if (cpu_data[cpu].vpe_id == vpe && 188 + ISVALID(smtc_nexttime[vpe][cpu])) { 189 + reference = (unsigned long)read_c0_count(); 190 + if ((smtc_nexttime[vpe][cpu] - reference) 191 + > (unsigned long)LONG_MAX) { 192 + smtc_nexttime[vpe][cpu] = 0L; 193 + emt(mtflags); 194 + local_irq_restore(flags); 195 + /* 196 + * We don't send IPIs to ourself. 197 + */ 198 + if (cpu != smp_processor_id()) { 199 + smtc_send_ipi(cpu, SMTC_CLOCK_TICK, 0); 200 + } else { 201 + cd = &per_cpu(mips_clockevent_device, cpu); 202 + cd->event_handler(cd); 203 + } 204 + } else { 205 + /* Local to VPE but Valid Time not yet reached. */ 206 + if (!ISVALID(nextstamp) || 207 + IS_SOONER(smtc_nexttime[vpe][cpu], nextstamp, 208 + reference)) { 209 + smtc_nextinvpe[vpe] = cpu; 210 + nextstamp = smtc_nexttime[vpe][cpu]; 211 + } 212 + emt(mtflags); 213 + local_irq_restore(flags); 214 + } 215 + } else { 216 + emt(mtflags); 217 + local_irq_restore(flags); 218 + 219 + } 220 + } 221 + /* Reprogram for interrupt at next soonest timestamp for VPE */ 222 + if (ISVALID(nextstamp)) { 223 + write_c0_compare(nextstamp); 224 + ehb(); 225 + if ((nextstamp - (unsigned long)read_c0_count()) 226 + > (unsigned long)LONG_MAX) 227 + goto repeat; 228 + } 229 + } 230 + 231 + 232 + irqreturn_t c0_compare_interrupt(int irq, void *dev_id) 233 + { 234 + int cpu = smp_processor_id(); 235 + 236 + /* If we're running SMTC, we've got MIPS MT and therefore MIPS32R2 */ 237 + handle_perf_irq(1); 238 + 239 + if (read_c0_cause() & (1 << 30)) { 240 + /* Clear Count/Compare Interrupt */ 241 + write_c0_compare(read_c0_compare()); 242 + smtc_distribute_timer(cpu_data[cpu].vpe_id); 243 + } 244 + return IRQ_HANDLED; 245 + } 246 + 247 + 248 + int __cpuinit mips_clockevent_init(void) 249 + { 250 + uint64_t mips_freq = mips_hpt_frequency; 251 + unsigned int cpu = smp_processor_id(); 252 + struct clock_event_device *cd; 253 + unsigned int irq; 254 + int i; 255 + int j; 256 + 257 + if (!cpu_has_counter || !mips_hpt_frequency) 258 + return -ENXIO; 259 + if (cpu == 0) { 260 + for (i = 0; i < num_possible_cpus(); i++) { 261 + smtc_nextinvpe[i] = 0; 262 + for (j = 0; j < num_possible_cpus(); j++) 263 + smtc_nexttime[i][j] = 0L; 264 + } 265 + /* 266 + * SMTC also can't have the usablility test 267 + * run by secondary TCs once Compare is in use. 268 + */ 269 + if (!c0_compare_int_usable()) 270 + return -ENXIO; 271 + } 272 + 273 + /* 274 + * With vectored interrupts things are getting platform specific. 275 + * get_c0_compare_int is a hook to allow a platform to return the 276 + * interrupt number of it's liking. 277 + */ 278 + irq = MIPS_CPU_IRQ_BASE + cp0_compare_irq; 279 + if (get_c0_compare_int) 280 + irq = get_c0_compare_int(); 281 + 282 + cd = &per_cpu(mips_clockevent_device, cpu); 283 + 284 + cd->name = "MIPS"; 285 + cd->features = CLOCK_EVT_FEAT_ONESHOT; 286 + 287 + /* Calculate the min / max delta */ 288 + cd->mult = div_sc((unsigned long) mips_freq, NSEC_PER_SEC, 32); 289 + cd->shift = 32; 290 + cd->max_delta_ns = clockevent_delta2ns(0x7fffffff, cd); 291 + cd->min_delta_ns = clockevent_delta2ns(0x300, cd); 292 + 293 + cd->rating = 300; 294 + cd->irq = irq; 295 + cd->cpumask = cpumask_of_cpu(cpu); 296 + cd->set_next_event = mips_next_event; 297 + cd->set_mode = mips_set_clock_mode; 298 + cd->event_handler = mips_event_handler; 299 + 300 + clockevents_register_device(cd); 301 + 302 + /* 303 + * On SMTC we only want to do the data structure 304 + * initialization and IRQ setup once. 305 + */ 306 + if (cpu) 307 + return 0; 308 + /* 309 + * And we need the hwmask associated with the c0_compare 310 + * vector to be initialized. 311 + */ 312 + irq_hwmask[irq] = (0x100 << cp0_compare_irq); 313 + if (cp0_timer_irq_installed) 314 + return 0; 315 + 316 + cp0_timer_irq_installed = 1; 317 + 318 + setup_irq(irq, &c0_compare_irqaction); 319 + 320 + return 0; 321 + }
+7 -3
arch/mips/kernel/cpu-probe.c
··· 54 54 * interrupt is requested" restriction in the MIPS32/MIPS64 architecture makes 55 55 * using this version a gamble. 56 56 */ 57 - static void r4k_wait_irqoff(void) 57 + void r4k_wait_irqoff(void) 58 58 { 59 59 local_irq_disable(); 60 60 if (!need_resched()) 61 - __asm__(" .set mips3 \n" 61 + __asm__(" .set push \n" 62 + " .set mips3 \n" 62 63 " wait \n" 63 - " .set mips0 \n"); 64 + " .set pop \n"); 64 65 local_irq_enable(); 66 + __asm__(" .globl __pastwait \n" 67 + "__pastwait: \n"); 68 + return; 65 69 } 66 70 67 71 /*
+5 -5
arch/mips/kernel/entry.S
··· 79 79 80 80 FEXPORT(restore_all) # restore full frame 81 81 #ifdef CONFIG_MIPS_MT_SMTC 82 - /* Detect and execute deferred IPI "interrupts" */ 83 - LONG_L s0, TI_REGS($28) 84 - LONG_S sp, TI_REGS($28) 85 - jal deferred_smtc_ipi 86 - LONG_S s0, TI_REGS($28) 87 82 #ifdef CONFIG_MIPS_MT_SMTC_IM_BACKSTOP 88 83 /* Re-arm any temporarily masked interrupts not explicitly "acked" */ 89 84 mfc0 v0, CP0_TCSTATUS ··· 107 112 xor t0, t0, t3 108 113 mtc0 t0, CP0_TCCONTEXT 109 114 #endif /* CONFIG_MIPS_MT_SMTC_IM_BACKSTOP */ 115 + /* Detect and execute deferred IPI "interrupts" */ 116 + LONG_L s0, TI_REGS($28) 117 + LONG_S sp, TI_REGS($28) 118 + jal deferred_smtc_ipi 119 + LONG_S s0, TI_REGS($28) 110 120 #endif /* CONFIG_MIPS_MT_SMTC */ 111 121 .set noat 112 122 RESTORE_TEMP
+2 -2
arch/mips/kernel/genex.S
··· 282 282 and t0, a0, t1 283 283 #ifdef CONFIG_MIPS_MT_SMTC_IM_BACKSTOP 284 284 mfc0 t2, CP0_TCCONTEXT 285 - or t0, t0, t2 286 - mtc0 t0, CP0_TCCONTEXT 285 + or t2, t0, t2 286 + mtc0 t2, CP0_TCCONTEXT 287 287 #endif /* CONFIG_MIPS_MT_SMTC_IM_BACKSTOP */ 288 288 xor t1, t1, t0 289 289 mtc0 t1, CP0_STATUS
+1 -1
arch/mips/kernel/mips-mt-fpaff.c
··· 159 159 /* 160 160 * FPU Use Factor empirically derived from experiments on 34K 161 161 */ 162 - #define FPUSEFACTOR 333 162 + #define FPUSEFACTOR 2000 163 163 164 164 static __init int mt_fp_affinity_init(void) 165 165 {
+9 -10
arch/mips/kernel/process.c
··· 55 55 while (1) { 56 56 tick_nohz_stop_sched_tick(1); 57 57 while (!need_resched()) { 58 - #ifdef CONFIG_SMTC_IDLE_HOOK_DEBUG 58 + #ifdef CONFIG_MIPS_MT_SMTC 59 59 extern void smtc_idle_loop_hook(void); 60 60 61 61 smtc_idle_loop_hook(); ··· 145 145 */ 146 146 p->thread.cp0_status = read_c0_status() & ~(ST0_CU2|ST0_CU1); 147 147 childregs->cp0_status &= ~(ST0_CU2|ST0_CU1); 148 + 149 + #ifdef CONFIG_MIPS_MT_SMTC 150 + /* 151 + * SMTC restores TCStatus after Status, and the CU bits 152 + * are aliased there. 153 + */ 154 + childregs->cp0_tcstatus &= ~(ST0_CU2|ST0_CU1); 155 + #endif 148 156 clear_tsk_thread_flag(p, TIF_USEDFPU); 149 157 150 158 #ifdef CONFIG_MIPS_MT_FPAFF 151 159 clear_tsk_thread_flag(p, TIF_FPUBOUND); 152 - 153 - /* 154 - * FPU affinity support is cleaner if we track the 155 - * user-visible CPU affinity from the very beginning. 156 - * The generic cpus_allowed mask will already have 157 - * been copied from the parent before copy_thread 158 - * is invoked. 159 - */ 160 - p->thread.user_cpus_allowed = p->cpus_allowed; 161 160 #endif /* CONFIG_MIPS_MT_FPAFF */ 162 161 163 162 if (clone_flags & CLONE_SETTLS)
+1 -1
arch/mips/kernel/ptrace.c
··· 238 238 case FPC_EIR: { /* implementation / version register */ 239 239 unsigned int flags; 240 240 #ifdef CONFIG_MIPS_MT_SMTC 241 - unsigned int irqflags; 241 + unsigned long irqflags; 242 242 unsigned int mtflags; 243 243 #endif /* CONFIG_MIPS_MT_SMTC */ 244 244
+136 -122
arch/mips/kernel/smtc.c
··· 1 - /* Copyright (C) 2004 Mips Technologies, Inc */ 1 + /* 2 + * This program is free software; you can redistribute it and/or 3 + * modify it under the terms of the GNU General Public License 4 + * as published by the Free Software Foundation; either version 2 5 + * of the License, or (at your option) any later version. 6 + * 7 + * This program is distributed in the hope that it will be useful, 8 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 9 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 10 + * GNU General Public License for more details. 11 + * 12 + * You should have received a copy of the GNU General Public License 13 + * along with this program; if not, write to the Free Software 14 + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 15 + * 16 + * Copyright (C) 2004 Mips Technologies, Inc 17 + * Copyright (C) 2008 Kevin D. Kissell 18 + */ 2 19 3 20 #include <linux/clockchips.h> 4 21 #include <linux/kernel.h> ··· 38 21 #include <asm/time.h> 39 22 #include <asm/addrspace.h> 40 23 #include <asm/smtc.h> 41 - #include <asm/smtc_ipi.h> 42 24 #include <asm/smtc_proc.h> 43 25 44 26 /* ··· 74 58 75 59 asiduse smtc_live_asid[MAX_SMTC_TLBS][MAX_SMTC_ASIDS]; 76 60 77 - /* 78 - * Clock interrupt "latch" buffers, per "CPU" 79 - */ 80 - 81 - static atomic_t ipi_timer_latch[NR_CPUS]; 82 61 83 62 /* 84 63 * Number of InterProcessor Interrupt (IPI) message buffers to allocate ··· 81 70 82 71 #define IPIBUF_PER_CPU 4 83 72 84 - static struct smtc_ipi_q IPIQ[NR_CPUS]; 73 + struct smtc_ipi_q IPIQ[NR_CPUS]; 85 74 static struct smtc_ipi_q freeIPIq; 86 75 87 76 ··· 293 282 * phys_cpu_present_map and the logical/physical mappings. 294 283 */ 295 284 296 - int __init mipsmt_build_cpu_map(int start_cpu_slot) 285 + int __init smtc_build_cpu_map(int start_cpu_slot) 297 286 { 298 287 int i, ntcs; 299 288 ··· 336 325 write_tc_c0_tcstatus((read_tc_c0_tcstatus() 337 326 & ~(TCSTATUS_TKSU | TCSTATUS_DA | TCSTATUS_IXMT)) 338 327 | TCSTATUS_A); 339 - write_tc_c0_tccontext(0); 328 + /* 329 + * TCContext gets an offset from the base of the IPIQ array 330 + * to be used in low-level code to detect the presence of 331 + * an active IPI queue 332 + */ 333 + write_tc_c0_tccontext((sizeof(struct smtc_ipi_q) * cpu) << 16); 340 334 /* Bind tc to vpe */ 341 335 write_tc_c0_tcbind(vpe); 342 336 /* In general, all TCs should have the same cpu_data indications */ ··· 352 336 cpu_data[cpu].options &= ~MIPS_CPU_FPU; 353 337 cpu_data[cpu].vpe_id = vpe; 354 338 cpu_data[cpu].tc_id = tc; 339 + /* Multi-core SMTC hasn't been tested, but be prepared */ 340 + cpu_data[cpu].core = (read_vpe_c0_ebase() >> 1) & 0xff; 355 341 } 356 342 343 + /* 344 + * Tweak to get Count registes in as close a sync as possible. 345 + * Value seems good for 34K-class cores. 346 + */ 357 347 358 - void mipsmt_prepare_cpus(void) 348 + #define CP0_SKEW 8 349 + 350 + void smtc_prepare_cpus(int cpus) 359 351 { 360 352 int i, vpe, tc, ntc, nvpe, tcpervpe[NR_CPUS], slop, cpu; 361 353 unsigned long flags; ··· 387 363 IPIQ[i].head = IPIQ[i].tail = NULL; 388 364 spin_lock_init(&IPIQ[i].lock); 389 365 IPIQ[i].depth = 0; 390 - atomic_set(&ipi_timer_latch[i], 0); 391 366 } 392 367 393 368 /* cpu_data index starts at zero */ 394 369 cpu = 0; 395 370 cpu_data[cpu].vpe_id = 0; 396 371 cpu_data[cpu].tc_id = 0; 372 + cpu_data[cpu].core = (read_c0_ebase() >> 1) & 0xff; 397 373 cpu++; 398 374 399 375 /* Report on boot-time options */ ··· 508 484 write_vpe_c0_compare(0); 509 485 /* Propagate Config7 */ 510 486 write_vpe_c0_config7(read_c0_config7()); 511 - write_vpe_c0_count(read_c0_count()); 487 + write_vpe_c0_count(read_c0_count() + CP0_SKEW); 488 + ehb(); 512 489 } 513 490 /* enable multi-threading within VPE */ 514 491 write_vpe_c0_vpecontrol(read_vpe_c0_vpecontrol() | VPECONTROL_TE); ··· 581 556 void __cpuinit smtc_boot_secondary(int cpu, struct task_struct *idle) 582 557 { 583 558 extern u32 kernelsp[NR_CPUS]; 584 - long flags; 559 + unsigned long flags; 585 560 int mtflags; 586 561 587 562 LOCK_MT_PRA(); ··· 610 585 611 586 void smtc_init_secondary(void) 612 587 { 613 - /* 614 - * Start timer on secondary VPEs if necessary. 615 - * plat_timer_setup has already have been invoked by init/main 616 - * on "boot" TC. Like per_cpu_trap_init() hack, this assumes that 617 - * SMTC init code assigns TCs consdecutively and in ascending order 618 - * to across available VPEs. 619 - */ 620 - if (((read_c0_tcbind() & TCBIND_CURTC) != 0) && 621 - ((read_c0_tcbind() & TCBIND_CURVPE) 622 - != cpu_data[smp_processor_id() - 1].vpe_id)){ 623 - write_c0_compare(read_c0_count() + mips_hpt_frequency/HZ); 624 - } 625 - 626 588 local_irq_enable(); 627 589 } 628 590 629 591 void smtc_smp_finish(void) 630 592 { 593 + int cpu = smp_processor_id(); 594 + 595 + /* 596 + * Lowest-numbered CPU per VPE starts a clock tick. 597 + * Like per_cpu_trap_init() hack, this assumes that 598 + * SMTC init code assigns TCs consdecutively and 599 + * in ascending order across available VPEs. 600 + */ 601 + if (cpu > 0 && (cpu_data[cpu].vpe_id != cpu_data[cpu - 1].vpe_id)) 602 + write_c0_compare(read_c0_count() + mips_hpt_frequency/HZ); 603 + 631 604 printk("TC %d going on-line as CPU %d\n", 632 605 cpu_data[smp_processor_id()].tc_id, smp_processor_id()); 633 606 } ··· 776 753 { 777 754 int tcstatus; 778 755 struct smtc_ipi *pipi; 779 - long flags; 756 + unsigned long flags; 780 757 int mtflags; 758 + unsigned long tcrestart; 759 + extern void r4k_wait_irqoff(void), __pastwait(void); 781 760 782 761 if (cpu == smp_processor_id()) { 783 762 printk("Cannot Send IPI to self!\n"); ··· 796 771 pipi->arg = (void *)action; 797 772 pipi->dest = cpu; 798 773 if (cpu_data[cpu].vpe_id != cpu_data[smp_processor_id()].vpe_id) { 799 - if (type == SMTC_CLOCK_TICK) 800 - atomic_inc(&ipi_timer_latch[cpu]); 801 774 /* If not on same VPE, enqueue and send cross-VPE interrupt */ 802 775 smtc_ipi_nq(&IPIQ[cpu], pipi); 803 776 LOCK_CORE_PRA(); ··· 823 800 824 801 if ((tcstatus & TCSTATUS_IXMT) != 0) { 825 802 /* 826 - * Spin-waiting here can deadlock, 827 - * so we queue the message for the target TC. 803 + * If we're in the the irq-off version of the wait 804 + * loop, we need to force exit from the wait and 805 + * do a direct post of the IPI. 806 + */ 807 + if (cpu_wait == r4k_wait_irqoff) { 808 + tcrestart = read_tc_c0_tcrestart(); 809 + if (tcrestart >= (unsigned long)r4k_wait_irqoff 810 + && tcrestart < (unsigned long)__pastwait) { 811 + write_tc_c0_tcrestart(__pastwait); 812 + tcstatus &= ~TCSTATUS_IXMT; 813 + write_tc_c0_tcstatus(tcstatus); 814 + goto postdirect; 815 + } 816 + } 817 + /* 818 + * Otherwise we queue the message for the target TC 819 + * to pick up when he does a local_irq_restore() 828 820 */ 829 821 write_tc_c0_tchalt(0); 830 822 UNLOCK_CORE_PRA(); 831 - /* Try to reduce redundant timer interrupt messages */ 832 - if (type == SMTC_CLOCK_TICK) { 833 - if (atomic_postincrement(&ipi_timer_latch[cpu])!=0){ 834 - smtc_ipi_nq(&freeIPIq, pipi); 835 - return; 836 - } 837 - } 838 823 smtc_ipi_nq(&IPIQ[cpu], pipi); 839 824 } else { 840 - if (type == SMTC_CLOCK_TICK) 841 - atomic_inc(&ipi_timer_latch[cpu]); 825 + postdirect: 842 826 post_direct_ipi(cpu, pipi); 843 827 write_tc_c0_tchalt(0); 844 828 UNLOCK_CORE_PRA(); ··· 913 883 smp_call_function_interrupt(); 914 884 } 915 885 916 - DECLARE_PER_CPU(struct clock_event_device, smtc_dummy_clockevent_device); 886 + DECLARE_PER_CPU(struct clock_event_device, mips_clockevent_device); 917 887 918 888 void ipi_decode(struct smtc_ipi *pipi) 919 889 { ··· 921 891 struct clock_event_device *cd; 922 892 void *arg_copy = pipi->arg; 923 893 int type_copy = pipi->type; 924 - int ticks; 925 - 926 894 smtc_ipi_nq(&freeIPIq, pipi); 927 895 switch (type_copy) { 928 896 case SMTC_CLOCK_TICK: 929 897 irq_enter(); 930 898 kstat_this_cpu.irqs[MIPS_CPU_IRQ_BASE + 1]++; 931 - cd = &per_cpu(smtc_dummy_clockevent_device, cpu); 932 - ticks = atomic_read(&ipi_timer_latch[cpu]); 933 - atomic_sub(ticks, &ipi_timer_latch[cpu]); 934 - while (ticks) { 935 - cd->event_handler(cd); 936 - ticks--; 937 - } 899 + cd = &per_cpu(mips_clockevent_device, cpu); 900 + cd->event_handler(cd); 938 901 irq_exit(); 939 902 break; 940 903 ··· 960 937 } 961 938 } 962 939 940 + /* 941 + * Similar to smtc_ipi_replay(), but invoked from context restore, 942 + * so it reuses the current exception frame rather than set up a 943 + * new one with self_ipi. 944 + */ 945 + 963 946 void deferred_smtc_ipi(void) 964 947 { 965 - struct smtc_ipi *pipi; 966 - unsigned long flags; 967 - /* DEBUG */ 968 - int q = smp_processor_id(); 948 + int cpu = smp_processor_id(); 969 949 970 950 /* 971 951 * Test is not atomic, but much faster than a dequeue, 972 952 * and the vast majority of invocations will have a null queue. 953 + * If irq_disabled when this was called, then any IPIs queued 954 + * after we test last will be taken on the next irq_enable/restore. 955 + * If interrupts were enabled, then any IPIs added after the 956 + * last test will be taken directly. 973 957 */ 974 - if (IPIQ[q].head != NULL) { 975 - while((pipi = smtc_ipi_dq(&IPIQ[q])) != NULL) { 976 - /* ipi_decode() should be called with interrupts off */ 977 - local_irq_save(flags); 958 + 959 + while (IPIQ[cpu].head != NULL) { 960 + struct smtc_ipi_q *q = &IPIQ[cpu]; 961 + struct smtc_ipi *pipi; 962 + unsigned long flags; 963 + 964 + /* 965 + * It may be possible we'll come in with interrupts 966 + * already enabled. 967 + */ 968 + local_irq_save(flags); 969 + 970 + spin_lock(&q->lock); 971 + pipi = __smtc_ipi_dq(q); 972 + spin_unlock(&q->lock); 973 + if (pipi != NULL) 978 974 ipi_decode(pipi); 979 - local_irq_restore(flags); 980 - } 975 + /* 976 + * The use of the __raw_local restore isn't 977 + * as obviously necessary here as in smtc_ipi_replay(), 978 + * but it's more efficient, given that we're already 979 + * running down the IPI queue. 980 + */ 981 + __raw_local_irq_restore(flags); 981 982 } 982 983 } 983 984 ··· 1022 975 struct smtc_ipi *pipi; 1023 976 unsigned long tcstatus; 1024 977 int sent; 1025 - long flags; 978 + unsigned long flags; 1026 979 unsigned int mtflags; 1027 980 unsigned int vpflags; 1028 981 ··· 1113 1066 1114 1067 /* 1115 1068 * SMTC-specific hacks invoked from elsewhere in the kernel. 1116 - * 1117 - * smtc_ipi_replay is called from raw_local_irq_restore which is only ever 1118 - * called with interrupts disabled. We do rely on interrupts being disabled 1119 - * here because using spin_lock_irqsave()/spin_unlock_irqrestore() would 1120 - * result in a recursive call to raw_local_irq_restore(). 1121 1069 */ 1122 1070 1123 - static void __smtc_ipi_replay(void) 1071 + /* 1072 + * smtc_ipi_replay is called from raw_local_irq_restore 1073 + */ 1074 + 1075 + void smtc_ipi_replay(void) 1124 1076 { 1125 1077 unsigned int cpu = smp_processor_id(); 1126 1078 1127 1079 /* 1128 1080 * To the extent that we've ever turned interrupts off, 1129 1081 * we may have accumulated deferred IPIs. This is subtle. 1130 - * If we use the smtc_ipi_qdepth() macro, we'll get an 1131 - * exact number - but we'll also disable interrupts 1132 - * and create a window of failure where a new IPI gets 1133 - * queued after we test the depth but before we re-enable 1134 - * interrupts. So long as IXMT never gets set, however, 1135 1082 * we should be OK: If we pick up something and dispatch 1136 1083 * it here, that's great. If we see nothing, but concurrent 1137 1084 * with this operation, another TC sends us an IPI, IXMT 1138 1085 * is clear, and we'll handle it as a real pseudo-interrupt 1139 - * and not a pseudo-pseudo interrupt. 1086 + * and not a pseudo-pseudo interrupt. The important thing 1087 + * is to do the last check for queued message *after* the 1088 + * re-enabling of interrupts. 1140 1089 */ 1141 - if (IPIQ[cpu].depth > 0) { 1142 - while (1) { 1143 - struct smtc_ipi_q *q = &IPIQ[cpu]; 1144 - struct smtc_ipi *pipi; 1145 - extern void self_ipi(struct smtc_ipi *); 1090 + while (IPIQ[cpu].head != NULL) { 1091 + struct smtc_ipi_q *q = &IPIQ[cpu]; 1092 + struct smtc_ipi *pipi; 1093 + unsigned long flags; 1146 1094 1147 - spin_lock(&q->lock); 1148 - pipi = __smtc_ipi_dq(q); 1149 - spin_unlock(&q->lock); 1150 - if (!pipi) 1151 - break; 1095 + /* 1096 + * It's just possible we'll come in with interrupts 1097 + * already enabled. 1098 + */ 1099 + local_irq_save(flags); 1152 1100 1101 + spin_lock(&q->lock); 1102 + pipi = __smtc_ipi_dq(q); 1103 + spin_unlock(&q->lock); 1104 + /* 1105 + ** But use a raw restore here to avoid recursion. 1106 + */ 1107 + __raw_local_irq_restore(flags); 1108 + 1109 + if (pipi) { 1153 1110 self_ipi(pipi); 1154 1111 smtc_cpu_stats[cpu].selfipis++; 1155 1112 } 1156 1113 } 1157 - } 1158 - 1159 - void smtc_ipi_replay(void) 1160 - { 1161 - raw_local_irq_disable(); 1162 - __smtc_ipi_replay(); 1163 1114 } 1164 1115 1165 1116 EXPORT_SYMBOL(smtc_ipi_replay); ··· 1238 1193 } 1239 1194 } 1240 1195 1241 - /* 1242 - * Now that we limit outstanding timer IPIs, check for hung TC 1243 - */ 1244 - for (tc = 0; tc < NR_CPUS; tc++) { 1245 - /* Don't check ourself - we'll dequeue IPIs just below */ 1246 - if ((tc != smp_processor_id()) && 1247 - atomic_read(&ipi_timer_latch[tc]) > timerq_limit) { 1248 - if (clock_hang_reported[tc] == 0) { 1249 - pdb_msg += sprintf(pdb_msg, 1250 - "TC %d looks hung with timer latch at %d\n", 1251 - tc, atomic_read(&ipi_timer_latch[tc])); 1252 - clock_hang_reported[tc]++; 1253 - } 1254 - } 1255 - } 1256 1196 emt(mtflags); 1257 1197 local_irq_restore(flags); 1258 1198 if (pdb_msg != &id_ho_db_msg[0]) 1259 1199 printk("CPU%d: %s", smp_processor_id(), id_ho_db_msg); 1260 1200 #endif /* CONFIG_SMTC_IDLE_HOOK_DEBUG */ 1261 1201 1262 - /* 1263 - * Replay any accumulated deferred IPIs. If "Instant Replay" 1264 - * is in use, there should never be any. 1265 - */ 1266 - #ifndef CONFIG_MIPS_MT_SMTC_INSTANT_REPLAY 1267 - { 1268 - unsigned long flags; 1269 - 1270 - local_irq_save(flags); 1271 - __smtc_ipi_replay(); 1272 - local_irq_restore(flags); 1273 - } 1274 - #endif /* CONFIG_MIPS_MT_SMTC_INSTANT_REPLAY */ 1202 + smtc_ipi_replay(); 1275 1203 } 1276 1204 1277 1205 void smtc_soft_dump(void) ··· 1260 1242 printk("%d: %ld\n", i, smtc_cpu_stats[i].selfipis); 1261 1243 } 1262 1244 smtc_ipi_qdump(); 1263 - printk("Timer IPI Backlogs:\n"); 1264 - for (i=0; i < NR_CPUS; i++) { 1265 - printk("%d: %d\n", i, atomic_read(&ipi_timer_latch[i])); 1266 - } 1267 1245 printk("%d Recoveries of \"stolen\" FPU\n", 1268 1246 atomic_read(&smtc_fpu_recoveries)); 1269 1247 }
+4 -2
arch/mips/kernel/traps.c
··· 825 825 if (cpus_intersects(current->cpus_allowed, mt_fpu_cpumask)) { 826 826 cpumask_t tmask; 827 827 828 - cpus_and(tmask, current->thread.user_cpus_allowed, 829 - mt_fpu_cpumask); 828 + current->thread.user_cpus_allowed 829 + = current->cpus_allowed; 830 + cpus_and(tmask, current->cpus_allowed, 831 + mt_fpu_cpumask); 830 832 set_cpus_allowed(current, tmask); 831 833 set_thread_flag(TIF_FPUBOUND); 832 834 }
+1 -1
arch/mips/mti-malta/Makefile
··· 15 15 obj-$(CONFIG_PCI) += malta-pci.o 16 16 17 17 # FIXME FIXME FIXME 18 - obj-$(CONFIG_MIPS_MT_SMTC) += malta_smtc.o 18 + obj-$(CONFIG_MIPS_MT_SMTC) += malta-smtc.o 19 19 20 20 EXTRA_CFLAGS += -Werror
+7 -2
arch/mips/mti-malta/malta-smtc.c
··· 84 84 85 85 static void __init msmtc_smp_setup(void) 86 86 { 87 - mipsmt_build_cpu_map(0); 87 + /* 88 + * we won't get the definitive value until 89 + * we've run smtc_prepare_cpus later, but 90 + * we would appear to need an upper bound now. 91 + */ 92 + smp_num_siblings = smtc_build_cpu_map(0); 88 93 } 89 94 90 95 static void __init msmtc_prepare_cpus(unsigned int max_cpus) 91 96 { 92 - mipsmt_prepare_cpus(); 97 + smtc_prepare_cpus(max_cpus); 93 98 } 94 99 95 100 struct plat_smp_ops msmtc_smp_ops = {
+46
include/asm-mips/cevt-r4k.h
··· 1 + /* 2 + * This file is subject to the terms and conditions of the GNU General Public 3 + * License. See the file "COPYING" in the main directory of this archive 4 + * for more details. 5 + * 6 + * Copyright (C) 2008 Kevin D. Kissell 7 + */ 8 + 9 + /* 10 + * Definitions used for common event timer implementation 11 + * for MIPS 4K-type processors and their MIPS MT variants. 12 + * Avoids unsightly extern declarations in C files. 13 + */ 14 + #ifndef __ASM_CEVT_R4K_H 15 + #define __ASM_CEVT_R4K_H 16 + 17 + DECLARE_PER_CPU(struct clock_event_device, mips_clockevent_device); 18 + 19 + void mips_event_handler(struct clock_event_device *dev); 20 + int c0_compare_int_usable(void); 21 + void mips_set_clock_mode(enum clock_event_mode, struct clock_event_device *); 22 + irqreturn_t c0_compare_interrupt(int, void *); 23 + 24 + extern struct irqaction c0_compare_irqaction; 25 + extern int cp0_timer_irq_installed; 26 + 27 + /* 28 + * Possibly handle a performance counter interrupt. 29 + * Return true if the timer interrupt should not be checked 30 + */ 31 + 32 + static inline int handle_perf_irq(int r2) 33 + { 34 + /* 35 + * The performance counter overflow interrupt may be shared with the 36 + * timer interrupt (cp0_perfcount_irq < 0). If it is and a 37 + * performance counter has overflowed (perf_irq() == IRQ_HANDLED) 38 + * and we can't reliably determine if a counter interrupt has also 39 + * happened (!r2) then don't check for a timer interrupt. 40 + */ 41 + return (cp0_perfcount_irq < 0) && 42 + perf_irq() == IRQ_HANDLED && 43 + !r2; 44 + } 45 + 46 + #endif /* __ASM_CEVT_R4K_H */
+23 -3
include/asm-mips/irqflags.h
··· 38 38 " .set pop \n" 39 39 " .endm"); 40 40 41 + extern void smtc_ipi_replay(void); 42 + 41 43 static inline void raw_local_irq_enable(void) 42 44 { 45 + #ifdef CONFIG_MIPS_MT_SMTC 46 + /* 47 + * SMTC kernel needs to do a software replay of queued 48 + * IPIs, at the cost of call overhead on each local_irq_enable() 49 + */ 50 + smtc_ipi_replay(); 51 + #endif 43 52 __asm__ __volatile__( 44 53 "raw_local_irq_enable" 45 54 : /* no outputs */ 46 55 : /* no inputs */ 47 56 : "memory"); 48 57 } 58 + 49 59 50 60 /* 51 61 * For cli() we have to insert nops to make sure that the new value ··· 195 185 " .set pop \n" 196 186 " .endm \n"); 197 187 198 - extern void smtc_ipi_replay(void); 199 188 200 189 static inline void raw_local_irq_restore(unsigned long flags) 201 190 { 202 191 unsigned long __tmp1; 203 192 204 - #ifdef CONFIG_MIPS_MT_SMTC_INSTANT_REPLAY 193 + #ifdef CONFIG_MIPS_MT_SMTC 205 194 /* 206 - * CONFIG_MIPS_MT_SMTC_INSTANT_REPLAY does prompt replay of deferred 195 + * SMTC kernel needs to do a software replay of queued 207 196 * IPIs, at the cost of branch and call overhead on each 208 197 * local_irq_restore() 209 198 */ 210 199 if (unlikely(!(flags & 0x0400))) 211 200 smtc_ipi_replay(); 212 201 #endif 202 + 203 + __asm__ __volatile__( 204 + "raw_local_irq_restore\t%0" 205 + : "=r" (__tmp1) 206 + : "0" (flags) 207 + : "memory"); 208 + } 209 + 210 + static inline void __raw_local_irq_restore(unsigned long flags) 211 + { 212 + unsigned long __tmp1; 213 213 214 214 __asm__ __volatile__( 215 215 "raw_local_irq_restore\t%0"
+3 -3
include/asm-mips/mipsregs.h
··· 1462 1462 { \ 1463 1463 unsigned int res; \ 1464 1464 unsigned int omt; \ 1465 - unsigned int flags; \ 1465 + unsigned long flags; \ 1466 1466 \ 1467 1467 local_irq_save(flags); \ 1468 1468 omt = __dmt(); \ ··· 1480 1480 { \ 1481 1481 unsigned int res; \ 1482 1482 unsigned int omt; \ 1483 - unsigned int flags; \ 1483 + unsigned long flags; \ 1484 1484 \ 1485 1485 local_irq_save(flags); \ 1486 1486 omt = __dmt(); \ ··· 1498 1498 { \ 1499 1499 unsigned int res; \ 1500 1500 unsigned int omt; \ 1501 - unsigned int flags; \ 1501 + unsigned long flags; \ 1502 1502 \ 1503 1503 local_irq_save(flags); \ 1504 1504 \
+5 -3
include/asm-mips/smtc.h
··· 6 6 */ 7 7 8 8 #include <asm/mips_mt.h> 9 + #include <asm/smtc_ipi.h> 9 10 10 11 /* 11 12 * System-wide SMTC status information ··· 39 38 struct task_struct; 40 39 41 40 void smtc_get_new_mmu_context(struct mm_struct *mm, unsigned long cpu); 42 - 41 + void self_ipi(struct smtc_ipi *); 43 42 void smtc_flush_tlb_asid(unsigned long asid); 44 - extern int mipsmt_build_cpu_map(int startslot); 45 - extern void mipsmt_prepare_cpus(void); 43 + extern int smtc_build_cpu_map(int startslot); 44 + extern void smtc_prepare_cpus(int cpus); 46 45 extern void smtc_smp_finish(void); 47 46 extern void smtc_boot_secondary(int cpu, struct task_struct *t); 48 47 extern void smtc_cpus_done(void); 48 + 49 49 50 50 /* 51 51 * Sharing the TLB between multiple VPEs means that the
+61 -11
include/asm-mips/stackframe.h
··· 297 297 #ifdef CONFIG_MIPS_MT_SMTC 298 298 .set mips32r2 299 299 /* 300 - * This may not really be necessary if ints are already 301 - * inhibited here. 300 + * We need to make sure the read-modify-write 301 + * of Status below isn't perturbed by an interrupt 302 + * or cross-TC access, so we need to do at least a DMT, 303 + * protected by an interrupt-inhibit. But setting IXMT 304 + * also creates a few-cycle window where an IPI could 305 + * be queued and not be detected before potentially 306 + * returning to a WAIT or user-mode loop. It must be 307 + * replayed. 308 + * 309 + * We're in the middle of a context switch, and 310 + * we can't dispatch it directly without trashing 311 + * some registers, so we'll try to detect this unlikely 312 + * case and program a software interrupt in the VPE, 313 + * as would be done for a cross-VPE IPI. To accomodate 314 + * the handling of that case, we're doing a DVPE instead 315 + * of just a DMT here to protect against other threads. 316 + * This is a lot of cruft to cover a tiny window. 317 + * If you can find a better design, implement it! 318 + * 302 319 */ 303 320 mfc0 v0, CP0_TCSTATUS 304 321 ori v0, TCSTATUS_IXMT 305 322 mtc0 v0, CP0_TCSTATUS 306 323 _ehb 307 - DMT 5 # dmt a1 324 + DVPE 5 # dvpe a1 308 325 jal mips_ihb 309 326 #endif /* CONFIG_MIPS_MT_SMTC */ 310 327 mfc0 a0, CP0_STATUS ··· 342 325 */ 343 326 LONG_L v1, PT_TCSTATUS(sp) 344 327 _ehb 345 - mfc0 v0, CP0_TCSTATUS 328 + mfc0 a0, CP0_TCSTATUS 346 329 andi v1, TCSTATUS_IXMT 347 - /* We know that TCStatua.IXMT should be set from above */ 348 - xori v0, v0, TCSTATUS_IXMT 349 - or v0, v0, v1 350 - mtc0 v0, CP0_TCSTATUS 351 - _ehb 352 - andi a1, a1, VPECONTROL_TE 330 + bnez v1, 0f 331 + 332 + /* 333 + * We'd like to detect any IPIs queued in the tiny window 334 + * above and request an software interrupt to service them 335 + * when we ERET. 336 + * 337 + * Computing the offset into the IPIQ array of the executing 338 + * TC's IPI queue in-line would be tedious. We use part of 339 + * the TCContext register to hold 16 bits of offset that we 340 + * can add in-line to find the queue head. 341 + */ 342 + mfc0 v0, CP0_TCCONTEXT 343 + la a2, IPIQ 344 + srl v0, v0, 16 345 + addu a2, a2, v0 346 + LONG_L v0, 0(a2) 347 + beqz v0, 0f 348 + /* 349 + * If we have a queue, provoke dispatch within the VPE by setting C_SW1 350 + */ 351 + mfc0 v0, CP0_CAUSE 352 + ori v0, v0, C_SW1 353 + mtc0 v0, CP0_CAUSE 354 + 0: 355 + /* 356 + * This test should really never branch but 357 + * let's be prudent here. Having atomized 358 + * the shared register modifications, we can 359 + * now EVPE, and must do so before interrupts 360 + * are potentially re-enabled. 361 + */ 362 + andi a1, a1, MVPCONTROL_EVP 353 363 beqz a1, 1f 354 - emt 364 + evpe 355 365 1: 366 + /* We know that TCStatua.IXMT should be set from above */ 367 + xori a0, a0, TCSTATUS_IXMT 368 + or a0, a0, v1 369 + mtc0 a0, CP0_TCSTATUS 370 + _ehb 371 + 356 372 .set mips0 357 373 #endif /* CONFIG_MIPS_MT_SMTC */ 358 374 LONG_L v1, PT_EPC(sp)