diff options
-rw-r--r-- | arch/ppc64/kernel/iSeries_setup.c | 84 |
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 | ||
835 | late_initcall(iSeries_src_init); | 835 | late_initcall(iSeries_src_init); |
836 | 836 | ||
837 | static unsigned long maxYieldTime = 0; | ||
838 | static unsigned long minYieldTime = 0xffffffffffffffffUL; | ||
839 | |||
840 | static inline void process_iSeries_events(void) | 837 | static 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) | |||
845 | static void yield_shared_processor(void) | 842 | static 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 | ||
874 | static int iSeries_idle(void) | 863 | static 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 | |||
889 | static 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 | ||