linux/kernel/sched
Yafang Shao f3fa0e40df sched/clock: Don't define sched_clock_irqtime as static key
The sched_clock_irqtime was defined as a static key in:

  8722903cbb ("sched: Define sched_clock_irqtime as static key")

However, this change introduces a 'sleeping in atomic context' warning:

	arch/x86/kernel/tsc.c:1214 mark_tsc_unstable()
	warn: sleeping in atomic context

As analyzed by Dan, the affected code path is as follows:

vcpu_load() <- disables preempt
-> kvm_arch_vcpu_load()
   -> mark_tsc_unstable() <- sleeps

virt/kvm/kvm_main.c
   166  void vcpu_load(struct kvm_vcpu *vcpu)
   167  {
   168          int cpu = get_cpu();
                          ^^^^^^^^^^
This get_cpu() disables preemption.

   169
   170          __this_cpu_write(kvm_running_vcpu, vcpu);
   171          preempt_notifier_register(&vcpu->preempt_notifier);
   172          kvm_arch_vcpu_load(vcpu, cpu);
   173          put_cpu();
   174  }

arch/x86/kvm/x86.c
  4979          if (unlikely(vcpu->cpu != cpu) || kvm_check_tsc_unstable()) {
  4980                  s64 tsc_delta = !vcpu->arch.last_host_tsc ? 0 :
  4981                                  rdtsc() - vcpu->arch.last_host_tsc;
  4982                  if (tsc_delta < 0)
  4983                          mark_tsc_unstable("KVM discovered backwards TSC");

arch/x86/kernel/tsc.c
    1206 void mark_tsc_unstable(char *reason)
    1207 {
    1208         if (tsc_unstable)
    1209                 return;
    1210
    1211         tsc_unstable = 1;
    1212         if (using_native_sched_clock())
    1213                 clear_sched_clock_stable();
--> 1214         disable_sched_clock_irqtime();
                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
kernel/jump_label.c
   245  void static_key_disable(struct static_key *key)
   246  {
   247          cpus_read_lock();
                ^^^^^^^^^^^^^^^^
This lock has a might_sleep() in it which triggers the static checker
warning.

   248          static_key_disable_cpuslocked(key);
   249          cpus_read_unlock();
   250  }

Let revert this change for now as {disable,enable}_sched_clock_irqtime
are used in many places, as pointed out by Sean, including the following:

The code path in clocksource_watchdog():

  clocksource_watchdog()
  |
  -> spin_lock(&watchdog_lock);
     |
     -> __clocksource_unstable()
        |
        -> clocksource.mark_unstable() == tsc_cs_mark_unstable()
           |
           -> disable_sched_clock_irqtime()

And the code path in sched_clock_register():

	/* Cannot register a sched_clock with interrupts on */
	local_irq_save(flags);

	...

	/* Enable IRQ time accounting if we have a fast enough sched_clock() */
	if (irqtime > 0 || (irqtime == -1 && rate >= 1000000))
		enable_sched_clock_irqtime();

	local_irq_restore(flags);

[ lkp@intel.com: reported a build error in the prev version ]
[ mingo: cherry-picked it over into sched/urgent ]

Closes: https://lore.kernel.org/kvm/37a79ba3-9ce0-479c-a5b0-2bd75d573ed3@stanley.mountain/
Fixes: 8722903cbb ("sched: Define sched_clock_irqtime as static key")
Reported-by: Dan Carpenter <dan.carpenter@linaro.org>
Debugged-by: Dan Carpenter <dan.carpenter@linaro.org>
Debugged-by: Sean Christopherson <seanjc@google.com>
Debugged-by: Michal Koutný <mkoutny@suse.com>
Signed-off-by: Yafang Shao <laoar.shao@gmail.com>
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Signed-off-by: Ingo Molnar <mingo@kernel.org>
Reviewed-by: Vincent Guittot <vincent.guittot@linaro.org>
Link: https://lkml.kernel.org/r/20250205032438.14668-1-laoar.shao@gmail.com
2025-03-10 14:22:58 +01:00
..
autogroup.c sched_ext: Fixes for v6.14-rc2 2025-02-14 11:14:24 -08:00
autogroup.h
build_policy.c sched_ext: Disallow loading BPF scheduler if isolcpus= domain isolation is in effect 2024-07-08 09:30:13 -10:00
build_utility.c
clock.c sched: Fix spelling in comments 2024-05-27 17:00:21 +02:00
completion.c
core_sched.c sched: Fix spelling in comments 2024-05-27 17:00:21 +02:00
core.c sched/core: Prevent rescheduling when interrupts are disabled 2025-02-27 21:13:57 +01:00
cpuacct.c
cpudeadline.c
cpudeadline.h
cpufreq_schedutil.c cpufreq/schedutil: Only bind threads if needed 2025-01-23 21:09:25 +01:00
cpufreq.c
cpupri.c
cpupri.h
cputime.c sched/clock: Don't define sched_clock_irqtime as static key 2025-03-10 14:22:58 +01:00
deadline.c sched/deadline: Use online cpus for validating runtime 2025-03-06 10:21:31 +01:00
debug.c Fix a cfs_rq->h_nr_runnable accounting bug that trips up a 2025-02-08 11:16:22 -08:00
ext.c sched_ext: Fix pick_task_scx() picking non-queued tasks when it's called without balance() 2025-02-25 08:28:52 -10:00
ext.h sched_ext: Fix incorrect autogroup migration detection 2025-01-27 08:31:50 -10:00
fair.c sched/fair: Fix potential memory corruption in child_cfs_rq_on_list 2025-03-05 17:30:54 +01:00
features.h sched/fair: Untangle NEXT_BUDDY and pick_next_task() 2024-12-09 11:48:13 +01:00
idle.c sched_ext: idle: Refresh idle masks during idle-to-idle transitions 2025-01-10 12:40:42 -10:00
isolation.c sched/isolation: Consolidate housekeeping cpumasks that are always identical 2024-12-02 12:24:28 +01:00
loadavg.c sched: Fix spelling in comments 2024-05-27 17:00:21 +02:00
Makefile
membarrier.c RISC-V Patches for the 6.9 Merge Window 2024-03-22 10:41:13 -07:00
pelt.c sched/fair: Use the new cfs_rq.h_nr_runnable 2024-12-09 11:48:11 +01:00
pelt.h sched: Move update_other_load_avgs() to kernel/sched/pelt.c 2024-09-11 20:00:21 -10:00
psi.c sched, psi: Don't account irq time if sched_clock_irqtime is disabled 2025-01-13 14:10:26 +01:00
rt.c treewide: const qualify ctl_tables where applicable 2025-01-28 13:48:37 +01:00
sched-pelt.h
sched.h sched/clock: Don't define sched_clock_irqtime as static key 2025-03-10 14:22:58 +01:00
smp.h
stats.c docs: Update Schedstat version to 17 2024-12-20 15:31:18 +01:00
stats.h Mainly individually changelogged singleton patches. The patch series in 2025-01-26 17:50:53 -08:00
stop_task.c sched: Add put_prev_task(.next) 2024-09-03 15:26:32 +02:00
swait.c
syscalls.c cpufreq/schedutil: Only bind threads if needed 2025-01-23 21:09:25 +01:00
topology.c treewide: const qualify ctl_tables where applicable 2025-01-28 13:48:37 +01:00
wait_bit.c sched/wait: Remove unused bit_wait_io_timeout 2024-10-07 09:28:41 +02:00
wait.c