Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge tag 'arch-cache-topo-5.20' of git://git.kernel.org/pub/scm/linux/kernel/git/sudeep.holla/linux into driver-core-next

Sudeep writes:

cacheinfo and arch_topology updates for v5.20

These are updates to fix some discrepancies we have in the CPU topology
parsing from the device tree /cpu-map node and the divergence from the
behaviour on a ACPI enabled platform. The expectation is that both DT
and ACPI enabled systems must present consistent view of the CPU topology.

The current assignment of generated cluster count as the physical package
identifier for each CPU is wrong. The device tree bindings for CPU
topology supports sockets to infer the socket or physical package
identifier for a given CPU. It is now being made use of you address the
issue. These updates also assigns the cluster identifier as parsed from
the device tree cluster nodes within /cpu-map without support for
nesting of the clusters as there are no such reported/known platforms.

In order to be on par with ACPI PPTT physical package/socket support,
these updates also include support for socket nodes in /cpu-map.

The only exception is that the last level cache id information can be
inferred from the same ACPI PPTT while we need to parse CPU cache nodes
in the device tree. The cacheinfo changes here is to enable the re-use
of the cacheinfo to detect the cache attributes for all the CPU quite
early even before the scondardaries are booted so that the information
can be used to build the schedular domains especially the last level
cache(LLC).

* tag 'arch-cache-topo-5.20' of git://git.kernel.org/pub/scm/linux/kernel/git/sudeep.holla/linux: (21 commits)
ACPI: Remove the unused find_acpi_cpu_cache_topology()
arch_topology: Warn that topology for nested clusters is not supported
arch_topology: Add support for parsing sockets in /cpu-map
arch_topology: Set cluster identifier in each core/thread from /cpu-map
arch_topology: Limit span of cpu_clustergroup_mask()
arch_topology: Don't set cluster identifier as physical package identifier
arch_topology: Avoid parsing through all the CPUs once a outlier CPU is found
arch_topology: Check for non-negative value rather than -1 for IDs validity
arch_topology: Set thread sibling cpumask only within the cluster
arch_topology: Drop LLC identifier stash from the CPU topology
arm64: topology: Remove redundant setting of llc_id in CPU topology
arch_topology: Use the last level cache information from the cacheinfo
arch_topology: Add support to parse and detect cache attributes
cacheinfo: Align checks in cache_shared_cpu_map_{setup,remove} for readability
cacheinfo: Use cache identifiers to check if the caches are shared if available
cacheinfo: Allow early detection and population of cache attributes
cacheinfo: Add support to check if last level cache(LLC) is valid or shared
cacheinfo: Move cache_leaves_are_shared out of CONFIG_OF
cacheinfo: Add helper to access any cache index for a given CPU
cacheinfo: Use of_cpu_device_node_get instead cpu_dev->of_node
...

+177 -135
-14
arch/arm64/kernel/topology.c
··· 89 89 return 0; 90 90 91 91 for_each_possible_cpu(cpu) { 92 - int i, cache_id; 93 - 94 92 topology_id = find_acpi_cpu_topology(cpu, 0); 95 93 if (topology_id < 0) 96 94 return topology_id; ··· 105 107 cpu_topology[cpu].cluster_id = topology_id; 106 108 topology_id = find_acpi_cpu_topology_package(cpu); 107 109 cpu_topology[cpu].package_id = topology_id; 108 - 109 - i = acpi_find_last_cache_level(cpu); 110 - 111 - if (i > 0) { 112 - /* 113 - * this is the only part of cpu_topology that has 114 - * a direct relationship with the cache topology 115 - */ 116 - cache_id = find_acpi_cpu_cache_topology(cpu, i); 117 - if (cache_id > 0) 118 - cpu_topology[cpu].llc_id = cache_id; 119 - } 120 110 } 121 111 122 112 return 0;
+2 -38
drivers/acpi/pptt.c
··· 437 437 pr_debug("found = %p %p\n", found_cache, cpu_node); 438 438 if (found_cache) 439 439 update_cache_properties(this_leaf, found_cache, 440 - cpu_node, table->revision); 440 + ACPI_TO_POINTER(ACPI_PTR_DIFF(cpu_node, table)), 441 + table->revision); 441 442 442 443 index++; 443 444 } ··· 689 688 int find_acpi_cpu_topology(unsigned int cpu, int level) 690 689 { 691 690 return find_acpi_cpu_topology_tag(cpu, level, 0); 692 - } 693 - 694 - /** 695 - * find_acpi_cpu_cache_topology() - Determine a unique cache topology value 696 - * @cpu: Kernel logical CPU number 697 - * @level: The cache level for which we would like a unique ID 698 - * 699 - * Determine a unique ID for each unified cache in the system 700 - * 701 - * Return: -ENOENT if the PPTT doesn't exist, or the CPU cannot be found. 702 - * Otherwise returns a value which represents a unique topological feature. 703 - */ 704 - int find_acpi_cpu_cache_topology(unsigned int cpu, int level) 705 - { 706 - struct acpi_table_header *table; 707 - struct acpi_pptt_cache *found_cache; 708 - acpi_status status; 709 - u32 acpi_cpu_id = get_acpi_id_for_cpu(cpu); 710 - struct acpi_pptt_processor *cpu_node = NULL; 711 - int ret = -1; 712 - 713 - status = acpi_get_table(ACPI_SIG_PPTT, 0, &table); 714 - if (ACPI_FAILURE(status)) { 715 - acpi_pptt_warn_missing(); 716 - return -ENOENT; 717 - } 718 - 719 - found_cache = acpi_find_cache_node(table, acpi_cpu_id, 720 - CACHE_TYPE_UNIFIED, 721 - level, 722 - &cpu_node); 723 - if (found_cache) 724 - ret = ACPI_PTR_DIFF(cpu_node, table); 725 - 726 - acpi_put_table(table); 727 - 728 - return ret; 729 691 } 730 692 731 693 /**
+80 -26
drivers/base/arch_topology.c
··· 7 7 */ 8 8 9 9 #include <linux/acpi.h> 10 + #include <linux/cacheinfo.h> 10 11 #include <linux/cpu.h> 11 12 #include <linux/cpufreq.h> 12 13 #include <linux/device.h> ··· 497 496 } 498 497 499 498 static int __init parse_core(struct device_node *core, int package_id, 500 - int core_id) 499 + int cluster_id, int core_id) 501 500 { 502 501 char name[20]; 503 502 bool leaf = true; ··· 513 512 cpu = get_cpu_for_node(t); 514 513 if (cpu >= 0) { 515 514 cpu_topology[cpu].package_id = package_id; 515 + cpu_topology[cpu].cluster_id = cluster_id; 516 516 cpu_topology[cpu].core_id = core_id; 517 517 cpu_topology[cpu].thread_id = i; 518 518 } else if (cpu != -ENODEV) { ··· 535 533 } 536 534 537 535 cpu_topology[cpu].package_id = package_id; 536 + cpu_topology[cpu].cluster_id = cluster_id; 538 537 cpu_topology[cpu].core_id = core_id; 539 538 } else if (leaf && cpu != -ENODEV) { 540 539 pr_err("%pOF: Can't get CPU for leaf core\n", core); ··· 545 542 return 0; 546 543 } 547 544 548 - static int __init parse_cluster(struct device_node *cluster, int depth) 545 + static int __init parse_cluster(struct device_node *cluster, int package_id, 546 + int cluster_id, int depth) 549 547 { 550 548 char name[20]; 551 549 bool leaf = true; 552 550 bool has_cores = false; 553 551 struct device_node *c; 554 - static int package_id __initdata; 555 552 int core_id = 0; 556 553 int i, ret; 557 554 ··· 566 563 c = of_get_child_by_name(cluster, name); 567 564 if (c) { 568 565 leaf = false; 569 - ret = parse_cluster(c, depth + 1); 566 + ret = parse_cluster(c, package_id, i, depth + 1); 567 + if (depth > 0) 568 + pr_warn("Topology for clusters of clusters not yet supported\n"); 570 569 of_node_put(c); 571 570 if (ret != 0) 572 571 return ret; ··· 592 587 } 593 588 594 589 if (leaf) { 595 - ret = parse_core(c, package_id, core_id++); 590 + ret = parse_core(c, package_id, cluster_id, 591 + core_id++); 596 592 } else { 597 593 pr_err("%pOF: Non-leaf cluster with core %s\n", 598 594 cluster, name); ··· 610 604 if (leaf && !has_cores) 611 605 pr_warn("%pOF: empty cluster\n", cluster); 612 606 613 - if (leaf) 614 - package_id++; 615 - 616 607 return 0; 608 + } 609 + 610 + static int __init parse_socket(struct device_node *socket) 611 + { 612 + char name[20]; 613 + struct device_node *c; 614 + bool has_socket = false; 615 + int package_id = 0, ret; 616 + 617 + do { 618 + snprintf(name, sizeof(name), "socket%d", package_id); 619 + c = of_get_child_by_name(socket, name); 620 + if (c) { 621 + has_socket = true; 622 + ret = parse_cluster(c, package_id, -1, 0); 623 + of_node_put(c); 624 + if (ret != 0) 625 + return ret; 626 + } 627 + package_id++; 628 + } while (c); 629 + 630 + if (!has_socket) 631 + ret = parse_cluster(socket, 0, -1, 0); 632 + 633 + return ret; 617 634 } 618 635 619 636 static int __init parse_dt_topology(void) ··· 659 630 if (!map) 660 631 goto out; 661 632 662 - ret = parse_cluster(map, 0); 633 + ret = parse_socket(map); 663 634 if (ret != 0) 664 635 goto out_map; 665 636 ··· 670 641 * only mark cores described in the DT as possible. 671 642 */ 672 643 for_each_possible_cpu(cpu) 673 - if (cpu_topology[cpu].package_id == -1) 644 + if (cpu_topology[cpu].package_id < 0) { 674 645 ret = -EINVAL; 646 + break; 647 + } 675 648 676 649 out_map: 677 650 of_node_put(map); ··· 698 667 /* not numa in package, lets use the package siblings */ 699 668 core_mask = &cpu_topology[cpu].core_sibling; 700 669 } 701 - if (cpu_topology[cpu].llc_id != -1) { 670 + 671 + if (last_level_cache_is_valid(cpu)) { 702 672 if (cpumask_subset(&cpu_topology[cpu].llc_sibling, core_mask)) 703 673 core_mask = &cpu_topology[cpu].llc_sibling; 704 674 } ··· 718 686 719 687 const struct cpumask *cpu_clustergroup_mask(int cpu) 720 688 { 689 + /* 690 + * Forbid cpu_clustergroup_mask() to span more or the same CPUs as 691 + * cpu_coregroup_mask(). 692 + */ 693 + if (cpumask_subset(cpu_coregroup_mask(cpu), 694 + &cpu_topology[cpu].cluster_sibling)) 695 + return get_cpu_mask(cpu); 696 + 721 697 return &cpu_topology[cpu].cluster_sibling; 722 698 } 723 699 ··· 738 698 for_each_online_cpu(cpu) { 739 699 cpu_topo = &cpu_topology[cpu]; 740 700 741 - if (cpu_topo->llc_id != -1 && cpuid_topo->llc_id == cpu_topo->llc_id) { 701 + if (last_level_cache_is_shared(cpu, cpuid)) { 742 702 cpumask_set_cpu(cpu, &cpuid_topo->llc_sibling); 743 703 cpumask_set_cpu(cpuid, &cpu_topo->llc_sibling); 744 704 } ··· 746 706 if (cpuid_topo->package_id != cpu_topo->package_id) 747 707 continue; 748 708 749 - if (cpuid_topo->cluster_id == cpu_topo->cluster_id && 750 - cpuid_topo->cluster_id != -1) { 709 + cpumask_set_cpu(cpuid, &cpu_topo->core_sibling); 710 + cpumask_set_cpu(cpu, &cpuid_topo->core_sibling); 711 + 712 + if (cpuid_topo->cluster_id != cpu_topo->cluster_id) 713 + continue; 714 + 715 + if (cpuid_topo->cluster_id >= 0) { 751 716 cpumask_set_cpu(cpu, &cpuid_topo->cluster_sibling); 752 717 cpumask_set_cpu(cpuid, &cpu_topo->cluster_sibling); 753 718 } 754 - 755 - cpumask_set_cpu(cpuid, &cpu_topo->core_sibling); 756 - cpumask_set_cpu(cpu, &cpuid_topo->core_sibling); 757 719 758 720 if (cpuid_topo->core_id != cpu_topo->core_id) 759 721 continue; ··· 792 750 cpu_topo->core_id = -1; 793 751 cpu_topo->cluster_id = -1; 794 752 cpu_topo->package_id = -1; 795 - cpu_topo->llc_id = -1; 796 753 797 754 clear_cpu_topology(cpu); 798 755 } ··· 821 780 #if defined(CONFIG_ARM64) || defined(CONFIG_RISCV) 822 781 void __init init_cpu_topology(void) 823 782 { 824 - reset_cpu_topology(); 783 + int ret, cpu; 825 784 826 - /* 827 - * Discard anything that was parsed if we hit an error so we 828 - * don't use partial information. 829 - */ 830 - if (parse_acpi_topology()) 785 + reset_cpu_topology(); 786 + ret = parse_acpi_topology(); 787 + if (!ret) 788 + ret = of_have_populated_dt() && parse_dt_topology(); 789 + 790 + if (ret) { 791 + /* 792 + * Discard anything that was parsed if we hit an error so we 793 + * don't use partial information. 794 + */ 831 795 reset_cpu_topology(); 832 - else if (of_have_populated_dt() && parse_dt_topology()) 833 - reset_cpu_topology(); 796 + return; 797 + } 798 + 799 + for_each_possible_cpu(cpu) { 800 + ret = detect_cache_attributes(cpu); 801 + if (ret) { 802 + pr_info("Early cacheinfo failed, ret = %d\n", ret); 803 + break; 804 + } 805 + } 834 806 } 835 807 #endif
+92 -51
drivers/base/cacheinfo.c
··· 14 14 #include <linux/cpu.h> 15 15 #include <linux/device.h> 16 16 #include <linux/init.h> 17 - #include <linux/of.h> 17 + #include <linux/of_device.h> 18 18 #include <linux/sched.h> 19 19 #include <linux/slab.h> 20 20 #include <linux/smp.h> ··· 25 25 #define ci_cacheinfo(cpu) (&per_cpu(ci_cpu_cacheinfo, cpu)) 26 26 #define cache_leaves(cpu) (ci_cacheinfo(cpu)->num_leaves) 27 27 #define per_cpu_cacheinfo(cpu) (ci_cacheinfo(cpu)->info_list) 28 + #define per_cpu_cacheinfo_idx(cpu, idx) \ 29 + (per_cpu_cacheinfo(cpu) + (idx)) 28 30 29 31 struct cpu_cacheinfo *get_cpu_cacheinfo(unsigned int cpu) 30 32 { 31 33 return ci_cacheinfo(cpu); 32 34 } 33 35 34 - #ifdef CONFIG_OF 35 36 static inline bool cache_leaves_are_shared(struct cacheinfo *this_leaf, 36 37 struct cacheinfo *sib_leaf) 37 38 { 39 + /* 40 + * For non DT/ACPI systems, assume unique level 1 caches, 41 + * system-wide shared caches for all other levels. This will be used 42 + * only if arch specific code has not populated shared_cpu_map 43 + */ 44 + if (!(IS_ENABLED(CONFIG_OF) || IS_ENABLED(CONFIG_ACPI))) 45 + return !(this_leaf->level == 1); 46 + 47 + if ((sib_leaf->attributes & CACHE_ID) && 48 + (this_leaf->attributes & CACHE_ID)) 49 + return sib_leaf->id == this_leaf->id; 50 + 38 51 return sib_leaf->fw_token == this_leaf->fw_token; 39 52 } 40 53 54 + bool last_level_cache_is_valid(unsigned int cpu) 55 + { 56 + struct cacheinfo *llc; 57 + 58 + if (!cache_leaves(cpu)) 59 + return false; 60 + 61 + llc = per_cpu_cacheinfo_idx(cpu, cache_leaves(cpu) - 1); 62 + 63 + return (llc->attributes & CACHE_ID) || !!llc->fw_token; 64 + 65 + } 66 + 67 + bool last_level_cache_is_shared(unsigned int cpu_x, unsigned int cpu_y) 68 + { 69 + struct cacheinfo *llc_x, *llc_y; 70 + 71 + if (!last_level_cache_is_valid(cpu_x) || 72 + !last_level_cache_is_valid(cpu_y)) 73 + return false; 74 + 75 + llc_x = per_cpu_cacheinfo_idx(cpu_x, cache_leaves(cpu_x) - 1); 76 + llc_y = per_cpu_cacheinfo_idx(cpu_y, cache_leaves(cpu_y) - 1); 77 + 78 + return cache_leaves_are_shared(llc_x, llc_y); 79 + } 80 + 81 + #ifdef CONFIG_OF 41 82 /* OF properties to query for a given cache type */ 42 83 struct cache_type_info { 43 84 const char *size_prop; ··· 198 157 { 199 158 struct device_node *np; 200 159 struct cacheinfo *this_leaf; 201 - struct device *cpu_dev = get_cpu_device(cpu); 202 - struct cpu_cacheinfo *this_cpu_ci = get_cpu_cacheinfo(cpu); 203 160 unsigned int index = 0; 204 161 205 - /* skip if fw_token is already populated */ 206 - if (this_cpu_ci->info_list->fw_token) { 207 - return 0; 208 - } 209 - 210 - if (!cpu_dev) { 211 - pr_err("No cpu device for CPU %d\n", cpu); 212 - return -ENODEV; 213 - } 214 - np = cpu_dev->of_node; 162 + np = of_cpu_device_node_get(cpu); 215 163 if (!np) { 216 164 pr_err("Failed to find cpu%d device node\n", cpu); 217 165 return -ENOENT; 218 166 } 219 167 220 168 while (index < cache_leaves(cpu)) { 221 - this_leaf = this_cpu_ci->info_list + index; 169 + this_leaf = per_cpu_cacheinfo_idx(cpu, index); 222 170 if (this_leaf->level != 1) 223 171 np = of_find_next_cache_node(np); 224 172 else ··· 226 196 } 227 197 #else 228 198 static inline int cache_setup_of_node(unsigned int cpu) { return 0; } 229 - static inline bool cache_leaves_are_shared(struct cacheinfo *this_leaf, 230 - struct cacheinfo *sib_leaf) 231 - { 232 - /* 233 - * For non-DT/ACPI systems, assume unique level 1 caches, system-wide 234 - * shared caches for all other levels. This will be used only if 235 - * arch specific code has not populated shared_cpu_map 236 - */ 237 - return !(this_leaf->level == 1); 238 - } 239 199 #endif 240 200 241 201 int __weak cache_setup_acpi(unsigned int cpu) ··· 234 214 } 235 215 236 216 unsigned int coherency_max_size; 217 + 218 + static int cache_setup_properties(unsigned int cpu) 219 + { 220 + int ret = 0; 221 + 222 + if (of_have_populated_dt()) 223 + ret = cache_setup_of_node(cpu); 224 + else if (!acpi_disabled) 225 + ret = cache_setup_acpi(cpu); 226 + 227 + return ret; 228 + } 237 229 238 230 static int cache_shared_cpu_map_setup(unsigned int cpu) 239 231 { ··· 257 225 if (this_cpu_ci->cpu_map_populated) 258 226 return 0; 259 227 260 - if (of_have_populated_dt()) 261 - ret = cache_setup_of_node(cpu); 262 - else if (!acpi_disabled) 263 - ret = cache_setup_acpi(cpu); 264 - 265 - if (ret) 266 - return ret; 228 + /* 229 + * skip setting up cache properties if LLC is valid, just need 230 + * to update the shared cpu_map if the cache attributes were 231 + * populated early before all the cpus are brought online 232 + */ 233 + if (!last_level_cache_is_valid(cpu)) { 234 + ret = cache_setup_properties(cpu); 235 + if (ret) 236 + return ret; 237 + } 267 238 268 239 for (index = 0; index < cache_leaves(cpu); index++) { 269 240 unsigned int i; 270 241 271 - this_leaf = this_cpu_ci->info_list + index; 272 - /* skip if shared_cpu_map is already populated */ 273 - if (!cpumask_empty(&this_leaf->shared_cpu_map)) 274 - continue; 242 + this_leaf = per_cpu_cacheinfo_idx(cpu, index); 275 243 276 244 cpumask_set_cpu(cpu, &this_leaf->shared_cpu_map); 277 245 for_each_online_cpu(i) { ··· 279 247 280 248 if (i == cpu || !sib_cpu_ci->info_list) 281 249 continue;/* skip if itself or no cacheinfo */ 282 - sib_leaf = sib_cpu_ci->info_list + index; 250 + 251 + sib_leaf = per_cpu_cacheinfo_idx(i, index); 283 252 if (cache_leaves_are_shared(this_leaf, sib_leaf)) { 284 253 cpumask_set_cpu(cpu, &sib_leaf->shared_cpu_map); 285 254 cpumask_set_cpu(i, &this_leaf->shared_cpu_map); ··· 296 263 297 264 static void cache_shared_cpu_map_remove(unsigned int cpu) 298 265 { 299 - struct cpu_cacheinfo *this_cpu_ci = get_cpu_cacheinfo(cpu); 300 266 struct cacheinfo *this_leaf, *sib_leaf; 301 267 unsigned int sibling, index; 302 268 303 269 for (index = 0; index < cache_leaves(cpu); index++) { 304 - this_leaf = this_cpu_ci->info_list + index; 270 + this_leaf = per_cpu_cacheinfo_idx(cpu, index); 305 271 for_each_cpu(sibling, &this_leaf->shared_cpu_map) { 306 - struct cpu_cacheinfo *sib_cpu_ci; 272 + struct cpu_cacheinfo *sib_cpu_ci = 273 + get_cpu_cacheinfo(sibling); 307 274 308 - if (sibling == cpu) /* skip itself */ 309 - continue; 275 + if (sibling == cpu || !sib_cpu_ci->info_list) 276 + continue;/* skip if itself or no cacheinfo */ 310 277 311 - sib_cpu_ci = get_cpu_cacheinfo(sibling); 312 - if (!sib_cpu_ci->info_list) 313 - continue; 314 - 315 - sib_leaf = sib_cpu_ci->info_list + index; 278 + sib_leaf = per_cpu_cacheinfo_idx(sibling, index); 316 279 cpumask_clear_cpu(cpu, &sib_leaf->shared_cpu_map); 317 280 cpumask_clear_cpu(sibling, &this_leaf->shared_cpu_map); 318 281 } ··· 339 310 return -ENOENT; 340 311 } 341 312 342 - static int detect_cache_attributes(unsigned int cpu) 313 + int detect_cache_attributes(unsigned int cpu) 343 314 { 344 315 int ret; 316 + 317 + /* Since early detection of the cacheinfo is allowed via this 318 + * function and this also gets called as CPU hotplug callbacks via 319 + * cacheinfo_cpu_online, the initialisation can be skipped and only 320 + * CPU maps can be updated as the CPU online status would be update 321 + * if called via cacheinfo_cpu_online path. 322 + */ 323 + if (per_cpu_cacheinfo(cpu)) 324 + goto update_cpu_map; 345 325 346 326 if (init_cache_level(cpu) || !cache_leaves(cpu)) 347 327 return -ENOENT; 348 328 349 329 per_cpu_cacheinfo(cpu) = kcalloc(cache_leaves(cpu), 350 330 sizeof(struct cacheinfo), GFP_KERNEL); 351 - if (per_cpu_cacheinfo(cpu) == NULL) 331 + if (per_cpu_cacheinfo(cpu) == NULL) { 332 + cache_leaves(cpu) = 0; 352 333 return -ENOMEM; 334 + } 353 335 354 336 /* 355 337 * populate_cache_leaves() may completely setup the cache leaves and ··· 369 329 ret = populate_cache_leaves(cpu); 370 330 if (ret) 371 331 goto free_ci; 332 + 333 + update_cpu_map: 372 334 /* 373 335 * For systems using DT for cache hierarchy, fw_token 374 336 * and shared_cpu_map will be set up here only if they are ··· 656 614 int rc; 657 615 struct device *ci_dev, *parent; 658 616 struct cacheinfo *this_leaf; 659 - struct cpu_cacheinfo *this_cpu_ci = get_cpu_cacheinfo(cpu); 660 617 const struct attribute_group **cache_groups; 661 618 662 619 rc = cpu_cache_sysfs_init(cpu); ··· 664 623 665 624 parent = per_cpu_cache_dev(cpu); 666 625 for (i = 0; i < cache_leaves(cpu); i++) { 667 - this_leaf = this_cpu_ci->info_list + i; 626 + this_leaf = per_cpu_cacheinfo_idx(cpu, i); 668 627 if (this_leaf->disable_sysfs) 669 628 continue; 670 629 if (this_leaf->type == CACHE_TYPE_NOCACHE)
-5
include/linux/acpi.h
··· 1429 1429 int find_acpi_cpu_topology_cluster(unsigned int cpu); 1430 1430 int find_acpi_cpu_topology_package(unsigned int cpu); 1431 1431 int find_acpi_cpu_topology_hetero_id(unsigned int cpu); 1432 - int find_acpi_cpu_cache_topology(unsigned int cpu, int level); 1433 1432 #else 1434 1433 static inline int acpi_pptt_cpu_is_thread(unsigned int cpu) 1435 1434 { ··· 1447 1448 return -EINVAL; 1448 1449 } 1449 1450 static inline int find_acpi_cpu_topology_hetero_id(unsigned int cpu) 1450 - { 1451 - return -EINVAL; 1452 - } 1453 - static inline int find_acpi_cpu_cache_topology(unsigned int cpu, int level) 1454 1451 { 1455 1452 return -EINVAL; 1456 1453 }
-1
include/linux/arch_topology.h
··· 68 68 int core_id; 69 69 int cluster_id; 70 70 int package_id; 71 - int llc_id; 72 71 cpumask_t thread_sibling; 73 72 cpumask_t core_sibling; 74 73 cpumask_t cluster_sibling;
+3
include/linux/cacheinfo.h
··· 82 82 int init_cache_level(unsigned int cpu); 83 83 int populate_cache_leaves(unsigned int cpu); 84 84 int cache_setup_acpi(unsigned int cpu); 85 + bool last_level_cache_is_valid(unsigned int cpu); 86 + bool last_level_cache_is_shared(unsigned int cpu_x, unsigned int cpu_y); 87 + int detect_cache_attributes(unsigned int cpu); 85 88 #ifndef CONFIG_ACPI_PPTT 86 89 /* 87 90 * acpi_find_last_cache_level is only called on ACPI enabled