From patchwork Fri Sep 30 14:21:27 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dario Faggioli X-Patchwork-Id: 9358345 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 8248C6077B for ; Fri, 30 Sep 2016 14:23:48 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 72AD92A05F for ; Fri, 30 Sep 2016 14:23:48 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 670882A062; Fri, 30 Sep 2016 14:23:48 +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=-3.6 required=2.0 tests=BAYES_00,DKIM_SIGNED, RCVD_IN_DNSWL_MED,RCVD_IN_SORBS_SPAM,T_DKIM_INVALID autolearn=ham version=3.3.1 Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) (using TLSv1.2 with cipher AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 345A02A05F for ; Fri, 30 Sep 2016 14:23:45 +0000 (UTC) Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.84_2) (envelope-from ) id 1bpygv-000371-FI; Fri, 30 Sep 2016 14:21:33 +0000 Received: from mail6.bemta3.messagelabs.com ([195.245.230.39]) by lists.xenproject.org with esmtp (Exim 4.84_2) (envelope-from ) id 1bpygt-00036j-RN for xen-devel@lists.xenproject.org; Fri, 30 Sep 2016 14:21:31 +0000 Received: from [85.158.137.68] by server-13.bemta-3.messagelabs.com id B0/6A-06162-BE47EE75; Fri, 30 Sep 2016 14:21:31 +0000 X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFmplleJIrShJLcpLzFFi42Lxqg1y0n1V8i7 c4OUkTovvWyYzOTB6HP5whSWAMYo1My8pvyKBNWPSrEuMBe0WFX/2rWdsYLyk3cXIxSEkMINR 4kLDfBYQh0VgDatEy7FVbCCOhMAlVom1d3cwdTFyAjkxEqtWz2SHsMskTv9bCmYLCahI3Ny+i gli1G9Giakbp4ElhAX0JI4c/QFlm0ucODEZzGYTMJB4s2MvK4gtIqAkcW/VZLBmZoHljBLzJh 1hBEmwCKhKrJl/B6yIV8BbYt3T3ywgNqeAj8SLzSDNHEDbvCXO7DMDCYsKyEmsvNwCVS4ocXL mExaQEmYBTYn1u/RBwswC8hLb385hnsAoMgtJ1SyEqllIqhYwMq9i1ChOLSpLLdI1stBLKspM zyjJTczM0TU0MNbLTS0uTkxPzUlMKtZLzs/dxAiMgHoGBsYdjO0n/A4xSnIwKYnyyh59Gy7El 5SfUpmRWJwRX1Sak1p8iFGDg0Ngwtm505mkWPLy81KVJHjvFL8LFxIsSk1PrUjLzAHGKEypBA ePkgivIEiat7ggMbc4Mx0idYrRmGPL1HtrmTiW7HqwlkkIbJKUOG8/SKkASGlGaR7cIFjquMQ oKyXMy8jAwCDEU5BalJtZgir/ilGcg1FJmJcdmIiEeDLzSuD2vQI6hQnolPyjb0BOKUlESEk1 MBarrj6xxfk9E9NpvnW/WGbvzQq6sW99sUzAhRz1tAUf5ikyNR4J/BAnkrO+IZErZc1iFmFh/ XnCAkd6zvxYtWib0xPG1FsLGeUT813MlG51/T1V9und95R/+3ey+0p3WK5jls7P011VuYd72u clMUs2fr66JOzpL8MVE5yTrvCfOFrp0GNxXEiJpTgj0VCLuag4EQBKOn7fGAMAAA== X-Env-Sender: raistlin.df@gmail.com X-Msg-Ref: server-13.tower-31.messagelabs.com!1475245289!63173860!1 X-Originating-IP: [74.125.82.66] X-SpamReason: No, hits=0.5 required=7.0 tests=BODY_RANDOM_LONG X-StarScan-Received: X-StarScan-Version: 8.84; banners=-,-,- X-VirusChecked: Checked Received: (qmail 4365 invoked from network); 30 Sep 2016 14:21:29 -0000 Received: from mail-wm0-f66.google.com (HELO mail-wm0-f66.google.com) (74.125.82.66) by server-13.tower-31.messagelabs.com with AES128-GCM-SHA256 encrypted SMTP; 30 Sep 2016 14:21:29 -0000 Received: by mail-wm0-f66.google.com with SMTP id p138so3691319wmb.0 for ; Fri, 30 Sep 2016 07:21:29 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=sender:subject:from:to:cc:date:message-id:in-reply-to:references :user-agent:mime-version:content-transfer-encoding; bh=P3fYMsm86d+R72DkSOWxAIohyhedlH08ue4wRprUIXE=; b=Z5Gk5BveylLV+263F54By8sbndv57zsw9nMgJryj9Xk8ieRW24YIv5sjerj/7PZeKs 9xBEI4GCt8xjHX8fwEByKT/qD3FujSbZntpxKSgkSHtV0Gp712py6VEUot2jitMhKD9Z Gt4TdYMR+FMKpZQ4vtPeZrZt8CWawjjwSNieTcLyEDuSa8212+UJmBuabqSvpSafHEXl iI4NEblqTe4skOqXKu+Ev2iVfX2mVjWJ2it2cYVxIB5bKd4rFyooTAbiGyNTwhqi2nDl ehyUd6mNHr9MJo7gMCgT+KCpHkGyqgR0KrHqXoKVHR5RJsBDzp7jX4SRlgORzOxVOKzP r37Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:sender:subject:from:to:cc:date:message-id :in-reply-to:references:user-agent:mime-version :content-transfer-encoding; bh=P3fYMsm86d+R72DkSOWxAIohyhedlH08ue4wRprUIXE=; b=c2Nj3EbgyyNJxpa3Yp/kUlZEauElosc3joZ+Pte7/8nbuumkwi8rdviliYLWrV/Z++ E/mMqqlMPahMRZpPyPQjvUr1Slq4vy/x5gTZb6PVed5QGLmPiFYbq8fofK5+6m5wfatg 6seKS4Pnsz/Bp6lTRS077S5cnm6SPIdDJ8n59XAwHM+17NzyFUsrf3Fu4zvB+1Ll8CvC qow+6k39PtBgIEFGy6mlgYhxlHk/+RE4RgUlv9qzg3DXLm9QmOa2I/q3ifgdM7LUlqlm HS0AB8+6iEUt3Po2+MiU74imQHObvnBIItc9Pd4uMNdUEJMbBt7wRUCoUUELzQCCzyKh CIdQ== X-Gm-Message-State: AA6/9RnuhcFKQOOcXAK7LK0dbhRv4fgL0xXRW3V7SPABl3MgpBa+ijFSWpdMic/gv5OAQA== X-Received: by 10.28.212.9 with SMTP id l9mr4323985wmg.77.1475245289279; Fri, 30 Sep 2016 07:21:29 -0700 (PDT) Received: from Solace.fritz.box ([80.66.223.126]) by smtp.gmail.com with ESMTPSA id bj8sm19838345wjc.49.2016.09.30.07.21.27 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Fri, 30 Sep 2016 07:21:28 -0700 (PDT) From: Dario Faggioli To: xen-devel@lists.xenproject.org Date: Fri, 30 Sep 2016 16:21:27 +0200 Message-ID: <147524528707.32325.2479597377146378983.stgit@Solace.fritz.box> In-Reply-To: <147524508103.32325.8143976887041193350.stgit@Solace.fritz.box> References: <147524508103.32325.8143976887041193350.stgit@Solace.fritz.box> User-Agent: StGit/0.17.1-dirty MIME-Version: 1.0 Cc: George Dunlap , Andrew Cooper , Anshul Makkar , Jan Beulich Subject: [Xen-devel] [PATCH v3 1/2] xen: credit2: implement yield() X-BeenThere: xen-devel@lists.xen.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Errors-To: xen-devel-bounces@lists.xen.org Sender: "Xen-devel" X-Virus-Scanned: ClamAV using ClamSMTP When a vcpu explicitly yields it is usually giving us an advice of "let someone else run and come back to me in a bit." Credit2 isn't, so far, doing anything when a vcpu yields, which means an yield is basically a NOP (well, actually, it's pure overhead, as it causes the scheduler kick in, but the result is --at least 99% of the time-- that the very same vcpu that yielded continues to run). With this patch, when a vcpu yields, we go and try picking the next vcpu on the runqueue that can run on the pcpu where the yielding vcpu is running. Of course, if we don't find any other vcpu that wants and can run there, the yielding vcpu will continue. Also, add an yield performance counter, and fix the style of a couple of comments. Signed-off-by: Dario Faggioli Reviewed-by: George Dunlap --- Cc: George Dunlap Cc: Anshul Makkar Cc: Jan Beulich Cc: Andrew Cooper --- Changes from v2: * implement yield as a "switch", rather than as a "knob", as suggested during review. Changes from v1: * add _us to the parameter name, as suggested during review; * get rid of the minimum value for the yield bias; * apply the idle bias via subtraction of credits to the yielding vcpu, rather than via addition to all the others; * merge the Credit2 bits of what was patch 7 here, as suggested during review. --- xen/common/sched_credit2.c | 54 +++++++++++++++++++++++++++++++----------- xen/common/schedule.c | 2 ++ xen/include/xen/perfc_defn.h | 1 + 3 files changed, 43 insertions(+), 14 deletions(-) diff --git a/xen/common/sched_credit2.c b/xen/common/sched_credit2.c index 72e31b5..c0646e9 100644 --- a/xen/common/sched_credit2.c +++ b/xen/common/sched_credit2.c @@ -181,7 +181,13 @@ */ #define __CSFLAG_runq_migrate_request 3 #define CSFLAG_runq_migrate_request (1<<__CSFLAG_runq_migrate_request) - +/* + * CSFLAG_vcpu_yield: this vcpu was running, and has called vcpu_yield(). The + * scheduler is invoked to see if we can give the cpu to someone else, and + * get back to the yielding vcpu in a while. + */ +#define __CSFLAG_vcpu_yield 4 +#define CSFLAG_vcpu_yield (1<<__CSFLAG_vcpu_yield) static unsigned int __read_mostly opt_migrate_resist = 500; integer_param("sched_credit2_migrate_resist", opt_migrate_resist); @@ -1431,6 +1437,14 @@ out: } static void +csched2_vcpu_yield(const struct scheduler *ops, struct vcpu *v) +{ + struct csched2_vcpu * const svc = CSCHED2_VCPU(v); + + __set_bit(__CSFLAG_vcpu_yield, &svc->flags); +} + +static void csched2_context_saved(const struct scheduler *ops, struct vcpu *vc) { struct csched2_vcpu * const svc = CSCHED2_VCPU(vc); @@ -2250,26 +2264,31 @@ runq_candidate(struct csched2_runqueue_data *rqd, struct list_head *iter; struct csched2_vcpu *snext = NULL; struct csched2_private *prv = CSCHED2_PRIV(per_cpu(scheduler, cpu)); + bool yield = __test_and_clear_bit(__CSFLAG_vcpu_yield, &scurr->flags); *skipped = 0; - /* Default to current if runnable, idle otherwise */ - if ( vcpu_runnable(scurr->vcpu) ) - snext = scurr; - else - snext = CSCHED2_VCPU(idle_vcpu[cpu]); - /* * Return the current vcpu if it has executed for less than ratelimit. * Adjuststment for the selected vcpu's credit and decision * for how long it will run will be taken in csched2_runtime. + * + * Note that, if scurr is yielding, we don't let rate limiting kick in. + * In fact, it may be the case that scurr is about to spin, and there's + * no point forcing it to do so until rate limiting expires. */ - if ( prv->ratelimit_us && !is_idle_vcpu(scurr->vcpu) && + if ( !yield && prv->ratelimit_us && !is_idle_vcpu(scurr->vcpu) && vcpu_runnable(scurr->vcpu) && (now - scurr->vcpu->runstate.state_entry_time) < MICROSECS(prv->ratelimit_us) ) return scurr; + /* Default to current if runnable, idle otherwise */ + if ( vcpu_runnable(scurr->vcpu) ) + snext = scurr; + else + snext = CSCHED2_VCPU(idle_vcpu[cpu]); + list_for_each( iter, &rqd->runq ) { struct csched2_vcpu * svc = list_entry(iter, struct csched2_vcpu, runq_elem); @@ -2293,8 +2312,10 @@ runq_candidate(struct csched2_runqueue_data *rqd, continue; } - /* If this is on a different processor, don't pull it unless - * its credit is at least CSCHED2_MIGRATE_RESIST higher. */ + /* + * If this is on a different processor, don't pull it unless + * its credit is at least CSCHED2_MIGRATE_RESIST higher. + */ if ( svc->vcpu->processor != cpu && snext->credit + CSCHED2_MIGRATE_RESIST > svc->credit ) { @@ -2303,9 +2324,12 @@ runq_candidate(struct csched2_runqueue_data *rqd, continue; } - /* If the next one on the list has more credit than current - * (or idle, if current is not runnable), choose it. */ - if ( svc->credit > snext->credit ) + /* + * If the next one on the list has more credit than current + * (or idle, if current is not runnable), or if current is + * yielding, choose it. + */ + if ( yield || svc->credit > snext->credit ) snext = svc; /* In any case, if we got this far, break. */ @@ -2391,7 +2415,8 @@ csched2_schedule( */ if ( tasklet_work_scheduled ) { - trace_var(TRC_CSCHED2_SCHED_TASKLET, 1, 0, NULL); + __clear_bit(__CSFLAG_vcpu_yield, &scurr->flags); + trace_var(TRC_CSCHED2_SCHED_TASKLET, 1, 0, NULL); snext = CSCHED2_VCPU(idle_vcpu[cpu]); } else @@ -2975,6 +3000,7 @@ static const struct scheduler sched_credit2_def = { .sleep = csched2_vcpu_sleep, .wake = csched2_vcpu_wake, + .yield = csched2_vcpu_yield, .adjust = csched2_dom_cntl, .adjust_global = csched2_sys_cntl, diff --git a/xen/common/schedule.c b/xen/common/schedule.c index 104d203..5b444c4 100644 --- a/xen/common/schedule.c +++ b/xen/common/schedule.c @@ -947,6 +947,8 @@ long vcpu_yield(void) SCHED_OP(VCPU2OP(v), yield, v); vcpu_schedule_unlock_irq(lock, v); + SCHED_STAT_CRANK(vcpu_yield); + TRACE_2D(TRC_SCHED_YIELD, current->domain->domain_id, current->vcpu_id); raise_softirq(SCHEDULE_SOFTIRQ); return 0; diff --git a/xen/include/xen/perfc_defn.h b/xen/include/xen/perfc_defn.h index 4a835b8..900fddd 100644 --- a/xen/include/xen/perfc_defn.h +++ b/xen/include/xen/perfc_defn.h @@ -23,6 +23,7 @@ PERFCOUNTER(vcpu_alloc, "sched: vcpu_alloc") PERFCOUNTER(vcpu_insert, "sched: vcpu_insert") PERFCOUNTER(vcpu_remove, "sched: vcpu_remove") PERFCOUNTER(vcpu_sleep, "sched: vcpu_sleep") +PERFCOUNTER(vcpu_yield, "sched: vcpu_yield") PERFCOUNTER(vcpu_wake_running, "sched: vcpu_wake_running") PERFCOUNTER(vcpu_wake_onrunq, "sched: vcpu_wake_onrunq") PERFCOUNTER(vcpu_wake_runnable, "sched: vcpu_wake_runnable")