Message ID | 79850642-ebac-5c23-d32d-b28737dcb91e@huawei.com |
---|---|
State | New |
Headers |
Return-Path: <linux-kernel-owner@vger.kernel.org> Delivered-To: ouuuleilei@gmail.com Received: by 2002:a5d:5915:0:0:0:0:0 with SMTP id v21csp834481wrd; Sat, 4 Mar 2023 00:45:49 -0800 (PST) X-Google-Smtp-Source: AK7set8+9RMNoAM15kYEnzjve0SnMhXhg5A8POfB53i3qu43wZsA+OjI6rX2P2/RR9OS5qQajBTF X-Received: by 2002:a05:6a20:6d04:b0:cd:929d:280a with SMTP id fv4-20020a056a206d0400b000cd929d280amr4188866pzb.18.1677919549209; Sat, 04 Mar 2023 00:45:49 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1677919549; cv=none; d=google.com; s=arc-20160816; b=marlBUPfQy8kljR4o0zd9b2zfGF4JuaYO7OcuYwi7ESzwHSQFgqMe3Od+fY4BQdnQR nGkEQrpCjrm45BFnYDGacb1511nb9BQFJ/5NnRdE4r/ttGHrB7VUgOVndlLQBf1wTerJ Rtj6rs9xFC+zQuudjxgWqu/jfsWmwp020coAPnWnRm+Ixa4L0m2kSzoP2dG95YYBXo+U i5Qb4SP//6zwYExmcpSPyih7MF9iv9mrVnK5aTHnx4GsMrmb1LkFSnw29Qik3kplLl1h iCEcooBk7UGt6niVvPBfv+NRBc2gqyXIwMmVZEdaLvDkawSMx2I+PoRW5W1pVDqtwMNT Z08Q== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:cc:to:subject:from :user-agent:mime-version:date:message-id; bh=3A+k8WXT5FsSzFZwb09S0qdYkHwJgf463aBMWr+lSeM=; b=k4Exnb8puXsiU3XFFeoU3ug32a9L8zIIY2FhGJ/TlVYyo1xURqr68t9wAt4QQRHS3e b748py8uvOZpFopQouN/DzWPICMK9XYln4lD+Id62zaAH9gDoogbpyiPIEvRh/cquHyM Tpse/hZ2ZG4MxUQdHC+Tbzcs4ev6RmIro6ODdK5NuMEUkZTTCCHLahX6Uqm7QzvZd4ap L4b5Dq2w26QfTZxxF1VdEERPkF7OdXWo52d85GptJz8izW+wWokjezqP1/e65z58FAy1 PKVHSvIFa56DXMh/itycUyHvekq1D2AARJf6bAJTWS2EsB0HhI1LjDZeFBULXviKP++m /MaQ== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=QUARANTINE sp=QUARANTINE dis=NONE) header.from=huawei.com Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id e20-20020a631e14000000b004fc698192a6si4767722pge.215.2023.03.04.00.45.37; Sat, 04 Mar 2023 00:45:49 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=QUARANTINE sp=QUARANTINE dis=NONE) header.from=huawei.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229500AbjCDI3s (ORCPT <rfc822;ouuuleilei@gmail.com> + 99 others); Sat, 4 Mar 2023 03:29:48 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:46530 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229437AbjCDI3r (ORCPT <rfc822;linux-kernel@vger.kernel.org>); Sat, 4 Mar 2023 03:29:47 -0500 Received: from szxga02-in.huawei.com (szxga02-in.huawei.com [45.249.212.188]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 18D46158BF for <linux-kernel@vger.kernel.org>; Sat, 4 Mar 2023 00:29:45 -0800 (PST) Received: from dggpeml500018.china.huawei.com (unknown [172.30.72.54]) by szxga02-in.huawei.com (SkyGuard) with ESMTP id 4PTHyh50P9z9tFb; Sat, 4 Mar 2023 16:27:40 +0800 (CST) Received: from [10.67.111.186] (10.67.111.186) by dggpeml500018.china.huawei.com (7.185.36.186) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2507.21; Sat, 4 Mar 2023 16:29:42 +0800 Message-ID: <79850642-ebac-5c23-d32d-b28737dcb91e@huawei.com> Date: Sat, 4 Mar 2023 16:29:42 +0800 MIME-Version: 1.0 User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:91.0) Gecko/20100101 Thunderbird/91.1.1 From: Zhang Qiao <zhangqiao22@huawei.com> Subject: [PATCH] sched/fair: sanitize vruntime of entity being migrated To: lkml <linux-kernel@vger.kernel.org> CC: Valentin Schneider <vschneid@redhat.com>, Zhang Qiao <zhangqiao22@huawei.com>, Ben Segall <bsegall@google.com>, Vincent Guittot <vincent.guittot@linaro.org>, Waiman Long <longman@redhat.com>, Peter Zijlstra <peterz@infradead.org>, Steven Rostedt <rostedt@goodmis.org>, Mel Gorman <mgorman@suse.de>, Dietmar Eggemann <dietmar.eggemann@arm.com>, Daniel Bristot de Oliveira <bristot@redhat.com>, Ingo Molnar <mingo@redhat.com>, Juri Lelli <juri.lelli@redhat.com> Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: 7bit X-Originating-IP: [10.67.111.186] X-ClientProxiedBy: dggems701-chm.china.huawei.com (10.3.19.178) To dggpeml500018.china.huawei.com (7.185.36.186) X-CFilter-Loop: Reflected X-Spam-Status: No, score=-4.2 required=5.0 tests=BAYES_00,RCVD_IN_DNSWL_MED, SPF_HELO_NONE,SPF_PASS autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: <linux-kernel.vger.kernel.org> X-Mailing-List: linux-kernel@vger.kernel.org X-getmail-retrieved-from-mailbox: =?utf-8?q?INBOX?= X-GMAIL-THRID: =?utf-8?q?1759426169413879730?= X-GMAIL-MSGID: =?utf-8?q?1759426169413879730?= |
Series |
sched/fair: sanitize vruntime of entity being migrated
|
|
Commit Message
Zhang Qiao
March 4, 2023, 8:29 a.m. UTC
Commit 829c1651e9c4 ("sched/fair: sanitize vruntime of
entity being placed") fix an overflowing bug, but ignore
a case that se->exec_start is reset after a migration.
For fix this case, we reset the vruntime of a loog sleep
task in migrate_task_rq_fair().
Fixes: 829c1651e9c4 ("sched/fair: sanitize vruntime of entity being placed")
Suggested-by: Vincent Guittot <vincent.guittot@linaro.org>
Signed-off-by: Zhang Qiao <zhangqiao22@huawei.com>
---
kernel/sched/fair.c | 73 ++++++++++++++++++++++++++++++++-------------
1 file changed, 53 insertions(+), 20 deletions(-)
vruntime += sched_vslice(cfs_rq, se);
/* sleeps up to a single latency don't count. */
- if (!initial) {
- unsigned long thresh;
-
- if (se_is_idle(se))
- thresh = sysctl_sched_min_granularity;
- else
- thresh = sysctl_sched_latency;
-
- /*
- * Halve their sleep time's effect, to allow
- * for a gentler effect of sleepers:
- */
- if (sched_feat(GENTLE_FAIR_SLEEPERS))
- thresh >>= 1;
-
- vruntime -= thresh;
- }
+ if (!initial)
+ vruntime -= sched_sleeper_credit(se);
/*
* Pull vruntime of the entity being placed to the base level of
@@ -4689,8 +4709,7 @@ place_entity(struct cfs_rq *cfs_rq, struct sched_entity *se, int initial)
* the base as it may be too far off and the comparison may get
* inversed due to s64 overflow.
*/
- sleep_time = rq_clock_task(rq_of(cfs_rq)) - se->exec_start;
- if ((s64)sleep_time > 60LL * NSEC_PER_SEC)
+ if (entity_is_long_sleep(se))
se->vruntime = vruntime;
else
se->vruntime = max_vruntime(se->vruntime, vruntime);
@@ -7635,7 +7654,21 @@ static void migrate_task_rq_fair(struct task_struct *p, int new_cpu)
if (READ_ONCE(p->__state) == TASK_WAKING) {
struct cfs_rq *cfs_rq = cfs_rq_of(se);
- se->vruntime -= u64_u32_load(cfs_rq->min_vruntime);
+ /*
+ * We determine a task whether sleep for long by checking se->exec_start,
+ * and if it is, sanitize its vruntime at place_entity(). However, after
+ * a migration, this detection method fails due to se->exec_start is reset.
+ *
+ * For fix this case, we add the same check at here. For a task which has
+ * slept for long, its vruntime should be reset cfs_rq->min_vruntime and get
+ * a sleep credit. Because waking task's vruntime will be added cfs_rq->min_vruntime
+ * when enqueue, so we only need resetting the se->vruntime of waking task
+ * to a credit at here.
+ */
+ if (entity_is_long_sleep(se))
+ se->vruntime = -sched_sleeper_credit(se);
+ else
+ se->vruntime -= u64_u32_load(cfs_rq->min_vruntime);
}
if (!task_on_rq_migrating(p)) {
Comments
On Sat, 4 Mar 2023 at 09:29, Zhang Qiao <zhangqiao22@huawei.com> wrote: > > Commit 829c1651e9c4 ("sched/fair: sanitize vruntime of > entity being placed") fix an overflowing bug, but ignore > a case that se->exec_start is reset after a migration. > > For fix this case, we reset the vruntime of a loog sleep > task in migrate_task_rq_fair(). some typo: "For fixing this case, we reset the vruntime of a long sleeping task in migrate_task_rq_fair()." > > Fixes: 829c1651e9c4 ("sched/fair: sanitize vruntime of entity being placed") > Suggested-by: Vincent Guittot <vincent.guittot@linaro.org> > Signed-off-by: Zhang Qiao <zhangqiao22@huawei.com> Your patch doesn't apply. It seems to be malformed > --- > kernel/sched/fair.c | 73 ++++++++++++++++++++++++++++++++------------- > 1 file changed, 53 insertions(+), 20 deletions(-) > > diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c > index ff4dbbae3b10..6697462baf0f 100644 > --- a/kernel/sched/fair.c > +++ b/kernel/sched/fair.c > @@ -4648,6 +4648,41 @@ static void check_spread(struct cfs_rq *cfs_rq, struct sched_entity *se) > #endif > } > +static inline bool entity_is_long_sleep(struct sched_entity *se) This extra space at the beg of the line above looks strange > +{ > + struct cfs_rq *cfs_rq; > + u64 sleep_time; > + > + if (se->exec_start == 0) > + return false; > + > + cfs_rq = cfs_rq_of(se); > + sleep_time = rq_clock_task(rq_of(cfs_rq)) - se->exec_start; > + if ((s64)sleep_time > 60LL * NSEC_PER_SEC) > + return true; > + > + return false; > +} > + > +static inline u64 sched_sleeper_credit(struct sched_entity *se) > +{ > + unsigned long thresh; > + > + if (se_is_idle(se)) > + thresh = sysctl_sched_min_granularity; > + else > + thresh = sysctl_sched_latency; > + > + /* > + * Halve their sleep time's effect, to allow > + * for a gentler effect of sleepers: > + */ > + if (sched_feat(GENTLE_FAIR_SLEEPERS)) > + thresh >>= 1; > + > + return thresh; > +} > + > static void > place_entity(struct cfs_rq *cfs_rq, struct sched_entity *se, int initial) > { > @@ -4664,23 +4699,8 @@ place_entity(struct cfs_rq *cfs_rq, struct sched_entity *se, int initial) > vruntime += sched_vslice(cfs_rq, se); > /* sleeps up to a single latency don't count. */ > - if (!initial) { > - unsigned long thresh; > - > - if (se_is_idle(se)) > - thresh = sysctl_sched_min_granularity; > - else > - thresh = sysctl_sched_latency; > - > - /* > - * Halve their sleep time's effect, to allow > - * for a gentler effect of sleepers: > - */ > - if (sched_feat(GENTLE_FAIR_SLEEPERS)) > - thresh >>= 1; > - > - vruntime -= thresh; > - } > + if (!initial) > + vruntime -= sched_sleeper_credit(se); > /* > * Pull vruntime of the entity being placed to the base level of > @@ -4689,8 +4709,7 @@ place_entity(struct cfs_rq *cfs_rq, struct sched_entity *se, int initial) > * the base as it may be too far off and the comparison may get > * inversed due to s64 overflow. > */ > - sleep_time = rq_clock_task(rq_of(cfs_rq)) - se->exec_start; > - if ((s64)sleep_time > 60LL * NSEC_PER_SEC) > + if (entity_is_long_sleep(se)) > se->vruntime = vruntime; > else > se->vruntime = max_vruntime(se->vruntime, vruntime); > @@ -7635,7 +7654,21 @@ static void migrate_task_rq_fair(struct task_struct *p, int new_cpu) > if (READ_ONCE(p->__state) == TASK_WAKING) { > struct cfs_rq *cfs_rq = cfs_rq_of(se); > - se->vruntime -= u64_u32_load(cfs_rq->min_vruntime); > + /* > + * We determine a task whether sleep for long by checking se->exec_start, > + * and if it is, sanitize its vruntime at place_entity(). However, after > + * a migration, this detection method fails due to se->exec_start is reset. some typo "We determine whether a task sleeps for long by checking se->exec_start, and if it is, we sanitize its vruntime at place_entity(). However, after a migration, this detection method fails due to se->exec_start being reset." > + * > + * For fix this case, we add the same check at here. For a task which has > + * slept for long, its vruntime should be reset cfs_rq->min_vruntime and get > + * a sleep credit. Because waking task's vruntime will be added cfs_rq->min_vruntime For fixing this case, we add the same check here. For a task which has slept for a long time, its vruntime should be reset to cfs_rq->min_vruntime with a sleep credit. Beside the typo and malformed patch, the proposed fix looks good to me > + * when enqueue, so we only need resetting the se->vruntime of waking task > + * to a credit at here. > + */ > + if (entity_is_long_sleep(se)) > + se->vruntime = -sched_sleeper_credit(se); > + else > + se->vruntime -= u64_u32_load(cfs_rq->min_vruntime); > } > if (!task_on_rq_migrating(p)) { > -- > 2.17.1 > > .
在 2023/3/6 19:12, Vincent Guittot 写道: > On Sat, 4 Mar 2023 at 09:29, Zhang Qiao <zhangqiao22@huawei.com> wrote: >> >> Commit 829c1651e9c4 ("sched/fair: sanitize vruntime of >> entity being placed") fix an overflowing bug, but ignore >> a case that se->exec_start is reset after a migration. >> >> For fix this case, we reset the vruntime of a loog sleep >> task in migrate_task_rq_fair(). > > some typo: > "For fixing this case, we reset the vruntime of a long sleeping task > in migrate_task_rq_fair()." > >> >> Fixes: 829c1651e9c4 ("sched/fair: sanitize vruntime of entity being placed") >> Suggested-by: Vincent Guittot <vincent.guittot@linaro.org> >> Signed-off-by: Zhang Qiao <zhangqiao22@huawei.com> > > Your patch doesn't apply. It seems to be malformed > >> --- >> kernel/sched/fair.c | 73 ++++++++++++++++++++++++++++++++------------- >> 1 file changed, 53 insertions(+), 20 deletions(-) >> >> diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c >> index ff4dbbae3b10..6697462baf0f 100644 >> --- a/kernel/sched/fair.c >> +++ b/kernel/sched/fair.c >> @@ -4648,6 +4648,41 @@ static void check_spread(struct cfs_rq *cfs_rq, struct sched_entity *se) >> #endif >> } >> +static inline bool entity_is_long_sleep(struct sched_entity *se) > > This extra space at the beg of the line above looks strange > >> +{ >> + struct cfs_rq *cfs_rq; >> + u64 sleep_time; >> + >> + if (se->exec_start == 0) >> + return false; >> + >> + cfs_rq = cfs_rq_of(se); >> + sleep_time = rq_clock_task(rq_of(cfs_rq)) - se->exec_start; >> + if ((s64)sleep_time > 60LL * NSEC_PER_SEC) >> + return true; >> + >> + return false; >> +} >> + >> +static inline u64 sched_sleeper_credit(struct sched_entity *se) >> +{ >> + unsigned long thresh; >> + >> + if (se_is_idle(se)) >> + thresh = sysctl_sched_min_granularity; >> + else >> + thresh = sysctl_sched_latency; >> + >> + /* >> + * Halve their sleep time's effect, to allow >> + * for a gentler effect of sleepers: >> + */ >> + if (sched_feat(GENTLE_FAIR_SLEEPERS)) >> + thresh >>= 1; >> + >> + return thresh; >> +} >> + >> static void >> place_entity(struct cfs_rq *cfs_rq, struct sched_entity *se, int initial) >> { >> @@ -4664,23 +4699,8 @@ place_entity(struct cfs_rq *cfs_rq, struct sched_entity *se, int initial) >> vruntime += sched_vslice(cfs_rq, se); >> /* sleeps up to a single latency don't count. */ >> - if (!initial) { >> - unsigned long thresh; >> - >> - if (se_is_idle(se)) >> - thresh = sysctl_sched_min_granularity; >> - else >> - thresh = sysctl_sched_latency; >> - >> - /* >> - * Halve their sleep time's effect, to allow >> - * for a gentler effect of sleepers: >> - */ >> - if (sched_feat(GENTLE_FAIR_SLEEPERS)) >> - thresh >>= 1; >> - >> - vruntime -= thresh; >> - } >> + if (!initial) >> + vruntime -= sched_sleeper_credit(se); >> /* >> * Pull vruntime of the entity being placed to the base level of >> @@ -4689,8 +4709,7 @@ place_entity(struct cfs_rq *cfs_rq, struct sched_entity *se, int initial) >> * the base as it may be too far off and the comparison may get >> * inversed due to s64 overflow. >> */ >> - sleep_time = rq_clock_task(rq_of(cfs_rq)) - se->exec_start; >> - if ((s64)sleep_time > 60LL * NSEC_PER_SEC) >> + if (entity_is_long_sleep(se)) >> se->vruntime = vruntime; >> else >> se->vruntime = max_vruntime(se->vruntime, vruntime); >> @@ -7635,7 +7654,21 @@ static void migrate_task_rq_fair(struct task_struct *p, int new_cpu) >> if (READ_ONCE(p->__state) == TASK_WAKING) { >> struct cfs_rq *cfs_rq = cfs_rq_of(se); >> - se->vruntime -= u64_u32_load(cfs_rq->min_vruntime); >> + /* >> + * We determine a task whether sleep for long by checking se->exec_start, >> + * and if it is, sanitize its vruntime at place_entity(). However, after >> + * a migration, this detection method fails due to se->exec_start is reset. > > some typo > > "We determine whether a task sleeps for long by checking > se->exec_start, and if it is, we sanitize its vruntime at > place_entity(). However, after a migration, this detection method > fails due to se->exec_start being reset." > >> + * >> + * For fix this case, we add the same check at here. For a task which has >> + * slept for long, its vruntime should be reset cfs_rq->min_vruntime and get >> + * a sleep credit. Because waking task's vruntime will be added cfs_rq->min_vruntime > > For fixing this case, we add the same check here. For a task which has > slept for a long time, its vruntime should be reset to > cfs_rq->min_vruntime with a sleep credit. > > Beside the typo and malformed patch, the proposed fix looks good to me HI, Vincent, Thank you for your correction. > >> + * when enqueue, so we only need resetting the se->vruntime of waking task >> + * to a credit at here. >> + */ >> + if (entity_is_long_sleep(se)) >> + se->vruntime = -sched_sleeper_credit(se); >> + else >> + se->vruntime -= u64_u32_load(cfs_rq->min_vruntime); >> } >> if (!task_on_rq_migrating(p)) { >> -- >> 2.17.1 >> >> . > . >
diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c index ff4dbbae3b10..6697462baf0f 100644 --- a/kernel/sched/fair.c +++ b/kernel/sched/fair.c @@ -4648,6 +4648,41 @@ static void check_spread(struct cfs_rq *cfs_rq, struct sched_entity *se) #endif } +static inline bool entity_is_long_sleep(struct sched_entity *se) +{ + struct cfs_rq *cfs_rq; + u64 sleep_time; + + if (se->exec_start == 0) + return false; + + cfs_rq = cfs_rq_of(se); + sleep_time = rq_clock_task(rq_of(cfs_rq)) - se->exec_start; + if ((s64)sleep_time > 60LL * NSEC_PER_SEC) + return true; + + return false; +} + +static inline u64 sched_sleeper_credit(struct sched_entity *se) +{ + unsigned long thresh; + + if (se_is_idle(se)) + thresh = sysctl_sched_min_granularity; + else + thresh = sysctl_sched_latency; + + /* + * Halve their sleep time's effect, to allow + * for a gentler effect of sleepers: + */ + if (sched_feat(GENTLE_FAIR_SLEEPERS)) + thresh >>= 1; + + return thresh; +} + static void place_entity(struct cfs_rq *cfs_rq, struct sched_entity *se, int initial) { @@ -4664,23 +4699,8 @@ place_entity(struct cfs_rq *cfs_rq, struct sched_entity *se, int initial)