From patchwork Fri Aug 9 14:58:26 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: 11086691 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 079701709 for ; Fri, 9 Aug 2019 15:00:43 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id EA92B1FFBD for ; Fri, 9 Aug 2019 15:00:42 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id E8FB01FFD8; Fri, 9 Aug 2019 15:00:42 +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 B7FE31FFBD for ; Fri, 9 Aug 2019 15:00:41 +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 1hw6MQ-0007SR-CX; Fri, 09 Aug 2019 14:59:18 +0000 Received: from all-amaz-eas1.inumbo.com ([34.197.232.57] helo=us1-amaz-eas2.inumbo.com) by lists.xenproject.org with esmtp (Exim 4.89) (envelope-from ) id 1hw6M5-0006hp-LY for xen-devel@lists.xenproject.org; Fri, 09 Aug 2019 14:58:57 +0000 X-Inumbo-ID: 33e2c9d2-bab6-11e9-a3d6-8bce01c347c5 Received: from mx1.suse.de (unknown [195.135.220.15]) by us1-amaz-eas2.inumbo.com (Halon) with ESMTPS id 33e2c9d2-bab6-11e9-a3d6-8bce01c347c5; Fri, 09 Aug 2019 14:58:53 +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 9A21CB03C; Fri, 9 Aug 2019 14:58:52 +0000 (UTC) From: Juergen Gross To: xen-devel@lists.xenproject.org Date: Fri, 9 Aug 2019 16:58:26 +0200 Message-Id: <20190809145833.1020-42-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 41/48] xen/sched: prepare per-cpupool scheduling granularity 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 On- and offlining cpus with core scheduling is rather complicated as the cpus are taken on- or offline one by one, but scheduling wants them rather to be handled per core. As the future plan is to be able to select scheduling granularity per cpupool prepare that by storing the granularity in struct cpupool and struct sched_resource (we need it there for free cpus which are not associated to any cpupool). Free cpus will always use granularity 1. Store the selected granularity option (cpu, core or socket) in the cpupool as well, as we will need it to select the appropriate cpu mask when populating the cpupool with cpus. This will make on- and offlining of cpus much easier and avoids writing code which would needed to be thrown away later. Signed-off-by: Juergen Gross --- V1: new patch --- xen/common/cpupool.c | 2 ++ xen/common/schedule.c | 23 +++++++++++++++-------- xen/include/xen/sched-if.h | 12 ++++++++++++ 3 files changed, 29 insertions(+), 8 deletions(-) diff --git a/xen/common/cpupool.c b/xen/common/cpupool.c index bace684464..8789fde3c4 100644 --- a/xen/common/cpupool.c +++ b/xen/common/cpupool.c @@ -177,6 +177,8 @@ static struct cpupool *cpupool_create( return NULL; } } + c->granularity = sched_granularity; + c->opt_granularity = opt_sched_granularity; *q = c; diff --git a/xen/common/schedule.c b/xen/common/schedule.c index b94fd2431a..7823b48e32 100644 --- a/xen/common/schedule.c +++ b/xen/common/schedule.c @@ -56,7 +56,8 @@ int sched_ratelimit_us = SCHED_DEFAULT_RATELIMIT_US; integer_param("sched_ratelimit_us", sched_ratelimit_us); /* Number of vcpus per struct sched_unit. */ -static unsigned int __read_mostly sched_granularity = 1; +enum sched_gran __read_mostly opt_sched_granularity = SCHED_GRAN_cpu; +unsigned int __read_mostly sched_granularity = 1; bool __read_mostly sched_disable_smt_switching; const cpumask_t *sched_res_mask = &cpumask_all; @@ -409,10 +410,10 @@ static struct sched_unit *sched_alloc_unit(struct vcpu *v) { struct sched_unit *unit, **prev_unit; struct domain *d = v->domain; + unsigned int gran = d->cpupool ? d->cpupool->granularity : 1; for_each_sched_unit ( d, unit ) - if ( unit->vcpu_list->vcpu_id / sched_granularity == - v->vcpu_id / sched_granularity ) + if ( unit->vcpu_list->vcpu_id / gran == v->vcpu_id / gran ) break; if ( unit ) @@ -1805,11 +1806,11 @@ static void sched_switch_units(struct sched_resource *sd, if ( is_idle_unit(prev) ) { prev->runstate_cnt[RUNSTATE_running] = 0; - prev->runstate_cnt[RUNSTATE_runnable] = sched_granularity; + prev->runstate_cnt[RUNSTATE_runnable] = sd->granularity; } if ( is_idle_unit(next) ) { - next->runstate_cnt[RUNSTATE_running] = sched_granularity; + next->runstate_cnt[RUNSTATE_running] = sd->granularity; next->runstate_cnt[RUNSTATE_runnable] = 0; } } @@ -2072,11 +2073,12 @@ static struct sched_unit *sched_wait_rendezvous_in(struct sched_unit *prev, { struct sched_unit *next; struct vcpu *v; + unsigned int gran = get_sched_res(cpu)->granularity; if ( !--prev->rendezvous_in_cnt ) { next = do_schedule(prev, now, cpu); - atomic_set(&next->rendezvous_out_cnt, sched_granularity + 1); + atomic_set(&next->rendezvous_out_cnt, gran + 1); return next; } @@ -2196,6 +2198,7 @@ static void schedule(void) struct sched_resource *sd; spinlock_t *lock; int cpu = smp_processor_id(); + unsigned int gran = get_sched_res(cpu)->granularity; ASSERT_NOT_IN_ATOMIC(); @@ -2221,11 +2224,11 @@ static void schedule(void) stop_timer(&sd->s_timer); - if ( sched_granularity > 1 ) + if ( gran > 1 ) { cpumask_t mask; - prev->rendezvous_in_cnt = sched_granularity; + prev->rendezvous_in_cnt = gran; cpumask_andnot(&mask, sd->cpus, cpumask_of(cpu)); cpumask_raise_softirq(&mask, SCHED_SLAVE_SOFTIRQ); next = sched_wait_rendezvous_in(prev, &lock, cpu, now); @@ -2291,6 +2294,9 @@ static int cpu_schedule_up(unsigned int cpu) init_timer(&sd->s_timer, s_timer_fn, NULL, cpu); atomic_set(&sd->urgent_count, 0); + /* We start with cpu granularity. */ + sd->granularity = 1; + /* Boot CPU is dealt with later in scheduler_init(). */ if ( cpu == 0 ) return 0; @@ -2581,6 +2587,7 @@ int schedule_cpu_switch(unsigned int cpu, struct cpupool *c) sched_free_vdata(old_ops, vpriv_old); sched_free_pdata(old_ops, ppriv_old, cpu); + get_sched_res(cpu)->granularity = c ? c->granularity : 1; get_sched_res(cpu)->cpupool = c; /* When a cpu is added to a pool, trigger it to go pick up some work */ if ( c != NULL ) diff --git a/xen/include/xen/sched-if.h b/xen/include/xen/sched-if.h index 73b19a2763..606a0d4a25 100644 --- a/xen/include/xen/sched-if.h +++ b/xen/include/xen/sched-if.h @@ -25,6 +25,15 @@ extern int sched_ratelimit_us; /* Scheduling resource mask. */ extern const cpumask_t *sched_res_mask; +/* Number of vcpus per struct sched_unit. */ +enum sched_gran { + SCHED_GRAN_cpu, + SCHED_GRAN_core, + SCHED_GRAN_socket +}; +extern enum sched_gran opt_sched_granularity; +extern unsigned int sched_granularity; + /* * In order to allow a scheduler to remap the lock->cpu mapping, * we have a per-cpu pointer, along with a pre-allocated set of @@ -47,6 +56,7 @@ struct sched_resource { struct timer s_timer; /* scheduling timer */ atomic_t urgent_count; /* how many urgent vcpus */ unsigned int processor; + unsigned int granularity; const cpumask_t *cpus; /* cpus covered by this struct */ }; @@ -531,6 +541,8 @@ struct cpupool struct cpupool *next; struct scheduler *sched; atomic_t refcnt; + unsigned int granularity; + enum sched_gran opt_granularity; }; #define cpupool_online_cpumask(_pool) \