From patchwork Fri Aug 9 14:58:16 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: =?utf-8?b?SsO8cmdlbiBHcm/Dnw==?= X-Patchwork-Id: 11086629 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id A0596746 for ; Fri, 9 Aug 2019 15:00:08 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 8D0E01FF29 for ; Fri, 9 Aug 2019 15:00:08 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 80D581FFBD; Fri, 9 Aug 2019 15:00:08 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-5.2 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_MED autolearn=ham version=3.3.1 Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) (using TLSv1.2 with cipher AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id C9EBF1FFFF for ; Fri, 9 Aug 2019 15:00:02 +0000 (UTC) Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.89) (envelope-from ) id 1hw6MI-00079v-Cx; Fri, 09 Aug 2019 14:59:10 +0000 Received: from us1-rack-dfw2.inumbo.com ([104.130.134.6]) by lists.xenproject.org with esmtp (Exim 4.89) (envelope-from ) id 1hw6M3-0006dm-Fr for xen-devel@lists.xenproject.org; Fri, 09 Aug 2019 14:58:55 +0000 X-Inumbo-ID: 32095c19-bab6-11e9-8980-bc764e045a96 Received: from mx1.suse.de (unknown [195.135.220.15]) by us1-rack-dfw2.inumbo.com (Halon) with ESMTPS id 32095c19-bab6-11e9-8980-bc764e045a96; Fri, 09 Aug 2019 14:58:50 +0000 (UTC) X-Virus-Scanned: by amavisd-new at test-mx.suse.de Received: from relay2.suse.de (unknown [195.135.220.254]) by mx1.suse.de (Postfix) with ESMTP id 12AAAB016; Fri, 9 Aug 2019 14:58:49 +0000 (UTC) From: Juergen Gross To: xen-devel@lists.xenproject.org Date: Fri, 9 Aug 2019 16:58:16 +0200 Message-Id: <20190809145833.1020-32-jgross@suse.com> X-Mailer: git-send-email 2.16.4 In-Reply-To: <20190809145833.1020-1-jgross@suse.com> References: <20190809145833.1020-1-jgross@suse.com> Subject: [Xen-devel] [PATCH v2 31/48] xen/sched: add support for multiple vcpus per sched unit where missing X-BeenThere: xen-devel@lists.xenproject.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Cc: Juergen Gross , Stefano Stabellini , Wei Liu , Konrad Rzeszutek Wilk , George Dunlap , Andrew Cooper , Ian Jackson , Tim Deegan , Julien Grall , Jan Beulich , Dario Faggioli MIME-Version: 1.0 Errors-To: xen-devel-bounces@lists.xenproject.org Sender: "Xen-devel" X-Virus-Scanned: ClamAV using ClamSMTP In several places there is support for multiple vcpus per sched unit missing. Add that missing support (with the exception of initial allocation) and missing helpers for that. Signed-off-by: Juergen Gross --- RFC V2: - fix vcpu_runstate_helper() V1: - add special handling for idle unit in unit_runnable() and unit_runnable_state() V2: - handle affinity_broken correctly (Jan Beulich) --- xen/common/domain.c | 5 ++- xen/common/schedule.c | 36 ++++++++++--------- xen/include/xen/sched-if.h | 88 +++++++++++++++++++++++++++++++++++++--------- 3 files changed, 95 insertions(+), 34 deletions(-) diff --git a/xen/common/domain.c b/xen/common/domain.c index 3797f954f5..0c763ceb25 100644 --- a/xen/common/domain.c +++ b/xen/common/domain.c @@ -1255,7 +1255,10 @@ int vcpu_reset(struct vcpu *v) v->async_exception_mask = 0; memset(v->async_exception_state, 0, sizeof(v->async_exception_state)); #endif - v->affinity_broken = 0; + if ( v->affinity_broken & VCPU_AFFINITY_OVERRIDE ) + vcpu_temporary_affinity(v, NR_CPUS, VCPU_AFFINITY_OVERRIDE); + if ( v->affinity_broken & VCPU_AFFINITY_WAIT ) + vcpu_temporary_affinity(v, NR_CPUS, VCPU_AFFINITY_WAIT); clear_bit(_VPF_blocked, &v->pause_flags); clear_bit(_VPF_in_reset, &v->pause_flags); diff --git a/xen/common/schedule.c b/xen/common/schedule.c index 2ecb76e3b9..1f45fc7373 100644 --- a/xen/common/schedule.c +++ b/xen/common/schedule.c @@ -240,8 +240,9 @@ static inline void vcpu_runstate_change( s_time_t delta; struct sched_unit *unit = v->sched_unit; - ASSERT(v->runstate.state != new_state); ASSERT(spin_is_locked(get_sched_res(v->processor)->schedule_lock)); + if ( v->runstate.state == new_state ) + return; vcpu_urgent_count_update(v); @@ -263,15 +264,16 @@ static inline void vcpu_runstate_change( static inline void sched_unit_runstate_change(struct sched_unit *unit, bool running, s_time_t new_entry_time) { - struct vcpu *v = unit->vcpu_list; + struct vcpu *v; - if ( running ) - vcpu_runstate_change(v, v->new_state, new_entry_time); - else - vcpu_runstate_change(v, - ((v->pause_flags & VPF_blocked) ? RUNSTATE_blocked : - (vcpu_runnable(v) ? RUNSTATE_runnable : RUNSTATE_offline)), - new_entry_time); + for_each_sched_unit_vcpu ( unit, v ) + if ( running ) + vcpu_runstate_change(v, v->new_state, new_entry_time); + else + vcpu_runstate_change(v, + ((v->pause_flags & VPF_blocked) ? RUNSTATE_blocked : + (vcpu_runnable(v) ? RUNSTATE_runnable : RUNSTATE_offline)), + new_entry_time); } void vcpu_runstate_get(struct vcpu *v, struct vcpu_runstate_info *runstate) @@ -1035,9 +1037,9 @@ int cpu_disable_scheduler(unsigned int cpu) if ( cpumask_empty(&online_affinity) && cpumask_test_cpu(cpu, unit->cpu_hard_affinity) ) { - if ( unit->vcpu_list->affinity_broken ) + if ( sched_check_affinity_broken(unit) ) { - /* The vcpu is temporarily pinned, can't move it. */ + /* The unit is temporarily pinned, can't move it. */ unit_schedule_unlock_irqrestore(lock, flags, unit); ret = -EADDRINUSE; break; @@ -1395,17 +1397,17 @@ int vcpu_temporary_affinity(struct vcpu *v, unsigned int cpu, uint8_t reason) ret = 0; v->affinity_broken &= ~reason; } - if ( !ret && !v->affinity_broken ) + if ( !ret && !sched_check_affinity_broken(unit) ) sched_set_affinity(v, unit->cpu_hard_affinity_saved, NULL); } else if ( cpu < nr_cpu_ids ) { if ( (v->affinity_broken & reason) || - (v->affinity_broken && v->processor != cpu) ) + (sched_check_affinity_broken(unit) && v->processor != cpu) ) ret = -EBUSY; else if ( cpumask_test_cpu(cpu, VCPU2ONLINE(v)) ) { - if ( !v->affinity_broken ) + if ( !sched_check_affinity_broken(unit) ) { cpumask_copy(unit->cpu_hard_affinity_saved, unit->cpu_hard_affinity); @@ -1701,14 +1703,14 @@ static void sched_switch_units(struct sched_resource *sd, (next->vcpu_list->runstate.state == RUNSTATE_runnable) ? (now - next->state_entry_time) : 0, prev->next_time); - ASSERT(prev->vcpu_list->runstate.state == RUNSTATE_running); + ASSERT(unit_running(prev)); TRACE_4D(TRC_SCHED_SWITCH, prev->domain->domain_id, prev->unit_id, next->domain->domain_id, next->unit_id); sched_unit_runstate_change(prev, false, now); - ASSERT(next->vcpu_list->runstate.state != RUNSTATE_running); + ASSERT(!unit_running(next)); sched_unit_runstate_change(next, true, now); /* @@ -1829,7 +1831,7 @@ void sched_context_switched(struct vcpu *vprev, struct vcpu *vnext) while ( atomic_read(&next->rendezvous_out_cnt) ) cpu_relax(); } - else if ( vprev != vnext ) + else if ( vprev != vnext && sched_granularity == 1 ) context_saved(vprev); } diff --git a/xen/include/xen/sched-if.h b/xen/include/xen/sched-if.h index aa896f49ef..e1d61a05b7 100644 --- a/xen/include/xen/sched-if.h +++ b/xen/include/xen/sched-if.h @@ -67,32 +67,70 @@ static inline bool is_idle_unit(const struct sched_unit *unit) static inline bool is_unit_online(const struct sched_unit *unit) { - return is_vcpu_online(unit->vcpu_list); + struct vcpu *v; + + for_each_sched_unit_vcpu ( unit, v ) + if ( is_vcpu_online(v) ) + return true; + + return false; +} + +static inline unsigned int unit_running(const struct sched_unit *unit) +{ + return unit->runstate_cnt[RUNSTATE_running]; } static inline bool unit_runnable(const struct sched_unit *unit) { - return vcpu_runnable(unit->vcpu_list); + struct vcpu *v; + + if ( is_idle_unit(unit) ) + return true; + + for_each_sched_unit_vcpu ( unit, v ) + if ( vcpu_runnable(v) ) + return true; + + return false; } static inline bool unit_runnable_state(const struct sched_unit *unit) { struct vcpu *v; - bool runnable; + bool runnable, ret = false; + + if ( is_idle_unit(unit) ) + return true; + + for_each_sched_unit_vcpu ( unit, v ) + { + runnable = vcpu_runnable(v); + + v->new_state = runnable ? RUNSTATE_running + : (v->pause_flags & VPF_blocked) + ? RUNSTATE_blocked : RUNSTATE_offline; - v = unit->vcpu_list; - runnable = vcpu_runnable(v); + if ( runnable ) + ret = true; + } - v->new_state = runnable ? RUNSTATE_running - : (v->pause_flags & VPF_blocked) - ? RUNSTATE_blocked : RUNSTATE_offline; - return runnable; + return ret; } static inline void sched_set_res(struct sched_unit *unit, struct sched_resource *res) { - unit->vcpu_list->processor = res->processor; + int cpu = cpumask_first(res->cpus); + struct vcpu *v; + + for_each_sched_unit_vcpu ( unit, v ) + { + ASSERT(cpu < nr_cpu_ids); + v->processor = cpu; + cpu = cpumask_next(cpu, res->cpus); + } + unit->res = res; } @@ -104,25 +142,37 @@ static inline unsigned int sched_unit_cpu(struct sched_unit *unit) static inline void sched_set_pause_flags(struct sched_unit *unit, unsigned int bit) { - __set_bit(bit, &unit->vcpu_list->pause_flags); + struct vcpu *v; + + for_each_sched_unit_vcpu ( unit, v ) + __set_bit(bit, &v->pause_flags); } static inline void sched_clear_pause_flags(struct sched_unit *unit, unsigned int bit) { - __clear_bit(bit, &unit->vcpu_list->pause_flags); + struct vcpu *v; + + for_each_sched_unit_vcpu ( unit, v ) + __clear_bit(bit, &v->pause_flags); } static inline void sched_set_pause_flags_atomic(struct sched_unit *unit, unsigned int bit) { - set_bit(bit, &unit->vcpu_list->pause_flags); + struct vcpu *v; + + for_each_sched_unit_vcpu ( unit, v ) + set_bit(bit, &v->pause_flags); } static inline void sched_clear_pause_flags_atomic(struct sched_unit *unit, unsigned int bit) { - clear_bit(bit, &unit->vcpu_list->pause_flags); + struct vcpu *v; + + for_each_sched_unit_vcpu ( unit, v ) + clear_bit(bit, &v->pause_flags); } static inline struct sched_unit *sched_idle_unit(unsigned int cpu) @@ -448,12 +498,18 @@ static inline int sched_adjust_cpupool(const struct scheduler *s, static inline void sched_unit_pause_nosync(struct sched_unit *unit) { - vcpu_pause_nosync(unit->vcpu_list); + struct vcpu *v; + + for_each_sched_unit_vcpu ( unit, v ) + vcpu_pause_nosync(v); } static inline void sched_unit_unpause(struct sched_unit *unit) { - vcpu_unpause(unit->vcpu_list); + struct vcpu *v; + + for_each_sched_unit_vcpu ( unit, v ) + vcpu_unpause(v); } #define REGISTER_SCHEDULER(x) static const struct scheduler *x##_entry \