Now that we have the information about which cores are fully idle, use it for tickling pcpus.
This way, if there are cores that are fully idle, we tickle a pcpu from one of them. This improve the SMT-awareness of the scheduler, guaranteeing a better distribution of load, right from vcpu wakeup. Signed-off-by: Dario Faggioli <dfaggi...@suse.com> --- Cc: George Dunlap <george.dun...@eu.citrix.com> --- xen/common/sched_credit.c | 51 +++++++++++++++++++++++++++------------------ 1 file changed, 31 insertions(+), 20 deletions(-) diff --git a/xen/common/sched_credit.c b/xen/common/sched_credit.c index c7ee85d56a..af3b81d377 100644 --- a/xen/common/sched_credit.c +++ b/xen/common/sched_credit.c @@ -424,6 +424,15 @@ static inline void __runq_tickle(struct csched_vcpu *new) cpumask_scratch_cpu(cpu)); cpumask_and(cpumask_scratch_cpu(cpu), cpumask_scratch_cpu(cpu), &idle_mask); + + /* Let's check fully idle cores first. */ + if ( cpumask_intersects(cpumask_scratch_cpu(cpu), prv->smt_idle) ) + { + cpumask_and(&mask, cpumask_scratch_cpu(cpu), prv->smt_idle); + break; + } + + /* Now, let's check all idlers. */ new_idlers_empty = cpumask_empty(cpumask_scratch_cpu(cpu)); /* @@ -441,11 +450,6 @@ static inline void __runq_tickle(struct csched_vcpu *new) * We have to do it indirectly, via _VPF_migrating (instead * of just tickling any idler suitable for cur) because cur * is running. - * - * If there are suitable idlers for new, no matter priorities, - * leave cur alone (as it is running and is, likely, cache-hot) - * and wake some of them (which is waking up and so is, likely, - * cache cold anyway). */ if ( new_idlers_empty && new->pri > cur->pri ) { @@ -460,23 +464,19 @@ static inline void __runq_tickle(struct csched_vcpu *new) /* Tickle cpu anyway, to let new preempt cur. */ SCHED_STAT_CRANK(tickled_busy_cpu); __cpumask_set_cpu(cpu, &mask); + goto tickle; } - else if ( !new_idlers_empty ) + + /* + * If there are suitable idlers for new, no matter priorities, + * leave cur alone (as it is running and is, likely, cache-hot) + * and wake some of them (which is waking up and so is, likely, + * cache cold anyway). + */ + if ( !new_idlers_empty ) { - /* Which of the idlers suitable for new shall we wake up? */ SCHED_STAT_CRANK(tickled_idle_cpu); - if ( opt_tickle_one_idle ) - { - if ( cpumask_test_cpu(cpu, cpumask_scratch_cpu(cpu)) ) - this_cpu(last_tickle_cpu) = cpu; - else - this_cpu(last_tickle_cpu) = - cpumask_cycle(this_cpu(last_tickle_cpu), - cpumask_scratch_cpu(cpu)); - __cpumask_set_cpu(this_cpu(last_tickle_cpu), &mask); - } - else - cpumask_or(&mask, &mask, cpumask_scratch_cpu(cpu)); + cpumask_or(&mask, &mask, cpumask_scratch_cpu(cpu)); } /* Did we find anyone? */ @@ -485,9 +485,20 @@ static inline void __runq_tickle(struct csched_vcpu *new) } } - tickle: if ( !cpumask_empty(&mask) ) { + /* Which of the idlers suitable for new shall we wake up? */ + if ( opt_tickle_one_idle ) + { + if ( cpumask_test_cpu(cpu, &mask) ) + this_cpu(last_tickle_cpu) = cpu; + else + this_cpu(last_tickle_cpu) = + cpumask_cycle(this_cpu(last_tickle_cpu), &mask); + cpumask_copy(&mask, cpumask_of(this_cpu(last_tickle_cpu))); + } + + tickle: if ( unlikely(tb_init_done) ) { /* Avoid TRACE_*: saves checking !tb_init_done each step */ _______________________________________________ Xen-devel mailing list Xen-devel@lists.xenproject.org https://lists.xenproject.org/mailman/listinfo/xen-devel