aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAnton Blanchard <anton@samba.org>2006-02-12 22:48:35 -0500
committerPaul Mackerras <paulus@samba.org>2006-02-23 19:36:31 -0500
commitcb2c9b2741346eb23b177187a51ff5abf08295bd (patch)
tree31433b46f96a00e22ca7e8402fd0bfe1fea3408d
parent47f78a49206b7f9b0d283ba46a2a5a6ee1796472 (diff)
[PATCH] powerpc: Fix runlatch performance issues
The runlatch SPR can take a lot of time to write. My original runlatch code would set it on every exception entry even though most of the time this was not required. It would also continually set it in the idle loop, which is an issue on an SMT capable processor. Now we cache the runlatch value in a threadinfo bit, and only check for it in decrementer and hardware interrupt exceptions as well as the idle loop. Boot on POWER3, POWER5 and iseries, and compile tested on pmac32. Signed-off-by: Anton Blanchard <anton@samba.org> Signed-off-by: Paul Mackerras <paulus@samba.org>
-rw-r--r--arch/powerpc/kernel/head_64.S12
-rw-r--r--arch/powerpc/kernel/process.c32
-rw-r--r--arch/powerpc/platforms/iseries/setup.c1
-rw-r--r--include/asm-powerpc/reg.h33
-rw-r--r--include/asm-powerpc/thread_info.h4
5 files changed, 40 insertions, 42 deletions
diff --git a/arch/powerpc/kernel/head_64.S b/arch/powerpc/kernel/head_64.S
index 2b03a09fe5e9..bb845eed0e98 100644
--- a/arch/powerpc/kernel/head_64.S
+++ b/arch/powerpc/kernel/head_64.S
@@ -319,7 +319,6 @@ exception_marker:
319label##_pSeries: \ 319label##_pSeries: \
320 HMT_MEDIUM; \ 320 HMT_MEDIUM; \
321 mtspr SPRN_SPRG1,r13; /* save r13 */ \ 321 mtspr SPRN_SPRG1,r13; /* save r13 */ \
322 RUNLATCH_ON(r13); \
323 EXCEPTION_PROLOG_PSERIES(PACA_EXGEN, label##_common) 322 EXCEPTION_PROLOG_PSERIES(PACA_EXGEN, label##_common)
324 323
325#define STD_EXCEPTION_ISERIES(n, label, area) \ 324#define STD_EXCEPTION_ISERIES(n, label, area) \
@@ -327,7 +326,6 @@ label##_pSeries: \
327label##_iSeries: \ 326label##_iSeries: \
328 HMT_MEDIUM; \ 327 HMT_MEDIUM; \
329 mtspr SPRN_SPRG1,r13; /* save r13 */ \ 328 mtspr SPRN_SPRG1,r13; /* save r13 */ \
330 RUNLATCH_ON(r13); \
331 EXCEPTION_PROLOG_ISERIES_1(area); \ 329 EXCEPTION_PROLOG_ISERIES_1(area); \
332 EXCEPTION_PROLOG_ISERIES_2; \ 330 EXCEPTION_PROLOG_ISERIES_2; \
333 b label##_common 331 b label##_common
@@ -337,7 +335,6 @@ label##_iSeries: \
337label##_iSeries: \ 335label##_iSeries: \
338 HMT_MEDIUM; \ 336 HMT_MEDIUM; \
339 mtspr SPRN_SPRG1,r13; /* save r13 */ \ 337 mtspr SPRN_SPRG1,r13; /* save r13 */ \
340 RUNLATCH_ON(r13); \
341 EXCEPTION_PROLOG_ISERIES_1(PACA_EXGEN); \ 338 EXCEPTION_PROLOG_ISERIES_1(PACA_EXGEN); \
342 lbz r10,PACAPROCENABLED(r13); \ 339 lbz r10,PACAPROCENABLED(r13); \
343 cmpwi 0,r10,0; \ 340 cmpwi 0,r10,0; \
@@ -390,6 +387,7 @@ label##_common: \
390label##_common: \ 387label##_common: \
391 EXCEPTION_PROLOG_COMMON(trap, PACA_EXGEN); \ 388 EXCEPTION_PROLOG_COMMON(trap, PACA_EXGEN); \
392 DISABLE_INTS; \ 389 DISABLE_INTS; \
390 bl .ppc64_runlatch_on; \
393 addi r3,r1,STACK_FRAME_OVERHEAD; \ 391 addi r3,r1,STACK_FRAME_OVERHEAD; \
394 bl hdlr; \ 392 bl hdlr; \
395 b .ret_from_except_lite 393 b .ret_from_except_lite
@@ -407,7 +405,6 @@ __start_interrupts:
407_machine_check_pSeries: 405_machine_check_pSeries:
408 HMT_MEDIUM 406 HMT_MEDIUM
409 mtspr SPRN_SPRG1,r13 /* save r13 */ 407 mtspr SPRN_SPRG1,r13 /* save r13 */
410 RUNLATCH_ON(r13)
411 EXCEPTION_PROLOG_PSERIES(PACA_EXMC, machine_check_common) 408 EXCEPTION_PROLOG_PSERIES(PACA_EXMC, machine_check_common)
412 409
413 . = 0x300 410 . = 0x300
@@ -434,7 +431,6 @@ END_FTR_SECTION_IFCLR(CPU_FTR_SLB)
434data_access_slb_pSeries: 431data_access_slb_pSeries:
435 HMT_MEDIUM 432 HMT_MEDIUM
436 mtspr SPRN_SPRG1,r13 433 mtspr SPRN_SPRG1,r13
437 RUNLATCH_ON(r13)
438 mfspr r13,SPRN_SPRG3 /* get paca address into r13 */ 434 mfspr r13,SPRN_SPRG3 /* get paca address into r13 */
439 std r3,PACA_EXSLB+EX_R3(r13) 435 std r3,PACA_EXSLB+EX_R3(r13)
440 mfspr r3,SPRN_DAR 436 mfspr r3,SPRN_DAR
@@ -460,7 +456,6 @@ data_access_slb_pSeries:
460instruction_access_slb_pSeries: 456instruction_access_slb_pSeries:
461 HMT_MEDIUM 457 HMT_MEDIUM
462 mtspr SPRN_SPRG1,r13 458 mtspr SPRN_SPRG1,r13
463 RUNLATCH_ON(r13)
464 mfspr r13,SPRN_SPRG3 /* get paca address into r13 */ 459 mfspr r13,SPRN_SPRG3 /* get paca address into r13 */
465 std r3,PACA_EXSLB+EX_R3(r13) 460 std r3,PACA_EXSLB+EX_R3(r13)
466 mfspr r3,SPRN_SRR0 /* SRR0 is faulting address */ 461 mfspr r3,SPRN_SRR0 /* SRR0 is faulting address */
@@ -491,7 +486,6 @@ instruction_access_slb_pSeries:
491 .globl system_call_pSeries 486 .globl system_call_pSeries
492system_call_pSeries: 487system_call_pSeries:
493 HMT_MEDIUM 488 HMT_MEDIUM
494 RUNLATCH_ON(r9)
495 mr r9,r13 489 mr r9,r13
496 mfmsr r10 490 mfmsr r10
497 mfspr r13,SPRN_SPRG3 491 mfspr r13,SPRN_SPRG3
@@ -575,7 +569,6 @@ slb_miss_user_pseries:
575system_reset_fwnmi: 569system_reset_fwnmi:
576 HMT_MEDIUM 570 HMT_MEDIUM
577 mtspr SPRN_SPRG1,r13 /* save r13 */ 571 mtspr SPRN_SPRG1,r13 /* save r13 */
578 RUNLATCH_ON(r13)
579 EXCEPTION_PROLOG_PSERIES(PACA_EXGEN, system_reset_common) 572 EXCEPTION_PROLOG_PSERIES(PACA_EXGEN, system_reset_common)
580 573
581 .globl machine_check_fwnmi 574 .globl machine_check_fwnmi
@@ -583,7 +576,6 @@ system_reset_fwnmi:
583machine_check_fwnmi: 576machine_check_fwnmi:
584 HMT_MEDIUM 577 HMT_MEDIUM
585 mtspr SPRN_SPRG1,r13 /* save r13 */ 578 mtspr SPRN_SPRG1,r13 /* save r13 */
586 RUNLATCH_ON(r13)
587 EXCEPTION_PROLOG_PSERIES(PACA_EXMC, machine_check_common) 579 EXCEPTION_PROLOG_PSERIES(PACA_EXMC, machine_check_common)
588 580
589#ifdef CONFIG_PPC_ISERIES 581#ifdef CONFIG_PPC_ISERIES
@@ -894,7 +886,6 @@ unrecov_fer:
894 .align 7 886 .align 7
895 .globl data_access_common 887 .globl data_access_common
896data_access_common: 888data_access_common:
897 RUNLATCH_ON(r10) /* It wont fit in the 0x300 handler */
898 mfspr r10,SPRN_DAR 889 mfspr r10,SPRN_DAR
899 std r10,PACA_EXGEN+EX_DAR(r13) 890 std r10,PACA_EXGEN+EX_DAR(r13)
900 mfspr r10,SPRN_DSISR 891 mfspr r10,SPRN_DSISR
@@ -1042,6 +1033,7 @@ hardware_interrupt_common:
1042 EXCEPTION_PROLOG_COMMON(0x500, PACA_EXGEN) 1033 EXCEPTION_PROLOG_COMMON(0x500, PACA_EXGEN)
1043hardware_interrupt_entry: 1034hardware_interrupt_entry:
1044 DISABLE_INTS 1035 DISABLE_INTS
1036 bl .ppc64_runlatch_on
1045 addi r3,r1,STACK_FRAME_OVERHEAD 1037 addi r3,r1,STACK_FRAME_OVERHEAD
1046 bl .do_IRQ 1038 bl .do_IRQ
1047 b .ret_from_except_lite 1039 b .ret_from_except_lite
diff --git a/arch/powerpc/kernel/process.c b/arch/powerpc/kernel/process.c
index 57703994a063..c225cf154bfe 100644
--- a/arch/powerpc/kernel/process.c
+++ b/arch/powerpc/kernel/process.c
@@ -888,3 +888,35 @@ void dump_stack(void)
888 show_stack(current, NULL); 888 show_stack(current, NULL);
889} 889}
890EXPORT_SYMBOL(dump_stack); 890EXPORT_SYMBOL(dump_stack);
891
892#ifdef CONFIG_PPC64
893void ppc64_runlatch_on(void)
894{
895 unsigned long ctrl;
896
897 if (cpu_has_feature(CPU_FTR_CTRL) && !test_thread_flag(TIF_RUNLATCH)) {
898 HMT_medium();
899
900 ctrl = mfspr(SPRN_CTRLF);
901 ctrl |= CTRL_RUNLATCH;
902 mtspr(SPRN_CTRLT, ctrl);
903
904 set_thread_flag(TIF_RUNLATCH);
905 }
906}
907
908void ppc64_runlatch_off(void)
909{
910 unsigned long ctrl;
911
912 if (cpu_has_feature(CPU_FTR_CTRL) && test_thread_flag(TIF_RUNLATCH)) {
913 HMT_medium();
914
915 clear_thread_flag(TIF_RUNLATCH);
916
917 ctrl = mfspr(SPRN_CTRLF);
918 ctrl &= ~CTRL_RUNLATCH;
919 mtspr(SPRN_CTRLT, ctrl);
920 }
921}
922#endif
diff --git a/arch/powerpc/platforms/iseries/setup.c b/arch/powerpc/platforms/iseries/setup.c
index 3f8790146b00..3ecc4a652d82 100644
--- a/arch/powerpc/platforms/iseries/setup.c
+++ b/arch/powerpc/platforms/iseries/setup.c
@@ -648,6 +648,7 @@ static void yield_shared_processor(void)
648 * here and let the timer_interrupt code sort out the actual time. 648 * here and let the timer_interrupt code sort out the actual time.
649 */ 649 */
650 get_lppaca()->int_dword.fields.decr_int = 1; 650 get_lppaca()->int_dword.fields.decr_int = 1;
651 ppc64_runlatch_on();
651 process_iSeries_events(); 652 process_iSeries_events();
652} 653}
653 654
diff --git a/include/asm-powerpc/reg.h b/include/asm-powerpc/reg.h
index 12ecc9b9f285..72bfe3af0460 100644
--- a/include/asm-powerpc/reg.h
+++ b/include/asm-powerpc/reg.h
@@ -615,27 +615,9 @@
615#define proc_trap() asm volatile("trap") 615#define proc_trap() asm volatile("trap")
616 616
617#ifdef CONFIG_PPC64 617#ifdef CONFIG_PPC64
618static inline void ppc64_runlatch_on(void) 618
619{ 619extern void ppc64_runlatch_on(void);
620 unsigned long ctrl; 620extern void ppc64_runlatch_off(void);
621
622 if (cpu_has_feature(CPU_FTR_CTRL)) {
623 ctrl = mfspr(SPRN_CTRLF);
624 ctrl |= CTRL_RUNLATCH;
625 mtspr(SPRN_CTRLT, ctrl);
626 }
627}
628
629static inline void ppc64_runlatch_off(void)
630{
631 unsigned long ctrl;
632
633 if (cpu_has_feature(CPU_FTR_CTRL)) {
634 ctrl = mfspr(SPRN_CTRLF);
635 ctrl &= ~CTRL_RUNLATCH;
636 mtspr(SPRN_CTRLT, ctrl);
637 }
638}
639 621
640extern unsigned long scom970_read(unsigned int address); 622extern unsigned long scom970_read(unsigned int address);
641extern void scom970_write(unsigned int address, unsigned long value); 623extern void scom970_write(unsigned int address, unsigned long value);
@@ -645,15 +627,6 @@ extern void scom970_write(unsigned int address, unsigned long value);
645#define __get_SP() ({unsigned long sp; \ 627#define __get_SP() ({unsigned long sp; \
646 asm volatile("mr %0,1": "=r" (sp)); sp;}) 628 asm volatile("mr %0,1": "=r" (sp)); sp;})
647 629
648#else /* __ASSEMBLY__ */
649
650#define RUNLATCH_ON(REG) \
651BEGIN_FTR_SECTION \
652 mfspr (REG),SPRN_CTRLF; \
653 ori (REG),(REG),CTRL_RUNLATCH; \
654 mtspr SPRN_CTRLT,(REG); \
655END_FTR_SECTION_IFSET(CPU_FTR_CTRL)
656
657#endif /* __ASSEMBLY__ */ 630#endif /* __ASSEMBLY__ */
658#endif /* __KERNEL__ */ 631#endif /* __KERNEL__ */
659#endif /* _ASM_POWERPC_REG_H */ 632#endif /* _ASM_POWERPC_REG_H */
diff --git a/include/asm-powerpc/thread_info.h b/include/asm-powerpc/thread_info.h
index c044ec16a879..237fc2b72974 100644
--- a/include/asm-powerpc/thread_info.h
+++ b/include/asm-powerpc/thread_info.h
@@ -113,7 +113,7 @@ static inline struct thread_info *current_thread_info(void)
113#define TIF_POLLING_NRFLAG 4 /* true if poll_idle() is polling 113#define TIF_POLLING_NRFLAG 4 /* true if poll_idle() is polling
114 TIF_NEED_RESCHED */ 114 TIF_NEED_RESCHED */
115#define TIF_32BIT 5 /* 32 bit binary */ 115#define TIF_32BIT 5 /* 32 bit binary */
116/* #define SPARE 6 */ 116#define TIF_RUNLATCH 6 /* Is the runlatch enabled? */
117#define TIF_ABI_PENDING 7 /* 32/64 bit switch needed */ 117#define TIF_ABI_PENDING 7 /* 32/64 bit switch needed */
118#define TIF_SYSCALL_AUDIT 8 /* syscall auditing active */ 118#define TIF_SYSCALL_AUDIT 8 /* syscall auditing active */
119#define TIF_SINGLESTEP 9 /* singlestepping active */ 119#define TIF_SINGLESTEP 9 /* singlestepping active */
@@ -131,7 +131,7 @@ static inline struct thread_info *current_thread_info(void)
131#define _TIF_NEED_RESCHED (1<<TIF_NEED_RESCHED) 131#define _TIF_NEED_RESCHED (1<<TIF_NEED_RESCHED)
132#define _TIF_POLLING_NRFLAG (1<<TIF_POLLING_NRFLAG) 132#define _TIF_POLLING_NRFLAG (1<<TIF_POLLING_NRFLAG)
133#define _TIF_32BIT (1<<TIF_32BIT) 133#define _TIF_32BIT (1<<TIF_32BIT)
134/* #define _SPARE (1<<SPARE) */ 134#define _TIF_RUNLATCH (1<<TIF_RUNLATCH)
135#define _TIF_ABI_PENDING (1<<TIF_ABI_PENDING) 135#define _TIF_ABI_PENDING (1<<TIF_ABI_PENDING)
136#define _TIF_SYSCALL_AUDIT (1<<TIF_SYSCALL_AUDIT) 136#define _TIF_SYSCALL_AUDIT (1<<TIF_SYSCALL_AUDIT)
137#define _TIF_SINGLESTEP (1<<TIF_SINGLESTEP) 137#define _TIF_SINGLESTEP (1<<TIF_SINGLESTEP)