|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [PATCH] xen/credit: Uncount units dropped by csched_schedule()
csched_schedule() takes snext off the runq without decrementing
nr_runnable, as it is about to run. A unit that stops being runnable
is normally removed and uncounted by csched_unit_sleep(), but if the
pick loop drops it first, the sleep finds nothing to do and the unit
stays counted:
CPU A CPU B
domain_pause() csched_schedule(), lock held
atomic_inc(&d->pause_count)
__runq_remove(snext)
vcpu_sleep_sync() !unit_runnable_state(): drop
waits for lock unlock
csched_unit_sleep()
not running, not queued:
nothing to do
domain_unpause()
vcpu_wake()
runq_insert() nr_runnable +1 again
Decrement nr_runnable when dropping the unit.
Fixes: 7c7b407e7772 ("xen/sched: introduce unit_runnable_state()")
Reported-by: Bengang Yuan <bengang.yuan@xxxxxxxxxx>
Assisted-by: Claude:claude-opus-5-5
Signed-off-by: Lin Liu <lin.liu01@xxxxxxxxxx>
---
xen/common/sched/credit.c | 10 ++++++++--
1 file changed, 8 insertions(+), 2 deletions(-)
diff --git a/xen/common/sched/credit.c b/xen/common/sched/credit.c
index 8df746bf6b..f1a9b4aed1 100644
--- a/xen/common/sched/credit.c
+++ b/xen/common/sched/credit.c
@@ -1965,7 +1965,8 @@ static void cf_check csched_schedule(
dec_nr_runnable(sched_cpu);
}
- do {
+ for ( ; ; )
+ {
snext = __runq_elem(runq->next);
/* Tasklet work (which runs in idle UNIT context) overrides all else.
*/
@@ -1993,7 +1994,12 @@ static void cf_check csched_schedule(
else
__runq_remove(snext);
- } while ( !unit_runnable_state(snext->unit) );
+ if ( unit_runnable_state(snext->unit) )
+ break;
+
+ /* Dropped snext is off the runq but still counted: uncount it. */
+ dec_nr_runnable(sched_cpu);
+ }
/*
* Update idlers mask if necessary. When we're idling, other CPUs
--
2.52.0
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |