|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [PATCH] xen/sched: fix credit2 smt idle handling
Credit2's smt_idle_mask_set() and smt_idle_mask_clear() are used to
identify idle cores where vcpus can be moved to. A core is thought to
be idle when all siblings are known to have the idle vcpu running on
them.
Unfortunately the information of a vcpu running on a cpu is per
runqueue. So in case not all siblings are in the same runqueue a core
will never be regarded to be idle, as the sibling not in the runqueue
is never known to run the idle vcpu.
This problem can be solved by and-ing the core's sibling cpumask with
the runqueue's active mask before doing the idle test.
In order for not having to allocate another cpumask the interfaces of
smt_idle_mask_set() and smt_idle_mask_clear() are modified to not take
a mask as input, but the runqueue data pointer, as those functions are
always called with the same masks as parameters.
Signed-off-by: Juergen Gross <jgross@xxxxxxxx>
---
xen/common/sched_credit2.c | 35 ++++++++++++++++-------------------
1 file changed, 16 insertions(+), 19 deletions(-)
diff --git a/xen/common/sched_credit2.c b/xen/common/sched_credit2.c
index 543dc3664d..ab50e7ad23 100644
--- a/xen/common/sched_credit2.c
+++ b/xen/common/sched_credit2.c
@@ -638,7 +638,8 @@ static inline bool has_cap(const struct csched2_vcpu *svc)
/*
* If all the siblings of cpu (including cpu itself) are both idle and
- * untickled, set all their bits in mask.
+ * untickled, set all their bits in mask. Note that only siblings handled
+ * by the rqd can be taken into account.
*
* NB that rqd->smt_idle is different than rqd->idle. rqd->idle
* records pcpus that at are merely idle (i.e., at the moment do not
@@ -653,25 +654,23 @@ static inline bool has_cap(const struct csched2_vcpu *svc)
* changes.
*/
static inline
-void smt_idle_mask_set(unsigned int cpu, const cpumask_t *idlers,
- cpumask_t *mask)
+void smt_idle_mask_set(unsigned int cpu, struct csched2_runqueue_data *rqd)
{
- const cpumask_t *cpu_siblings = per_cpu(cpu_sibling_mask, cpu);
-
- if ( cpumask_subset(cpu_siblings, idlers) )
- cpumask_or(mask, mask, cpu_siblings);
+ cpumask_and(cpumask_scratch, per_cpu(cpu_sibling_mask, cpu), &rqd->active);
+ if ( cpumask_subset(cpumask_scratch, &rqd->idle) &&
+ !cpumask_intersects(cpumask_scratch, &rqd->tickled) )
+ cpumask_or(&rqd->smt_idle, &rqd->smt_idle, cpumask_scratch);
}
/*
* Clear the bits of all the siblings of cpu from mask (if necessary).
*/
static inline
-void smt_idle_mask_clear(unsigned int cpu, cpumask_t *mask)
+void smt_idle_mask_clear(unsigned int cpu, struct csched2_runqueue_data *rqd)
{
- const cpumask_t *cpu_siblings = per_cpu(cpu_sibling_mask, cpu);
-
- if ( cpumask_subset(cpu_siblings, mask) )
- cpumask_andnot(mask, mask, per_cpu(cpu_sibling_mask, cpu));
+ cpumask_and(cpumask_scratch, per_cpu(cpu_sibling_mask, cpu), &rqd->active);
+ if ( cpumask_subset(cpumask_scratch, &rqd->smt_idle) )
+ cpumask_andnot(&rqd->smt_idle, &rqd->smt_idle, cpumask_scratch);
}
/*
@@ -1323,7 +1322,7 @@ static inline void
tickle_cpu(unsigned int cpu, struct csched2_runqueue_data *rqd)
{
__cpumask_set_cpu(cpu, &rqd->tickled);
- smt_idle_mask_clear(cpu, &rqd->smt_idle);
+ smt_idle_mask_clear(cpu, rqd);
cpu_raise_softirq(cpu, SCHEDULE_SOFTIRQ);
}
@@ -3468,8 +3467,7 @@ csched2_schedule(
if ( tickled )
{
__cpumask_clear_cpu(cpu, &rqd->tickled);
- cpumask_andnot(cpumask_scratch, &rqd->idle, &rqd->tickled);
- smt_idle_mask_set(cpu, cpumask_scratch, &rqd->smt_idle);
+ smt_idle_mask_set(cpu, rqd);
}
if ( unlikely(tb_init_done) )
@@ -3553,7 +3551,7 @@ csched2_schedule(
if ( cpumask_test_cpu(cpu, &rqd->idle) )
{
__cpumask_clear_cpu(cpu, &rqd->idle);
- smt_idle_mask_clear(cpu, &rqd->smt_idle);
+ smt_idle_mask_clear(cpu, rqd);
}
/*
@@ -3599,14 +3597,13 @@ csched2_schedule(
if ( cpumask_test_cpu(cpu, &rqd->idle) )
{
__cpumask_clear_cpu(cpu, &rqd->idle);
- smt_idle_mask_clear(cpu, &rqd->smt_idle);
+ smt_idle_mask_clear(cpu, rqd);
}
}
else if ( !cpumask_test_cpu(cpu, &rqd->idle) )
{
__cpumask_set_cpu(cpu, &rqd->idle);
- cpumask_andnot(cpumask_scratch, &rqd->idle, &rqd->tickled);
- smt_idle_mask_set(cpu, cpumask_scratch, &rqd->smt_idle);
+ smt_idle_mask_set(cpu, rqd);
}
/* Make sure avgload gets updated periodically even
* if there's no activity */
--
2.16.4
_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxxx
https://lists.xenproject.org/mailman/listinfo/xen-devel
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |