.. | .. |
---|
98 | 98 | * |
---|
99 | 99 | * Return: The cache structure and the level we terminated with. |
---|
100 | 100 | */ |
---|
101 | | -static int acpi_pptt_walk_cache(struct acpi_table_header *table_hdr, |
---|
102 | | - int local_level, |
---|
103 | | - struct acpi_subtable_header *res, |
---|
104 | | - struct acpi_pptt_cache **found, |
---|
105 | | - int level, int type) |
---|
| 101 | +static unsigned int acpi_pptt_walk_cache(struct acpi_table_header *table_hdr, |
---|
| 102 | + unsigned int local_level, |
---|
| 103 | + struct acpi_subtable_header *res, |
---|
| 104 | + struct acpi_pptt_cache **found, |
---|
| 105 | + unsigned int level, int type) |
---|
106 | 106 | { |
---|
107 | 107 | struct acpi_pptt_cache *cache; |
---|
108 | 108 | |
---|
.. | .. |
---|
119 | 119 | if (*found != NULL && cache != *found) |
---|
120 | 120 | pr_warn("Found duplicate cache level/type unable to determine uniqueness\n"); |
---|
121 | 121 | |
---|
122 | | - pr_debug("Found cache @ level %d\n", level); |
---|
| 122 | + pr_debug("Found cache @ level %u\n", level); |
---|
123 | 123 | *found = cache; |
---|
124 | 124 | /* |
---|
125 | 125 | * continue looking at this node's resource list |
---|
.. | .. |
---|
132 | 132 | return local_level; |
---|
133 | 133 | } |
---|
134 | 134 | |
---|
135 | | -static struct acpi_pptt_cache *acpi_find_cache_level(struct acpi_table_header *table_hdr, |
---|
136 | | - struct acpi_pptt_processor *cpu_node, |
---|
137 | | - int *starting_level, int level, |
---|
138 | | - int type) |
---|
| 135 | +static struct acpi_pptt_cache * |
---|
| 136 | +acpi_find_cache_level(struct acpi_table_header *table_hdr, |
---|
| 137 | + struct acpi_pptt_processor *cpu_node, |
---|
| 138 | + unsigned int *starting_level, unsigned int level, |
---|
| 139 | + int type) |
---|
139 | 140 | { |
---|
140 | 141 | struct acpi_subtable_header *res; |
---|
141 | | - int number_of_levels = *starting_level; |
---|
| 142 | + unsigned int number_of_levels = *starting_level; |
---|
142 | 143 | int resource = 0; |
---|
143 | 144 | struct acpi_pptt_cache *ret = NULL; |
---|
144 | | - int local_level; |
---|
| 145 | + unsigned int local_level; |
---|
145 | 146 | |
---|
146 | 147 | /* walk down from processor node */ |
---|
147 | 148 | while ((res = acpi_get_pptt_resource(table_hdr, cpu_node, resource))) { |
---|
.. | .. |
---|
164 | 165 | } |
---|
165 | 166 | |
---|
166 | 167 | /** |
---|
167 | | - * acpi_count_levels() - Given a PPTT table, and a cpu node, count the caches |
---|
| 168 | + * acpi_count_levels() - Given a PPTT table, and a CPU node, count the caches |
---|
168 | 169 | * @table_hdr: Pointer to the head of the PPTT table |
---|
169 | 170 | * @cpu_node: processor node we wish to count caches for |
---|
170 | 171 | * |
---|
.. | .. |
---|
209 | 210 | struct acpi_pptt_processor *cpu_node; |
---|
210 | 211 | u32 proc_sz; |
---|
211 | 212 | |
---|
| 213 | + if (table_hdr->revision > 1) |
---|
| 214 | + return (node->flags & ACPI_PPTT_ACPI_LEAF_NODE); |
---|
| 215 | + |
---|
212 | 216 | table_end = (unsigned long)table_hdr + table_hdr->length; |
---|
213 | 217 | node_entry = ACPI_PTR_DIFF(node, table_hdr); |
---|
214 | 218 | entry = ACPI_ADD_PTR(struct acpi_subtable_header, table_hdr, |
---|
.. | .. |
---|
232 | 236 | /** |
---|
233 | 237 | * acpi_find_processor_node() - Given a PPTT table find the requested processor |
---|
234 | 238 | * @table_hdr: Pointer to the head of the PPTT table |
---|
235 | | - * @acpi_cpu_id: cpu we are searching for |
---|
| 239 | + * @acpi_cpu_id: CPU we are searching for |
---|
236 | 240 | * |
---|
237 | 241 | * Find the subtable entry describing the provided processor. |
---|
238 | 242 | * This is done by iterating the PPTT table looking for processor nodes |
---|
.. | .. |
---|
318 | 322 | unsigned int level, |
---|
319 | 323 | struct acpi_pptt_processor **node) |
---|
320 | 324 | { |
---|
321 | | - int total_levels = 0; |
---|
| 325 | + unsigned int total_levels = 0; |
---|
322 | 326 | struct acpi_pptt_cache *found = NULL; |
---|
323 | 327 | struct acpi_pptt_processor *cpu_node; |
---|
324 | 328 | u8 acpi_type = acpi_cache_type(type); |
---|
325 | 329 | |
---|
326 | | - pr_debug("Looking for CPU %d's level %d cache type %d\n", |
---|
| 330 | + pr_debug("Looking for CPU %d's level %u cache type %d\n", |
---|
327 | 331 | acpi_cpu_id, level, acpi_type); |
---|
328 | 332 | |
---|
329 | 333 | cpu_node = acpi_find_processor_node(table_hdr, acpi_cpu_id); |
---|
.. | .. |
---|
429 | 433 | } |
---|
430 | 434 | } |
---|
431 | 435 | |
---|
| 436 | +static bool flag_identical(struct acpi_table_header *table_hdr, |
---|
| 437 | + struct acpi_pptt_processor *cpu) |
---|
| 438 | +{ |
---|
| 439 | + struct acpi_pptt_processor *next; |
---|
| 440 | + |
---|
| 441 | + /* heterogeneous machines must use PPTT revision > 1 */ |
---|
| 442 | + if (table_hdr->revision < 2) |
---|
| 443 | + return false; |
---|
| 444 | + |
---|
| 445 | + /* Locate the last node in the tree with IDENTICAL set */ |
---|
| 446 | + if (cpu->flags & ACPI_PPTT_ACPI_IDENTICAL) { |
---|
| 447 | + next = fetch_pptt_node(table_hdr, cpu->parent); |
---|
| 448 | + if (!(next && next->flags & ACPI_PPTT_ACPI_IDENTICAL)) |
---|
| 449 | + return true; |
---|
| 450 | + } |
---|
| 451 | + |
---|
| 452 | + return false; |
---|
| 453 | +} |
---|
| 454 | + |
---|
432 | 455 | /* Passing level values greater than this will result in search termination */ |
---|
433 | 456 | #define PPTT_ABORT_PACKAGE 0xFF |
---|
434 | 457 | |
---|
435 | | -static struct acpi_pptt_processor *acpi_find_processor_package_id(struct acpi_table_header *table_hdr, |
---|
436 | | - struct acpi_pptt_processor *cpu, |
---|
437 | | - int level, int flag) |
---|
| 458 | +static struct acpi_pptt_processor *acpi_find_processor_tag(struct acpi_table_header *table_hdr, |
---|
| 459 | + struct acpi_pptt_processor *cpu, |
---|
| 460 | + int level, int flag) |
---|
438 | 461 | { |
---|
439 | 462 | struct acpi_pptt_processor *prev_node; |
---|
440 | 463 | |
---|
441 | 464 | while (cpu && level) { |
---|
442 | | - if (cpu->flags & flag) |
---|
| 465 | + /* special case the identical flag to find last identical */ |
---|
| 466 | + if (flag == ACPI_PPTT_ACPI_IDENTICAL) { |
---|
| 467 | + if (flag_identical(table_hdr, cpu)) |
---|
| 468 | + break; |
---|
| 469 | + } else if (cpu->flags & flag) |
---|
443 | 470 | break; |
---|
444 | 471 | pr_debug("level %d\n", level); |
---|
445 | 472 | prev_node = fetch_pptt_node(table_hdr, cpu->parent); |
---|
.. | .. |
---|
451 | 478 | return cpu; |
---|
452 | 479 | } |
---|
453 | 480 | |
---|
| 481 | +static void acpi_pptt_warn_missing(void) |
---|
| 482 | +{ |
---|
| 483 | + pr_warn_once("No PPTT table found, CPU and cache topology may be inaccurate\n"); |
---|
| 484 | +} |
---|
| 485 | + |
---|
454 | 486 | /** |
---|
455 | 487 | * topology_get_acpi_cpu_tag() - Find a unique topology value for a feature |
---|
456 | 488 | * @table: Pointer to the head of the PPTT table |
---|
457 | | - * @cpu: Kernel logical cpu number |
---|
| 489 | + * @cpu: Kernel logical CPU number |
---|
458 | 490 | * @level: A level that terminates the search |
---|
459 | 491 | * @flag: A flag which terminates the search |
---|
460 | 492 | * |
---|
461 | | - * Get a unique value given a cpu, and a topology level, that can be |
---|
| 493 | + * Get a unique value given a CPU, and a topology level, that can be |
---|
462 | 494 | * matched to determine which cpus share common topological features |
---|
463 | 495 | * at that level. |
---|
464 | 496 | * |
---|
465 | | - * Return: Unique value, or -ENOENT if unable to locate cpu |
---|
| 497 | + * Return: Unique value, or -ENOENT if unable to locate CPU |
---|
466 | 498 | */ |
---|
467 | 499 | static int topology_get_acpi_cpu_tag(struct acpi_table_header *table, |
---|
468 | 500 | unsigned int cpu, int level, int flag) |
---|
.. | .. |
---|
472 | 504 | |
---|
473 | 505 | cpu_node = acpi_find_processor_node(table, acpi_cpu_id); |
---|
474 | 506 | if (cpu_node) { |
---|
475 | | - cpu_node = acpi_find_processor_package_id(table, cpu_node, |
---|
476 | | - level, flag); |
---|
| 507 | + cpu_node = acpi_find_processor_tag(table, cpu_node, |
---|
| 508 | + level, flag); |
---|
477 | 509 | /* |
---|
478 | 510 | * As per specification if the processor structure represents |
---|
479 | 511 | * an actual processor, then ACPI processor ID must be valid. |
---|
.. | .. |
---|
498 | 530 | |
---|
499 | 531 | status = acpi_get_table(ACPI_SIG_PPTT, 0, &table); |
---|
500 | 532 | if (ACPI_FAILURE(status)) { |
---|
501 | | - pr_warn_once("No PPTT table found, cpu topology may be inaccurate\n"); |
---|
| 533 | + acpi_pptt_warn_missing(); |
---|
502 | 534 | return -ENOENT; |
---|
503 | 535 | } |
---|
504 | 536 | retval = topology_get_acpi_cpu_tag(table, cpu, level, flag); |
---|
505 | | - pr_debug("Topology Setup ACPI cpu %d, level %d ret = %d\n", |
---|
| 537 | + pr_debug("Topology Setup ACPI CPU %d, level %d ret = %d\n", |
---|
506 | 538 | cpu, level, retval); |
---|
507 | 539 | acpi_put_table(table); |
---|
508 | 540 | |
---|
.. | .. |
---|
532 | 564 | |
---|
533 | 565 | status = acpi_get_table(ACPI_SIG_PPTT, 0, &table); |
---|
534 | 566 | if (ACPI_FAILURE(status)) { |
---|
535 | | - pr_warn_once("No PPTT table found, cpu topology may be inaccurate\n"); |
---|
| 567 | + acpi_pptt_warn_missing(); |
---|
536 | 568 | return ret; |
---|
537 | 569 | } |
---|
538 | 570 | |
---|
.. | .. |
---|
549 | 581 | |
---|
550 | 582 | /** |
---|
551 | 583 | * acpi_find_last_cache_level() - Determines the number of cache levels for a PE |
---|
552 | | - * @cpu: Kernel logical cpu number |
---|
| 584 | + * @cpu: Kernel logical CPU number |
---|
553 | 585 | * |
---|
554 | | - * Given a logical cpu number, returns the number of levels of cache represented |
---|
| 586 | + * Given a logical CPU number, returns the number of levels of cache represented |
---|
555 | 587 | * in the PPTT. Errors caused by lack of a PPTT table, or otherwise, return 0 |
---|
556 | 588 | * indicating we didn't find any cache levels. |
---|
557 | 589 | * |
---|
.. | .. |
---|
564 | 596 | int number_of_levels = 0; |
---|
565 | 597 | acpi_status status; |
---|
566 | 598 | |
---|
567 | | - pr_debug("Cache Setup find last level cpu=%d\n", cpu); |
---|
| 599 | + pr_debug("Cache Setup find last level CPU=%d\n", cpu); |
---|
568 | 600 | |
---|
569 | 601 | acpi_cpu_id = get_acpi_id_for_cpu(cpu); |
---|
570 | 602 | status = acpi_get_table(ACPI_SIG_PPTT, 0, &table); |
---|
571 | 603 | if (ACPI_FAILURE(status)) { |
---|
572 | | - pr_warn_once("No PPTT table found, cache topology may be inaccurate\n"); |
---|
| 604 | + acpi_pptt_warn_missing(); |
---|
573 | 605 | } else { |
---|
574 | 606 | number_of_levels = acpi_find_cache_levels(table, acpi_cpu_id); |
---|
575 | 607 | acpi_put_table(table); |
---|
.. | .. |
---|
581 | 613 | |
---|
582 | 614 | /** |
---|
583 | 615 | * cache_setup_acpi() - Override CPU cache topology with data from the PPTT |
---|
584 | | - * @cpu: Kernel logical cpu number |
---|
| 616 | + * @cpu: Kernel logical CPU number |
---|
585 | 617 | * |
---|
586 | 618 | * Updates the global cache info provided by cpu_get_cacheinfo() |
---|
587 | 619 | * when there are valid properties in the acpi_pptt_cache nodes. A |
---|
588 | 620 | * successful parse may not result in any updates if none of the |
---|
589 | | - * cache levels have any valid flags set. Futher, a unique value is |
---|
| 621 | + * cache levels have any valid flags set. Further, a unique value is |
---|
590 | 622 | * associated with each known CPU cache entry. This unique value |
---|
591 | | - * can be used to determine whether caches are shared between cpus. |
---|
| 623 | + * can be used to determine whether caches are shared between CPUs. |
---|
592 | 624 | * |
---|
593 | 625 | * Return: -ENOENT on failure to find table, or 0 on success |
---|
594 | 626 | */ |
---|
.. | .. |
---|
597 | 629 | struct acpi_table_header *table; |
---|
598 | 630 | acpi_status status; |
---|
599 | 631 | |
---|
600 | | - pr_debug("Cache Setup ACPI cpu %d\n", cpu); |
---|
| 632 | + pr_debug("Cache Setup ACPI CPU %d\n", cpu); |
---|
601 | 633 | |
---|
602 | 634 | status = acpi_get_table(ACPI_SIG_PPTT, 0, &table); |
---|
603 | 635 | if (ACPI_FAILURE(status)) { |
---|
604 | | - pr_warn_once("No PPTT table found, cache topology may be inaccurate\n"); |
---|
| 636 | + acpi_pptt_warn_missing(); |
---|
605 | 637 | return -ENOENT; |
---|
606 | 638 | } |
---|
607 | 639 | |
---|
.. | .. |
---|
626 | 658 | } |
---|
627 | 659 | |
---|
628 | 660 | /** |
---|
629 | | - * find_acpi_cpu_topology() - Determine a unique topology value for a given cpu |
---|
630 | | - * @cpu: Kernel logical cpu number |
---|
| 661 | + * find_acpi_cpu_topology() - Determine a unique topology value for a given CPU |
---|
| 662 | + * @cpu: Kernel logical CPU number |
---|
631 | 663 | * @level: The topological level for which we would like a unique ID |
---|
632 | 664 | * |
---|
633 | 665 | * Determine a topology unique ID for each thread/core/cluster/mc_grouping |
---|
.. | .. |
---|
640 | 672 | * other levels beyond this use a generated value to uniquely identify |
---|
641 | 673 | * a topological feature. |
---|
642 | 674 | * |
---|
643 | | - * Return: -ENOENT if the PPTT doesn't exist, or the cpu cannot be found. |
---|
| 675 | + * Return: -ENOENT if the PPTT doesn't exist, or the CPU cannot be found. |
---|
644 | 676 | * Otherwise returns a value which represents a unique topological feature. |
---|
645 | 677 | */ |
---|
646 | 678 | int find_acpi_cpu_topology(unsigned int cpu, int level) |
---|
.. | .. |
---|
650 | 682 | |
---|
651 | 683 | /** |
---|
652 | 684 | * find_acpi_cpu_cache_topology() - Determine a unique cache topology value |
---|
653 | | - * @cpu: Kernel logical cpu number |
---|
| 685 | + * @cpu: Kernel logical CPU number |
---|
654 | 686 | * @level: The cache level for which we would like a unique ID |
---|
655 | 687 | * |
---|
656 | 688 | * Determine a unique ID for each unified cache in the system |
---|
657 | 689 | * |
---|
658 | | - * Return: -ENOENT if the PPTT doesn't exist, or the cpu cannot be found. |
---|
| 690 | + * Return: -ENOENT if the PPTT doesn't exist, or the CPU cannot be found. |
---|
659 | 691 | * Otherwise returns a value which represents a unique topological feature. |
---|
660 | 692 | */ |
---|
661 | 693 | int find_acpi_cpu_cache_topology(unsigned int cpu, int level) |
---|
.. | .. |
---|
669 | 701 | |
---|
670 | 702 | status = acpi_get_table(ACPI_SIG_PPTT, 0, &table); |
---|
671 | 703 | if (ACPI_FAILURE(status)) { |
---|
672 | | - pr_warn_once("No PPTT table found, topology may be inaccurate\n"); |
---|
| 704 | + acpi_pptt_warn_missing(); |
---|
673 | 705 | return -ENOENT; |
---|
674 | 706 | } |
---|
675 | 707 | |
---|
.. | .. |
---|
685 | 717 | return ret; |
---|
686 | 718 | } |
---|
687 | 719 | |
---|
688 | | - |
---|
689 | 720 | /** |
---|
690 | | - * find_acpi_cpu_topology_package() - Determine a unique cpu package value |
---|
691 | | - * @cpu: Kernel logical cpu number |
---|
| 721 | + * find_acpi_cpu_topology_package() - Determine a unique CPU package value |
---|
| 722 | + * @cpu: Kernel logical CPU number |
---|
692 | 723 | * |
---|
693 | | - * Determine a topology unique package ID for the given cpu. |
---|
| 724 | + * Determine a topology unique package ID for the given CPU. |
---|
694 | 725 | * This ID can then be used to group peers, which will have matching ids. |
---|
695 | 726 | * |
---|
696 | 727 | * The search terminates when either a level is found with the PHYSICAL_PACKAGE |
---|
697 | 728 | * flag set or we reach a root node. |
---|
698 | 729 | * |
---|
699 | | - * Return: -ENOENT if the PPTT doesn't exist, or the cpu cannot be found. |
---|
700 | | - * Otherwise returns a value which represents the package for this cpu. |
---|
| 730 | + * Return: -ENOENT if the PPTT doesn't exist, or the CPU cannot be found. |
---|
| 731 | + * Otherwise returns a value which represents the package for this CPU. |
---|
701 | 732 | */ |
---|
702 | 733 | int find_acpi_cpu_topology_package(unsigned int cpu) |
---|
703 | 734 | { |
---|
704 | 735 | return find_acpi_cpu_topology_tag(cpu, PPTT_ABORT_PACKAGE, |
---|
705 | 736 | ACPI_PPTT_PHYSICAL_PACKAGE); |
---|
706 | 737 | } |
---|
| 738 | + |
---|
| 739 | +/** |
---|
| 740 | + * find_acpi_cpu_topology_hetero_id() - Get a core architecture tag |
---|
| 741 | + * @cpu: Kernel logical CPU number |
---|
| 742 | + * |
---|
| 743 | + * Determine a unique heterogeneous tag for the given CPU. CPUs with the same |
---|
| 744 | + * implementation should have matching tags. |
---|
| 745 | + * |
---|
| 746 | + * The returned tag can be used to group peers with identical implementation. |
---|
| 747 | + * |
---|
| 748 | + * The search terminates when a level is found with the identical implementation |
---|
| 749 | + * flag set or we reach a root node. |
---|
| 750 | + * |
---|
| 751 | + * Due to limitations in the PPTT data structure, there may be rare situations |
---|
| 752 | + * where two cores in a heterogeneous machine may be identical, but won't have |
---|
| 753 | + * the same tag. |
---|
| 754 | + * |
---|
| 755 | + * Return: -ENOENT if the PPTT doesn't exist, or the CPU cannot be found. |
---|
| 756 | + * Otherwise returns a value which represents a group of identical cores |
---|
| 757 | + * similar to this CPU. |
---|
| 758 | + */ |
---|
| 759 | +int find_acpi_cpu_topology_hetero_id(unsigned int cpu) |
---|
| 760 | +{ |
---|
| 761 | + return find_acpi_cpu_topology_tag(cpu, PPTT_ABORT_PACKAGE, |
---|
| 762 | + ACPI_PPTT_ACPI_IDENTICAL); |
---|
| 763 | +} |
---|