From patchwork Fri Oct 21 16:54:01 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Vincent Guittot X-Patchwork-Id: 4780 Return-Path: X-Original-To: patchwork@peony.canonical.com Delivered-To: patchwork@peony.canonical.com Received: from fiordland.canonical.com (fiordland.canonical.com [91.189.94.145]) by peony.canonical.com (Postfix) with ESMTP id 7DF1A23EF5 for ; Fri, 21 Oct 2011 16:54:18 +0000 (UTC) Received: from mail-gy0-f180.google.com (mail-gy0-f180.google.com [209.85.160.180]) by fiordland.canonical.com (Postfix) with ESMTP id 389B6A182E2 for ; Fri, 21 Oct 2011 16:54:18 +0000 (UTC) Received: by gyf1 with SMTP id 1so5823131gyf.11 for ; Fri, 21 Oct 2011 09:54:17 -0700 (PDT) Received: by 10.223.85.139 with SMTP id o11mr25980568fal.0.1319216057235; Fri, 21 Oct 2011 09:54:17 -0700 (PDT) X-Forwarded-To: linaro-patchwork@canonical.com X-Forwarded-For: patch@linaro.org linaro-patchwork@canonical.com Delivered-To: patches@linaro.org Received: by 10.152.1.71 with SMTP id 7cs22813lak; Fri, 21 Oct 2011 09:54:17 -0700 (PDT) Received: by 10.227.143.74 with SMTP id t10mr5862835wbu.68.1319216056577; Fri, 21 Oct 2011 09:54:16 -0700 (PDT) Received: from mail-ww0-f50.google.com (mail-ww0-f50.google.com [74.125.82.50]) by mx.google.com with ESMTPS id m11si3700765wbh.66.2011.10.21.09.54.15 (version=TLSv1/SSLv3 cipher=OTHER); Fri, 21 Oct 2011 09:54:16 -0700 (PDT) Received-SPF: neutral (google.com: 74.125.82.50 is neither permitted nor denied by best guess record for domain of vincent.guittot@linaro.org) client-ip=74.125.82.50; Authentication-Results: mx.google.com; spf=neutral (google.com: 74.125.82.50 is neither permitted nor denied by best guess record for domain of vincent.guittot@linaro.org) smtp.mail=vincent.guittot@linaro.org Received: by wwi18 with SMTP id 18so5981229wwi.31 for ; Fri, 21 Oct 2011 09:54:15 -0700 (PDT) Received: by 10.216.72.145 with SMTP id t17mr2707805wed.88.1319216055738; Fri, 21 Oct 2011 09:54:15 -0700 (PDT) Received: from localhost.localdomain (pas72-1-88-161-60-229.fbx.proxad.net. [88.161.60.229]) by mx.google.com with ESMTPS id gd18sm22840206wbb.5.2011.10.21.09.54.14 (version=TLSv1/SSLv3 cipher=OTHER); Fri, 21 Oct 2011 09:54:14 -0700 (PDT) From: Vincent Guittot To: linaro-dev@lists.linaro.org Cc: patches@linaro.org, Vincent Guittot Subject: [RFC PATCH 02/11] ARM: cpu topology: modify cpu topology Date: Fri, 21 Oct 2011 18:54:01 +0200 Message-Id: <1319216041-2424-1-git-send-email-vincent.guittot@linaro.org> X-Mailer: git-send-email 1.7.4.1 Modify the CPU topology policy according to the sched_mc level and the cortex family Signed-off-by: Vincent Guittot --- arch/arm/kernel/topology.c | 104 +++++++++++++++++++++++++++++++++++-------- 1 files changed, 84 insertions(+), 20 deletions(-) diff --git a/arch/arm/kernel/topology.c b/arch/arm/kernel/topology.c index d89c66c..34512fe 100644 --- a/arch/arm/kernel/topology.c +++ b/arch/arm/kernel/topology.c @@ -44,6 +44,13 @@ struct cputopo_arm cpu_topology[NR_CPUS]; /* + * cpu topology mask management + */ + +static void default_cpu_topology_mask(void); +static void (*set_cpu_topology_mask)(void) = default_cpu_topology_mask; + +/* * default topology function */ @@ -66,26 +73,33 @@ static void clear_cpu_topology_mask(void) smp_wmb(); } -static void default_cpu_topology_mask(unsigned int cpuid) +/* + * default_cpu_topology_mask set the core and thread mask as described in the + * ARM ARM + */ +static void default_cpu_topology_mask(void) { - struct cputopo_arm *cpuid_topo = &cpu_topology[cpuid]; - unsigned int cpu; + unsigned int cpuid, cpu; - for_each_possible_cpu(cpu) { - struct cputopo_arm *cpu_topo = &cpu_topology[cpu]; + for_each_possible_cpu(cpuid) { + struct cputopo_arm *cpuid_topo = &cpu_topology[cpuid]; - if (cpuid_topo->socket_id == cpu_topo->socket_id) { - cpumask_set_cpu(cpuid, &cpu_topo->core_sibling); - if (cpu != cpuid) - cpumask_set_cpu(cpu, - &cpuid_topo->core_sibling); + for_each_possible_cpu(cpu) { + struct cputopo_arm *cpu_topo = &cpu_topology[cpu]; - if (cpuid_topo->core_id == cpu_topo->core_id) { - cpumask_set_cpu(cpuid, - &cpu_topo->thread_sibling); + if (cpuid_topo->socket_id == cpu_topo->socket_id) { + cpumask_set_cpu(cpuid, &cpu_topo->core_sibling); if (cpu != cpuid) cpumask_set_cpu(cpu, - &cpuid_topo->thread_sibling); + &cpuid_topo->core_sibling); + + if (cpuid_topo->core_id == cpu_topo->core_id) { + cpumask_set_cpu(cpuid, + &cpu_topo->thread_sibling); + if (cpu != cpuid) + cpumask_set_cpu(cpu, + &cpuid_topo->thread_sibling); + } } } } @@ -93,6 +107,55 @@ static void default_cpu_topology_mask(unsigned int cpuid) } /* + * For Cortex-A9 MPcore dual core, we emulate a multi-package single core + * topology in power mode. + */ +static void power_cpu_topology_mask_CA9(void) +{ + unsigned int cpuid; + for_each_possible_cpu(cpuid) { + struct cputopo_arm *cpuid_topo = &(cpu_topology[cpuid]); + + cpumask_set_cpu(cpuid, &cpuid_topo->core_sibling); + cpumask_set_cpu(cpuid, &cpuid_topo->thread_sibling); + + } + smp_wmb(); +} + +#define ARM_FAMILY_MASK 0xFF0FFFF0 +#define ARM_CORTEX_A9_FAMILY 0x410FC090 + +/* update_cpu_topology_policy select a cpu topology policy according to the + * available cores. + * TODO: The current version assumes that all cores are exactly the same which + * might not be true. We need to update it to take into account various + * configuration among which system with different kind of core. + */ +static int update_cpu_topology_policy(void) +{ + unsigned long cpuid; + + if (sched_mc_power_savings == POWERSAVINGS_BALANCE_NONE) { + set_cpu_topology_mask = default_cpu_topology_mask; + return 0; + } + + cpuid = read_cpuid_id(); + cpuid &= ARM_FAMILY_MASK; + + switch (cpuid) { + case ARM_CORTEX_A9_FAMILY: + set_cpu_topology_mask = power_cpu_topology_mask_CA9; + break; + default: + set_cpu_topology_mask = default_cpu_topology_mask; + break; + } + + return 0; +} +/* * store_cpu_topology is called at boot when only one cpu is running * and with the mutex cpu_hotplug.lock locked, when several cpus have booted, * which prevents simultaneous write access to cpu_topology array @@ -159,14 +222,15 @@ void store_cpu_topology(unsigned int cpuid) */ int arch_update_cpu_topology(void) { - unsigned int cpuid; - /* clear core mask */ + + /* clear core threads mask */ clear_cpu_topology_mask(); - /* update core and thread sibling masks */ - for_each_possible_cpu(cpuid) { - default_cpu_topology_mask(cpuid); - } + /* set topology policy */ + update_cpu_topology_policy(); + + /* set topology mask and power */ + (*set_cpu_topology_mask)(); return 1; }