aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNicolas Pitre <nicolas.pitre@linaro.org>2013-05-27 14:09:50 -0400
committerAndrey Konovalov <andrey.konovalov@linaro.org>2013-05-28 23:37:46 +0400
commit90d0e0a125f44ead5ae47e5c8cf9d2c72cda1c6c (patch)
tree17df2d05373e3eacd96071a91510ff6f50f7f08c
parent82d931619b0843d88ff2dea3f50b0b00b4d0bc3d (diff)
Let's keep only those logical CPUs with same initial CPU cluster to create a uniform scheduler profile without having to modify any of the probed topology and compute capacity data. This has the potential to create a non contiguous CPU numbering space when the switcher is active with potential impact on buggy user space tools. It is however better to fix those tools rather than making the switcher more intrusive. Signed-off-by: Nicolas Pitre <nico@linaro.org>
-rw-r--r--arch/arm/common/bL_switcher.c30
1 files changed, 21 insertions, 9 deletions
diff --git a/arch/arm/common/bL_switcher.c b/arch/arm/common/bL_switcher.c
index 914b90345df..c3b9427f0a0 100644
--- a/arch/arm/common/bL_switcher.c
+++ b/arch/arm/common/bL_switcher.c
@@ -288,7 +288,7 @@ struct bL_thread {
struct completion started;
};
-static struct bL_thread bL_threads[MAX_CPUS_PER_CLUSTER];
+static struct bL_thread bL_threads[NR_CPUS];
static int bL_switcher_thread(void *arg)
{
@@ -341,7 +341,7 @@ int bL_switch_request(unsigned int cpu, unsigned int new_cluster_id)
{
struct bL_thread *t;
- if (cpu >= MAX_CPUS_PER_CLUSTER) {
+ if (cpu >= ARRAY_SIZE(bL_threads)) {
pr_err("%s: cpu %d out of bounds\n", __func__, cpu);
return -EINVAL;
}
@@ -366,7 +366,7 @@ EXPORT_SYMBOL_GPL(bL_switch_request);
static DEFINE_MUTEX(bL_switcher_activation_lock);
static BLOCKING_NOTIFIER_HEAD(bL_activation_notifier);
static unsigned int bL_switcher_active;
-static unsigned int bL_switcher_cpu_original_cluster[MAX_CPUS_PER_CLUSTER];
+static unsigned int bL_switcher_cpu_original_cluster[NR_CPUS];
static cpumask_t bL_switcher_removed_logical_cpus;
int bL_switcher_register_notifier(struct notifier_block *nb)
@@ -402,8 +402,8 @@ static void bL_switcher_restore_cpus(void)
static int bL_switcher_halve_cpus(void)
{
- int i, j, gic_id, ret;
- unsigned int cpu, cluster, cntpart, mask;
+ int i, j, cluster_0, gic_id, ret;
+ unsigned int cpu, cluster, mask;
cpumask_t available_cpus;
/* First pass to validate what we have */
@@ -426,18 +426,30 @@ static int bL_switcher_halve_cpus(void)
/*
* Now let's do the pairing. We match each CPU with another CPU
- * from a different cluster. To keep the logical CPUs contiguous,
- * the pairing is done backward from the end of the CPU list.
+ * from a different cluster. To get a uniform scheduling behavior
+ * without fiddling with CPU topology and compute capacity data,
+ * we'll use logical CPUs initially belonging to the same cluster.
*/
memset(bL_switcher_cpu_pairing, -1, sizeof(bL_switcher_cpu_pairing));
cpumask_copy(&available_cpus, cpu_online_mask);
+ cluster_0 = -1;
for_each_cpu(i, &available_cpus) {
int match = -1;
cluster = MPIDR_AFFINITY_LEVEL(cpu_logical_map(i), 1);
+ if (cluster_0 == -1)
+ cluster_0 = cluster;
+ if (cluster != cluster_0)
+ continue;
cpumask_clear_cpu(i, &available_cpus);
for_each_cpu(j, &available_cpus) {
- cntpart = MPIDR_AFFINITY_LEVEL(cpu_logical_map(j), 1);
- if (cntpart != cluster)
+ cluster = MPIDR_AFFINITY_LEVEL(cpu_logical_map(j), 1);
+ /*
+ * Let's remember the last match to create "odd"
+ * pairing on purpose in order for other code not
+ * to assume any relation between physical and
+ * logical CPU numbers.
+ */
+ if (cluster != cluster_0)
match = j;
}
if (match != -1) {