From patchwork Tue Jun 3 17:31:03 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lorenzo Pieralisi X-Patchwork-Id: 31331 Return-Path: X-Original-To: linaro@patches.linaro.org Delivered-To: linaro@patches.linaro.org Received: from mail-ob0-f197.google.com (mail-ob0-f197.google.com [209.85.214.197]) by ip-10-151-82-157.ec2.internal (Postfix) with ESMTPS id 159E520AE6 for ; Tue, 3 Jun 2014 17:33:43 +0000 (UTC) Received: by mail-ob0-f197.google.com with SMTP id vb8sf35819174obc.8 for ; Tue, 03 Jun 2014 10:33:43 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:delivered-to:date:from:to:subject:message-id :references:mime-version:in-reply-to:user-agent:cc:precedence :list-id:list-unsubscribe:list-archive:list-post:list-help :list-subscribe:sender:errors-to:x-original-sender :x-original-authentication-results:mailing-list:content-type :content-disposition; bh=+EGz6IYD4/nOOhTmov7b8ZGzVCOV5olBw45BOvU1SnU=; b=AO8Ixcej1FfCj0Z7SI2xIxJ3KXDKvVG1g39OOz8npMXL1bRVlCXMHnTuWjrkMe0Jwi SDQJJ5CEgS5NWHvzM60VpCKl39AzZAAWhvTjkVZVLNRAjN8zNExKM91u/IQIG99or+zn 8Y4eqRFZvfHXQgKm1xkYkSlmRIFl7LB1R+8jzBTziq/hIcAg8N7ivp9G/HLqHNjTXlP2 jYWf5c6ad8erdY4giw93ufNCdjU2lXE9nFCdin38OBCLT6rmq/AeajrUcarr+MCRXJML TtC9GJqmPbPUvfCcGR+WJK1Q73a6s7L2IaXe6Yi0x5DcZ6c4Ozguq6FiZ2mNKdXL8Npq MCEQ== X-Gm-Message-State: ALoCoQnd9rWCfaOmGyX0VgXKcz3A0FWvkOHS4CBSVEInWzyQFM3NAKkHP80Rg737e6Vp0QXvsyxt X-Received: by 10.42.27.18 with SMTP id h18mr9545615icc.25.1401816823326; Tue, 03 Jun 2014 10:33:43 -0700 (PDT) X-BeenThere: patchwork-forward@linaro.org Received: by 10.140.93.131 with SMTP id d3ls2687058qge.52.gmail; Tue, 03 Jun 2014 10:33:43 -0700 (PDT) X-Received: by 10.220.94.8 with SMTP id x8mr3343660vcm.67.1401816823184; Tue, 03 Jun 2014 10:33:43 -0700 (PDT) Received: from mail-ve0-f180.google.com (mail-ve0-f180.google.com [209.85.128.180]) by mx.google.com with ESMTPS id j8si10418176vcr.60.2014.06.03.10.33.43 for (version=TLSv1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Tue, 03 Jun 2014 10:33:43 -0700 (PDT) Received-SPF: pass (google.com: domain of patch+caf_=patchwork-forward=linaro.org@linaro.org designates 209.85.128.180 as permitted sender) client-ip=209.85.128.180; Received: by mail-ve0-f180.google.com with SMTP id db12so7339364veb.39 for ; Tue, 03 Jun 2014 10:33:43 -0700 (PDT) X-Received: by 10.58.216.163 with SMTP id or3mr2457895vec.80.1401816823064; Tue, 03 Jun 2014 10:33:43 -0700 (PDT) X-Forwarded-To: patchwork-forward@linaro.org X-Forwarded-For: patch@linaro.org patchwork-forward@linaro.org Delivered-To: patch@linaro.org Received: by 10.220.221.72 with SMTP id ib8csp13533vcb; Tue, 3 Jun 2014 10:33:42 -0700 (PDT) X-Received: by 10.224.8.131 with SMTP id h3mr64315211qah.61.1401816821566; Tue, 03 Jun 2014 10:33:41 -0700 (PDT) Received: from bombadil.infradead.org (bombadil.infradead.org. [2001:1868:205::9]) by mx.google.com with ESMTPS id r2si23884672qat.30.2014.06.03.10.33.41 for (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 03 Jun 2014 10:33:41 -0700 (PDT) Received-SPF: none (google.com: linux-arm-kernel-bounces+patch=linaro.org@lists.infradead.org does not designate permitted sender hosts) client-ip=2001:1868:205::9; Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.80.1 #2 (Red Hat Linux)) id 1WrsYa-0002PA-Ct; Tue, 03 Jun 2014 17:31:28 +0000 Received: from service87.mimecast.com ([91.220.42.44]) by bombadil.infradead.org with esmtp (Exim 4.80.1 #2 (Red Hat Linux)) id 1WrsYU-0002Ng-QP for linux-arm-kernel@lists.infradead.org; Tue, 03 Jun 2014 17:31:26 +0000 Received: from cam-owa1.Emea.Arm.com (fw-tnat.cambridge.arm.com [217.140.96.21]) by service87.mimecast.com; Tue, 03 Jun 2014 18:30:57 +0100 Received: from red-moon ([10.1.255.212]) by cam-owa1.Emea.Arm.com with Microsoft SMTPSVC(6.0.3790.3959); Tue, 3 Jun 2014 18:30:53 +0100 Date: Tue, 3 Jun 2014 18:31:03 +0100 From: Lorenzo Pieralisi To: Mark Brown Subject: Re: [PATCH] arm64: topology: add MPIDR-based detection Message-ID: <20140603173103.GA18004@red-moon> References: <1401644249-23792-1-git-send-email-broonie@kernel.org> MIME-Version: 1.0 In-Reply-To: <1401644249-23792-1-git-send-email-broonie@kernel.org> User-Agent: Mutt/1.5.21 (2010-09-15) X-OriginalArrivalTime: 03 Jun 2014 17:30:53.0361 (UTC) FILETIME=[91E1DA10:01CF7F51] X-MC-Unique: 114060318305700401 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20140603_103123_295377_0DBFE536 X-CRM114-Status: GOOD ( 20.84 ) X-Spam-Score: -0.7 (/) X-Spam-Report: SpamAssassin version 3.3.2 on bombadil.infradead.org summary: Content analysis details: (-0.7 points) pts rule name description ---- ---------------------- -------------------------------------------------- -0.7 RCVD_IN_DNSWL_LOW RBL: Sender listed at http://www.dnswl.org/, low trust [91.220.42.44 listed in list.dnswl.org] -0.0 SPF_PASS SPF: sender matches SPF record Cc: "linaro-kernel@lists.linaro.org" , Mark Brown , Catalin Marinas , Will Deacon , Zi Shen Lim , "linux-arm-kernel@lists.infradead.org" X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: , List-Help: , List-Subscribe: , Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patch=linaro.org@lists.infradead.org X-Removed-Original-Auth: Dkim didn't pass. X-Original-Sender: lorenzo.pieralisi@arm.com X-Original-Authentication-Results: mx.google.com; spf=pass (google.com: domain of patch+caf_=patchwork-forward=linaro.org@linaro.org designates 209.85.128.180 as permitted sender) smtp.mail=patch+caf_=patchwork-forward=linaro.org@linaro.org Mailing-list: list patchwork-forward@linaro.org; contact patchwork-forward+owners@linaro.org X-Google-Group-Id: 836684582541 Content-Disposition: inline Mark, On Sun, Jun 01, 2014 at 06:37:29PM +0100, Mark Brown wrote: > From: Zi Shen Lim > > Create cpu topology based on MPIDR. When hardware sets MPIDR to sane > values, this method will always work. Therefore it should also work well > as the fallback method. [1] > > When we have multiple processing elements in the system, we create > the cpu topology by mapping each affinity level (from lowest to highest) > to threads (if they exist), cores, and clusters. > > We combine data from all higher affinity levels into cluster_id > so we don't lose any information from MPIDR. [2] I refactored the patch (UP code path) and deliberately removed the code that packs affinity levels into the cluster id. I do not like packing the affinity levels and on second thoughts packing the unused affinity levels into cluster_id is as correct as packing the unused affinity levels into core_id (ie it is arbitrary), so I do not think we should do it, that's the reason why we defined DT bindings to add a proper topology semantics and we should use them when the MPIDR values deviate from the "recommendations". Patch attached, my ack included, should be ready to go, unless you object to that. Lorenzo > [1] http://www.spinics.net/lists/arm-kernel/msg317445.html > [2] https://lkml.org/lkml/2014/4/23/703 > > Signed-off-by: Zi Shen Lim > Signed-off-by: Mark Brown > --- > arch/arm64/include/asm/cputype.h | 2 ++ > arch/arm64/kernel/topology.c | 51 +++++++++++++++++++++++++++++----------- > 2 files changed, 39 insertions(+), 14 deletions(-) > > diff --git a/arch/arm64/include/asm/cputype.h b/arch/arm64/include/asm/cputype.h > index 27f54a7cc81b..ed48a3a7836a 100644 > --- a/arch/arm64/include/asm/cputype.h > +++ b/arch/arm64/include/asm/cputype.h > @@ -18,6 +18,8 @@ > > #define INVALID_HWID ULONG_MAX > > +#define MPIDR_UP_BITMASK (0x1 << 30) > +#define MPIDR_MT_BITMASK (0x1 << 24) > #define MPIDR_HWID_BITMASK 0xff00ffffff > > #define MPIDR_LEVEL_BITS_SHIFT 3 > diff --git a/arch/arm64/kernel/topology.c b/arch/arm64/kernel/topology.c > index 43514f905916..9a0160068503 100644 > --- a/arch/arm64/kernel/topology.c > +++ b/arch/arm64/kernel/topology.c > @@ -20,6 +20,7 @@ > #include > #include > > +#include > #include > > static int __init get_cpu_for_node(struct device_node *node) > @@ -188,13 +189,9 @@ static int __init parse_dt_topology(void) > * Check that all cores are in the topology; the SMP code will > * only mark cores described in the DT as possible. > */ > - for_each_possible_cpu(cpu) { > - if (cpu_topology[cpu].cluster_id == -1) { > - pr_err("CPU%d: No topology information specified\n", > - cpu); > + for_each_possible_cpu(cpu) > + if (cpu_topology[cpu].cluster_id == -1) > ret = -EINVAL; > - } > - } > > out_map: > of_node_put(map); > @@ -219,14 +216,6 @@ static void update_siblings_masks(unsigned int cpuid) > struct cpu_topology *cpu_topo, *cpuid_topo = &cpu_topology[cpuid]; > int cpu; > > - if (cpuid_topo->cluster_id == -1) { > - /* > - * DT does not contain topology information for this cpu. > - */ > - pr_debug("CPU%u: No topology information configured\n", cpuid); > - return; > - } > - > /* update core and thread sibling masks */ > for_each_possible_cpu(cpu) { > cpu_topo = &cpu_topology[cpu]; > @@ -249,6 +238,40 @@ static void update_siblings_masks(unsigned int cpuid) > > void store_cpu_topology(unsigned int cpuid) > { > + struct cpu_topology *cpuid_topo = &cpu_topology[cpuid]; > + u64 mpidr; > + > + if (cpuid_topo->cluster_id != -1) > + goto topology_populated; > + > + mpidr = read_cpuid_mpidr(); > + > + /* Create cpu topology mapping based on MPIDR. */ > + if (mpidr & MPIDR_UP_BITMASK) { > + /* Uniprocessor system */ > + cpuid_topo->thread_id = -1; > + cpuid_topo->core_id = MPIDR_AFFINITY_LEVEL(mpidr, 0); > + cpuid_topo->cluster_id = 0; > + } else if (mpidr & MPIDR_MT_BITMASK) { > + /* Multiprocessor system : Multi-threads per core */ > + cpuid_topo->thread_id = MPIDR_AFFINITY_LEVEL(mpidr, 0); > + cpuid_topo->core_id = MPIDR_AFFINITY_LEVEL(mpidr, 1); > + cpuid_topo->cluster_id = MPIDR_AFFINITY_LEVEL(mpidr, 2) | > + MPIDR_AFFINITY_LEVEL(mpidr, 3) << 8; > + } else { > + /* Multiprocessor system : Single-thread per core */ > + cpuid_topo->thread_id = -1; > + cpuid_topo->core_id = MPIDR_AFFINITY_LEVEL(mpidr, 0); > + cpuid_topo->cluster_id = MPIDR_AFFINITY_LEVEL(mpidr, 1) | > + MPIDR_AFFINITY_LEVEL(mpidr, 2) << 8 | > + MPIDR_AFFINITY_LEVEL(mpidr, 3) << 16; > + } > + > + pr_debug("CPU%u: cluster %d core %d thread %d mpidr %llx\n", > + cpuid, cpuid_topo->cluster_id, cpuid_topo->core_id, > + cpuid_topo->thread_id, mpidr); > + > +topology_populated: > update_siblings_masks(cpuid); > } > > -- > 2.0.0.rc4 > > >From 1f77b5e2e0b7f3deb11618d37f4ec7d03a45b95d Mon Sep 17 00:00:00 2001 From: Zi Shen Lim Date: Sun, 1 Jun 2014 18:37:29 +0100 Subject: [PATCH] arm64: topology: add MPIDR-based detection Create cpu topology based on MPIDR. When hardware sets MPIDR to sane values, this method will always work. Therefore it should also work well as the fallback method. [1] When we have multiple processing elements in the system, we create the cpu topology by mapping each affinity level (from lowest to highest) to threads (if they exist), cores, and clusters. [1] http://www.spinics.net/lists/arm-kernel/msg317445.html Acked-by: Lorenzo Pieralisi Signed-off-by: Zi Shen Lim Signed-off-by: Mark Brown --- arch/arm64/include/asm/cputype.h | 2 ++ arch/arm64/kernel/topology.c | 47 ++++++++++++++++++++++++++++------------ 2 files changed, 35 insertions(+), 14 deletions(-) diff --git a/arch/arm64/include/asm/cputype.h b/arch/arm64/include/asm/cputype.h index c404fb0..7639e8b 100644 --- a/arch/arm64/include/asm/cputype.h +++ b/arch/arm64/include/asm/cputype.h @@ -18,6 +18,8 @@ #define INVALID_HWID ULONG_MAX +#define MPIDR_UP_BITMASK (0x1 << 30) +#define MPIDR_MT_BITMASK (0x1 << 24) #define MPIDR_HWID_BITMASK 0xff00ffffff #define MPIDR_LEVEL_BITS_SHIFT 3 diff --git a/arch/arm64/kernel/topology.c b/arch/arm64/kernel/topology.c index 43514f9..b6ee26b 100644 --- a/arch/arm64/kernel/topology.c +++ b/arch/arm64/kernel/topology.c @@ -20,6 +20,7 @@ #include #include +#include #include static int __init get_cpu_for_node(struct device_node *node) @@ -188,13 +189,9 @@ static int __init parse_dt_topology(void) * Check that all cores are in the topology; the SMP code will * only mark cores described in the DT as possible. */ - for_each_possible_cpu(cpu) { - if (cpu_topology[cpu].cluster_id == -1) { - pr_err("CPU%d: No topology information specified\n", - cpu); + for_each_possible_cpu(cpu) + if (cpu_topology[cpu].cluster_id == -1) ret = -EINVAL; - } - } out_map: of_node_put(map); @@ -219,14 +216,6 @@ static void update_siblings_masks(unsigned int cpuid) struct cpu_topology *cpu_topo, *cpuid_topo = &cpu_topology[cpuid]; int cpu; - if (cpuid_topo->cluster_id == -1) { - /* - * DT does not contain topology information for this cpu. - */ - pr_debug("CPU%u: No topology information configured\n", cpuid); - return; - } - /* update core and thread sibling masks */ for_each_possible_cpu(cpu) { cpu_topo = &cpu_topology[cpu]; @@ -249,6 +238,36 @@ static void update_siblings_masks(unsigned int cpuid) void store_cpu_topology(unsigned int cpuid) { + struct cpu_topology *cpuid_topo = &cpu_topology[cpuid]; + u64 mpidr; + + if (cpuid_topo->cluster_id != -1) + goto topology_populated; + + mpidr = read_cpuid_mpidr(); + + /* Uniprocessor systems can rely on default topology values */ + if (mpidr & MPIDR_UP_BITMASK) + return; + + /* Create cpu topology mapping based on MPIDR. */ + if (mpidr & MPIDR_MT_BITMASK) { + /* Multiprocessor system : Multi-threads per core */ + cpuid_topo->thread_id = MPIDR_AFFINITY_LEVEL(mpidr, 0); + cpuid_topo->core_id = MPIDR_AFFINITY_LEVEL(mpidr, 1); + cpuid_topo->cluster_id = MPIDR_AFFINITY_LEVEL(mpidr, 2); + } else { + /* Multiprocessor system : Single-thread per core */ + cpuid_topo->thread_id = -1; + cpuid_topo->core_id = MPIDR_AFFINITY_LEVEL(mpidr, 0); + cpuid_topo->cluster_id = MPIDR_AFFINITY_LEVEL(mpidr, 1); + } + + pr_debug("CPU%u: cluster %d core %d thread %d mpidr %#016llx\n", + cpuid, cpuid_topo->cluster_id, cpuid_topo->core_id, + cpuid_topo->thread_id, mpidr); + +topology_populated: update_siblings_masks(cpuid); } -- 1.8.4