aboutsummaryrefslogtreecommitdiffstats
path: root/arch/ppc64/kernel/iSeries_setup.c
diff options
context:
space:
mode:
authorAnton Blanchard <anton@samba.org>2005-07-07 20:56:32 -0400
committerLinus Torvalds <torvalds@g5.osdl.org>2005-07-07 21:23:41 -0400
commit3c57bb9f454e8fc7b3d815b991b0dec43c766641 (patch)
treef9bfb5f481a3967eee66603107065fa728602448 /arch/ppc64/kernel/iSeries_setup.c
parent08d5e3eb4b2141e1031835c89a62ee3ddf896641 (diff)
[PATCH] ppc64: iSeries idle fixups
- remove min/max yield time, we dont use the values anywhere - separate shared and dedicated idle loops - check need_resched again with irqs off to avoid sleeping with pending work - continually set runlatch off in idle loop, this means we dont need to turn the runlatch off on exception exit and suffer that associated cost for all exceptions. (A future patch will turn the runlatch on at exception entry) Signed-off-by: Anton Blanchard <anton@samba.org> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'arch/ppc64/kernel/iSeries_setup.c')
-rw-r--r--arch/ppc64/kernel/iSeries_setup.c84
1 files changed, 47 insertions, 37 deletions
diff --git a/arch/ppc64/kernel/iSeries_setup.c b/arch/ppc64/kernel/iSeries_setup.c
index fae215ea54b4..b4c919e18fa7 100644
--- a/arch/ppc64/kernel/iSeries_setup.c
+++ b/arch/ppc64/kernel/iSeries_setup.c
@@ -834,9 +834,6 @@ static int __init iSeries_src_init(void)
834 834
835late_initcall(iSeries_src_init); 835late_initcall(iSeries_src_init);
836 836
837static unsigned long maxYieldTime = 0;
838static unsigned long minYieldTime = 0xffffffffffffffffUL;
839
840static inline void process_iSeries_events(void) 837static inline void process_iSeries_events(void)
841{ 838{
842 asm volatile ("li 0,0x5555; sc" : : : "r0", "r3"); 839 asm volatile ("li 0,0x5555; sc" : : : "r0", "r3");
@@ -845,7 +842,6 @@ static inline void process_iSeries_events(void)
845static void yield_shared_processor(void) 842static void yield_shared_processor(void)
846{ 843{
847 unsigned long tb; 844 unsigned long tb;
848 unsigned long yieldTime;
849 845
850 HvCall_setEnabledInterrupts(HvCall_MaskIPI | 846 HvCall_setEnabledInterrupts(HvCall_MaskIPI |
851 HvCall_MaskLpEvent | 847 HvCall_MaskLpEvent |
@@ -856,13 +852,6 @@ static void yield_shared_processor(void)
856 /* Compute future tb value when yield should expire */ 852 /* Compute future tb value when yield should expire */
857 HvCall_yieldProcessor(HvCall_YieldTimed, tb+tb_ticks_per_jiffy); 853 HvCall_yieldProcessor(HvCall_YieldTimed, tb+tb_ticks_per_jiffy);
858 854
859 yieldTime = get_tb() - tb;
860 if (yieldTime > maxYieldTime)
861 maxYieldTime = yieldTime;
862
863 if (yieldTime < minYieldTime)
864 minYieldTime = yieldTime;
865
866 /* 855 /*
867 * The decrementer stops during the yield. Force a fake decrementer 856 * The decrementer stops during the yield. Force a fake decrementer
868 * here and let the timer_interrupt code sort out the actual time. 857 * here and let the timer_interrupt code sort out the actual time.
@@ -871,45 +860,62 @@ static void yield_shared_processor(void)
871 process_iSeries_events(); 860 process_iSeries_events();
872} 861}
873 862
874static int iSeries_idle(void) 863static int iseries_shared_idle(void)
875{ 864{
876 struct paca_struct *lpaca; 865 while (1) {
877 long oldval; 866 while (!need_resched() && !hvlpevent_is_pending()) {
867 local_irq_disable();
868 ppc64_runlatch_off();
869
870 /* Recheck with irqs off */
871 if (!need_resched() && !hvlpevent_is_pending())
872 yield_shared_processor();
878 873
879 /* ensure iSeries run light will be out when idle */ 874 HMT_medium();
880 ppc64_runlatch_off(); 875 local_irq_enable();
876 }
877
878 ppc64_runlatch_on();
881 879
882 lpaca = get_paca(); 880 if (hvlpevent_is_pending())
881 process_iSeries_events();
882
883 schedule();
884 }
885
886 return 0;
887}
888
889static int iseries_dedicated_idle(void)
890{
891 struct paca_struct *lpaca = get_paca();
892 long oldval;
883 893
884 while (1) { 894 while (1) {
885 if (lpaca->lppaca.shared_proc) { 895 oldval = test_and_clear_thread_flag(TIF_NEED_RESCHED);
886 if (hvlpevent_is_pending())
887 process_iSeries_events();
888 if (!need_resched())
889 yield_shared_processor();
890 } else {
891 oldval = test_and_clear_thread_flag(TIF_NEED_RESCHED);
892 896
893 if (!oldval) { 897 if (!oldval) {
894 set_thread_flag(TIF_POLLING_NRFLAG); 898 set_thread_flag(TIF_POLLING_NRFLAG);
895 899
896 while (!need_resched()) { 900 while (!need_resched()) {
901 ppc64_runlatch_off();
902 HMT_low();
903
904 if (hvlpevent_is_pending()) {
897 HMT_medium(); 905 HMT_medium();
898 if (hvlpevent_is_pending()) 906 ppc64_runlatch_on();
899 process_iSeries_events(); 907 process_iSeries_events();
900 HMT_low();
901 } 908 }
902
903 HMT_medium();
904 clear_thread_flag(TIF_POLLING_NRFLAG);
905 } else {
906 set_need_resched();
907 } 909 }
910
911 HMT_medium();
912 clear_thread_flag(TIF_POLLING_NRFLAG);
913 } else {
914 set_need_resched();
908 } 915 }
909 916
910 ppc64_runlatch_on(); 917 ppc64_runlatch_on();
911 schedule(); 918 schedule();
912 ppc64_runlatch_off();
913 } 919 }
914 920
915 return 0; 921 return 0;
@@ -940,6 +946,10 @@ void __init iSeries_early_setup(void)
940 ppc_md.get_rtc_time = iSeries_get_rtc_time; 946 ppc_md.get_rtc_time = iSeries_get_rtc_time;
941 ppc_md.calibrate_decr = iSeries_calibrate_decr; 947 ppc_md.calibrate_decr = iSeries_calibrate_decr;
942 ppc_md.progress = iSeries_progress; 948 ppc_md.progress = iSeries_progress;
943 ppc_md.idle_loop = iSeries_idle; 949
950 if (get_paca()->lppaca.shared_proc)
951 ppc_md.idle_loop = iseries_shared_idle;
952 else
953 ppc_md.idle_loop = iseries_dedicated_idle;
944} 954}
945 955