From: Patrick Bellasi <patrick.bellasi@arm.com> To: linux-kernel@vger.kernel.org, linux-pm@vger.kernel.org Cc: Ingo Molnar <mingo@redhat.com>, Peter Zijlstra <peterz@infradead.org>, Tejun Heo <tj@kernel.org>, "Rafael J . Wysocki" <rafael.j.wysocki@intel.com>, Viresh Kumar <viresh.kumar@linaro.org>, Vincent Guittot <vincent.guittot@linaro.org>, Paul Turner <pjt@google.com>, Quentin Perret <quentin.perret@arm.com>, Dietmar Eggemann <dietmar.eggemann@arm.com>, Morten Rasmussen <morten.rasmussen@arm.com>, Juri Lelli <juri.lelli@redhat.com>, Todd Kjos <tkjos@google.com>, Joel Fernandes <joelaf@google.com>, Steve Muckle <smuckle@google.com>, Suren Baghdasaryan <surenb@google.com> Subject: [PATCH v4 04/16] sched/core: uclamp: update CPU's refcount on clamp changes Date: Tue, 28 Aug 2018 14:53:12 +0100 Message-ID: <20180828135324.21976-5-patrick.bellasi@arm.com> (raw) In-Reply-To: <20180828135324.21976-1-patrick.bellasi@arm.com> Utilization clamp values enforced on a CPU by a task can be updated at run-time, for example via a sched_setattr syscall, while a task is currently RUNNABLE on that CPU. In these cases, the task can be already refcounting a clamp group for its CPU and thus we need to update this reference to ensure the new constraints are immediately enforced. Since a clamp value change always implies a clamp group refcount update, this patch hooks into the clamp group refcount getter to trigger a CPU refcount syncup. Such a syncup is required only by currently RUNNABLE tasks which are also referencing at least one valid clamp group. Signed-off-by: Patrick Bellasi <patrick.bellasi@arm.com> Cc: Ingo Molnar <mingo@redhat.com> Cc: Peter Zijlstra <peterz@infradead.org> Cc: Paul Turner <pjt@google.com> Cc: Suren Baghdasaryan <surenb@google.com> Cc: Todd Kjos <tkjos@google.com> Cc: Joel Fernandes <joelaf@google.com> Cc: Juri Lelli <juri.lelli@redhat.com> Cc: Quentin Perret <quentin.perret@arm.com> Cc: Dietmar Eggemann <dietmar.eggemann@arm.com> Cc: Morten Rasmussen <morten.rasmussen@arm.com> Cc: linux-kernel@vger.kernel.org Cc: linux-pm@vger.kernel.org --- Changes in v4: Message-ID: <20180816132249.GA2960@e110439-lin> - inline uclamp_task_active() code into uclamp_task_update_active() - get rid of the now unused uclamp_task_active() Other: - allow to call uclamp_group_get() without a task pointer, which is used to refcount the initial clamp group for all the global objects (init_task, root_task_group and system_defaults) - rebased on v4.19-rc1 Changes in v3: Message-ID: <CAJuCfpF6=L=0LrmNnJrTNPazT4dWKqNv+thhN0dwpKCgUzs9sg@mail.gmail.com> - rename UCLAMP_NONE into UCLAMP_NOT_VALID Other: - rabased on tip/sched/core Changes in v2: Message-ID: <20180413111900.GF4082@hirez.programming.kicks-ass.net> - get rid of the group_id back annotation which is not requires at this stage where we have only per-task clamping support. It will be introduce later when CGroups support is added. Other: - rabased on v4.18-rc4 - this code has been split from a previous patch to simplify the review --- kernel/sched/core.c | 65 ++++++++++++++++++++++++++++++++++++++++---- kernel/sched/sched.h | 16 +++++++++++ 2 files changed, 76 insertions(+), 5 deletions(-) diff --git a/kernel/sched/core.c b/kernel/sched/core.c index 8f908035701f..64e5c96bfdaf 100644 --- a/kernel/sched/core.c +++ b/kernel/sched/core.c @@ -1080,6 +1080,54 @@ static inline void uclamp_cpu_put(struct rq *rq, struct task_struct *p) uclamp_cpu_put_id(p, rq, clamp_id); } +/** + * uclamp_task_update_active: update the clamp group of a RUNNABLE task + * @p: the task which clamp groups must be updated + * @clamp_id: the clamp index to consider + * @group_id: the clamp group to update + * + * Each time the clamp value of a task group is changed, the old and new clamp + * groups have to be updated for each CPU containing a RUNNABLE task belonging + * to this tasks group. Sleeping tasks are not updated since they will be + * enqueued with the proper clamp group index at their next activation. + */ +static inline void +uclamp_task_update_active(struct task_struct *p, int clamp_id, int group_id) +{ + struct rq_flags rf; + struct rq *rq; + + /* + * Lock the task and the CPU where the task is (or was) queued. + * + * We might lock the (previous) RQ of a !RUNNABLE task, but that's the + * price to pay to safely serialize util_{min,max} updates with + * enqueues, dequeues and migration operations. + * This is the same locking schema used by __set_cpus_allowed_ptr(). + */ + rq = task_rq_lock(p, &rf); + + /* + * The setting of the clamp group is serialized by task_rq_lock(). + * Thus, if the task is not yet RUNNABLE and its task_struct is not + * affecting a valid clamp group, then the next time it's going to be + * enqueued it will already see the updated clamp group value. + */ + if (!task_on_rq_queued(p) && !p->on_cpu) + goto done; + if (!uclamp_task_affects(p, clamp_id)) + goto done; + + /* Release p's currently referenced clamp group */ + uclamp_cpu_put_id(p, rq, clamp_id); + + /* Get p's new clamp group */ + uclamp_cpu_get_id(p, rq, clamp_id); + +done: + task_rq_unlock(rq, p, &rf); +} + /** * uclamp_group_put: decrease the reference count for a clamp group * @clamp_id: the clamp index which was affected by a task group @@ -1115,6 +1163,7 @@ static inline void uclamp_group_put(int clamp_id, int group_id) /** * uclamp_group_get: increase the reference count for a clamp group + * @p: the task which clamp value must be tracked * @clamp_id: the clamp index affected by the task * @next_group_id: the clamp group to refcount * @uc_se: the utilization clamp data for the task @@ -1125,7 +1174,8 @@ static inline void uclamp_group_put(int clamp_id, int group_id) * this new clamp value. The corresponding clamp group index will be used by * the task to reference count the clamp value on CPUs while enqueued. */ -static inline void uclamp_group_get(int clamp_id, int next_group_id, +static inline void uclamp_group_get(struct task_struct *p, + int clamp_id, int next_group_id, struct uclamp_se *uc_se, unsigned int clamp_value) { @@ -1144,6 +1194,10 @@ static inline void uclamp_group_get(int clamp_id, int next_group_id, uc_map[next_group_id].se_count += 1; raw_spin_unlock_irqrestore(&uc_map[next_group_id].se_lock, flags); + /* Update CPU's clamp group refcounts of RUNNABLE task */ + if (p) + uclamp_task_update_active(p, clamp_id, next_group_id); + /* Release the previous clamp group */ uclamp_group_put(clamp_id, prev_group_id); } @@ -1202,12 +1256,12 @@ static inline int __setscheduler_uclamp(struct task_struct *p, /* Update each required clamp group */ if (attr->sched_flags & SCHED_FLAG_UTIL_CLAMP_MIN) { uc_se = &p->uclamp[UCLAMP_MIN]; - uclamp_group_get(UCLAMP_MIN, group_id[UCLAMP_MIN], + uclamp_group_get(p, UCLAMP_MIN, group_id[UCLAMP_MIN], uc_se, attr->sched_util_min); } if (attr->sched_flags & SCHED_FLAG_UTIL_CLAMP_MAX) { uc_se = &p->uclamp[UCLAMP_MAX]; - uclamp_group_get(UCLAMP_MAX, group_id[UCLAMP_MAX], + uclamp_group_get(p, UCLAMP_MAX, group_id[UCLAMP_MAX], uc_se, attr->sched_util_max); } @@ -1255,7 +1309,7 @@ static void uclamp_fork(struct task_struct *p, bool reset) } p->uclamp[clamp_id].group_id = UCLAMP_NOT_VALID; - uclamp_group_get(clamp_id, next_group_id, uc_se, + uclamp_group_get(NULL, clamp_id, next_group_id, uc_se, p->uclamp[clamp_id].value); } } @@ -1289,7 +1343,8 @@ static void __init init_uclamp(void) /* Init init_task's clamp group */ uc_se = &init_task.uclamp[clamp_id]; uc_se->group_id = UCLAMP_NOT_VALID; - uclamp_group_get(clamp_id, 0, uc_se, uclamp_none(clamp_id)); + uclamp_group_get(NULL, clamp_id, 0, uc_se, + uclamp_none(clamp_id)); } } diff --git a/kernel/sched/sched.h b/kernel/sched/sched.h index 513608ae4908..25d1d218ae10 100644 --- a/kernel/sched/sched.h +++ b/kernel/sched/sched.h @@ -2210,6 +2210,22 @@ static inline bool uclamp_group_active(struct uclamp_group *uc_grp, { return uc_grp[group_id].tasks > 0; } + +/** + * uclamp_task_affects: check if a task affects a utilization clamp + * @p: the task to consider + * @clamp_id: the utilization clamp to check + * + * A task affects a clamp index if: + * - it's currently enqueued on a CPU + * - it references a valid clamp group index for the specified clamp index + * + * Return: true if p currently affects the specified clamp_id + */ +static inline bool uclamp_task_affects(struct task_struct *p, int clamp_id) +{ + return (p->uclamp[clamp_id].group_id != UCLAMP_NOT_VALID); +} #endif /* CONFIG_UCLAMP_TASK */ #ifdef CONFIG_CPU_FREQ -- 2.18.0
next prev parent reply index Thread overview: 80+ messages / expand[flat|nested] mbox.gz Atom feed top 2018-08-28 13:53 [PATCH v4 00/16] Add utilization clamping support Patrick Bellasi 2018-08-28 13:53 ` [PATCH v4 01/16] sched/core: uclamp: extend sched_setattr to support utilization clamping Patrick Bellasi 2018-09-05 11:01 ` Juri Lelli 2018-08-28 13:53 ` [PATCH v4 02/16] sched/core: uclamp: map TASK's clamp values into CPU's clamp groups Patrick Bellasi 2018-09-05 10:45 ` Juri Lelli 2018-09-06 13:48 ` Patrick Bellasi 2018-09-06 14:13 ` Juri Lelli 2018-09-06 8:17 ` Juri Lelli 2018-09-06 14:00 ` Patrick Bellasi 2018-09-08 23:47 ` Suren Baghdasaryan 2018-09-12 10:32 ` Patrick Bellasi 2018-09-12 13:49 ` Peter Zijlstra 2018-09-12 15:56 ` Patrick Bellasi 2018-09-12 16:12 ` Peter Zijlstra 2018-09-12 17:35 ` Patrick Bellasi 2018-09-12 17:42 ` Peter Zijlstra 2018-09-12 17:52 ` Patrick Bellasi 2018-09-13 19:14 ` Peter Zijlstra 2018-09-14 8:51 ` Patrick Bellasi 2018-09-12 16:24 ` Peter Zijlstra 2018-09-12 17:42 ` Patrick Bellasi 2018-09-13 19:20 ` Peter Zijlstra 2018-09-14 8:47 ` Patrick Bellasi 2018-08-28 13:53 ` [PATCH v4 03/16] sched/core: uclamp: add CPU's clamp groups accounting Patrick Bellasi 2018-09-12 17:34 ` Peter Zijlstra 2018-09-12 17:44 ` Patrick Bellasi 2018-09-13 19:12 ` Peter Zijlstra 2018-09-14 9:07 ` Patrick Bellasi 2018-09-14 11:52 ` Peter Zijlstra 2018-09-14 13:41 ` Patrick Bellasi 2018-08-28 13:53 ` Patrick Bellasi [this message] 2018-08-28 13:53 ` [PATCH v4 05/16] sched/core: uclamp: enforce last task UCLAMP_MAX Patrick Bellasi 2018-08-28 13:53 ` [PATCH v4 06/16] sched/cpufreq: uclamp: add utilization clamping for FAIR tasks Patrick Bellasi 2018-09-14 9:32 ` Peter Zijlstra 2018-09-14 13:19 ` Patrick Bellasi 2018-09-14 13:36 ` Peter Zijlstra 2018-09-14 13:57 ` Patrick Bellasi 2018-09-27 10:23 ` Quentin Perret 2018-08-28 13:53 ` [PATCH v4 07/16] sched/core: uclamp: extend cpu's cgroup controller Patrick Bellasi 2018-08-28 18:29 ` Randy Dunlap 2018-08-29 8:53 ` Patrick Bellasi 2018-08-28 13:53 ` [PATCH v4 08/16] sched/core: uclamp: propagate parent clamps Patrick Bellasi 2018-09-09 3:02 ` Suren Baghdasaryan 2018-09-12 12:51 ` Patrick Bellasi 2018-09-12 15:56 ` Suren Baghdasaryan 2018-09-11 15:18 ` Tejun Heo 2018-09-11 16:26 ` Patrick Bellasi 2018-09-11 16:28 ` Tejun Heo 2018-08-28 13:53 ` [PATCH v4 09/16] sched/core: uclamp: map TG's clamp values into CPU's clamp groups Patrick Bellasi 2018-09-09 18:52 ` Suren Baghdasaryan 2018-09-12 14:19 ` Patrick Bellasi 2018-09-12 15:53 ` Suren Baghdasaryan 2018-08-28 13:53 ` [PATCH v4 10/16] sched/core: uclamp: use TG's clamps to restrict Task's clamps Patrick Bellasi 2018-08-28 13:53 ` [PATCH v4 11/16] sched/core: uclamp: add system default clamps Patrick Bellasi 2018-09-10 16:20 ` Suren Baghdasaryan 2018-09-11 16:46 ` Patrick Bellasi 2018-09-11 19:25 ` Suren Baghdasaryan 2018-08-28 13:53 ` [PATCH v4 12/16] sched/core: uclamp: update CPU's refcount on TG's clamp changes Patrick Bellasi 2018-08-28 13:53 ` [PATCH v4 13/16] sched/core: uclamp: use percentage clamp values Patrick Bellasi 2018-08-28 13:53 ` [PATCH v4 14/16] sched/core: uclamp: request CAP_SYS_ADMIN by default Patrick Bellasi 2018-09-04 13:47 ` Juri Lelli 2018-09-06 14:40 ` Patrick Bellasi 2018-09-06 14:59 ` Juri Lelli 2018-09-06 17:21 ` Patrick Bellasi 2018-09-14 11:10 ` Peter Zijlstra 2018-09-14 14:07 ` Patrick Bellasi 2018-09-14 14:28 ` Peter Zijlstra 2018-09-17 12:27 ` Patrick Bellasi 2018-09-21 9:13 ` Peter Zijlstra 2018-09-24 15:14 ` Patrick Bellasi 2018-09-24 15:56 ` Peter Zijlstra 2018-09-24 17:23 ` Patrick Bellasi 2018-09-24 16:26 ` Peter Zijlstra 2018-09-24 17:19 ` Patrick Bellasi 2018-09-25 15:49 ` Peter Zijlstra 2018-09-26 10:43 ` Patrick Bellasi 2018-09-27 10:00 ` Quentin Perret 2018-09-26 17:51 ` Patrick Bellasi 2018-08-28 13:53 ` [PATCH v4 15/16] sched/core: uclamp: add clamp group discretization support Patrick Bellasi 2018-08-28 13:53 ` [PATCH v4 16/16] sched/cpufreq: uclamp: add utilization clamping for RT tasks Patrick Bellasi
Reply instructions: You may reply publicly to this message via plain-text email using any one of the following methods: * Save the following mbox file, import it into your mail client, and reply-to-all from there: mbox Avoid top-posting and favor interleaved quoting: https://en.wikipedia.org/wiki/Posting_style#Interleaved_style * Reply using the --to, --cc, and --in-reply-to switches of git-send-email(1): git send-email \ --in-reply-to=20180828135324.21976-5-patrick.bellasi@arm.com \ --to=patrick.bellasi@arm.com \ --cc=dietmar.eggemann@arm.com \ --cc=joelaf@google.com \ --cc=juri.lelli@redhat.com \ --cc=linux-kernel@vger.kernel.org \ --cc=linux-pm@vger.kernel.org \ --cc=mingo@redhat.com \ --cc=morten.rasmussen@arm.com \ --cc=peterz@infradead.org \ --cc=pjt@google.com \ --cc=quentin.perret@arm.com \ --cc=rafael.j.wysocki@intel.com \ --cc=smuckle@google.com \ --cc=surenb@google.com \ --cc=tj@kernel.org \ --cc=tkjos@google.com \ --cc=vincent.guittot@linaro.org \ --cc=viresh.kumar@linaro.org \ /path/to/YOUR_REPLY https://kernel.org/pub/software/scm/git/docs/git-send-email.html * If your mail client supports setting the In-Reply-To header via mailto: links, try the mailto: link
LKML Archive on lore.kernel.org Archives are clonable: git clone --mirror https://lore.kernel.org/lkml/0 lkml/git/0.git git clone --mirror https://lore.kernel.org/lkml/1 lkml/git/1.git git clone --mirror https://lore.kernel.org/lkml/2 lkml/git/2.git git clone --mirror https://lore.kernel.org/lkml/3 lkml/git/3.git git clone --mirror https://lore.kernel.org/lkml/4 lkml/git/4.git git clone --mirror https://lore.kernel.org/lkml/5 lkml/git/5.git git clone --mirror https://lore.kernel.org/lkml/6 lkml/git/6.git git clone --mirror https://lore.kernel.org/lkml/7 lkml/git/7.git git clone --mirror https://lore.kernel.org/lkml/8 lkml/git/8.git git clone --mirror https://lore.kernel.org/lkml/9 lkml/git/9.git # If you have public-inbox 1.1+ installed, you may # initialize and index your mirror using the following commands: public-inbox-init -V2 lkml lkml/ https://lore.kernel.org/lkml \ linux-kernel@vger.kernel.org public-inbox-index lkml Example config snippet for mirrors Newsgroup available over NNTP: nntp://nntp.lore.kernel.org/org.kernel.vger.linux-kernel AGPL code for this site: git clone https://public-inbox.org/public-inbox.git