aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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