From 17924ef93c9979db90111fda2c41476e624e3620 Mon Sep 17 00:00:00 2001 From: Michal Suchanek Date: May 09 2023 08:22:53 +0000 Subject: powerpc: Move idle_loop_prolog()/epilog() functions to header file (PED-3947 bsc#1210544 ltc#202303). --- diff --git a/patches.suse/powerpc-Move-idle_loop_prolog-epilog-functions-to-he.patch b/patches.suse/powerpc-Move-idle_loop_prolog-epilog-functions-to-he.patch new file mode 100644 index 0000000..63b3ae5 --- /dev/null +++ b/patches.suse/powerpc-Move-idle_loop_prolog-epilog-functions-to-he.patch @@ -0,0 +1,210 @@ +From e4a884cc28fa3f5d8b81de46998ffe29b4ad169e Mon Sep 17 00:00:00 2001 +From: "Gautham R. Shenoy" +Date: Tue, 7 Apr 2020 14:17:39 +0530 +Subject: [PATCH] powerpc: Move idle_loop_prolog()/epilog() functions to header + file + +References: PED-3947 bsc#1210544 ltc#202303 +Patch-mainline: v5.8-rc1 +Git-commit: e4a884cc28fa3f5d8b81de46998ffe29b4ad169e + +Currently prior to entering an idle state on a Linux Guest, the +pseries cpuidle driver implement an idle_loop_prolog() and +idle_loop_epilog() functions which ensure that idle_purr is correctly +computed, and the hypervisor is informed that the CPU cycles have been +donated. + +These prolog and epilog functions are also required in the default +idle call, i.e pseries_lpar_idle(). Hence move these accessor +functions to a common header file and call them from +pseries_lpar_idle(). Since the existing header files such as +asm/processor.h have enough clutter, create a new header file +asm/idle.h. Finally rename idle_loop_prolog() and idle_loop_epilog() +to pseries_idle_prolog() and pseries_idle_epilog() as they are only +relavent for on pseries guests. + +Signed-off-by: Gautham R. Shenoy +Signed-off-by: Michael Ellerman +Link: https://lore.kernel.org/r/1586249263-14048-2-git-send-email-ego@linux.vnet.ibm.com +Acked-by: Michal Suchanek +--- + arch/powerpc/include/asm/idle.h | 31 ++++++++++++++++++++++ + arch/powerpc/platforms/pseries/setup.c | 7 +++-- + drivers/cpuidle/cpuidle-pseries.c | 36 +++++--------------------- + 3 files changed, 43 insertions(+), 31 deletions(-) + create mode 100644 arch/powerpc/include/asm/idle.h + +diff --git a/arch/powerpc/include/asm/idle.h b/arch/powerpc/include/asm/idle.h +new file mode 100644 +index 000000000000..32064a4c0dd7 +--- /dev/null ++++ b/arch/powerpc/include/asm/idle.h +@@ -0,0 +1,31 @@ ++/* SPDX-License-Identifier: GPL-2.0-or-later */ ++#ifndef _ASM_POWERPC_IDLE_H ++#define _ASM_POWERPC_IDLE_H ++#include ++#include ++ ++#ifdef CONFIG_PPC_PSERIES ++static inline void pseries_idle_prolog(unsigned long *in_purr) ++{ ++ ppc64_runlatch_off(); ++ *in_purr = mfspr(SPRN_PURR); ++ /* ++ * Indicate to the HV that we are idle. Now would be ++ * a good time to find other work to dispatch. ++ */ ++ get_lppaca()->idle = 1; ++} ++ ++static inline void pseries_idle_epilog(unsigned long in_purr) ++{ ++ u64 wait_cycles; ++ ++ wait_cycles = be64_to_cpu(get_lppaca()->wait_state_cycles); ++ wait_cycles += mfspr(SPRN_PURR) - in_purr; ++ get_lppaca()->wait_state_cycles = cpu_to_be64(wait_cycles); ++ get_lppaca()->idle = 0; ++ ++ ppc64_runlatch_on(); ++} ++#endif /* CONFIG_PPC_PSERIES */ ++#endif +diff --git a/arch/powerpc/platforms/pseries/setup.c b/arch/powerpc/platforms/pseries/setup.c +--- a/arch/powerpc/platforms/pseries/setup.c ++++ b/arch/powerpc/platforms/pseries/setup.c +@@ -68,6 +68,7 @@ + #include + #include + #include ++#include + + #include "pseries.h" + #include "../../../../drivers/pci/pci.h" +@@ -319,6 +320,8 @@ machine_early_initcall(pseries, alloc_dispatch_log_kmem_cache); + + static void pseries_lpar_idle(void) + { ++ unsigned long in_purr; ++ + /* + * Default handler to go into low thread priority and possibly + * low power mode by ceding processor to hypervisor +@@ -328,7 +331,7 @@ static void pseries_lpar_idle(void) + return; + + /* Indicate to hypervisor that we are idle. */ +- get_lppaca()->idle = 1; ++ pseries_idle_prolog(&in_purr); + + /* + * Yield the processor to the hypervisor. We return if +@@ -339,7 +342,7 @@ static void pseries_lpar_idle(void) + */ + cede_processor(); + +- get_lppaca()->idle = 0; ++ pseries_idle_epilog(in_purr); + } + + /* +diff --git a/drivers/cpuidle/cpuidle-pseries.c b/drivers/cpuidle/cpuidle-pseries.c +index 74c247972bb3..46d5e05fcf97 100644 +--- a/drivers/cpuidle/cpuidle-pseries.c ++++ b/drivers/cpuidle/cpuidle-pseries.c +@@ -19,6 +19,7 @@ + #include + #include + #include ++#include + #include + + struct cpuidle_driver pseries_idle_driver = { +@@ -31,29 +32,6 @@ static struct cpuidle_state *cpuidle_state_table __read_mostly; + static u64 snooze_timeout __read_mostly; + static bool snooze_timeout_en __read_mostly; + +-static inline void idle_loop_prolog(unsigned long *in_purr) +-{ +- ppc64_runlatch_off(); +- *in_purr = mfspr(SPRN_PURR); +- /* +- * Indicate to the HV that we are idle. Now would be +- * a good time to find other work to dispatch. +- */ +- get_lppaca()->idle = 1; +-} +- +-static inline void idle_loop_epilog(unsigned long in_purr) +-{ +- u64 wait_cycles; +- +- wait_cycles = be64_to_cpu(get_lppaca()->wait_state_cycles); +- wait_cycles += mfspr(SPRN_PURR) - in_purr; +- get_lppaca()->wait_state_cycles = cpu_to_be64(wait_cycles); +- get_lppaca()->idle = 0; +- +- ppc64_runlatch_on(); +-} +- + static int snooze_loop(struct cpuidle_device *dev, + struct cpuidle_driver *drv, + int index) +@@ -63,7 +41,7 @@ static int snooze_loop(struct cpuidle_device *dev, + + set_thread_flag(TIF_POLLING_NRFLAG); + +- idle_loop_prolog(&in_purr); ++ pseries_idle_prolog(&in_purr); + local_irq_enable(); + snooze_exit_time = get_tb() + snooze_timeout; + +@@ -87,7 +65,7 @@ static int snooze_loop(struct cpuidle_device *dev, + + local_irq_disable(); + +- idle_loop_epilog(in_purr); ++ pseries_idle_epilog(in_purr); + + return index; + } +@@ -115,7 +93,7 @@ static int dedicated_cede_loop(struct cpuidle_device *dev, + { + unsigned long in_purr; + +- idle_loop_prolog(&in_purr); ++ pseries_idle_prolog(&in_purr); + get_lppaca()->donate_dedicated_cpu = 1; + + HMT_medium(); +@@ -124,7 +102,7 @@ static int dedicated_cede_loop(struct cpuidle_device *dev, + local_irq_disable(); + get_lppaca()->donate_dedicated_cpu = 0; + +- idle_loop_epilog(in_purr); ++ pseries_idle_epilog(in_purr); + + return index; + } +@@ -135,7 +113,7 @@ static int shared_cede_loop(struct cpuidle_device *dev, + { + unsigned long in_purr; + +- idle_loop_prolog(&in_purr); ++ pseries_idle_prolog(&in_purr); + + /* + * Yield the processor to the hypervisor. We return if +@@ -147,7 +125,7 @@ static int shared_cede_loop(struct cpuidle_device *dev, + check_and_cede_processor(); + + local_irq_disable(); +- idle_loop_epilog(in_purr); ++ pseries_idle_epilog(in_purr); + + return index; + } +-- +2.40.0 + diff --git a/series.conf b/series.conf index 42650ab..e71ab49 100644 --- a/series.conf +++ b/series.conf @@ -56765,6 +56765,7 @@ patches.suse/firmware-imx-scu-fix-corruption-of-header.patch patches.suse/firmware-imx-scu-Fix-possible-memory-leak-in-imx_scu.patch patches.suse/drivers-soc-ti-knav_qmss_queue-Make-knav_gp_range_op.patch + patches.suse/powerpc-Move-idle_loop_prolog-epilog-functions-to-he.patch patches.suse/powerpc-eeh-Fix-pseries_eeh_configure_bridge.patch patches.suse/powerpc-pseries-ras-Avoid-calling-rtas_token-in-NMI-.patch patches.suse/powerpc-pseries-ras-Fix-FWNMI_VALID-off-by-one.patch