From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752373AbcGAKWS (ORCPT ); Fri, 1 Jul 2016 06:22:18 -0400 Received: from mx2.suse.de ([195.135.220.15]:58656 "EHLO mx2.suse.de" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751523AbcGAKWL (ORCPT ); Fri, 1 Jul 2016 06:22:11 -0400 Date: Fri, 1 Jul 2016 12:21:43 +0200 From: Borislav Petkov To: Fenghua Yu Cc: Thomas Gleixner , Ingo Molnar , "H. Peter Anvin" , Tony Luck , Peter Zijlstra , Stephane Eranian , Ravi V Shankar , Vikas Shivappa , linux-kernel , x86 Subject: Re: [PATCH] cacheinfo: Introduce cache id Message-ID: <20160701102143.GB4749@pd.tnic> References: <1467251771-55501-1-git-send-email-fenghua.yu@intel.com> MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Disposition: inline Content-Transfer-Encoding: 8bit In-Reply-To: <1467251771-55501-1-git-send-email-fenghua.yu@intel.com> User-Agent: Mutt/1.5.24 (2015-08-30) Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On Wed, Jun 29, 2016 at 06:56:10PM -0700, Fenghua Yu wrote: > From: Fenghua Yu > > Each cache node is described by cacheinfo and is a unique node across What is a cache node? > the platform. But there is no id for a cache node. We introduce cache ID > to identify a cache node. > > Intel Cache Allocation Technology (CAT) allows some control on the > allocation policy within each cache that it controls. We need a unique > cache ID for each cache level to allow the user to specify which > controls are applied to which cache. > > The cache id is first enabled on x86. It can be enabled on other platforms > as well. The cache id is not necessary contiguous. > > Add an "id" entry to /sys/devices/system/cpu/cpu*/cache/index*/ > > Signed-off-by: Fenghua Yu > --- > arch/x86/kernel/cpu/intel_cacheinfo.c | 21 +++++++++++++++++++++ > drivers/base/cacheinfo.c | 5 +++++ > include/linux/cacheinfo.h | 3 +++ > 3 files changed, 29 insertions(+) > > diff --git a/arch/x86/kernel/cpu/intel_cacheinfo.c b/arch/x86/kernel/cpu/intel_cacheinfo.c > index de6626c..aefc1e5 100644 > --- a/arch/x86/kernel/cpu/intel_cacheinfo.c > +++ b/arch/x86/kernel/cpu/intel_cacheinfo.c > @@ -153,6 +153,7 @@ struct _cpuid4_info_regs { > union _cpuid4_leaf_eax eax; > union _cpuid4_leaf_ebx ebx; > union _cpuid4_leaf_ecx ecx; > + unsigned int id; > unsigned long size; > struct amd_northbridge *nb; > }; > @@ -894,6 +895,9 @@ static void __cache_cpumap_setup(unsigned int cpu, int index, > static void ci_leaf_init(struct cacheinfo *this_leaf, > struct _cpuid4_info_regs *base) > { > + this_leaf->id = base->id; > + /* Set CACHE_ID bit in attributes to enable cache id in x86. */ No need for that comment. > + this_leaf->attributes = CACHE_ID; > this_leaf->level = base->eax.split.level; > this_leaf->type = cache_type_map[base->eax.split.type]; > this_leaf->coherency_line_size = > @@ -920,6 +924,22 @@ static int __init_cache_level(unsigned int cpu) > return 0; > } > > +/* > + * The max shared threads number comes from CPUID.4:EAX[25-14] with input > + * ECX as cache index. Then right shift apicid by the number's order to get > + * cache id for this cache node. > + */ > +static void get_cache_id(int cpu, struct _cpuid4_info_regs *id4_regs) > +{ > + struct cpuinfo_x86 *c = &cpu_data(cpu); > + unsigned long num_threads_sharing; > + int index_msb; > + > + num_threads_sharing = 1 + id4_regs->eax.split.num_threads_sharing; > + index_msb = get_count_order(num_threads_sharing); > + id4_regs->id = c->apicid >> index_msb; > +} > + > static int __populate_cache_leaves(unsigned int cpu) > { > unsigned int idx, ret; > @@ -931,6 +951,7 @@ static int __populate_cache_leaves(unsigned int cpu) > ret = cpuid4_cache_lookup_regs(idx, &id4_regs); > if (ret) > return ret; > + get_cache_id(cpu, &id4_regs); > ci_leaf_init(this_leaf++, &id4_regs); > __cache_cpumap_setup(cpu, idx, &id4_regs); > } > diff --git a/drivers/base/cacheinfo.c b/drivers/base/cacheinfo.c > index e9fd32e..2a21c15 100644 > --- a/drivers/base/cacheinfo.c > +++ b/drivers/base/cacheinfo.c > @@ -233,6 +233,7 @@ static ssize_t file_name##_show(struct device *dev, \ > return sprintf(buf, "%u\n", this_leaf->object); \ > } > > +show_one(id, id); > show_one(level, level); > show_one(coherency_line_size, coherency_line_size); > show_one(number_of_sets, number_of_sets); > @@ -314,6 +315,7 @@ static ssize_t write_policy_show(struct device *dev, > return n; > } > > +static DEVICE_ATTR_RO(id); > static DEVICE_ATTR_RO(level); > static DEVICE_ATTR_RO(type); > static DEVICE_ATTR_RO(coherency_line_size); > @@ -327,6 +329,7 @@ static DEVICE_ATTR_RO(shared_cpu_list); > static DEVICE_ATTR_RO(physical_line_partition); > > static struct attribute *cache_default_attrs[] = { > + &dev_attr_id.attr, > &dev_attr_type.attr, > &dev_attr_level.attr, > &dev_attr_shared_cpu_map.attr, > @@ -350,6 +353,8 @@ cache_default_attrs_is_visible(struct kobject *kobj, > const struct cpumask *mask = &this_leaf->shared_cpu_map; > umode_t mode = attr->mode; > > + if ((attr == &dev_attr_id.attr) && this_leaf->attributes & CACHE_ID) > + return mode; > if ((attr == &dev_attr_type.attr) && this_leaf->type) > return mode; > if ((attr == &dev_attr_level.attr) && this_leaf->level) > diff --git a/include/linux/cacheinfo.h b/include/linux/cacheinfo.h > index 2189935..16e5573 100644 > --- a/include/linux/cacheinfo.h > +++ b/include/linux/cacheinfo.h > @@ -18,6 +18,7 @@ enum cache_type { > > /** > * struct cacheinfo - represent a cache leaf node > + * @id: id of this cache node. This is unique id across the platform. So you need to explain what a "cache node" is. Especially since this is generic code and other arches might not necessarily have a notion of a "cache node" - whatever that is. And since this patch adds the generic functionality and then enables it on x86, it should be split into two patches. -- Regards/Gruss, Boris. SUSE Linux GmbH, GF: Felix Imendörffer, Jane Smithard, Graham Norton, HRB 21284 (AG Nürnberg) --