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

cpu topology: always define CPU topology information

This can result in an empty topology directory in sysfs, and requires
in-kernel users to protect all uses with #ifdef - see
<http://marc.info/?l=linux-netdev&m=120639033904472&w=2>.

The documentation of CPU topology specifies what the defaults should be if
only partial information is available from the hardware. So we can
provide these defaults as a fallback.

This patch:

- Adds default definitions of the 4 topology macros to <linux/topology.h>
- Changes drivers/base/topology.c to use the topology macros unconditionally
and to cope with definitions that aren't lvalues
- Updates documentation accordingly

[ From: Andrew Morton <akpm@linux-foundation.org>
- fold now-duplicated code
- fix layout
]

Signed-off-by: Ben Hutchings <bhutchings@solarflare.com>
Cc: Vegard Nossum <vegard.nossum@gmail.com>
Cc: Nick Piggin <nickpiggin@yahoo.com.au>
Cc: Chandra Seetharaman <sekharan@us.ibm.com>
Cc: Suresh Siddha <suresh.b.siddha@intel.com>
Cc: Mike Travis <travis@sgi.com>
Cc: Christoph Lameter <clameter@sgi.com>
Cc: John Hawkes <hawkes@sgi.com>
Cc: Zhang, Yanmin <yanmin.zhang@intel.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Ingo Molnar <mingo@elte.hu>

authored by

Ben Hutchings and committed by
Ingo Molnar
c50cbb05 aab2545f

+32 -45
+9 -17
Documentation/cputopology.txt
··· 14 14 To implement it in an architecture-neutral way, a new source file, 15 15 drivers/base/topology.c, is to export the 4 attributes. 16 16 17 - If one architecture wants to support this feature, it just needs to 18 - implement 4 defines, typically in file include/asm-XXX/topology.h. 19 - The 4 defines are: 17 + For an architecture to support this feature, it must define some of 18 + these macros in include/asm-XXX/topology.h: 20 19 #define topology_physical_package_id(cpu) 21 20 #define topology_core_id(cpu) 22 21 #define topology_thread_siblings(cpu) ··· 24 25 The type of **_id is int. 25 26 The type of siblings is cpumask_t. 26 27 27 - To be consistent on all architectures, the 4 attributes should have 28 - default values if their values are unavailable. Below is the rule. 29 - 1) physical_package_id: If cpu has no physical package id, -1 is the 30 - default value. 31 - 2) core_id: If cpu doesn't support multi-core, its core id is 0. 32 - 3) thread_siblings: Just include itself, if the cpu doesn't support 33 - HT/multi-thread. 34 - 4) core_siblings: Just include itself, if the cpu doesn't support 35 - multi-core and HT/Multi-thread. 36 - 37 - So be careful when declaring the 4 defines in include/asm-XXX/topology.h. 38 - 39 - If an attribute isn't defined on an architecture, it won't be exported. 40 - 28 + To be consistent on all architectures, include/linux/topology.h 29 + provides default definitions for any of the above macros that are 30 + not defined by include/asm-XXX/topology.h: 31 + 1) physical_package_id: -1 32 + 2) core_id: 0 33 + 3) thread_siblings: just the given CPU 34 + 4) core_siblings: just the given CPU
+10 -28
drivers/base/topology.c
··· 59 59 static inline ssize_t show_##name(struct sys_device *dev, char *buf) \ 60 60 { \ 61 61 unsigned int cpu = dev->id; \ 62 - return show_cpumap(0, &(topology_##name(cpu)), buf); \ 62 + cpumask_t siblings = topology_##name(cpu); \ 63 + return show_cpumap(0, &siblings, buf); \ 63 64 } 64 65 65 66 #define define_siblings_show_list(name) \ 66 67 static inline ssize_t show_##name##_list(struct sys_device *dev, char *buf) \ 67 68 { \ 68 69 unsigned int cpu = dev->id; \ 69 - return show_cpumap(1, &(topology_##name(cpu)), buf); \ 70 + cpumask_t siblings = topology_##name(cpu); \ 71 + return show_cpumap(1, &siblings, buf); \ 70 72 } 71 73 72 74 #define define_siblings_show_func(name) \ 73 75 define_siblings_show_map(name); define_siblings_show_list(name) 74 76 75 - #ifdef topology_physical_package_id 76 77 define_id_show_func(physical_package_id); 77 78 define_one_ro(physical_package_id); 78 - #define ref_physical_package_id_attr &attr_physical_package_id.attr, 79 - #else 80 - #define ref_physical_package_id_attr 81 - #endif 82 79 83 - #ifdef topology_core_id 84 80 define_id_show_func(core_id); 85 81 define_one_ro(core_id); 86 - #define ref_core_id_attr &attr_core_id.attr, 87 - #else 88 - #define ref_core_id_attr 89 - #endif 90 82 91 - #ifdef topology_thread_siblings 92 83 define_siblings_show_func(thread_siblings); 93 84 define_one_ro(thread_siblings); 94 85 define_one_ro(thread_siblings_list); 95 - #define ref_thread_siblings_attr \ 96 - &attr_thread_siblings.attr, &attr_thread_siblings_list.attr, 97 - #else 98 - #define ref_thread_siblings_attr 99 - #endif 100 86 101 - #ifdef topology_core_siblings 102 87 define_siblings_show_func(core_siblings); 103 88 define_one_ro(core_siblings); 104 89 define_one_ro(core_siblings_list); 105 - #define ref_core_siblings_attr \ 106 - &attr_core_siblings.attr, &attr_core_siblings_list.attr, 107 - #else 108 - #define ref_core_siblings_attr 109 - #endif 110 90 111 91 static struct attribute *default_attrs[] = { 112 - ref_physical_package_id_attr 113 - ref_core_id_attr 114 - ref_thread_siblings_attr 115 - ref_core_siblings_attr 92 + &attr_physical_package_id.attr, 93 + &attr_core_id.attr, 94 + &attr_thread_siblings.attr, 95 + &attr_thread_siblings_list.attr, 96 + &attr_core_siblings.attr, 97 + &attr_core_siblings_list.attr, 116 98 NULL 117 99 }; 118 100
+13
include/linux/topology.h
··· 179 179 #endif 180 180 #endif /* CONFIG_NUMA */ 181 181 182 + #ifndef topology_physical_package_id 183 + #define topology_physical_package_id(cpu) ((void)(cpu), -1) 184 + #endif 185 + #ifndef topology_core_id 186 + #define topology_core_id(cpu) ((void)(cpu), 0) 187 + #endif 188 + #ifndef topology_thread_siblings 189 + #define topology_thread_siblings(cpu) cpumask_of_cpu(cpu) 190 + #endif 191 + #ifndef topology_core_siblings 192 + #define topology_core_siblings(cpu) cpumask_of_cpu(cpu) 193 + #endif 194 + 182 195 #endif /* _LINUX_TOPOLOGY_H */