[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 |