Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

um: work around sched_yield not yielding in time-travel mode

sched_yield by a userspace may not actually cause scheduling in
time-travel mode as no time has passed. In the case seen it appears to
be a badly implemented userspace spinlock in ASAN. Unfortunately, with
time-travel it causes an extreme slowdown or even deadlock depending on
the kernel configuration (CONFIG_UML_MAX_USERSPACE_ITERATIONS).

Work around it by accounting time to the process whenever it executes a
sched_yield syscall.

Signed-off-by: Benjamin Berg <benjamin.berg@intel.com>
Link: https://patch.msgid.link/20250314130815.226872-1-benjamin@sipsolutions.net
Signed-off-by: Johannes Berg <johannes.berg@intel.com>

authored by

Benjamin Berg and committed by
Johannes Berg
887c5c12 089db01e

+13
+2
arch/um/include/linux/time-internal.h
··· 83 83 #define time_travel_del_event(...) time_travel_not_configured() 84 84 #endif /* CONFIG_UML_TIME_TRAVEL_SUPPORT */ 85 85 86 + extern unsigned long tt_extra_sched_jiffies; 87 + 86 88 /* 87 89 * Without CONFIG_UML_TIME_TRAVEL_SUPPORT this is a linker error if used, 88 90 * which is intentional since we really shouldn't link it in that case.
+11
arch/um/kernel/skas/syscall.c
··· 31 31 goto out; 32 32 33 33 syscall = UPT_SYSCALL_NR(r); 34 + 35 + /* 36 + * If no time passes, then sched_yield may not actually yield, causing 37 + * broken spinlock implementations in userspace (ASAN) to hang for long 38 + * periods of time. 39 + */ 40 + if ((time_travel_mode == TT_MODE_INFCPU || 41 + time_travel_mode == TT_MODE_EXTERNAL) && 42 + syscall == __NR_sched_yield) 43 + tt_extra_sched_jiffies += 1; 44 + 34 45 if (syscall >= 0 && syscall < __NR_syscalls) { 35 46 unsigned long ret = EXECUTE_SYSCALL(syscall, regs); 36 47