23 #include <linux/cpu.h> 24 #include <linux/cpumask.h> 25 #include <asm/processor.h> 26 #include <linux/topology.h> 27 #include <linux/slab.h> 35 #define M0_TRACE_SUBSYSTEM M0_TRACE_SUBSYS_LIB 56 DEFAULT_L1_SZ = 32 * 1024,
58 DEFAULT_L2_SZ = 6144 * 1024,
61 PROCESSOR_INTEL_CPUID4_OP = 4,
63 PROCESSOR_INTEL_CTYPE_MASK = 0x1f,
64 PROCESSOR_INTEL_CTYPE_NULL = 0,
66 PROCESSOR_INTEL_CLEVEL_MASK = 0x7,
67 PROCESSOR_INTEL_CLEVEL_SHIFT = 5,
69 PROCESSOR_INTEL_CSHARE_MASK = 0xfff,
70 PROCESSOR_INTEL_CSHARE_SHIFT = 14,
72 PROCESSOR_INTEL_LINESZ_MASK = 0xfff,
74 PROCESSOR_INTEL_PARTITION_MASK = 0x3f,
75 PROCESSOR_INTEL_PARTITION_SHIFT = 12,
77 PROCESSOR_INTEL_ASSOCIATIVITY_MASK = 0x3f,
78 PROCESSOR_INTEL_ASSOCIATIVITY_SHIFT = 22,
80 PROCESSOR_L1_CACHE = 1,
81 PROCESSOR_L2_CACHE = 2,
84 PROCESSOR_AMD_L1_OP = 0x80000005,
86 PROCESSOR_AMD_CSIZE_SHIFT = 24,
105 static struct m0_list x86_cpus;
108 #if defined (CONFIG_X86_64) || defined (CONFIG_AARCH64) 122 const cpumask_t *
src,
130 for (bit = 0; bit < bmpsz; ++bit) {
131 val = cpumask_test_cpu(bit,
src);
147 return cpu_to_node(
id);
175 switch (cache_level) {
176 case PROCESSOR_L1_CACHE:
179 case PROCESSOR_L2_CACHE:
195 static inline uint32_t processor_x86cache_level_get(uint32_t eax)
197 return (eax >> PROCESSOR_INTEL_CLEVEL_SHIFT) &
198 PROCESSOR_INTEL_CLEVEL_MASK;
209 static inline uint32_t processor_x86cache_shares_get(uint32_t eax)
211 return (eax >> PROCESSOR_INTEL_CSHARE_SHIFT) &
212 PROCESSOR_INTEL_CSHARE_MASK;
236 struct cpuinfo_x86 *
p = &cpu_data(
id);
238 if (
p->x86_vendor == X86_VENDOR_INTEL) {
241 cpuid_count(PROCESSOR_INTEL_CPUID4_OP,
count,
242 &eax, &ebx, &ecx, &edx);
243 cachetype = eax & PROCESSOR_INTEL_CTYPE_MASK;
245 }
while (cachetype != PROCESSOR_INTEL_CTYPE_NULL);
263 uint32_t cache_level,
264 uint32_t cache_leaves)
266 uint32_t cache_id =
id;
275 bool l3_present =
false;
276 bool cache_shared_at_core =
false;
278 struct cpuinfo_x86 *
p = &cpu_data(
id);
285 if (
p->x86_vendor == X86_VENDOR_INTEL &&
286 p->cpuid_level >= PROCESSOR_INTEL_CPUID4_OP &&
287 cache_level < cache_leaves) {
289 cpuid_count(PROCESSOR_INTEL_CPUID4_OP, cache_level,
290 &eax, &ebx, &ecx, &edx);
291 shares = processor_x86cache_shares_get(eax);
299 if (cache_leaves > 3)
301 phys = topology_physical_package_id(
id);
302 core = topology_core_id(
id);
303 switch (cache_level) {
304 case PROCESSOR_L1_CACHE:
305 cache_shared_at_core =
true;
307 case PROCESSOR_L2_CACHE:
309 cache_shared_at_core =
true;
316 if (cache_shared_at_core)
317 cache_id = phys << 16 |
core;
334 uint32_t cache_level)
342 struct cpuinfo_x86 *
p;
344 switch (cache_level) {
345 case PROCESSOR_L1_CACHE:
346 cpuid(PROCESSOR_AMD_L1_OP, &eax, &ebx, &ecx, &l1);
347 sz = (l1 >> PROCESSOR_AMD_CSIZE_SHIFT) * 1024;
349 case PROCESSOR_L2_CACHE:
351 sz =
p->x86_cache_size;
370 uint32_t cache_level)
383 bool use_defaults =
true;
384 struct cpuinfo_x86 *
p = &cpu_data(
id);
386 if (
p->cpuid_level >= PROCESSOR_INTEL_CPUID4_OP) {
387 cpuid_count(PROCESSOR_INTEL_CPUID4_OP, cache_level,
388 &eax, &ebx, &ecx, &edx);
389 level = processor_x86cache_level_get(eax);
390 if (
level == cache_level) {
391 linesz = ebx & PROCESSOR_INTEL_LINESZ_MASK;
392 partition = (ebx >> PROCESSOR_INTEL_PARTITION_SHIFT)
393 & PROCESSOR_INTEL_PARTITION_MASK;
394 asso = (ebx >> PROCESSOR_INTEL_ASSOCIATIVITY_SHIFT)
395 & PROCESSOR_INTEL_ASSOCIATIVITY_MASK;
397 sz = (linesz+1) * (sets+1) * (partition+1) * (asso+1);
398 use_defaults =
false;
403 switch (cache_level) {
404 case PROCESSOR_L1_CACHE:
407 case PROCESSOR_L2_CACHE:
427 uint32_t cache_level)
430 struct cpuinfo_x86 *
p = &cpu_data(
id);
432 switch (
p->x86_vendor) {
437 sz = processor_amd_cache_sz_get(
id, cache_level);
439 case X86_VENDOR_INTEL:
443 sz = processor_intel_cache_sz_get(
id, cache_level);
449 sz = processor_cache_sz_get(
id, cache_level);
464 static void processor_x86_attrs_get(
void *arg)
473 pinfo->pn_info.pd_id = cpu;
477 c_leaves = processor_x86cache_leaves_get(cpu);
481 pinfo->pn_info.pd_l1 =
482 processor_x86_cacheid_get(cpu, PROCESSOR_L1_CACHE, c_leaves);
483 pinfo->pn_info.pd_l2 =
484 processor_x86_cacheid_get(cpu, PROCESSOR_L2_CACHE, c_leaves);
486 pinfo->pn_info.pd_l1_sz =
487 processor_x86_cache_sz_get(cpu, PROCESSOR_L1_CACHE);
488 pinfo->pn_info.pd_l2_sz =
489 processor_x86_cache_sz_get(cpu, PROCESSOR_L2_CACHE);
518 if (
pinfo->pn_info.pd_id ==
id) {
519 *pd =
pinfo->pn_info;
534 static void processor_x86cache_destroy(
void)
542 node = x86_cpus.l_head;
547 node = x86_cpus.l_head;
560 static int processor_x86cache_create(
void)
571 for_each_online_cpu(cpu) {
574 processor_x86cache_destroy();
583 smp_call_function_single(cpu, processor_x86_attrs_get,
584 (
void *)
pinfo,
true);
597 #if defined (CONFIG_X86_64) || defined (CONFIG_AARCH64) 604 rc = processor_x86cache_create();
607 #elif defined (CONFIG_AARCH64) 616 processor_x86cache_destroy();
618 #elif defined (CONFIG_AARCH64) 629 processors_bitmap_copy(
map, cpu_possible_mask, nr_cpu_ids);
634 processors_bitmap_copy(
map, cpu_present_mask, nr_cpu_ids);
639 processors_bitmap_copy(
map, cpu_online_mask, nr_cpu_ids);
647 if (
id >= nr_cpu_ids)
650 return processor_x86_info_get(
id, pd);
656 return smp_processor_id();
661 #undef M0_TRACE_SUBSYSTEM
static struct m0_addb2_philter p
M0_INTERNAL void m0_list_add(struct m0_list *head, struct m0_list_link *new)
M0_INTERNAL void m0_processors_possible(struct m0_bitmap *map)
M0_INTERNAL void m0_list_init(struct m0_list *head)
enum m0_trace_level level
M0_INTERNAL m0_processor_nr_t m0_processor_nr_max(void)
static struct net_test_cmd_node * node
M0_INTERNAL void m0_list_fini(struct m0_list *head)
M0_INTERNAL void m0_list_del(struct m0_list_link *old)
M0_INTERNAL void m0_processors_fini(void)
struct m0_processor_descr pn_info
M0_INTERNAL m0_processor_nr_t m0_processor_id_get(void)
return M0_ERR(-EOPNOTSUPP)
struct m0_list_link pn_link
uint32_t m0_processor_nr_t
#define m0_list_for_each_entry(head, pos, type, member)
M0_INTERNAL int m0_processors_init(void)
static uint32_t processor_pipelineid_get(m0_processor_nr_t id)
static uint32_t processor_numanodeid_get(m0_processor_nr_t id)
M0_INTERNAL void m0_processors_online(struct m0_bitmap *map)
static bool processor_init
M0_INTERNAL void m0_bitmap_set(struct m0_bitmap *map, size_t idx, bool val)
M0_INTERNAL bool m0_list_is_empty(const struct m0_list *head)
#define M0_ALLOC_PTR(ptr)
M0_INTERNAL int m0_processor_describe(m0_processor_nr_t id, struct m0_processor_descr *pd)
struct m0_pdclust_src_addr src
#define m0_list_entry(link, type, member)
M0_INTERNAL void m0_processors_available(struct m0_bitmap *map)