Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > linux.kernel > #1474600 > unrolled thread
| Started by | Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com> |
|---|---|
| First post | 2016-09-01 23:10 +0200 |
| Last post | 2016-09-08 10:10 +0200 |
| Articles | 10 — 3 participants |
Back to article view | Back to linux.kernel
[PATCH v2 0/8] Support Intel® Turbo Boost Max Technology 3.0 Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com> - 2016-09-01 23:10 +0200
[PATCH v2 4/8] sched, x86: use arch_update_cpu_topology to indicate x86 need sched domain rebuild Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com> - 2016-09-01 23:10 +0200
[PATCH v2 6/8] acpi: bus: Enable HWP CPPC objects Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com> - 2016-09-01 23:20 +0200
[PATCH v2 8/8] cpufreq: intel_pstate: Use CPPC to get max performance Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com> - 2016-09-01 23:20 +0200
[PATCH v2 3/8] x86, cpu: provide a function topology_num_packages to enumerate #packages Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com> - 2016-09-01 23:20 +0200
[PATCH v2 2/8] sched: Extend scheduler's asym packing Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com> - 2016-09-01 23:30 +0200
Re: [PATCH v2 2/8] sched: Extend scheduler's asym packing Peter Zijlstra <peterz@infradead.org> - 2016-09-08 10:10 +0200
Re: [PATCH v2 2/8] sched: Extend scheduler's asym packing Tim Chen <tim.c.chen@linux.intel.com> - 2016-09-08 20:10 +0200
Re: [PATCH v2 2/8] sched: Extend scheduler's asym packing Peter Zijlstra <peterz@infradead.org> - 2016-09-08 20:30 +0200
Re: [PATCH v2 0/8] Support Intel® Turbo Boost Max Technology 3.0 Peter Zijlstra <peterz@infradead.org> - 2016-09-08 10:10 +0200
| From | Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com> |
|---|---|
| Date | 2016-09-01 23:10 +0200 |
| Subject | [PATCH v2 0/8] Support Intel® Turbo Boost Max Technology 3.0 |
| Message-ID | <scHpf-70l-11@gated-at.bofh.it> |
v2
- The patchset is split into two parts so that CPPC changes can be merged first
1. Only ACPI CPPC changes (It is posted separately)
2. ITMT changes (scheduler and Intel P-State)
- Changes in patch: sched,x86: Enable Turbo Boost Max Technology
1. Use arch_update_cpu_topology to indicate need to completely
rebuild sched domain when ITMT related sched domain flags change
2. Enable client (single node) platform capable of ITMT with ITMT
scheduling by default
3. Implement arch_asym_cpu_priority to provide the cpu priority
value to scheduler for asym packing.
4. Fix a compile bug for i386 architecture.
- Changes in patch: sched: Extend scheduler's asym packing
1. Use arch_asym_cpu_priority() to provide cpu priority
value used for asym packing to the scheduler.
- Changes in acpi: bus: Enable HWP CPPC objects and
acpi: bus: Set _OSC for diverse core support
Minor code cleanup by removing #ifdef
- Changes in Kconfig for Intel P-State
Avoid building CPPC lib for i386 for issue reported by 0-day
- Feature is enabled by default for single socket systems
With Intel® Turbo Boost Max Technology 3.0 (ITMT), single-threaded performance is
optimized by identifying processor's fastest core and running critical workloads
on it.
Refere to:
http://www.intel.com/content/www/us/en/architecture-and-technology/turbo-boost/turbo-boost-max-technology.html
This patchset consist of all changes required to support ITMT feature:
- Use CPPC information in Intel P-State driver to get performance information
- Scheduler enhancements
- cppc lib patches (split in to a seprate series)
This featured can be enabled by writing at runtime
# echo 1 > /proc/sys/kernel/sched_itmt_enabled
This featured can be disabled by writing at runtime
# echo 0 > /proc/sys/kernel/sched_itmt_enabled
Srinivas Pandruvada (3):
acpi: bus: Enable HWP CPPC objects
acpi: bus: Set _OSC for diverse core support
cpufreq: intel_pstate: Use CPPC to get max performance
Tim Chen (5):
sched, x86: Add SD_ASYM_PACKING flags to x86 cpu topology for ITMT
sched: Extend scheduler's asym packing
x86, cpu: provide a function topology_num_packages to enumerate
#packages
sched, x86: use arch_update_cpu_topology to indicate x86 need sched
domain rebuild
sched,x86: Enable Turbo Boost Max Technology
arch/x86/Kconfig | 9 +++
arch/x86/include/asm/topology.h | 25 +++++++
arch/x86/kernel/Makefile | 1 +
arch/x86/kernel/itmt.c | 161 ++++++++++++++++++++++++++++++++++++++++
arch/x86/kernel/smpboot.c | 92 ++++++++++++++++++-----
drivers/acpi/bus.c | 8 ++
drivers/cpufreq/Kconfig.x86 | 1 +
drivers/cpufreq/intel_pstate.c | 75 ++++++++++++++++++-
include/linux/acpi.h | 1 +
include/linux/sched.h | 2 +
kernel/sched/core.c | 21 ++++++
kernel/sched/fair.c | 35 ++++++---
kernel/sched/sched.h | 12 +++
13 files changed, 411 insertions(+), 32 deletions(-)
create mode 100644 arch/x86/kernel/itmt.c
--
2.7.4
[toc] | [next] | [standalone]
| From | Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com> |
|---|---|
| Date | 2016-09-01 23:10 +0200 |
| Subject | [PATCH v2 4/8] sched, x86: use arch_update_cpu_topology to indicate x86 need sched domain rebuild |
| Message-ID | <scHph-70l-79@gated-at.bofh.it> |
| In reply to | #1474600 |
From: Tim Chen <tim.c.chen@linux.intel.com>
Provides x86 with arch_update_cpu_topology function. This function
allows us to indicate that a condition is detected that the sched
domain of x86 needs a complete rebuild. This is done by setting the
x86_topology_update flag.
Signed-off-by: Tim Chen <tim.c.chen@linux.intel.com>
Signed-off-by: Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com>
---
arch/x86/include/asm/topology.h | 2 ++
arch/x86/kernel/smpboot.c | 11 +++++++++++
2 files changed, 13 insertions(+)
diff --git a/arch/x86/include/asm/topology.h b/arch/x86/include/asm/topology.h
index 0bcf3b7..8d6df77 100644
--- a/arch/x86/include/asm/topology.h
+++ b/arch/x86/include/asm/topology.h
@@ -147,6 +147,8 @@ struct pci_bus;
int x86_pci_root_bus_node(int bus);
void x86_pci_root_bus_resources(int bus, struct list_head *resources);
+extern bool x86_topology_update;
+
#ifdef CONFIG_SCHED_ITMT
extern unsigned int __read_mostly sysctl_sched_itmt_enabled;
#endif /* CONFIG_SCHED_ITMT */
diff --git a/arch/x86/kernel/smpboot.c b/arch/x86/kernel/smpboot.c
index 292df31..737b9edf 100644
--- a/arch/x86/kernel/smpboot.c
+++ b/arch/x86/kernel/smpboot.c
@@ -110,6 +110,17 @@ static bool logical_packages_frozen __read_mostly;
int __max_smt_threads __read_mostly;
unsigned int __read_mostly sysctl_sched_itmt_enabled;
+/* Flag to indicate if a complete sched domain rebuild is required */
+bool x86_topology_update;
+
+int arch_update_cpu_topology(void)
+{
+ if (x86_topology_update) {
+ x86_topology_update = false;
+ return 1;
+ } else
+ return 0;
+}
static inline void smpboot_setup_warm_reset_vector(unsigned long start_eip)
{
--
2.7.4
[toc] | [prev] | [next] | [standalone]
| From | Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com> |
|---|---|
| Date | 2016-09-01 23:20 +0200 |
| Subject | [PATCH v2 6/8] acpi: bus: Enable HWP CPPC objects |
| Message-ID | <scHyX-75a-37@gated-at.bofh.it> |
| In reply to | #1474600 |
Need to set platform wide _OSC bits to enable CPPC and CPPC version 2.
If platform supports CPPC, then BIOS exposess CPPC tables.
Signed-off-by: Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com>
---
drivers/acpi/bus.c | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/drivers/acpi/bus.c b/drivers/acpi/bus.c
index 85b7d07..1001b92 100644
--- a/drivers/acpi/bus.c
+++ b/drivers/acpi/bus.c
@@ -330,6 +330,11 @@ static void acpi_bus_osc_support(void)
capbuf[OSC_SUPPORT_DWORD] |= OSC_SB_HOTPLUG_OST_SUPPORT;
capbuf[OSC_SUPPORT_DWORD] |= OSC_SB_PCLPI_SUPPORT;
+ if (IS_ENABLED(CONFIG_X86) && boot_cpu_has(X86_FEATURE_HWP)) {
+ capbuf[OSC_SUPPORT_DWORD] |= OSC_SB_CPC_SUPPORT;
+ capbuf[OSC_SUPPORT_DWORD] |= OSC_SB_CPCV2_SUPPORT;
+ }
+
if (!ghes_disable)
capbuf[OSC_SUPPORT_DWORD] |= OSC_SB_APEI_SUPPORT;
if (ACPI_FAILURE(acpi_get_handle(NULL, "\\_SB", &handle)))
--
2.7.4
[toc] | [prev] | [next] | [standalone]
| From | Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com> |
|---|---|
| Date | 2016-09-01 23:20 +0200 |
| Subject | [PATCH v2 8/8] cpufreq: intel_pstate: Use CPPC to get max performance |
| Message-ID | <scHyX-75a-39@gated-at.bofh.it> |
| In reply to | #1474600 |
This change uses acpi cppc_lib interface to get CPPC performance limits.
Once CPPC limits of all online cores are read, first check if there is
difference in max performance. If there is a difference, then the
scheduler interface is called to update per cpu priority. After updating
priority of all current cpus, the itmt feature is enabled.
Signed-off-by: Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com>
---
drivers/cpufreq/Kconfig.x86 | 1 +
drivers/cpufreq/intel_pstate.c | 75 ++++++++++++++++++++++++++++++++++++++++--
2 files changed, 73 insertions(+), 3 deletions(-)
diff --git a/drivers/cpufreq/Kconfig.x86 b/drivers/cpufreq/Kconfig.x86
index adbd1de..3328c6b 100644
--- a/drivers/cpufreq/Kconfig.x86
+++ b/drivers/cpufreq/Kconfig.x86
@@ -6,6 +6,7 @@ config X86_INTEL_PSTATE
bool "Intel P state control"
depends on X86
select ACPI_PROCESSOR if ACPI
+ select ACPI_CPPC_LIB if X86_64 && ACPI
help
This driver provides a P state for Intel core processors.
The driver implements an internal governor and will become
diff --git a/drivers/cpufreq/intel_pstate.c b/drivers/cpufreq/intel_pstate.c
index bdbe936..a0bf244 100644
--- a/drivers/cpufreq/intel_pstate.c
+++ b/drivers/cpufreq/intel_pstate.c
@@ -44,6 +44,7 @@
#ifdef CONFIG_ACPI
#include <acpi/processor.h>
+#include <acpi/cppc_acpi.h>
#endif
#define FRAC_BITS 8
@@ -193,6 +194,8 @@ struct _pid {
* @sample: Storage for storing last Sample data
* @acpi_perf_data: Stores ACPI perf information read from _PSS
* @valid_pss_table: Set to true for valid ACPI _PSS entries found
+ * @cppc_data: Stores CPPC information for HWP capable CPUs
+ * @valid_cppc_table: Set to true for valid CPPC entries are found
*
* This structure stores per CPU instance data for all CPUs.
*/
@@ -215,6 +218,8 @@ struct cpudata {
#ifdef CONFIG_ACPI
struct acpi_processor_performance acpi_perf_data;
bool valid_pss_table;
+ struct cppc_cpudata *cppc_data;
+ bool valid_cppc_table;
#endif
};
@@ -361,6 +366,15 @@ static struct perf_limits *limits = &powersave_limits;
#endif
#ifdef CONFIG_ACPI
+static cpumask_t cppc_rd_cpu_mask;
+
+/* Call set_sched_itmt from a work function to be able to use hotplug locks */
+static void intel_pstste_sched_itmt_work_fn(struct work_struct *work)
+{
+ set_sched_itmt(true);
+}
+
+static DECLARE_WORK(sched_itmt_work, intel_pstste_sched_itmt_work_fn);
static bool intel_pstate_get_ppc_enable_status(void)
{
@@ -377,14 +391,63 @@ static void intel_pstate_init_acpi_perf_limits(struct cpufreq_policy *policy)
int ret;
int i;
- if (hwp_active)
+ cpu = all_cpu_data[policy->cpu];
+
+ if (hwp_active) {
+ struct cppc_perf_caps *perf_caps;
+
+ cpu->cppc_data = kzalloc(sizeof(struct cppc_cpudata),
+ GFP_KERNEL);
+ if (!cpu->cppc_data)
+ return;
+
+ perf_caps = &cpu->cppc_data->perf_caps;
+ ret = cppc_get_perf_caps(policy->cpu, perf_caps);
+ if (ret) {
+ kfree(cpu->cppc_data);
+ return;
+ }
+
+ cpu->valid_cppc_table = true;
+ pr_debug("cpu:%d H:0x%x N:0x%x L:0x%x\n", policy->cpu,
+ perf_caps->highest_perf, perf_caps->nominal_perf,
+ perf_caps->lowest_perf);
+
+ cpumask_set_cpu(policy->cpu, &cppc_rd_cpu_mask);
+ if (cpumask_subset(topology_core_cpumask(policy->cpu),
+ &cppc_rd_cpu_mask)) {
+ int cpu_index;
+ int max_prio;
+ bool itmt_support = false;
+
+ cpu = all_cpu_data[0];
+ max_prio = cpu->cppc_data->perf_caps.highest_perf;
+ for_each_cpu(cpu_index, &cppc_rd_cpu_mask) {
+ cpu = all_cpu_data[cpu_index];
+ perf_caps = &cpu->cppc_data->perf_caps;
+ if (max_prio != perf_caps->highest_perf) {
+ itmt_support = true;
+ break;
+ }
+ }
+
+ if (!itmt_support)
+ return;
+
+ for_each_cpu(cpu_index, &cppc_rd_cpu_mask) {
+ cpu = all_cpu_data[cpu_index];
+ perf_caps = &cpu->cppc_data->perf_caps;
+ sched_set_itmt_core_prio(
+ perf_caps->highest_perf, cpu_index);
+ }
+ schedule_work(&sched_itmt_work);
+ }
return;
+ }
if (!intel_pstate_get_ppc_enable_status())
return;
- cpu = all_cpu_data[policy->cpu];
-
ret = acpi_processor_register_performance(&cpu->acpi_perf_data,
policy->cpu);
if (ret)
@@ -444,6 +507,12 @@ static void intel_pstate_exit_perf_limits(struct cpufreq_policy *policy)
struct cpudata *cpu;
cpu = all_cpu_data[policy->cpu];
+
+ if (cpu->valid_cppc_table) {
+ cpumask_clear_cpu(policy->cpu, &cppc_rd_cpu_mask);
+ kfree(cpu->cppc_data);
+ }
+
if (!cpu->valid_pss_table)
return;
--
2.7.4
[toc] | [prev] | [next] | [standalone]
| From | Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com> |
|---|---|
| Date | 2016-09-01 23:20 +0200 |
| Subject | [PATCH v2 3/8] x86, cpu: provide a function topology_num_packages to enumerate #packages |
| Message-ID | <scHyY-75a-77@gated-at.bofh.it> |
| In reply to | #1474600 |
From: Tim Chen <tim.c.chen@linux.intel.com>
We compute the the number of active packages during boot and
topology update. Provide a function to export this info for
functions that need this topology info.
Signed-off-by: Tim Chen <tim.c.chen@linux.intel.com>
Signed-off-by: Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com>
---
arch/x86/include/asm/topology.h | 1 +
arch/x86/kernel/smpboot.c | 5 +++++
2 files changed, 6 insertions(+)
diff --git a/arch/x86/include/asm/topology.h b/arch/x86/include/asm/topology.h
index 98b669d..0bcf3b7 100644
--- a/arch/x86/include/asm/topology.h
+++ b/arch/x86/include/asm/topology.h
@@ -129,6 +129,7 @@ static inline int topology_max_smt_threads(void)
}
int topology_update_package_map(unsigned int apicid, unsigned int cpu);
+extern int topology_num_packages(void);
extern int topology_phys_to_logical_pkg(unsigned int pkg);
#else
#define topology_max_packages() (1)
diff --git a/arch/x86/kernel/smpboot.c b/arch/x86/kernel/smpboot.c
index 3782bd4..292df31 100644
--- a/arch/x86/kernel/smpboot.c
+++ b/arch/x86/kernel/smpboot.c
@@ -297,6 +297,11 @@ found:
return 0;
}
+int topology_num_packages(void)
+{
+ return logical_packages;
+}
+
/**
* topology_phys_to_logical_pkg - Map a physical package id to a logical
*
--
2.7.4
[toc] | [prev] | [next] | [standalone]
| From | Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com> |
|---|---|
| Date | 2016-09-01 23:30 +0200 |
| Subject | [PATCH v2 2/8] sched: Extend scheduler's asym packing |
| Message-ID | <scHIC-79t-39@gated-at.bofh.it> |
| In reply to | #1474600 |
From: Tim Chen <tim.c.chen@linux.intel.com>
We generalize the scheduler's asym packing to provide an ordering
of the cpu beyond just the cpu number. This allows the use of the
ASYM_PACKING scheduler machinery to move loads to preferred CPU in a
sched domain. The preference is defined with the cpu priority
given by arch_asym_cpu_priority(cpu).
We also record the most preferred cpu in a sched group when
we build the cpu's capacity for fast lookup of preferred cpu
during load balancing.
Signed-off-by: Tim Chen <tim.c.chen@linux.intel.com>
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Signed-off-by: Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com>
---
include/linux/sched.h | 2 ++
kernel/sched/core.c | 18 ++++++++++++++++++
kernel/sched/fair.c | 35 ++++++++++++++++++++++++-----------
kernel/sched/sched.h | 12 ++++++++++++
4 files changed, 56 insertions(+), 11 deletions(-)
diff --git a/include/linux/sched.h b/include/linux/sched.h
index b0fa726..15d3f29 100644
--- a/include/linux/sched.h
+++ b/include/linux/sched.h
@@ -1052,6 +1052,8 @@ static inline int cpu_numa_flags(void)
}
#endif
+int arch_asym_cpu_priority(int cpu);
+
struct sched_domain_attr {
int relax_domain_level;
};
diff --git a/kernel/sched/core.c b/kernel/sched/core.c
index e86c4a5..08135ca 100644
--- a/kernel/sched/core.c
+++ b/kernel/sched/core.c
@@ -6237,7 +6237,25 @@ static void init_sched_groups_capacity(int cpu, struct sched_domain *sd)
WARN_ON(!sg);
do {
+ int cpu, max_cpu = -1, prev_cpu = -1;
+
sg->group_weight = cpumask_weight(sched_group_cpus(sg));
+
+ if (!(sd->flags & SD_ASYM_PACKING))
+ goto next;
+
+ for_each_cpu(cpu, sched_group_cpus(sg)) {
+ if (prev_cpu < 0) {
+ prev_cpu = cpu;
+ max_cpu = cpu;
+ } else {
+ if (sched_asym_prefer(cpu, max_cpu))
+ max_cpu = cpu;
+ }
+ }
+ sg->asym_prefer_cpu = max_cpu;
+
+next:
sg = sg->next;
} while (sg != sd->groups);
diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c
index 5d558cc..d8f51d9 100644
--- a/kernel/sched/fair.c
+++ b/kernel/sched/fair.c
@@ -100,6 +100,16 @@ const_debug unsigned int sysctl_sched_migration_cost = 500000UL;
*/
unsigned int __read_mostly sysctl_sched_shares_window = 10000000UL;
+#ifdef CONFIG_SMP
+/*
+ * For asym packing, by default the lower numbered cpu has higher priority.
+ */
+int __weak arch_asym_cpu_priority(int cpu)
+{
+ return -cpu;
+}
+#endif
+
#ifdef CONFIG_CFS_BANDWIDTH
/*
* Amount of runtime to allocate from global (tg) to local (per-cfs_rq) pool
@@ -6853,16 +6863,18 @@ static bool update_sd_pick_busiest(struct lb_env *env,
if (env->idle == CPU_NOT_IDLE)
return true;
/*
- * ASYM_PACKING needs to move all the work to the lowest
- * numbered CPUs in the group, therefore mark all groups
- * higher than ourself as busy.
+ * ASYM_PACKING needs to move all the work to the highest
+ * prority CPUs in the group, therefore mark all groups
+ * of lower priority than ourself as busy.
*/
- if (sgs->sum_nr_running && env->dst_cpu < group_first_cpu(sg)) {
+ if (sgs->sum_nr_running &&
+ sched_asym_prefer(env->dst_cpu, group_priority_cpu(sg))) {
if (!sds->busiest)
return true;
- /* Prefer to move from highest possible cpu's work */
- if (group_first_cpu(sds->busiest) < group_first_cpu(sg))
+ /* Prefer to move from lowest priority cpu's work */
+ if (sched_asym_prefer(group_priority_cpu(sds->busiest),
+ group_priority_cpu(sg)))
return true;
}
@@ -7014,8 +7026,8 @@ static int check_asym_packing(struct lb_env *env, struct sd_lb_stats *sds)
if (!sds->busiest)
return 0;
- busiest_cpu = group_first_cpu(sds->busiest);
- if (env->dst_cpu > busiest_cpu)
+ busiest_cpu = group_priority_cpu(sds->busiest);
+ if (sched_asym_prefer(busiest_cpu, env->dst_cpu))
return 0;
env->imbalance = DIV_ROUND_CLOSEST(
@@ -7356,10 +7368,11 @@ static int need_active_balance(struct lb_env *env)
/*
* ASYM_PACKING needs to force migrate tasks from busy but
- * higher numbered CPUs in order to pack all tasks in the
- * lowest numbered CPUs.
+ * lower priority CPUs in order to pack all tasks in the
+ * highest priority CPUs.
*/
- if ((sd->flags & SD_ASYM_PACKING) && env->src_cpu > env->dst_cpu)
+ if ((sd->flags & SD_ASYM_PACKING) &&
+ sched_asym_prefer(env->dst_cpu, env->src_cpu))
return 1;
}
diff --git a/kernel/sched/sched.h b/kernel/sched/sched.h
index b7fc1ce..f338934 100644
--- a/kernel/sched/sched.h
+++ b/kernel/sched/sched.h
@@ -532,6 +532,17 @@ struct dl_rq {
#ifdef CONFIG_SMP
+static inline bool sched_asym_prefer(int a, int b)
+{
+ return arch_asym_cpu_priority(a) > arch_asym_cpu_priority(b);
+}
+
+/*
+ * Return lowest numbered cpu in the group as the most preferred cpu
+ * for ASYM_PACKING for default case.
+ */
+#define group_priority_cpu(group) group->asym_prefer_cpu
+
/*
* We add the notion of a root-domain which will be used to define per-domain
* variables. Each exclusive cpuset essentially defines an island domain by
@@ -884,6 +895,7 @@ struct sched_group {
unsigned int group_weight;
struct sched_group_capacity *sgc;
+ int asym_prefer_cpu; /* cpu of highest priority in group */
/*
* The CPUs this group covers.
--
2.7.4
[toc] | [prev] | [next] | [standalone]
| From | Peter Zijlstra <peterz@infradead.org> |
|---|---|
| Date | 2016-09-08 10:10 +0200 |
| Subject | Re: [PATCH v2 2/8] sched: Extend scheduler's asym packing |
| Message-ID | <sf2zf-3eC-9@gated-at.bofh.it> |
| In reply to | #1474655 |
On Thu, Sep 01, 2016 at 01:33:38PM -0700, Srinivas Pandruvada wrote:
> +++ b/kernel/sched/sched.h
> @@ -532,6 +532,17 @@ struct dl_rq {
>
> #ifdef CONFIG_SMP
>
> +static inline bool sched_asym_prefer(int a, int b)
> +{
> + return arch_asym_cpu_priority(a) > arch_asym_cpu_priority(b);
> +}
> +
> +/*
> + * Return lowest numbered cpu in the group as the most preferred cpu
> + * for ASYM_PACKING for default case.
> + */
> +#define group_priority_cpu(group) group->asym_prefer_cpu
> +
Both these are no longer used outside of sched/fair.c, and should
probably be moved there. Also the later has no reason for being a macro.
[toc] | [prev] | [next] | [standalone]
| From | Tim Chen <tim.c.chen@linux.intel.com> |
|---|---|
| Date | 2016-09-08 20:10 +0200 |
| Subject | Re: [PATCH v2 2/8] sched: Extend scheduler's asym packing |
| Message-ID | <sfbVT-HP-17@gated-at.bofh.it> |
| In reply to | #1478893 |
On Thu, Sep 08, 2016 at 10:01:11AM +0200, Peter Zijlstra wrote:
> On Thu, Sep 01, 2016 at 01:33:38PM -0700, Srinivas Pandruvada wrote:
> > +++ b/kernel/sched/sched.h
> > @@ -532,6 +532,17 @@ struct dl_rq {
> >
> > #ifdef CONFIG_SMP
> >
> > +static inline bool sched_asym_prefer(int a, int b)
> > +{
> > + return arch_asym_cpu_priority(a) > arch_asym_cpu_priority(b);
> > +}
> > +
> > +/*
> > + * Return lowest numbered cpu in the group as the most preferred cpu
> > + * for ASYM_PACKING for default case.
> > + */
> > +#define group_priority_cpu(group) group->asym_prefer_cpu
> > +
>
> Both these are no longer used outside of sched/fair.c, and should
> probably be moved there. Also the later has no reason for being a macro.
Peter,
The sched_asym_prefer is used in sched/core.c to set asym_prefer_cpu
in a group. So we will still need the definition in sched.h. I've removed
the group_priority_cpu macro.
Updated patch below.
Thanks.
Tim
--->8---
From: Tim Chen <tim.c.chen@linux.intel.com>
Subject: [PATCH 2/8] sched: Extend scheduler's asym packing
We generalize the scheduler's asym packing to provide an ordering
of the cpu beyond just the cpu number. This allows the use of the
ASYM_PACKING scheduler machinery to move loads to preferred CPU in a
sched domain. The preference is defined with the cpu priority
given by arch_asym_cpu_priority(cpu).
We also record the most preferred cpu in a sched group when
we build the cpu's capacity for fast lookup of preferred cpu
during load balancing.
Signed-off-by: Tim Chen <tim.c.chen@linux.intel.com>
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Signed-off-by: Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com>
---
include/linux/sched.h | 2 ++
kernel/sched/core.c | 18 ++++++++++++++++++
kernel/sched/fair.c | 35 ++++++++++++++++++++++++-----------
kernel/sched/sched.h | 6 ++++++
4 files changed, 50 insertions(+), 11 deletions(-)
diff --git a/include/linux/sched.h b/include/linux/sched.h
index 62c68e5..aeea288 100644
--- a/include/linux/sched.h
+++ b/include/linux/sched.h
@@ -1052,6 +1052,8 @@ static inline int cpu_numa_flags(void)
}
#endif
+int arch_asym_cpu_priority(int cpu);
+
struct sched_domain_attr {
int relax_domain_level;
};
diff --git a/kernel/sched/core.c b/kernel/sched/core.c
index e86c4a5..08135ca 100644
--- a/kernel/sched/core.c
+++ b/kernel/sched/core.c
@@ -6237,7 +6237,25 @@ static void init_sched_groups_capacity(int cpu, struct sched_domain *sd)
WARN_ON(!sg);
do {
+ int cpu, max_cpu = -1, prev_cpu = -1;
+
sg->group_weight = cpumask_weight(sched_group_cpus(sg));
+
+ if (!(sd->flags & SD_ASYM_PACKING))
+ goto next;
+
+ for_each_cpu(cpu, sched_group_cpus(sg)) {
+ if (prev_cpu < 0) {
+ prev_cpu = cpu;
+ max_cpu = cpu;
+ } else {
+ if (sched_asym_prefer(cpu, max_cpu))
+ max_cpu = cpu;
+ }
+ }
+ sg->asym_prefer_cpu = max_cpu;
+
+next:
sg = sg->next;
} while (sg != sd->groups);
diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c
index 039de34..8e2a078 100644
--- a/kernel/sched/fair.c
+++ b/kernel/sched/fair.c
@@ -100,6 +100,16 @@ const_debug unsigned int sysctl_sched_migration_cost = 500000UL;
*/
unsigned int __read_mostly sysctl_sched_shares_window = 10000000UL;
+#ifdef CONFIG_SMP
+/*
+ * For asym packing, by default the lower numbered cpu has higher priority.
+ */
+int __weak arch_asym_cpu_priority(int cpu)
+{
+ return -cpu;
+}
+#endif
+
#ifdef CONFIG_CFS_BANDWIDTH
/*
* Amount of runtime to allocate from global (tg) to local (per-cfs_rq) pool
@@ -6862,16 +6872,18 @@ static bool update_sd_pick_busiest(struct lb_env *env,
if (env->idle == CPU_NOT_IDLE)
return true;
/*
- * ASYM_PACKING needs to move all the work to the lowest
- * numbered CPUs in the group, therefore mark all groups
- * higher than ourself as busy.
+ * ASYM_PACKING needs to move all the work to the highest
+ * prority CPUs in the group, therefore mark all groups
+ * of lower priority than ourself as busy.
*/
- if (sgs->sum_nr_running && env->dst_cpu < group_first_cpu(sg)) {
+ if (sgs->sum_nr_running &&
+ sched_asym_prefer(env->dst_cpu, sg->asym_prefer_cpu)) {
if (!sds->busiest)
return true;
- /* Prefer to move from highest possible cpu's work */
- if (group_first_cpu(sds->busiest) < group_first_cpu(sg))
+ /* Prefer to move from lowest priority cpu's work */
+ if (sched_asym_prefer(sds->busiest->asym_prefer_cpu,
+ sg->asym_prefer_cpu))
return true;
}
@@ -7023,8 +7035,8 @@ static int check_asym_packing(struct lb_env *env, struct sd_lb_stats *sds)
if (!sds->busiest)
return 0;
- busiest_cpu = group_first_cpu(sds->busiest);
- if (env->dst_cpu > busiest_cpu)
+ busiest_cpu = sds->busiest->asym_prefer_cpu;
+ if (sched_asym_prefer(busiest_cpu, env->dst_cpu))
return 0;
env->imbalance = DIV_ROUND_CLOSEST(
@@ -7365,10 +7377,11 @@ static int need_active_balance(struct lb_env *env)
/*
* ASYM_PACKING needs to force migrate tasks from busy but
- * higher numbered CPUs in order to pack all tasks in the
- * lowest numbered CPUs.
+ * lower priority CPUs in order to pack all tasks in the
+ * highest priority CPUs.
*/
- if ((sd->flags & SD_ASYM_PACKING) && env->src_cpu > env->dst_cpu)
+ if ((sd->flags & SD_ASYM_PACKING) &&
+ sched_asym_prefer(env->dst_cpu, env->src_cpu))
return 1;
}
diff --git a/kernel/sched/sched.h b/kernel/sched/sched.h
index c64fc51..b6f449d 100644
--- a/kernel/sched/sched.h
+++ b/kernel/sched/sched.h
@@ -532,6 +532,11 @@ struct dl_rq {
#ifdef CONFIG_SMP
+static inline bool sched_asym_prefer(int a, int b)
+{
+ return arch_asym_cpu_priority(a) > arch_asym_cpu_priority(b);
+}
+
/*
* We add the notion of a root-domain which will be used to define per-domain
* variables. Each exclusive cpuset essentially defines an island domain by
@@ -884,6 +889,7 @@ struct sched_group {
unsigned int group_weight;
struct sched_group_capacity *sgc;
+ int asym_prefer_cpu; /* cpu of highest priority in group */
/*
* The CPUs this group covers.
--
2.5.5
[toc] | [prev] | [next] | [standalone]
| From | Peter Zijlstra <peterz@infradead.org> |
|---|---|
| Date | 2016-09-08 20:30 +0200 |
| Subject | Re: [PATCH v2 2/8] sched: Extend scheduler's asym packing |
| Message-ID | <sfcff-S4-1@gated-at.bofh.it> |
| In reply to | #1479419 |
On Thu, Sep 08, 2016 at 11:03:26AM -0700, Tim Chen wrote:
> On Thu, Sep 08, 2016 at 10:01:11AM +0200, Peter Zijlstra wrote:
> > On Thu, Sep 01, 2016 at 01:33:38PM -0700, Srinivas Pandruvada wrote:
> > > +++ b/kernel/sched/sched.h
> > > @@ -532,6 +532,17 @@ struct dl_rq {
> > >
> > > #ifdef CONFIG_SMP
> > >
> > > +static inline bool sched_asym_prefer(int a, int b)
> > > +{
> > > + return arch_asym_cpu_priority(a) > arch_asym_cpu_priority(b);
> > > +}
> > > +
> > > +/*
> > > + * Return lowest numbered cpu in the group as the most preferred cpu
> > > + * for ASYM_PACKING for default case.
> > > + */
> > > +#define group_priority_cpu(group) group->asym_prefer_cpu
> > > +
> >
> > Both these are no longer used outside of sched/fair.c, and should
> > probably be moved there. Also the later has no reason for being a macro.
>
> Peter,
>
> The sched_asym_prefer is used in sched/core.c to set asym_prefer_cpu
> in a group. So we will still need the definition in sched.h. I've removed
> the group_priority_cpu macro.
Ah indeed. Thanks!
[toc] | [prev] | [next] | [standalone]
| From | Peter Zijlstra <peterz@infradead.org> |
|---|---|
| Date | 2016-09-08 10:10 +0200 |
| Message-ID | <sf2zf-3eC-5@gated-at.bofh.it> |
| In reply to | #1474600 |
Ingo, aside from the fact that Srinivas still has to update patch 6 and I just spotted a few niggles, how do you want to merge this?
[toc] | [prev] | [standalone]
Back to top | Article view | linux.kernel
csiph-web