On Wed, Jun 29, 2016 at 06:56:10PM -0700, Fenghua Yu wrote: > From: Fenghua Yu <fenghua...@intel.com> > > 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 <fenghua...@intel.com> > --- > 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) --