Message ID | 20230531124604.477939524@infradead.org |
---|---|
State | New |
Headers |
Return-Path: <linux-kernel-owner@vger.kernel.org> Delivered-To: ouuuleilei@gmail.com Received: by 2002:a59:994d:0:b0:3d9:f83d:47d9 with SMTP id k13csp2871880vqr; Wed, 31 May 2023 06:16:08 -0700 (PDT) X-Google-Smtp-Source: ACHHUZ6qv434qFjrA25RC9s+u5nQWDeb1alj4f4vHK1+rIivAAR1gidghSard8Vp4fWu0dFKmPdg X-Received: by 2002:a05:6358:7241:b0:125:908e:22ce with SMTP id i1-20020a056358724100b00125908e22cemr2778052rwa.9.1685538967815; Wed, 31 May 2023 06:16:07 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1685538967; cv=none; d=google.com; s=arc-20160816; b=qjnfc9r0Hhwevf6YyUr1gPfvfDmT0Jd9vMneiqNTBYyQkF+/BQ66lKfwC+qT/JU6Fq qbRbii1694m732Q+pGM4UCg1/7u+vmDHFfHw6Bjakknh7MjM4XfRD/sJhdhUBy0kGkUq V2pu9s1fJFKVgKct51aaSRlNeaOQfpa9/83aVA6i/lwU3H1KH8pAPMEBMgrfvjkLTLnj uNfwuwLY9h9S6lMZRXpDp028nqV0s4b73vyqDf2XLcupWDuJO2g6WzM+thr11YY2odJZ 9MnKqBUgS6aiOp+ClbnZOSAo9y0P6e1sP309RWQ5sJfjp1bKSbnYLa8KaP9m5yVfGcvY d7LQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:mime-version:references:subject:cc:to:from:date :user-agent:message-id:dkim-signature; bh=PBSWmj9vFVjjLqcL4+nxKoAvy2PS0YCtwS6oEGVZY9I=; b=o7xIy/lyjD/m8e7LitytyG3TrNRXV5nQXCmTuItnYIwlOwOIUeFmFWLmI2MEcK4hSH QkoeZyTLQks71ONBI7SEKVaZCvwNK1Lt3BcAv8GgfsQT/RuRP3cMxyPhFjJgjgSU2QAT chiS3MAbCKv3dn+Fu7xN/1cIjQvvmsjv2o6uFHF5OHW0LFZKijBngLtYE4TAuRS7frVe +VsaZdbHG20uLpeXuy3DuKRIxk/arsNJYCnf0YHGQkLNTOb98wMUbdrz9hoSIvgYyFGL ofhFgnBfyiPKUzIezVkYY+Y+YzbA2i8L7XKSoB2FeB2Bls9g1qGMNEE883HW7lSSA2Y1 /3CA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@infradead.org header.s=casper.20170209 header.b=HK+Caj9r; 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 Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id z19-20020a17090abd9300b00256bef4bae7si931746pjr.105.2023.05.31.06.15.55; Wed, 31 May 2023 06:16:07 -0700 (PDT) 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; dkim=pass header.i=@infradead.org header.s=casper.20170209 header.b=HK+Caj9r; 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 Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236047AbjEaMtj (ORCPT <rfc822;andrewvogler123@gmail.com> + 99 others); Wed, 31 May 2023 08:49:39 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:45494 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S235992AbjEaMtA (ORCPT <rfc822;linux-kernel@vger.kernel.org>); Wed, 31 May 2023 08:49:00 -0400 Received: from casper.infradead.org (casper.infradead.org [IPv6:2001:8b0:10b:1236::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 5396BE4D for <linux-kernel@vger.kernel.org>; Wed, 31 May 2023 05:48:26 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=infradead.org; s=casper.20170209; h=Content-Type:MIME-Version:References: Subject:Cc:To:From:Date:Message-ID:Sender:Reply-To:Content-Transfer-Encoding: Content-ID:Content-Description:In-Reply-To; bh=PBSWmj9vFVjjLqcL4+nxKoAvy2PS0YCtwS6oEGVZY9I=; b=HK+Caj9r6h1z6KIgMujfd8PAKB ZyhYVnYFBeMYPB7WX57TqP32+u0yeT7U7Nhea18FLdt0lWvyIVCWR10Ieg0LEd6hAA+uWLqLRw8Yx zozyJIqLEgDwspR4NESvHqogFaIjwHmgSDuvnmgxYI84l6stgVybvmcgQfr9L5fNtFiRobXeI0Pax hZ08j6NEAkXdCYkYP6RpYrs7oqJi31Kf1knppewryVJd9c2hRTS7k685Fpke3uQJUcNAMq9naeJnz ZCQoFempJQHna20ZC4wyKBSRyL2SrypVYUc2VlkgmGIRFYDU8gasck+Z7Pj9WnGMuT2yl86Giyrff YeBji3fA==; Received: from j130084.upc-j.chello.nl ([24.132.130.84] helo=noisy.programming.kicks-ass.net) by casper.infradead.org with esmtpsa (Exim 4.94.2 #2 (Red Hat Linux)) id 1q4LEq-007GRd-0U; Wed, 31 May 2023 12:47:40 +0000 Received: from hirez.programming.kicks-ass.net (hirez.programming.kicks-ass.net [192.168.1.225]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits)) (Client did not present a certificate) by noisy.programming.kicks-ass.net (Postfix) with ESMTPS id 956C9300F2D; Wed, 31 May 2023 14:47:37 +0200 (CEST) Received: by hirez.programming.kicks-ass.net (Postfix, from userid 0) id 1F0CD22BA6460; Wed, 31 May 2023 14:47:34 +0200 (CEST) Message-ID: <20230531124604.477939524@infradead.org> User-Agent: quilt/0.66 Date: Wed, 31 May 2023 13:58:52 +0200 From: Peter Zijlstra <peterz@infradead.org> To: mingo@kernel.org, vincent.guittot@linaro.org Cc: linux-kernel@vger.kernel.org, peterz@infradead.org, juri.lelli@redhat.com, dietmar.eggemann@arm.com, rostedt@goodmis.org, bsegall@google.com, mgorman@suse.de, bristot@redhat.com, corbet@lwn.net, qyousef@layalina.io, chris.hyser@oracle.com, patrick.bellasi@matbug.net, pjt@google.com, pavel@ucw.cz, qperret@google.com, tim.c.chen@linux.intel.com, joshdon@google.com, timj@gnu.org, kprateek.nayak@amd.com, yu.c.chen@intel.com, youssefesmat@chromium.org, joel@joelfernandes.org, efault@gmx.de, tglx@linutronix.de Subject: [RFC][PATCH 13/15] sched/fair: Implement latency-nice References: <20230531115839.089944915@infradead.org> MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 X-Spam-Status: No, score=-4.4 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,RCVD_IN_DNSWL_MED,SPF_HELO_NONE, SPF_NONE,T_SCC_BODY_TEXT_LINE,URIBL_BLOCKED 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?1767415708926781041?= X-GMAIL-MSGID: =?utf-8?q?1767415708926781041?= |
Series |
sched: EEVDF and latency-nice and/or slice-attr
|
|
Commit Message
Peter Zijlstra
May 31, 2023, 11:58 a.m. UTC
Implement latency-nice as a modulation of the EEVDF r_i parameter, specifically apply the inverse sched_prio_to_weight[] relation on base_slice. Given a base slice of 3 [ms], this gives a range of: latency-nice 19: 3*1024 / 15 ~= 204.8 [ms] latency-nice -20: 3*1024 / 88761 ~= 0.034 [ms] (which might not make sense) Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org> Tested-by: K Prateek Nayak <kprateek.nayak@amd.com> --- kernel/sched/core.c | 14 ++++++++++---- kernel/sched/fair.c | 22 +++++++++++++++------- kernel/sched/sched.h | 2 ++ 3 files changed, 27 insertions(+), 11 deletions(-)
Comments
On Wed, 31 May 2023 at 14:47, Peter Zijlstra <peterz@infradead.org> wrote: > > Implement latency-nice as a modulation of the EEVDF r_i parameter, > specifically apply the inverse sched_prio_to_weight[] relation on > base_slice. > > Given a base slice of 3 [ms], this gives a range of: > > latency-nice 19: 3*1024 / 15 ~= 204.8 [ms] > latency-nice -20: 3*1024 / 88761 ~= 0.034 [ms] I have reread the publication. I have question about Theorem 1: The lag of any active client k in a steady system is bounded as follows, -rmax < lagk (d) < max(rmax ; q); and Corollary 2: Consider a steady system and a client k such that no request of client k is larger than a time quantum. Then at any time t, the lag of client k is bounded as follows: -q < lagk (t) < q q being the time quanta a task can run and rmax the maximum slice of active task I wonder how it applies to us. What is our time quanta q ? I guess that it's the tick because it is assumed that the algorithm evaluates which task should run next for each q interval in order to fulfill the fairness IIUC.So I don't think that we can assume a q shorter than the tick (at least with current implementation) unless we trigger some additional interrupts Then asking for a request shorter than the tick also means that scheduler must enqueue a new request (on behalf of the task) during the tick and evaluate if the task is still the one to be scheduled now. So similarly to q, the request size r should be at least a tick in order to reevaluate which task will run next after the end of a request. In fact, the real limit is : r/wi >= tick/(Sum wj) On Arm64 system, tick is 4ms long and on arm32 it raises to 10ms We can always not follow these assumptions made in the publication but I wonder how we can then rely on its theorems and corollaries > > (which might not make sense) > > Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org> > Tested-by: K Prateek Nayak <kprateek.nayak@amd.com> > --- > kernel/sched/core.c | 14 ++++++++++---- > kernel/sched/fair.c | 22 +++++++++++++++------- > kernel/sched/sched.h | 2 ++ > 3 files changed, 27 insertions(+), 11 deletions(-) > > --- a/kernel/sched/core.c > +++ b/kernel/sched/core.c > @@ -1305,6 +1305,12 @@ static void set_load_weight(struct task_ > } > } > > +static inline void set_latency_prio(struct task_struct *p, int prio) > +{ > + p->latency_prio = prio; > + set_latency_fair(&p->se, prio - MAX_RT_PRIO); > +} > + > #ifdef CONFIG_UCLAMP_TASK > /* > * Serializes updates of utilization clamp values > @@ -4464,9 +4470,10 @@ static void __sched_fork(unsigned long c > p->se.nr_migrations = 0; > p->se.vruntime = 0; > p->se.vlag = 0; > - p->se.slice = sysctl_sched_base_slice; > INIT_LIST_HEAD(&p->se.group_node); > > + set_latency_prio(p, p->latency_prio); > + > #ifdef CONFIG_FAIR_GROUP_SCHED > p->se.cfs_rq = NULL; > #endif > @@ -4718,8 +4725,7 @@ int sched_fork(unsigned long clone_flags > > p->prio = p->normal_prio = p->static_prio; > set_load_weight(p, false); > - > - p->latency_prio = NICE_TO_PRIO(0); > + set_latency_prio(p, NICE_TO_PRIO(0)); > > /* > * We don't need the reset flag anymore after the fork. It has > @@ -7507,7 +7513,7 @@ static void __setscheduler_latency(struc > const struct sched_attr *attr) > { > if (attr->sched_flags & SCHED_FLAG_LATENCY_NICE) > - p->latency_prio = NICE_TO_PRIO(attr->sched_latency_nice); > + set_latency_prio(p, NICE_TO_PRIO(attr->sched_latency_nice)); > } > > /* > --- a/kernel/sched/fair.c > +++ b/kernel/sched/fair.c > @@ -952,6 +952,21 @@ int sched_update_scaling(void) > } > #endif > > +void set_latency_fair(struct sched_entity *se, int prio) > +{ > + u32 weight = sched_prio_to_weight[prio]; > + u64 base = sysctl_sched_base_slice; > + > + /* > + * For EEVDF the virtual time slope is determined by w_i (iow. > + * nice) while the request time r_i is determined by > + * latency-nice. > + * > + * Smaller request gets better latency. > + */ > + se->slice = div_u64(base << SCHED_FIXEDPOINT_SHIFT, weight); > +} > + > static void clear_buddies(struct cfs_rq *cfs_rq, struct sched_entity *se); > > /* > @@ -964,13 +979,6 @@ static void update_deadline(struct cfs_r > return; > > /* > - * For EEVDF the virtual time slope is determined by w_i (iow. > - * nice) while the request time r_i is determined by > - * sysctl_sched_base_slice. > - */ > - se->slice = sysctl_sched_base_slice; > - > - /* > * EEVDF: vd_i = ve_i + r_i / w_i > */ > se->deadline = se->vruntime + calc_delta_fair(se->slice, se); > --- a/kernel/sched/sched.h > +++ b/kernel/sched/sched.h > @@ -2495,6 +2495,8 @@ extern unsigned int sysctl_numa_balancin > extern unsigned int sysctl_numa_balancing_hot_threshold; > #endif > > +extern void set_latency_fair(struct sched_entity *se, int prio); > + > #ifdef CONFIG_SCHED_HRTICK > > /* > >
On Tue, Jun 06, 2023 at 04:54:13PM +0200, Vincent Guittot wrote: > On Wed, 31 May 2023 at 14:47, Peter Zijlstra <peterz@infradead.org> wrote: > > > > Implement latency-nice as a modulation of the EEVDF r_i parameter, > > specifically apply the inverse sched_prio_to_weight[] relation on > > base_slice. > > > > Given a base slice of 3 [ms], this gives a range of: > > > > latency-nice 19: 3*1024 / 15 ~= 204.8 [ms] > > latency-nice -20: 3*1024 / 88761 ~= 0.034 [ms] > > I have reread the publication. I have question about > > Theorem 1: The lag of any active client k in a steady system is > bounded as follows, > -rmax < lagk (d) < max(rmax ; q); > > and > > Corollary 2: Consider a steady system and a client k such that no > request of client k is larger than a > time quantum. Then at any time t, the lag of client k is bounded as follows: > -q < lagk (t) < q > > q being the time quanta a task can run > and rmax the maximum slice of active task > > I wonder how it applies to us. What is our time quanta q ? > I guess that it's the tick because it is assumed that the algorithm > evaluates which task should run next for each q interval in order to > fulfill the fairness IIUC.So I don't think that we can assume a q > shorter than the tick (at least with current implementation) unless we > trigger some additional interrupts Indeed, TICK_NSEC is our unit of accounting (unless HRTICK, but I've not looked at that, it might not DTRT -- also, I still need to rewrite that whole thing to not be so damn expensive). > Then asking for a request shorter than the tick also means that > scheduler must enqueue a new request (on behalf of the task) during > the tick and evaluate if the task is still the one to be scheduled > now. If there is no 'interrupt', we won't update time and the scheduler can't do anything -- as you well know. The paper only requires (and we slightly violate this) to push forward the deadline. See the comment with update_deadline(). Much like pure EDF without a combined CBS. > So similarly to q, the request size r should be at least a tick > in order to reevaluate which task will run next after the end of a > request. In fact, the real limit is : r/wi >= tick/(Sum wj) > We can always not follow these assumptions made in the publication but > I wonder how we can then rely on its theorems and corollaries Again, I'm not entirely following, the corollaries take r_i < q into account, that's where the max(rmax, q) term comes from. You're right in that r_i < q does not behave 'right', but it doesn't invalidate the results. Note that if a task overshoots, it will build of significant negative lag (right side of the tree) and won't be eligible for it's next actual period. This 'hole' in the schedule is then used to make up for the extra time it used previously. The much bigger problem with those bounds is this little caveat: 'in a steady state'. They conveniently fail to consider the impact of leave/join operations on the whole thing -- and that's a much more interesting case.
On Thu, Jun 08, 2023 at 12:34:58PM +0200, Peter Zijlstra wrote: > > Then asking for a request shorter than the tick also means that > > scheduler must enqueue a new request (on behalf of the task) during > > the tick and evaluate if the task is still the one to be scheduled > > now. > > If there is no 'interrupt', we won't update time and the scheduler can't > do anything -- as you well know. The paper only requires (and we > slightly violate this) to push forward the deadline. See the comment > with update_deadline(). > > Much like pure EDF without a combined CBS. > > > So similarly to q, the request size r should be at least a tick > > in order to reevaluate which task will run next after the end of a > > request. In fact, the real limit is : r/wi >= tick/(Sum wj) > > > We can always not follow these assumptions made in the publication but > > I wonder how we can then rely on its theorems and corollaries > > Again, I'm not entirely following, the corollaries take r_i < q into > account, that's where the max(rmax, q) term comes from. > > You're right in that r_i < q does not behave 'right', but it doesn't > invalidate the results. Note that if a task overshoots, it will build of > significant negative lag (right side of the tree) and won't be eligible > for it's next actual period. This 'hole' in the schedule is then used to > make up for the extra time it used previously. So notably, if your task *does* behave correctly and does not consume the full request, then it will not build up (large) negative lag and wakeup-preemption can make it go quickly on the next period. This is where that FUDGE hack comes in, except I got it wrong, I think it needs to be something like: if (delta / W >= vslice) { se->vlag += vslice if (se->vlag > 0) se->vlag = 0; } To ensure it can't gain time. It's still a gruesome hack, but at least is shouldn't be able to game the system.
Peter Zijlstra <peterz@infradead.org> writes: > --- a/kernel/sched/fair.c > +++ b/kernel/sched/fair.c > @@ -952,6 +952,21 @@ int sched_update_scaling(void) > } > #endif > > +void set_latency_fair(struct sched_entity *se, int prio) > +{ > + u32 weight = sched_prio_to_weight[prio]; > + u64 base = sysctl_sched_base_slice; > + > + /* > + * For EEVDF the virtual time slope is determined by w_i (iow. > + * nice) while the request time r_i is determined by > + * latency-nice. > + * > + * Smaller request gets better latency. > + */ > + se->slice = div_u64(base << SCHED_FIXEDPOINT_SHIFT, weight); > +} > + > static void clear_buddies(struct cfs_rq *cfs_rq, struct sched_entity *se); > > /* This seems questionable in combination with the earlier changes that make things use se->slice by itself as the expected time slice: > @@ -6396,13 +6629,12 @@ static inline void unthrottle_offline_cf > static void hrtick_start_fair(struct rq *rq, struct task_struct *p) > { > struct sched_entity *se = &p->se; > - struct cfs_rq *cfs_rq = cfs_rq_of(se); > > SCHED_WARN_ON(task_rq(p) != rq); > > if (rq->cfs.h_nr_running > 1) { > - u64 slice = sched_slice(cfs_rq, se); > u64 ran = se->sum_exec_runtime - se->prev_sum_exec_runtime; > + u64 slice = se->slice; > s64 delta = slice - ran; > > if (delta < 0) { > @@ -12136,8 +12382,8 @@ static void rq_offline_fair(struct rq *r > static inline bool > __entity_slice_used(struct sched_entity *se, int min_nr_tasks) > { > - u64 slice = sched_slice(cfs_rq_of(se), se); > u64 rtime = se->sum_exec_runtime - se->prev_sum_exec_runtime; > + u64 slice = se->slice; > > return (rtime * min_nr_tasks > slice); > } > @@ -12832,7 +13078,7 @@ static unsigned int get_rr_interval_fair > * idle runqueue: > */ > if (rq->cfs.load.weight) > - rr_interval = NS_TO_JIFFIES(sched_slice(cfs_rq_of(se), se)); > + rr_interval = NS_TO_JIFFIES(se->slice); > > return rr_interval; > } We probably do not want a task with normal weight and low latency-weight (aka high latency / latency-nice value) to be expected to have a very very high slice value for some of these. get_rr_interval_fair is whatever, it's not really a number that exists, and CONFIG_SCHED_CORE isn't updated for EEVDF at all, but HRTICK at least probably should be updated. Having such a task run for 68 times normal seems likely to have far worse latency effects than any gains from other parts.
--- a/kernel/sched/core.c +++ b/kernel/sched/core.c @@ -1305,6 +1305,12 @@ static void set_load_weight(struct task_ } } +static inline void set_latency_prio(struct task_struct *p, int prio) +{ + p->latency_prio = prio; + set_latency_fair(&p->se, prio - MAX_RT_PRIO); +} + #ifdef CONFIG_UCLAMP_TASK /* * Serializes updates of utilization clamp values @@ -4464,9 +4470,10 @@ static void __sched_fork(unsigned long c p->se.nr_migrations = 0; p->se.vruntime = 0; p->se.vlag = 0; - p->se.slice = sysctl_sched_base_slice; INIT_LIST_HEAD(&p->se.group_node); + set_latency_prio(p, p->latency_prio); + #ifdef CONFIG_FAIR_GROUP_SCHED p->se.cfs_rq = NULL; #endif @@ -4718,8 +4725,7 @@ int sched_fork(unsigned long clone_flags p->prio = p->normal_prio = p->static_prio; set_load_weight(p, false); - - p->latency_prio = NICE_TO_PRIO(0); + set_latency_prio(p, NICE_TO_PRIO(0)); /* * We don't need the reset flag anymore after the fork. It has @@ -7507,7 +7513,7 @@ static void __setscheduler_latency(struc const struct sched_attr *attr) { if (attr->sched_flags & SCHED_FLAG_LATENCY_NICE) - p->latency_prio = NICE_TO_PRIO(attr->sched_latency_nice); + set_latency_prio(p, NICE_TO_PRIO(attr->sched_latency_nice)); } /* --- a/kernel/sched/fair.c +++ b/kernel/sched/fair.c @@ -952,6 +952,21 @@ int sched_update_scaling(void) } #endif +void set_latency_fair(struct sched_entity *se, int prio) +{ + u32 weight = sched_prio_to_weight[prio]; + u64 base = sysctl_sched_base_slice; + + /* + * For EEVDF the virtual time slope is determined by w_i (iow. + * nice) while the request time r_i is determined by + * latency-nice. + * + * Smaller request gets better latency. + */ + se->slice = div_u64(base << SCHED_FIXEDPOINT_SHIFT, weight); +} + static void clear_buddies(struct cfs_rq *cfs_rq, struct sched_entity *se); /* @@ -964,13 +979,6 @@ static void update_deadline(struct cfs_r return; /* - * For EEVDF the virtual time slope is determined by w_i (iow. - * nice) while the request time r_i is determined by - * sysctl_sched_base_slice. - */ - se->slice = sysctl_sched_base_slice; - - /* * EEVDF: vd_i = ve_i + r_i / w_i */ se->deadline = se->vruntime + calc_delta_fair(se->slice, se); --- a/kernel/sched/sched.h +++ b/kernel/sched/sched.h @@ -2495,6 +2495,8 @@ extern unsigned int sysctl_numa_balancin extern unsigned int sysctl_numa_balancing_hot_threshold; #endif +extern void set_latency_fair(struct sched_entity *se, int prio); + #ifdef CONFIG_SCHED_HRTICK /*