diff options
Diffstat (limited to 'arch')
-rw-r--r-- | arch/mips/Kconfig | 5 | ||||
-rw-r--r-- | arch/mips/kernel/process.c | 11 | ||||
-rw-r--r-- | arch/mips/kernel/scall32-o32.S | 11 | ||||
-rw-r--r-- | arch/mips/kernel/setup.c | 5 | ||||
-rw-r--r-- | arch/mips/kernel/smp-mt.c | 11 | ||||
-rw-r--r-- | arch/mips/kernel/traps.c | 30 |
6 files changed, 72 insertions, 1 deletions
diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index f9be549645ea..87f0b79c6b15 100644 --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig | |||
@@ -1464,6 +1464,11 @@ config MIPS_VPE_LOADER | |||
1464 | 1464 | ||
1465 | endchoice | 1465 | endchoice |
1466 | 1466 | ||
1467 | config MIPS_MT_FPAFF | ||
1468 | bool "Dynamic FPU affinity for FP-intensive threads" | ||
1469 | depends on MIPS_MT | ||
1470 | default y | ||
1471 | |||
1467 | config MIPS_VPE_LOADER_TOM | 1472 | config MIPS_VPE_LOADER_TOM |
1468 | bool "Load VPE program into memory hidden from linux" | 1473 | bool "Load VPE program into memory hidden from linux" |
1469 | depends on MIPS_VPE_LOADER | 1474 | depends on MIPS_VPE_LOADER |
diff --git a/arch/mips/kernel/process.c b/arch/mips/kernel/process.c index 8b393df460a2..199a06e873c6 100644 --- a/arch/mips/kernel/process.c +++ b/arch/mips/kernel/process.c | |||
@@ -185,6 +185,17 @@ int copy_thread(int nr, unsigned long clone_flags, unsigned long usp, | |||
185 | childregs->cp0_status &= ~(ST0_CU2|ST0_CU1); | 185 | childregs->cp0_status &= ~(ST0_CU2|ST0_CU1); |
186 | clear_tsk_thread_flag(p, TIF_USEDFPU); | 186 | clear_tsk_thread_flag(p, TIF_USEDFPU); |
187 | 187 | ||
188 | #ifdef CONFIG_MIPS_MT_FPAFF | ||
189 | /* | ||
190 | * FPU affinity support is cleaner if we track the | ||
191 | * user-visible CPU affinity from the very beginning. | ||
192 | * The generic cpus_allowed mask will already have | ||
193 | * been copied from the parent before copy_thread | ||
194 | * is invoked. | ||
195 | */ | ||
196 | p->thread.user_cpus_allowed = p->cpus_allowed; | ||
197 | #endif /* CONFIG_MIPS_MT_FPAFF */ | ||
198 | |||
188 | if (clone_flags & CLONE_SETTLS) | 199 | if (clone_flags & CLONE_SETTLS) |
189 | ti->tp_value = regs->regs[7]; | 200 | ti->tp_value = regs->regs[7]; |
190 | 201 | ||
diff --git a/arch/mips/kernel/scall32-o32.S b/arch/mips/kernel/scall32-o32.S index 4e36b87be1ed..a0ac0e5f61ad 100644 --- a/arch/mips/kernel/scall32-o32.S +++ b/arch/mips/kernel/scall32-o32.S | |||
@@ -569,8 +569,19 @@ einval: li v0, -EINVAL | |||
569 | sys sys_tkill 2 | 569 | sys sys_tkill 2 |
570 | sys sys_sendfile64 5 | 570 | sys sys_sendfile64 5 |
571 | sys sys_futex 6 | 571 | sys sys_futex 6 |
572 | #ifdef CONFIG_MIPS_MT_FPAFF | ||
573 | /* | ||
574 | * For FPU affinity scheduling on MIPS MT processors, we need to | ||
575 | * intercept sys_sched_xxxaffinity() calls until we get a proper hook | ||
576 | * in kernel/sched.c. Considered only temporary we only support these | ||
577 | * hooks for the 32-bit kernel - there is no MIPS64 MT processor atm. | ||
578 | */ | ||
579 | sys mipsmt_sys_sched_setaffinity 3 | ||
580 | sys mipsmt_sys_sched_getaffinity 3 | ||
581 | #else | ||
572 | sys sys_sched_setaffinity 3 | 582 | sys sys_sched_setaffinity 3 |
573 | sys sys_sched_getaffinity 3 /* 4240 */ | 583 | sys sys_sched_getaffinity 3 /* 4240 */ |
584 | #endif /* CONFIG_MIPS_MT_FPAFF */ | ||
574 | sys sys_io_setup 2 | 585 | sys sys_io_setup 2 |
575 | sys sys_io_destroy 1 | 586 | sys sys_io_destroy 1 |
576 | sys sys_io_getevents 5 | 587 | sys sys_io_getevents 5 |
diff --git a/arch/mips/kernel/setup.c b/arch/mips/kernel/setup.c index dcbfd27071f0..bcf1b10e518f 100644 --- a/arch/mips/kernel/setup.c +++ b/arch/mips/kernel/setup.c | |||
@@ -529,7 +529,10 @@ void __init setup_arch(char **cmdline_p) | |||
529 | 529 | ||
530 | int __init fpu_disable(char *s) | 530 | int __init fpu_disable(char *s) |
531 | { | 531 | { |
532 | cpu_data[0].options &= ~MIPS_CPU_FPU; | 532 | int i; |
533 | |||
534 | for (i = 0; i < NR_CPUS; i++) | ||
535 | cpu_data[i].options &= ~MIPS_CPU_FPU; | ||
533 | 536 | ||
534 | return 1; | 537 | return 1; |
535 | } | 538 | } |
diff --git a/arch/mips/kernel/smp-mt.c b/arch/mips/kernel/smp-mt.c index 19b8e4b31b79..57770902b9ae 100644 --- a/arch/mips/kernel/smp-mt.c +++ b/arch/mips/kernel/smp-mt.c | |||
@@ -150,6 +150,11 @@ void plat_smp_setup(void) | |||
150 | unsigned long val; | 150 | unsigned long val; |
151 | int i, num; | 151 | int i, num; |
152 | 152 | ||
153 | #ifdef CONFIG_MIPS_MT_FPAFF | ||
154 | /* If we have an FPU, enroll ourselves in the FPU-full mask */ | ||
155 | if (cpu_has_fpu) | ||
156 | cpu_set(0, mt_fpu_cpumask); | ||
157 | #endif /* CONFIG_MIPS_MT_FPAFF */ | ||
153 | if (!cpu_has_mipsmt) | 158 | if (!cpu_has_mipsmt) |
154 | return; | 159 | return; |
155 | 160 | ||
@@ -312,6 +317,12 @@ void prom_smp_finish(void) | |||
312 | { | 317 | { |
313 | write_c0_compare(read_c0_count() + (8* mips_hpt_frequency/HZ)); | 318 | write_c0_compare(read_c0_count() + (8* mips_hpt_frequency/HZ)); |
314 | 319 | ||
320 | #ifdef CONFIG_MIPS_MT_FPAFF | ||
321 | /* If we have an FPU, enroll ourselves in the FPU-full mask */ | ||
322 | if (cpu_has_fpu) | ||
323 | cpu_set(smp_processor_id(), mt_fpu_cpumask); | ||
324 | #endif /* CONFIG_MIPS_MT_FPAFF */ | ||
325 | |||
315 | local_irq_enable(); | 326 | local_irq_enable(); |
316 | } | 327 | } |
317 | 328 | ||
diff --git a/arch/mips/kernel/traps.c b/arch/mips/kernel/traps.c index 6336fe8008ec..e9902d89dc0a 100644 --- a/arch/mips/kernel/traps.c +++ b/arch/mips/kernel/traps.c | |||
@@ -758,6 +758,36 @@ asmlinkage void do_cpu(struct pt_regs *regs) | |||
758 | ¤t->thread.fpu.soft); | 758 | ¤t->thread.fpu.soft); |
759 | if (sig) | 759 | if (sig) |
760 | force_sig(sig, current); | 760 | force_sig(sig, current); |
761 | #ifdef CONFIG_MIPS_MT_FPAFF | ||
762 | else { | ||
763 | /* | ||
764 | * MIPS MT processors may have fewer FPU contexts | ||
765 | * than CPU threads. If we've emulated more than | ||
766 | * some threshold number of instructions, force | ||
767 | * migration to a "CPU" that has FP support. | ||
768 | */ | ||
769 | if(mt_fpemul_threshold > 0 | ||
770 | && ((current->thread.emulated_fp++ | ||
771 | > mt_fpemul_threshold))) { | ||
772 | /* | ||
773 | * If there's no FPU present, or if the | ||
774 | * application has already restricted | ||
775 | * the allowed set to exclude any CPUs | ||
776 | * with FPUs, we'll skip the procedure. | ||
777 | */ | ||
778 | if (cpus_intersects(current->cpus_allowed, | ||
779 | mt_fpu_cpumask)) { | ||
780 | cpumask_t tmask; | ||
781 | |||
782 | cpus_and(tmask, | ||
783 | current->thread.user_cpus_allowed, | ||
784 | mt_fpu_cpumask); | ||
785 | set_cpus_allowed(current, tmask); | ||
786 | current->thread.mflags |= MF_FPUBOUND; | ||
787 | } | ||
788 | } | ||
789 | } | ||
790 | #endif /* CONFIG_MIPS_MT_FPAFF */ | ||
761 | } | 791 | } |
762 | 792 | ||
763 | return; | 793 | return; |