diff options
author | Paul Mackerras <paulus@samba.org> | 2013-08-12 02:29:33 -0400 |
---|---|---|
committer | Benjamin Herrenschmidt <benh@kernel.crashing.org> | 2013-08-14 01:00:22 -0400 |
commit | 256f2d4b463d3030ebc8d2b54f427543814a2bdc (patch) | |
tree | bbf8fb26d8cd8aa154b879eadd503bd5b5a1ffaf /arch | |
parent | a8a5356cd511db229aeaad636dc0f83d8c4d0a15 (diff) |
powerpc: Use ibm, chip-id property to compute cpu_core_mask if available
Some systems have an ibm,chip-id property in the cpu nodes in the
device tree. On these systems, we now use that to compute the
cpu_core_mask (i.e. the set of core siblings) rather than looking
at cache properties.
Signed-off-by: Paul Mackerras <paulus@samba.org>
Tested-by: Vasant Hegde <hegdevasant@linux.vnet.ibm.com>
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Diffstat (limited to 'arch')
-rw-r--r-- | arch/powerpc/kernel/smp.c | 48 |
1 files changed, 45 insertions, 3 deletions
diff --git a/arch/powerpc/kernel/smp.c b/arch/powerpc/kernel/smp.c index 0cc69d5deac9..009900dd8f25 100644 --- a/arch/powerpc/kernel/smp.c +++ b/arch/powerpc/kernel/smp.c | |||
@@ -609,6 +609,33 @@ int cpu_first_thread_of_core(int core) | |||
609 | } | 609 | } |
610 | EXPORT_SYMBOL_GPL(cpu_first_thread_of_core); | 610 | EXPORT_SYMBOL_GPL(cpu_first_thread_of_core); |
611 | 611 | ||
612 | static void traverse_siblings_chip_id(int cpu, bool add, int chipid) | ||
613 | { | ||
614 | const struct cpumask *mask; | ||
615 | struct device_node *np; | ||
616 | int i, plen; | ||
617 | const __be32 *prop; | ||
618 | |||
619 | mask = add ? cpu_online_mask : cpu_present_mask; | ||
620 | for_each_cpu(i, mask) { | ||
621 | np = of_get_cpu_node(i, NULL); | ||
622 | if (!np) | ||
623 | continue; | ||
624 | prop = of_get_property(np, "ibm,chip-id", &plen); | ||
625 | if (prop && plen == sizeof(int) && | ||
626 | of_read_number(prop, 1) == chipid) { | ||
627 | if (add) { | ||
628 | cpumask_set_cpu(cpu, cpu_core_mask(i)); | ||
629 | cpumask_set_cpu(i, cpu_core_mask(cpu)); | ||
630 | } else { | ||
631 | cpumask_clear_cpu(cpu, cpu_core_mask(i)); | ||
632 | cpumask_clear_cpu(i, cpu_core_mask(cpu)); | ||
633 | } | ||
634 | } | ||
635 | of_node_put(np); | ||
636 | } | ||
637 | } | ||
638 | |||
612 | /* Must be called when no change can occur to cpu_present_mask, | 639 | /* Must be called when no change can occur to cpu_present_mask, |
613 | * i.e. during cpu online or offline. | 640 | * i.e. during cpu online or offline. |
614 | */ | 641 | */ |
@@ -633,14 +660,29 @@ static struct device_node *cpu_to_l2cache(int cpu) | |||
633 | 660 | ||
634 | static void traverse_core_siblings(int cpu, bool add) | 661 | static void traverse_core_siblings(int cpu, bool add) |
635 | { | 662 | { |
636 | struct device_node *l2_cache; | 663 | struct device_node *l2_cache, *np; |
637 | const struct cpumask *mask; | 664 | const struct cpumask *mask; |
638 | int i; | 665 | int i, chip, plen; |
666 | const __be32 *prop; | ||
667 | |||
668 | /* First see if we have ibm,chip-id properties in cpu nodes */ | ||
669 | np = of_get_cpu_node(cpu, NULL); | ||
670 | if (np) { | ||
671 | chip = -1; | ||
672 | prop = of_get_property(np, "ibm,chip-id", &plen); | ||
673 | if (prop && plen == sizeof(int)) | ||
674 | chip = of_read_number(prop, 1); | ||
675 | of_node_put(np); | ||
676 | if (chip >= 0) { | ||
677 | traverse_siblings_chip_id(cpu, add, chip); | ||
678 | return; | ||
679 | } | ||
680 | } | ||
639 | 681 | ||
640 | l2_cache = cpu_to_l2cache(cpu); | 682 | l2_cache = cpu_to_l2cache(cpu); |
641 | mask = add ? cpu_online_mask : cpu_present_mask; | 683 | mask = add ? cpu_online_mask : cpu_present_mask; |
642 | for_each_cpu(i, mask) { | 684 | for_each_cpu(i, mask) { |
643 | struct device_node *np = cpu_to_l2cache(i); | 685 | np = cpu_to_l2cache(i); |
644 | if (!np) | 686 | if (!np) |
645 | continue; | 687 | continue; |
646 | if (np == l2_cache) { | 688 | if (np == l2_cache) { |