arch/x86/kernel/tsc.c | 27 +++++++++++++++++++++++++++ include/linux/sched/clock.h | 5 ++++- kernel/sched/clock.c | 4 ++-- 3 files changed, 33 insertions(+), 3 deletions(-)
System instability are seen during resume from hibernation when system is under heavy CPU load. this is caused by the lack of update of sched clock data
Signed-off-by: Atharva Tiwari <evepolonium@gmail.com>
---
arch/x86/kernel/tsc.c | 27 +++++++++++++++++++++++++++
include/linux/sched/clock.h | 5 ++++-
kernel/sched/clock.c | 4 ++--
3 files changed, 33 insertions(+), 3 deletions(-)
diff --git a/arch/x86/kernel/tsc.c b/arch/x86/kernel/tsc.c
index 67aeaba4ba9c..28a5c3ff2e90 100644
--- a/arch/x86/kernel/tsc.c
+++ b/arch/x86/kernel/tsc.c
@@ -15,6 +15,7 @@
#include <linux/timex.h>
#include <linux/static_key.h>
#include <linux/static_call.h>
+#include <linux/suspend.h>
#include <asm/hpet.h>
#include <asm/timer.h>
@@ -1599,3 +1600,29 @@ unsigned long calibrate_delay_is_known(void)
return 0;
}
#endif
+static int tsc_pm_notifier(struct notifier_block *notifier,
+ unsigned long pm_event, void *unused)
+{
+ switch (pm_event) {
+ case PM_HIBERNATION_PREPARE:
+ clear_sched_clock_stable();
+ break;
+ case PM_POST_HIBERNATION:
+ if (!check_tsc_unstable())
+ set_sched_clock_stable();
+ break;
+ }
+
+ return 0;
+};
+
+static struct notifier_block tsc_pm_notifier_block = {
+ .notifier_call = tsc_pm_notifier,
+}
+
+static int tsc_setup_pm_notifier(void)
+{
+ return register_pm_notifier(&tsc_pm_notifier_block);
+}
+
+subsys_initcall(tsc_setup_pm_notifier);
diff --git a/include/linux/sched/clock.h b/include/linux/sched/clock.h
index 196f0ca351a2..69efc280f14c 100644
--- a/include/linux/sched/clock.h
+++ b/include/linux/sched/clock.h
@@ -40,7 +40,9 @@ static inline void sched_clock_tick(void)
static inline void clear_sched_clock_stable(void)
{
}
-
+static inline void set_sched_clock_stable(void)
+{
+}
static inline void sched_clock_idle_sleep_event(void)
{
}
@@ -65,6 +67,7 @@ static __always_inline u64 local_clock(void)
}
#else
extern int sched_clock_stable(void);
+extern void set_sched_clock_stable(void);
extern void clear_sched_clock_stable(void);
/*
diff --git a/kernel/sched/clock.c b/kernel/sched/clock.c
index a09655b48140..efe8f2b69657 100644
--- a/kernel/sched/clock.c
+++ b/kernel/sched/clock.c
@@ -114,7 +114,7 @@ notrace static void __scd_stamp(struct sched_clock_data *scd)
scd->tick_raw = sched_clock();
}
-notrace static void __set_sched_clock_stable(void)
+notrace void set_sched_clock_stable(void)
{
struct sched_clock_data *scd;
@@ -234,7 +234,7 @@ static int __init sched_clock_init_late(void)
smp_mb(); /* matches {set,clear}_sched_clock_stable() */
if (__sched_clock_stable_early)
- __set_sched_clock_stable();
+ set_sched_clock_stable();
return 0;
}
--
2.43.0
Hi Atharva, kernel test robot noticed the following build errors: [auto build test ERROR on tip/master] [also build test ERROR on tip/sched/core linus/master tip/auto-latest tip/x86/core v6.13-rc3 next-20241217] [If your patch is applied to the wrong git tree, kindly drop us a note. And when submitting patch, we suggest to use '--base' as documented in https://git-scm.com/docs/git-format-patch#_base_tree_information] url: https://github.com/intel-lab-lkp/linux/commits/Atharva-Tiwari/x86-tsc-avoid-system-instability-in-hibernation/20241210-214059 base: tip/master patch link: https://lore.kernel.org/r/20241210133930.1195-1-evepolonium%40gmail.com patch subject: [PATCH] x86 tsc: avoid system instability in hibernation config: x86_64-kexec (https://download.01.org/0day-ci/archive/20241217/202412172141.6wHjHpsF-lkp@intel.com/config) compiler: clang version 19.1.3 (https://github.com/llvm/llvm-project ab51eccf88f5321e7c60591c5546b254b6afab99) reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20241217/202412172141.6wHjHpsF-lkp@intel.com/reproduce) If you fix the issue in a separate patch/commit (i.e. not just a new version of the same patch/commit), kindly add following tags | Reported-by: kernel test robot <lkp@intel.com> | Closes: https://lore.kernel.org/oe-kbuild-all/202412172141.6wHjHpsF-lkp@intel.com/ All errors (new ones prefixed by >>): In file included from arch/x86/kernel/tsc.c:18: In file included from include/linux/suspend.h:5: In file included from include/linux/swap.h:9: In file included from include/linux/memcontrol.h:21: In file included from include/linux/mm.h:2223: include/linux/vmstat.h:504:43: warning: arithmetic between different enumeration types ('enum zone_stat_item' and 'enum numa_stat_item') [-Wenum-enum-conversion] 504 | return vmstat_text[NR_VM_ZONE_STAT_ITEMS + | ~~~~~~~~~~~~~~~~~~~~~ ^ 505 | item]; | ~~~~ include/linux/vmstat.h:511:43: warning: arithmetic between different enumeration types ('enum zone_stat_item' and 'enum numa_stat_item') [-Wenum-enum-conversion] 511 | return vmstat_text[NR_VM_ZONE_STAT_ITEMS + | ~~~~~~~~~~~~~~~~~~~~~ ^ 512 | NR_VM_NUMA_EVENT_ITEMS + | ~~~~~~~~~~~~~~~~~~~~~~ include/linux/vmstat.h:518:36: warning: arithmetic between different enumeration types ('enum node_stat_item' and 'enum lru_list') [-Wenum-enum-conversion] 518 | return node_stat_name(NR_LRU_BASE + lru) + 3; // skip "nr_" | ~~~~~~~~~~~ ^ ~~~ include/linux/vmstat.h:524:43: warning: arithmetic between different enumeration types ('enum zone_stat_item' and 'enum numa_stat_item') [-Wenum-enum-conversion] 524 | return vmstat_text[NR_VM_ZONE_STAT_ITEMS + | ~~~~~~~~~~~~~~~~~~~~~ ^ 525 | NR_VM_NUMA_EVENT_ITEMS + | ~~~~~~~~~~~~~~~~~~~~~~ >> arch/x86/kernel/tsc.c:1621:2: error: expected ';' after top level declarator 1621 | } | ^ | ; 4 warnings and 1 error generated. vim +1621 arch/x86/kernel/tsc.c 1618 1619 static struct notifier_block tsc_pm_notifier_block = { 1620 .notifier_call = tsc_pm_notifier, > 1621 } 1622 -- 0-DAY CI Kernel Test Service https://github.com/intel/lkp-tests/wiki
© 2016 - 2024 Red Hat, Inc.