From: Patrick Bellasi <patrick.bellasi@arm.com>
To: Peter Zijlstra <peterz@infradead.org>, Ingo Molnar <mingo@redhat.com>
Cc: linux-kernel@vger.kernel.org, linux-pm@vger.kernel.org
Subject: [RFC PATCH 14/14] sched/{fair,tune}: track RUNNABLE tasks impact on per CPU boost value
Date: Wed, 19 Aug 2015 19:47:24 +0100 [thread overview]
Message-ID: <1440010044-3402-15-git-send-email-patrick.bellasi@arm.com> (raw)
In-Reply-To: <1440010044-3402-1-git-send-email-patrick.bellasi@arm.com>
When per-task boosting is enabled, every time a task enters/exits a CPU
its boost value could impact the currently selected OPP for that CPU.
Thus, the "aggregated" boost value for that CPU potentially needs to
be updated to match the current maximum boost value among all the tasks
currently RUNNABLE on that CPU.
This patch introduces the required support to keep track of which boost
groups are impacting a CPU. Each time a task is enqueued/dequeued to/from
a CPU its boost group is used to increment a per-cpu counter of RUNNABLE
tasks on that CPU.
Only when the number of runnable tasks for a specific boost group
becomes 1 or 0 the corresponding boost group changes its effects on
that CPU, specifically:
a) boost_group::tasks == 1: this boost group starts to impact the CPU
b) boost_group::tasks == 0: this boost group stops to impact the CPU
In each of these two conditions the aggregation function:
sched_cpu_update(cpu)
could be required to run in order to identify the new maximum boost
value required for the CPU.
The proposed patch minimizes the number of times the aggregation
function is executed while still providing the required support to
always boost a CPU to the maximum boost value required by all its
currently RUNNABLE tasks.
cc: Ingo Molnar <mingo@redhat.com>
cc: Peter Zijlstra <peterz@infradead.org>
Signed-off-by: Patrick Bellasi <patrick.bellasi@arm.com>
---
kernel/sched/fair.c | 17 +++++++---
kernel/sched/tune.c | 94 +++++++++++++++++++++++++++++++++++++++++++++++++++++
kernel/sched/tune.h | 23 +++++++++++++
3 files changed, 130 insertions(+), 4 deletions(-)
create mode 100644 kernel/sched/tune.h
diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c
index 633fcab4..98470c4 100644
--- a/kernel/sched/fair.c
+++ b/kernel/sched/fair.c
@@ -34,6 +34,7 @@
#include <trace/events/sched.h>
#include "sched.h"
+#include "tune.h"
/*
* Targeted preemption latency for CPU-bound tasks:
@@ -4145,6 +4146,8 @@ enqueue_task_fair(struct rq *rq, struct task_struct *p, int flags)
if (!se) {
add_nr_running(rq, 1);
+ schedtune_enqueue_task(p, cpu_of(rq));
+
/*
* We want to potentially trigger a freq switch request only for
* tasks that are waking up; this is because we get here also during
@@ -4213,6 +4216,7 @@ static void dequeue_task_fair(struct rq *rq, struct task_struct *p, int flags)
if (!se) {
sub_nr_running(rq, 1);
+ schedtune_dequeue_task(p, cpu_of(rq));
/*
* We want to potentially trigger a freq switch request only for
@@ -4769,10 +4773,15 @@ schedtune_margin(unsigned long signal, unsigned long boost)
}
static inline unsigned int
-schedtune_cpu_margin(unsigned long util)
+schedtune_cpu_margin(unsigned long util, int cpu)
{
- unsigned int boost = get_sysctl_sched_cfs_boost();
+ unsigned int boost;
+#ifdef CONFIG_CGROUP_SCHEDTUNE
+ boost = schedtune_cpu_boost(cpu);
+#else
+ boost = get_sysctl_sched_cfs_boost();
+#endif
if (boost == 0)
return 0;
@@ -4782,7 +4791,7 @@ schedtune_cpu_margin(unsigned long util)
#else /* CONFIG_SCHED_TUNE */
static inline unsigned int
-schedtune_cpu_margin(unsigned long util)
+schedtune_cpu_margin(unsigned long util, int cpu)
{
return 0;
}
@@ -4793,7 +4802,7 @@ static inline unsigned long
boosted_cpu_util(int cpu)
{
unsigned long util = cpu_util(cpu);
- unsigned long margin = schedtune_cpu_margin(util);
+ unsigned long margin = schedtune_cpu_margin(util, cpu);
return util + margin;
}
diff --git a/kernel/sched/tune.c b/kernel/sched/tune.c
index 3223ef3..3838106 100644
--- a/kernel/sched/tune.c
+++ b/kernel/sched/tune.c
@@ -2,6 +2,7 @@
#include <linux/err.h>
#include <linux/percpu.h>
#include <linux/printk.h>
+#include <linux/rcupdate.h>
#include <linux/slab.h>
#include "sched.h"
@@ -158,6 +159,87 @@ schedtune_boostgroup_update(int idx, int boost)
return 0;
}
+static inline void
+schedtune_tasks_update(struct task_struct *p, int cpu, int idx, int task_count)
+{
+ struct boost_groups *bg;
+ int tasks;
+
+ bg = &per_cpu(cpu_boost_groups, cpu);
+
+ /* Update boosted tasks count while avoiding to make it negative */
+ if (task_count < 0 && bg->group[idx].tasks <= -task_count)
+ bg->group[idx].tasks = 0;
+ else
+ bg->group[idx].tasks += task_count;
+
+ /* Boost group activation or deactivation on that RQ */
+ tasks = bg->group[idx].tasks;
+ if (tasks == 1 || tasks == 0)
+ schedtune_cpu_update(cpu);
+}
+
+/*
+ * NOTE: This function must be called while holding the lock on the CPU RQ
+ */
+void schedtune_enqueue_task(struct task_struct *p, int cpu)
+{
+ struct schedtune *st;
+ int idx;
+
+ /*
+ * When a task is marked PF_EXITING by do_exit() it's going to be
+ * dequeued and enqueued multiple times in the exit path.
+ * Thus we avoid any further update, since we do not want to change
+ * CPU boosting while the task is exiting.
+ */
+ if (p->flags & PF_EXITING)
+ return;
+
+ /* Get task boost group */
+ rcu_read_lock();
+ st = task_schedtune(p);
+ idx = st->idx;
+ rcu_read_unlock();
+
+ schedtune_tasks_update(p, cpu, idx, 1);
+}
+
+/*
+ * NOTE: This function must be called while holding the lock on the CPU RQ
+ */
+void schedtune_dequeue_task(struct task_struct *p, int cpu)
+{
+ struct schedtune *st;
+ int idx;
+
+ /*
+ * When a task is marked PF_EXITING by do_exit() it's going to be
+ * dequeued and enqueued multiple times in the exit path.
+ * Thus we avoid any further update, since we do not want to change
+ * CPU boosting while the task is exiting.
+ * The last dequeue will be done by cgroup exit() callback.
+ */
+ if (p->flags & PF_EXITING)
+ return;
+
+ /* Get task boost group */
+ rcu_read_lock();
+ st = task_schedtune(p);
+ idx = st->idx;
+ rcu_read_unlock();
+
+ schedtune_tasks_update(p, cpu, idx, -1);
+}
+
+int schedtune_cpu_boost(int cpu)
+{
+ struct boost_groups *bg;
+
+ bg = &per_cpu(cpu_boost_groups, cpu);
+ return bg->boost_max;
+}
+
static u64
boost_read(struct cgroup_subsys_state *css, struct cftype *cft)
{
@@ -293,9 +375,21 @@ schedtune_css_free(struct cgroup_subsys_state *css)
kfree(st);
}
+static void
+schedtune_exit(struct cgroup_subsys_state *css,
+ struct cgroup_subsys_state *old_css,
+ struct task_struct *tsk)
+{
+ struct schedtune *old_st = css_st(old_css);
+ int cpu = task_cpu(tsk);
+
+ schedtune_tasks_update(tsk, cpu, old_st->idx, -1);
+}
+
struct cgroup_subsys schedtune_cgrp_subsys = {
.css_alloc = schedtune_css_alloc,
.css_free = schedtune_css_free,
+ .exit = schedtune_exit,
.legacy_cftypes = files,
.early_init = 1,
};
diff --git a/kernel/sched/tune.h b/kernel/sched/tune.h
new file mode 100644
index 0000000..4519028
--- /dev/null
+++ b/kernel/sched/tune.h
@@ -0,0 +1,23 @@
+
+#ifdef CONFIG_SCHED_TUNE
+
+#ifdef CONFIG_CGROUP_SCHEDTUNE
+
+extern int schedtune_cpu_boost(int cpu);
+
+extern void schedtune_enqueue_task(struct task_struct *p, int cpu);
+extern void schedtune_dequeue_task(struct task_struct *p, int cpu);
+
+#else /* CONFIG_CGROUP_SCHEDTUNE */
+
+#define schedtune_enqueue_task(task, cpu) do { } while (0)
+#define schedtune_dequeue_task(task, cpu) do { } while (0)
+
+#endif /* CONFIG_CGROUP_SCHEDTUNE */
+
+#else /* CONFIG_SCHED_TUNE */
+
+#define schedtune_enqueue_task(task, cpu) do { } while (0)
+#define schedtune_dequeue_task(task, cpu) do { } while (0)
+
+#endif /* CONFIG_SCHED_TUNE */
--
2.5.0
prev parent reply other threads:[~2015-08-19 18:48 UTC|newest]
Thread overview: 29+ messages / expand[flat|nested] mbox.gz Atom feed top
2015-08-19 18:47 [RFC PATCH 00/14] sched: Central, scheduler-driven, power-perfomance control Patrick Bellasi
2015-08-19 18:47 ` [RFC PATCH 01/14] sched/cpufreq_sched: use static key for cpu frequency selection Patrick Bellasi
2015-08-19 18:47 ` [RFC PATCH 02/14] sched/fair: add triggers for OPP change requests Patrick Bellasi
2015-08-19 18:47 ` [RFC PATCH 03/14] sched/{core,fair}: trigger OPP change request on fork() Patrick Bellasi
2015-08-19 18:47 ` [RFC PATCH 04/14] sched/{fair,cpufreq_sched}: add reset_capacity interface Patrick Bellasi
2015-08-19 18:47 ` [RFC PATCH 05/14] sched/fair: jump to max OPP when crossing UP threshold Patrick Bellasi
2015-08-19 18:47 ` [RFC PATCH 06/14] sched/cpufreq_sched: modify pcpu_capacity handling Patrick Bellasi
2015-08-19 18:47 ` [RFC PATCH 07/14] sched/fair: cpufreq_sched triggers for load balancing Patrick Bellasi
2015-08-19 18:47 ` [RFC PATCH 08/14] sched/tune: add detailed documentation Patrick Bellasi
2015-09-02 6:49 ` [RFC,08/14] " Ricky Liang
2015-09-03 9:18 ` [RFC 08/14] " Patrick Bellasi
2015-09-04 7:59 ` Ricky Liang
2015-09-09 20:16 ` Steve Muckle
2015-09-11 11:09 ` Patrick Bellasi
2015-09-14 20:00 ` Steve Muckle
2015-09-15 15:00 ` Patrick Bellasi
2015-09-15 15:19 ` Peter Zijlstra
2015-09-16 0:34 ` Steve Muckle
2015-09-16 7:47 ` Ingo Molnar
2015-09-15 23:55 ` Steve Muckle
2015-09-16 9:26 ` Juri Lelli
2015-09-16 13:49 ` Vincent Guittot
2015-09-16 10:03 ` Patrick Bellasi
2015-08-19 18:47 ` [RFC PATCH 09/14] sched/tune: add sysctl interface to define a boost value Patrick Bellasi
2015-08-19 18:47 ` [RFC PATCH 10/14] sched/fair: add function to convert boost value into "margin" Patrick Bellasi
2015-08-19 18:47 ` [RFC PATCH 11/14] sched/fair: add boosted CPU usage Patrick Bellasi
2015-08-19 18:47 ` [RFC PATCH 12/14] sched/tune: add initial support for CGroups based boosting Patrick Bellasi
2015-08-19 18:47 ` [RFC PATCH 13/14] sched/tune: compute and keep track of per CPU boost value Patrick Bellasi
2015-08-19 18:47 ` Patrick Bellasi [this message]
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=1440010044-3402-15-git-send-email-patrick.bellasi@arm.com \
--to=patrick.bellasi@arm.com \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-pm@vger.kernel.org \
--cc=mingo@redhat.com \
--cc=peterz@infradead.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
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
Powered by JetHome