mirror of
https://github.com/torvalds/linux.git
synced 2026-09-14 16:10:02 +02:00
selftests/powerpc/pmu/ebb: fix lost_exception_test hang with sched yield change
commit 79104becf4 ("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 <venkat88@linux.ibm.com>
Signed-off-by: Athira Rajeev <atrajeev@linux.ibm.com>
Tested-by: Venkat Rao Bagalkote <venkat88@linux.ibm.com>
Signed-off-by: Madhavan Srinivasan <maddy@linux.ibm.com>
Link: https://patch.msgid.link/20260903074036.63309-1-atrajeev@linux.ibm.com
This commit is contained in:
parent
11ae2e1dc5
commit
ef17515a8e
|
|
@ -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))
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user