Thread (2 messages) flat view 2 messages, 2 authors, 3d ago

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))
  
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help