From patchwork Tue May 28 10:32:50 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: 10964593 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 55878112C for ; Tue, 28 May 2019 10:34:37 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 43D9227D16 for ; Tue, 28 May 2019 10:34:37 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 3833328755; Tue, 28 May 2019 10:34:37 +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 AB94A27D16 for ; Tue, 28 May 2019 10:34:36 +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 1hVZQS-0005MQ-4n; Tue, 28 May 2019 10:33:48 +0000 Received: from us1-rack-dfw2.inumbo.com ([104.130.134.6]) by lists.xenproject.org with esmtp (Exim 4.89) (envelope-from ) id 1hVZQA-0004kh-Ad for xen-devel@lists.xenproject.org; Tue, 28 May 2019 10:33:30 +0000 X-Inumbo-ID: 06f4d7dd-8134-11e9-8980-bc764e045a96 Received: from mx1.suse.de (unknown [195.135.220.15]) by us1-rack-dfw2.inumbo.com (Halon) with ESMTPS id 06f4d7dd-8134-11e9-8980-bc764e045a96; Tue, 28 May 2019 10:33:27 +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 5358CB04F; Tue, 28 May 2019 10:33:26 +0000 (UTC) From: Juergen Gross To: xen-devel@lists.xenproject.org Date: Tue, 28 May 2019 12:32:50 +0200 Message-Id: <20190528103313.1343-38-jgross@suse.com> X-Mailer: git-send-email 2.16.4 In-Reply-To: <20190528103313.1343-1-jgross@suse.com> References: <20190528103313.1343-1-jgross@suse.com> Subject: [Xen-devel] [PATCH 37/60] 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 , Tim Deegan , Stefano Stabellini , Wei Liu , Konrad Rzeszutek Wilk , George Dunlap , Andrew Cooper , Ian Jackson , Dario Faggioli , Julien Grall , Jan Beulich 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() --- xen/common/schedule.c | 26 ++++++++------- xen/include/xen/sched-if.h | 80 +++++++++++++++++++++++++++++++++++++--------- 2 files changed, 79 insertions(+), 27 deletions(-) diff --git a/xen/common/schedule.c b/xen/common/schedule.c index 352803622d..a4dbc19403 100644 --- a/xen/common/schedule.c +++ b/xen/common/schedule.c @@ -180,8 +180,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); @@ -203,15 +204,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; + 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) @@ -1590,7 +1592,7 @@ static void sched_switch_units(struct sched_resource *sd, (next->vcpu->runstate.state == RUNSTATE_runnable) ? (now - next->state_entry_time) : 0, prev->next_time); - ASSERT(prev->vcpu->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); @@ -1598,7 +1600,7 @@ static void sched_switch_units(struct sched_resource *sd, sched_unit_runstate_change(prev, false, now); prev->last_run_time = now; - ASSERT(next->vcpu->runstate.state != RUNSTATE_running); + ASSERT(!unit_running(next)); sched_unit_runstate_change(next, true, now); /* @@ -1720,7 +1722,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 805cefaa07..98d4dc65e2 100644 --- a/xen/include/xen/sched-if.h +++ b/xen/include/xen/sched-if.h @@ -65,29 +65,61 @@ static inline bool is_idle_unit(const struct sched_unit *unit) return is_idle_vcpu(unit->vcpu); } +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); + 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; - v = unit->vcpu; - runnable = vcpu_runnable(v); + if ( is_idle_unit(unit) ) + return true; - v->new_state = runnable ? RUNSTATE_running - : (v->pause_flags & VPF_blocked) - ? RUNSTATE_blocked : RUNSTATE_offline; - return runnable; + 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; + + if ( runnable ) + ret = true; + } + + return ret; } static inline void sched_set_res(struct sched_unit *unit, struct sched_resource *res) { - unit->vcpu->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; } @@ -99,25 +131,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->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->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->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->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) @@ -443,12 +487,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); + 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); + struct vcpu *v; + + for_each_sched_unit_vcpu ( unit, v ) + vcpu_unpause(v); } #define REGISTER_SCHEDULER(x) static const struct scheduler *x##_entry \