aboutsummaryrefslogtreecommitdiffstats
path: root/arch/sparc
diff options
context:
space:
mode:
authorchris hyser <chris.hyser@oracle.com>2015-04-22 12:28:31 -0400
committerDavid S. Miller <davem@davemloft.net>2015-04-22 15:42:56 -0400
commitacc455cffa75070d55e74fc7802b49edbc080e92 (patch)
tree5db4c6179acf7f899baceff40fe528200355ff1c /arch/sparc
parenta62d016cece2fce1d5e4eedf36b17f03a7a5c78e (diff)
sparc64: Setup sysfs to mark LDOM sockets, cores and threads correctly
commit 5f4826a362405748bbf73957027b77993e61e1af Author: chris hyser <chris.hyser@oracle.com> Date: Tue Apr 21 10:31:38 2015 -0400 sparc64: Setup sysfs to mark LDOM sockets, cores and threads correctly The current sparc kernel has no representation for sockets though tools like lscpu can pull this from sysfs. This patch walks the machine description cache and socket hierarchy and marks sockets as well as cores and threads such that a representative sysfs is created by drivers/base/topology.c. Before this patch: $ lscpu Architecture: sparc64 CPU op-mode(s): 32-bit, 64-bit Byte Order: Big Endian CPU(s): 1024 On-line CPU(s) list: 0-1023 Thread(s) per core: 8 Core(s) per socket: 1 <--- wrong Socket(s): 128 <--- wrong NUMA node(s): 4 NUMA node0 CPU(s): 0-255 NUMA node1 CPU(s): 256-511 NUMA node2 CPU(s): 512-767 NUMA node3 CPU(s): 768-1023 After this patch: $ lscpu Architecture: sparc64 CPU op-mode(s): 32-bit, 64-bit Byte Order: Big Endian CPU(s): 1024 On-line CPU(s) list: 0-1023 Thread(s) per core: 8 Core(s) per socket: 32 Socket(s): 4 NUMA node(s): 4 NUMA node0 CPU(s): 0-255 NUMA node1 CPU(s): 256-511 NUMA node2 CPU(s): 512-767 NUMA node3 CPU(s): 768-1023 Most of this patch was done by Chris with updates by David. Signed-off-by: Chris Hyser <chris.hyser@oracle.com> Signed-off-by: David Ahern <david.ahern@oracle.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'arch/sparc')
-rw-r--r--arch/sparc/include/asm/cpudata_64.h3
-rw-r--r--arch/sparc/include/asm/topology_64.h3
-rw-r--r--arch/sparc/kernel/mdesc.c136
-rw-r--r--arch/sparc/kernel/smp_64.c13
4 files changed, 127 insertions, 28 deletions
diff --git a/arch/sparc/include/asm/cpudata_64.h b/arch/sparc/include/asm/cpudata_64.h
index a6e424d185d0..a6cfdabb6054 100644
--- a/arch/sparc/include/asm/cpudata_64.h
+++ b/arch/sparc/include/asm/cpudata_64.h
@@ -24,7 +24,8 @@ typedef struct {
24 unsigned int icache_line_size; 24 unsigned int icache_line_size;
25 unsigned int ecache_size; 25 unsigned int ecache_size;
26 unsigned int ecache_line_size; 26 unsigned int ecache_line_size;
27 int core_id; 27 unsigned short sock_id;
28 unsigned short core_id;
28 int proc_id; 29 int proc_id;
29} cpuinfo_sparc; 30} cpuinfo_sparc;
30 31
diff --git a/arch/sparc/include/asm/topology_64.h b/arch/sparc/include/asm/topology_64.h
index ed8f071132e4..d1761df5cca6 100644
--- a/arch/sparc/include/asm/topology_64.h
+++ b/arch/sparc/include/asm/topology_64.h
@@ -40,11 +40,12 @@ static inline int pcibus_to_node(struct pci_bus *pbus)
40#ifdef CONFIG_SMP 40#ifdef CONFIG_SMP
41#define topology_physical_package_id(cpu) (cpu_data(cpu).proc_id) 41#define topology_physical_package_id(cpu) (cpu_data(cpu).proc_id)
42#define topology_core_id(cpu) (cpu_data(cpu).core_id) 42#define topology_core_id(cpu) (cpu_data(cpu).core_id)
43#define topology_core_cpumask(cpu) (&cpu_core_map[cpu]) 43#define topology_core_cpumask(cpu) (&cpu_core_sib_map[cpu])
44#define topology_thread_cpumask(cpu) (&per_cpu(cpu_sibling_map, cpu)) 44#define topology_thread_cpumask(cpu) (&per_cpu(cpu_sibling_map, cpu))
45#endif /* CONFIG_SMP */ 45#endif /* CONFIG_SMP */
46 46
47extern cpumask_t cpu_core_map[NR_CPUS]; 47extern cpumask_t cpu_core_map[NR_CPUS];
48extern cpumask_t cpu_core_sib_map[NR_CPUS];
48static inline const struct cpumask *cpu_coregroup_mask(int cpu) 49static inline const struct cpumask *cpu_coregroup_mask(int cpu)
49{ 50{
50 return &cpu_core_map[cpu]; 51 return &cpu_core_map[cpu];
diff --git a/arch/sparc/kernel/mdesc.c b/arch/sparc/kernel/mdesc.c
index 26c80e18d7b1..6f80936e0eea 100644
--- a/arch/sparc/kernel/mdesc.c
+++ b/arch/sparc/kernel/mdesc.c
@@ -614,45 +614,68 @@ static void fill_in_one_cache(cpuinfo_sparc *c, struct mdesc_handle *hp, u64 mp)
614 } 614 }
615} 615}
616 616
617static void mark_core_ids(struct mdesc_handle *hp, u64 mp, int core_id) 617static void find_back_node_value(struct mdesc_handle *hp, u64 node,
618 char *srch_val,
619 void (*func)(struct mdesc_handle *, u64, int),
620 u64 val, int depth)
618{ 621{
619 u64 a; 622 u64 arc;
620
621 mdesc_for_each_arc(a, hp, mp, MDESC_ARC_TYPE_BACK) {
622 u64 t = mdesc_arc_target(hp, a);
623 const char *name;
624 const u64 *id;
625 623
626 name = mdesc_node_name(hp, t); 624 /* Since we have an estimate of recursion depth, do a sanity check. */
627 if (!strcmp(name, "cpu")) { 625 if (depth == 0)
628 id = mdesc_get_property(hp, t, "id", NULL); 626 return;
629 if (*id < NR_CPUS)
630 cpu_data(*id).core_id = core_id;
631 } else {
632 u64 j;
633 627
634 mdesc_for_each_arc(j, hp, t, MDESC_ARC_TYPE_BACK) { 628 mdesc_for_each_arc(arc, hp, node, MDESC_ARC_TYPE_BACK) {
635 u64 n = mdesc_arc_target(hp, j); 629 u64 n = mdesc_arc_target(hp, arc);
636 const char *n_name; 630 const char *name = mdesc_node_name(hp, n);
637 631
638 n_name = mdesc_node_name(hp, n); 632 if (!strcmp(srch_val, name))
639 if (strcmp(n_name, "cpu")) 633 (*func)(hp, n, val);
640 continue;
641 634
642 id = mdesc_get_property(hp, n, "id", NULL); 635 find_back_node_value(hp, n, srch_val, func, val, depth-1);
643 if (*id < NR_CPUS)
644 cpu_data(*id).core_id = core_id;
645 }
646 }
647 } 636 }
648} 637}
649 638
639static void __mark_core_id(struct mdesc_handle *hp, u64 node,
640 int core_id)
641{
642 const u64 *id = mdesc_get_property(hp, node, "id", NULL);
643
644 if (*id < num_possible_cpus())
645 cpu_data(*id).core_id = core_id;
646}
647
648static void __mark_sock_id(struct mdesc_handle *hp, u64 node,
649 int sock_id)
650{
651 const u64 *id = mdesc_get_property(hp, node, "id", NULL);
652
653 if (*id < num_possible_cpus())
654 cpu_data(*id).sock_id = sock_id;
655}
656
657static void mark_core_ids(struct mdesc_handle *hp, u64 mp,
658 int core_id)
659{
660 find_back_node_value(hp, mp, "cpu", __mark_core_id, core_id, 10);
661}
662
663static void mark_sock_ids(struct mdesc_handle *hp, u64 mp,
664 int sock_id)
665{
666 find_back_node_value(hp, mp, "cpu", __mark_sock_id, sock_id, 10);
667}
668
650static void set_core_ids(struct mdesc_handle *hp) 669static void set_core_ids(struct mdesc_handle *hp)
651{ 670{
652 int idx; 671 int idx;
653 u64 mp; 672 u64 mp;
654 673
655 idx = 1; 674 idx = 1;
675
676 /* Identify unique cores by looking for cpus backpointed to by
677 * level 1 instruction caches.
678 */
656 mdesc_for_each_node_by_name(hp, mp, "cache") { 679 mdesc_for_each_node_by_name(hp, mp, "cache") {
657 const u64 *level; 680 const u64 *level;
658 const char *type; 681 const char *type;
@@ -667,11 +690,72 @@ static void set_core_ids(struct mdesc_handle *hp)
667 continue; 690 continue;
668 691
669 mark_core_ids(hp, mp, idx); 692 mark_core_ids(hp, mp, idx);
693 idx++;
694 }
695}
696
697static int set_sock_ids_by_cache(struct mdesc_handle *hp, int level)
698{
699 u64 mp;
700 int idx = 1;
701 int fnd = 0;
702
703 /* Identify unique sockets by looking for cpus backpointed to by
704 * shared level n caches.
705 */
706 mdesc_for_each_node_by_name(hp, mp, "cache") {
707 const u64 *cur_lvl;
708
709 cur_lvl = mdesc_get_property(hp, mp, "level", NULL);
710 if (*cur_lvl != level)
711 continue;
712
713 mark_sock_ids(hp, mp, idx);
714 idx++;
715 fnd = 1;
716 }
717 return fnd;
718}
719
720static void set_sock_ids_by_socket(struct mdesc_handle *hp, u64 mp)
721{
722 int idx = 1;
670 723
724 mdesc_for_each_node_by_name(hp, mp, "socket") {
725 u64 a;
726
727 mdesc_for_each_arc(a, hp, mp, MDESC_ARC_TYPE_FWD) {
728 u64 t = mdesc_arc_target(hp, a);
729 const char *name;
730 const u64 *id;
731
732 name = mdesc_node_name(hp, t);
733 if (strcmp(name, "cpu"))
734 continue;
735
736 id = mdesc_get_property(hp, t, "id", NULL);
737 if (*id < num_possible_cpus())
738 cpu_data(*id).sock_id = idx;
739 }
671 idx++; 740 idx++;
672 } 741 }
673} 742}
674 743
744static void set_sock_ids(struct mdesc_handle *hp)
745{
746 u64 mp;
747
748 /* If machine description exposes sockets data use it.
749 * Otherwise fallback to use shared L3 or L2 caches.
750 */
751 mp = mdesc_node_by_name(hp, MDESC_NODE_NULL, "sockets");
752 if (mp != MDESC_NODE_NULL)
753 return set_sock_ids_by_socket(hp, mp);
754
755 if (!set_sock_ids_by_cache(hp, 3))
756 set_sock_ids_by_cache(hp, 2);
757}
758
675static void mark_proc_ids(struct mdesc_handle *hp, u64 mp, int proc_id) 759static void mark_proc_ids(struct mdesc_handle *hp, u64 mp, int proc_id)
676{ 760{
677 u64 a; 761 u64 a;
@@ -707,7 +791,6 @@ static void __set_proc_ids(struct mdesc_handle *hp, const char *exec_unit_name)
707 continue; 791 continue;
708 792
709 mark_proc_ids(hp, mp, idx); 793 mark_proc_ids(hp, mp, idx);
710
711 idx++; 794 idx++;
712 } 795 }
713} 796}
@@ -900,6 +983,7 @@ void mdesc_fill_in_cpu_data(cpumask_t *mask)
900 983
901 set_core_ids(hp); 984 set_core_ids(hp);
902 set_proc_ids(hp); 985 set_proc_ids(hp);
986 set_sock_ids(hp);
903 987
904 mdesc_release(hp); 988 mdesc_release(hp);
905 989
diff --git a/arch/sparc/kernel/smp_64.c b/arch/sparc/kernel/smp_64.c
index 61139d9924ca..19cd08d18672 100644
--- a/arch/sparc/kernel/smp_64.c
+++ b/arch/sparc/kernel/smp_64.c
@@ -60,8 +60,12 @@ DEFINE_PER_CPU(cpumask_t, cpu_sibling_map) = CPU_MASK_NONE;
60cpumask_t cpu_core_map[NR_CPUS] __read_mostly = 60cpumask_t cpu_core_map[NR_CPUS] __read_mostly =
61 { [0 ... NR_CPUS-1] = CPU_MASK_NONE }; 61 { [0 ... NR_CPUS-1] = CPU_MASK_NONE };
62 62
63cpumask_t cpu_core_sib_map[NR_CPUS] __read_mostly = {
64 [0 ... NR_CPUS-1] = CPU_MASK_NONE };
65
63EXPORT_PER_CPU_SYMBOL(cpu_sibling_map); 66EXPORT_PER_CPU_SYMBOL(cpu_sibling_map);
64EXPORT_SYMBOL(cpu_core_map); 67EXPORT_SYMBOL(cpu_core_map);
68EXPORT_SYMBOL(cpu_core_sib_map);
65 69
66static cpumask_t smp_commenced_mask; 70static cpumask_t smp_commenced_mask;
67 71
@@ -1243,6 +1247,15 @@ void smp_fill_in_sib_core_maps(void)
1243 } 1247 }
1244 } 1248 }
1245 1249
1250 for_each_present_cpu(i) {
1251 unsigned int j;
1252
1253 for_each_present_cpu(j) {
1254 if (cpu_data(i).sock_id == cpu_data(j).sock_id)
1255 cpumask_set_cpu(j, &cpu_core_sib_map[i]);
1256 }
1257 }
1258
1246 for_each_present_cpu(i) { 1259 for_each_present_cpu(i) {
1247 unsigned int j; 1260 unsigned int j;
1248 1261