Re: [PATCH] selftests/powerpc/pmu/ebb: fix lost_exception_test hang with sched yield change
From: Venkat Rao Bagalkote <hidden>
Date: 2026-09-03 08:41:58
On 03/09/26 1:10 pm, Athira Rajeev wrote:
commit 79104becf42b ("sched/fair: Forfeit vruntime on yield") changed
yield_task_fair() to only bump the deadline when the entity is eligible
(vruntime <= avg_vruntime). When the entity is ineligible the yield
becomes a complete no-op from scheduling perspective.
lost_exception_test calls sched_yield() 100,000 times per iteration to
race the EBB exception delivery with a context switch to the eat_cpu
companion process. After enough iterations the test process's vruntime
races ahead of avg_vruntime (each eligible yield bumps vruntime to
deadline, then advances deadline by one slice). Once ineligible,
yield_task_fair() does nothing: so the scheduler won't pick the
eat_cpu child. No context switch occurs, the PMAO race is never
triggered, and ebb_count stays at 0 forever causing the test to
hang until timeout.
Fix by replacing sched_yield() with nanosleep(0, 1ns). nanosleep() goes
through hrtimer_nanosleep() -> do_nanosleep(), which puts the task into
TASK_INTERRUPTIBLE and removes it from the run queue entirely. This
guarantees the scheduler picks the eat_cpu child, restoring the
context-switch guarantee the test requires. The 1ns duration is enough
to engage the hrtimer path while keeping the sleep effectively
instantaneous; the same race window between PMU overflow and context
switch is preserved.
Reported-by: Venkat Rao Bagalkote <redacted>
Signed-off-by: Athira Rajeev <redacted>
---Tested this by applying on top of todays mainline, and this patch fixes reported issue. Tested-by: Venkat Rao Bagalkote <redacted> # ./lost_exception_test test: lost_exception tags: git_version:v7.3-rc1-102-gdfad704d6abd Binding to cpu 8 main test running as pid 370267 EBB Handler is at 0x10005c60 ebb_state: ebb_count = 1017999 spurious = 0 negative = 0 no_overflow = 0 pmc[1] count = 0x0 pmc[2] count = 0x0 pmc[3] count = 0x0 pmc[4] count = 0x1a0b3f13 pmc[5] count = 0x0 pmc[6] count = 0x0 HW state: MMCR0 0x0000000084000000 FC PMAE MMCR2 0x0000000000000000 EBBHR 0x0000000010005c60 BESCR 0x8000000000000000 GE PMC1 0x0000000000000000 PMC2 0x0000000000000000 PMC3 0x0000000000000000 PMC4 0x000000000000dead PMC5 0x000000000000008a PMC6 0x0000000000000568 SIAR 0x0000000010005104 PMC4 count (0x1a0b3f13) is between 0x125318b2 and 0x1e37a62e delta +0x7b82661/-0x42c671b success: lost_exception Regards, Venkat.
quoted hunk ↗ jump to hunk
.../selftests/powerpc/pmu/ebb/lost_exception_test.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-)diff --git a/tools/testing/selftests/powerpc/pmu/ebb/lost_exception_test.c b/tools/testing/selftests/powerpc/pmu/ebb/lost_exception_test.c index ba2681a12cc7..9be5945f3b1f 100644 --- a/tools/testing/selftests/powerpc/pmu/ebb/lost_exception_test.c +++ b/tools/testing/selftests/powerpc/pmu/ebb/lost_exception_test.c@@ -8,6 +8,7 @@ #include <stdio.h> #include <stdlib.h> #include <sys/mman.h> +#include <time.h> #include "ebb.h"@@ -22,6 +23,7 @@ static int test_body(void) { int i, orig_period, max_period; struct event event; + struct timespec ts = { .tv_sec = 0, .tv_nsec = 1 }; SKIP_IF(!ebb_is_supported());@@ -57,10 +59,15 @@ static int test_body(void) * kernel to decide our timeslice is up and context switch to * the other thread. When we come back our EBB will have been * lost and we'll spin in this while loop forever. + * + * Use nanosleep(0) instead of sched_yield() to guarantee a + * context switch to the eat_cpu child regardless of the + * eligibility state. sched_yield() via yield_task_fair() may + * become a no-op when the task is ineligible (vruntime ahead + * of avg_vruntime), preventing the required context switch. */ - for (i = 0; i < 100000; i++) - sched_yield(); + nanosleep(&ts, NULL); /* Change the sample period slightly to try and hit the race */ if (sample_period >= (orig_period + 200))