diff options
Diffstat (limited to 'drivers/base')
-rw-r--r-- | drivers/base/cpu.c | 48 | ||||
-rw-r--r-- | drivers/base/node.c | 29 | ||||
-rw-r--r-- | drivers/base/topology.c | 41 |
3 files changed, 104 insertions, 14 deletions
diff --git a/drivers/base/cpu.c b/drivers/base/cpu.c index 499b003f9278..2c76afff3b15 100644 --- a/drivers/base/cpu.c +++ b/drivers/base/cpu.c | |||
@@ -103,6 +103,51 @@ static SYSDEV_ATTR(crash_notes, 0400, show_crash_notes, NULL); | |||
103 | #endif | 103 | #endif |
104 | 104 | ||
105 | /* | 105 | /* |
106 | * Print cpu online, possible, present, and system maps | ||
107 | */ | ||
108 | static ssize_t print_cpus_map(char *buf, cpumask_t *map) | ||
109 | { | ||
110 | int n = cpulist_scnprintf(buf, PAGE_SIZE-2, *map); | ||
111 | |||
112 | buf[n++] = '\n'; | ||
113 | buf[n] = '\0'; | ||
114 | return n; | ||
115 | } | ||
116 | |||
117 | #define print_cpus_func(type) \ | ||
118 | static ssize_t print_cpus_##type(struct sysdev_class *class, char *buf) \ | ||
119 | { \ | ||
120 | return print_cpus_map(buf, &cpu_##type##_map); \ | ||
121 | } \ | ||
122 | struct sysdev_class_attribute attr_##type##_map = \ | ||
123 | _SYSDEV_CLASS_ATTR(type, 0444, print_cpus_##type, NULL) | ||
124 | |||
125 | print_cpus_func(online); | ||
126 | print_cpus_func(possible); | ||
127 | print_cpus_func(present); | ||
128 | |||
129 | struct sysdev_class_attribute *cpu_state_attr[] = { | ||
130 | &attr_online_map, | ||
131 | &attr_possible_map, | ||
132 | &attr_present_map, | ||
133 | }; | ||
134 | |||
135 | static int cpu_states_init(void) | ||
136 | { | ||
137 | int i; | ||
138 | int err = 0; | ||
139 | |||
140 | for (i = 0; i < ARRAY_SIZE(cpu_state_attr); i++) { | ||
141 | int ret; | ||
142 | ret = sysdev_class_create_file(&cpu_sysdev_class, | ||
143 | cpu_state_attr[i]); | ||
144 | if (!err) | ||
145 | err = ret; | ||
146 | } | ||
147 | return err; | ||
148 | } | ||
149 | |||
150 | /* | ||
106 | * register_cpu - Setup a sysfs device for a CPU. | 151 | * register_cpu - Setup a sysfs device for a CPU. |
107 | * @cpu - cpu->hotpluggable field set to 1 will generate a control file in | 152 | * @cpu - cpu->hotpluggable field set to 1 will generate a control file in |
108 | * sysfs for this CPU. | 153 | * sysfs for this CPU. |
@@ -147,6 +192,9 @@ int __init cpu_dev_init(void) | |||
147 | int err; | 192 | int err; |
148 | 193 | ||
149 | err = sysdev_class_register(&cpu_sysdev_class); | 194 | err = sysdev_class_register(&cpu_sysdev_class); |
195 | if (!err) | ||
196 | err = cpu_states_init(); | ||
197 | |||
150 | #if defined(CONFIG_SCHED_MC) || defined(CONFIG_SCHED_SMT) | 198 | #if defined(CONFIG_SCHED_MC) || defined(CONFIG_SCHED_SMT) |
151 | if (!err) | 199 | if (!err) |
152 | err = sched_create_sysfs_power_savings_entries(&cpu_sysdev_class); | 200 | err = sched_create_sysfs_power_savings_entries(&cpu_sysdev_class); |
diff --git a/drivers/base/node.c b/drivers/base/node.c index e59861f18ce5..12fde2d03d69 100644 --- a/drivers/base/node.c +++ b/drivers/base/node.c | |||
@@ -19,21 +19,34 @@ static struct sysdev_class node_class = { | |||
19 | }; | 19 | }; |
20 | 20 | ||
21 | 21 | ||
22 | static ssize_t node_read_cpumap(struct sys_device * dev, char * buf) | 22 | static ssize_t node_read_cpumap(struct sys_device *dev, int type, char *buf) |
23 | { | 23 | { |
24 | struct node *node_dev = to_node(dev); | 24 | struct node *node_dev = to_node(dev); |
25 | cpumask_t mask = node_to_cpumask(node_dev->sysdev.id); | 25 | node_to_cpumask_ptr(mask, node_dev->sysdev.id); |
26 | int len; | 26 | int len; |
27 | 27 | ||
28 | /* 2004/06/03: buf currently PAGE_SIZE, need > 1 char per 4 bits. */ | 28 | /* 2008/04/07: buf currently PAGE_SIZE, need 9 chars per 32 bits. */ |
29 | BUILD_BUG_ON(MAX_NUMNODES/4 > PAGE_SIZE/2); | 29 | BUILD_BUG_ON((NR_CPUS/32 * 9) > (PAGE_SIZE-1)); |
30 | 30 | ||
31 | len = cpumask_scnprintf(buf, PAGE_SIZE-1, mask); | 31 | len = type? |
32 | len += sprintf(buf + len, "\n"); | 32 | cpulist_scnprintf(buf, PAGE_SIZE-2, *mask): |
33 | cpumask_scnprintf(buf, PAGE_SIZE-2, *mask); | ||
34 | buf[len++] = '\n'; | ||
35 | buf[len] = '\0'; | ||
33 | return len; | 36 | return len; |
34 | } | 37 | } |
35 | 38 | ||
36 | static SYSDEV_ATTR(cpumap, S_IRUGO, node_read_cpumap, NULL); | 39 | static inline ssize_t node_read_cpumask(struct sys_device *dev, char *buf) |
40 | { | ||
41 | return node_read_cpumap(dev, 0, buf); | ||
42 | } | ||
43 | static inline ssize_t node_read_cpulist(struct sys_device *dev, char *buf) | ||
44 | { | ||
45 | return node_read_cpumap(dev, 1, buf); | ||
46 | } | ||
47 | |||
48 | static SYSDEV_ATTR(cpumap, S_IRUGO, node_read_cpumask, NULL); | ||
49 | static SYSDEV_ATTR(cpulist, S_IRUGO, node_read_cpulist, NULL); | ||
37 | 50 | ||
38 | #define K(x) ((x) << (PAGE_SHIFT - 10)) | 51 | #define K(x) ((x) << (PAGE_SHIFT - 10)) |
39 | static ssize_t node_read_meminfo(struct sys_device * dev, char * buf) | 52 | static ssize_t node_read_meminfo(struct sys_device * dev, char * buf) |
@@ -149,6 +162,7 @@ int register_node(struct node *node, int num, struct node *parent) | |||
149 | 162 | ||
150 | if (!error){ | 163 | if (!error){ |
151 | sysdev_create_file(&node->sysdev, &attr_cpumap); | 164 | sysdev_create_file(&node->sysdev, &attr_cpumap); |
165 | sysdev_create_file(&node->sysdev, &attr_cpulist); | ||
152 | sysdev_create_file(&node->sysdev, &attr_meminfo); | 166 | sysdev_create_file(&node->sysdev, &attr_meminfo); |
153 | sysdev_create_file(&node->sysdev, &attr_numastat); | 167 | sysdev_create_file(&node->sysdev, &attr_numastat); |
154 | sysdev_create_file(&node->sysdev, &attr_distance); | 168 | sysdev_create_file(&node->sysdev, &attr_distance); |
@@ -166,6 +180,7 @@ int register_node(struct node *node, int num, struct node *parent) | |||
166 | void unregister_node(struct node *node) | 180 | void unregister_node(struct node *node) |
167 | { | 181 | { |
168 | sysdev_remove_file(&node->sysdev, &attr_cpumap); | 182 | sysdev_remove_file(&node->sysdev, &attr_cpumap); |
183 | sysdev_remove_file(&node->sysdev, &attr_cpulist); | ||
169 | sysdev_remove_file(&node->sysdev, &attr_meminfo); | 184 | sysdev_remove_file(&node->sysdev, &attr_meminfo); |
170 | sysdev_remove_file(&node->sysdev, &attr_numastat); | 185 | sysdev_remove_file(&node->sysdev, &attr_numastat); |
171 | sysdev_remove_file(&node->sysdev, &attr_distance); | 186 | sysdev_remove_file(&node->sysdev, &attr_distance); |
diff --git a/drivers/base/topology.c b/drivers/base/topology.c index e1d3ad4db2f0..fdf4044d2e74 100644 --- a/drivers/base/topology.c +++ b/drivers/base/topology.c | |||
@@ -40,15 +40,38 @@ static ssize_t show_##name(struct sys_device *dev, char *buf) \ | |||
40 | return sprintf(buf, "%d\n", topology_##name(cpu)); \ | 40 | return sprintf(buf, "%d\n", topology_##name(cpu)); \ |
41 | } | 41 | } |
42 | 42 | ||
43 | #define define_siblings_show_func(name) \ | 43 | static ssize_t show_cpumap(int type, cpumask_t *mask, char *buf) |
44 | static ssize_t show_##name(struct sys_device *dev, char *buf) \ | 44 | { |
45 | ptrdiff_t len = PTR_ALIGN(buf + PAGE_SIZE - 1, PAGE_SIZE) - buf; | ||
46 | int n = 0; | ||
47 | |||
48 | if (len > 1) { | ||
49 | n = type? | ||
50 | cpulist_scnprintf(buf, len-2, *mask): | ||
51 | cpumask_scnprintf(buf, len-2, *mask); | ||
52 | buf[n++] = '\n'; | ||
53 | buf[n] = '\0'; | ||
54 | } | ||
55 | return n; | ||
56 | } | ||
57 | |||
58 | #define define_siblings_show_map(name) \ | ||
59 | static inline ssize_t show_##name(struct sys_device *dev, char *buf) \ | ||
45 | { \ | 60 | { \ |
46 | ssize_t len = -1; \ | ||
47 | unsigned int cpu = dev->id; \ | 61 | unsigned int cpu = dev->id; \ |
48 | len = cpumask_scnprintf(buf, NR_CPUS+1, topology_##name(cpu)); \ | 62 | return show_cpumap(0, &(topology_##name(cpu)), buf); \ |
49 | return (len + sprintf(buf + len, "\n")); \ | ||
50 | } | 63 | } |
51 | 64 | ||
65 | #define define_siblings_show_list(name) \ | ||
66 | static inline ssize_t show_##name##_list(struct sys_device *dev, char *buf) \ | ||
67 | { \ | ||
68 | unsigned int cpu = dev->id; \ | ||
69 | return show_cpumap(1, &(topology_##name(cpu)), buf); \ | ||
70 | } | ||
71 | |||
72 | #define define_siblings_show_func(name) \ | ||
73 | define_siblings_show_map(name); define_siblings_show_list(name) | ||
74 | |||
52 | #ifdef topology_physical_package_id | 75 | #ifdef topology_physical_package_id |
53 | define_id_show_func(physical_package_id); | 76 | define_id_show_func(physical_package_id); |
54 | define_one_ro(physical_package_id); | 77 | define_one_ro(physical_package_id); |
@@ -68,7 +91,9 @@ define_one_ro(core_id); | |||
68 | #ifdef topology_thread_siblings | 91 | #ifdef topology_thread_siblings |
69 | define_siblings_show_func(thread_siblings); | 92 | define_siblings_show_func(thread_siblings); |
70 | define_one_ro(thread_siblings); | 93 | define_one_ro(thread_siblings); |
71 | #define ref_thread_siblings_attr &attr_thread_siblings.attr, | 94 | define_one_ro(thread_siblings_list); |
95 | #define ref_thread_siblings_attr \ | ||
96 | &attr_thread_siblings.attr, &attr_thread_siblings_list.attr, | ||
72 | #else | 97 | #else |
73 | #define ref_thread_siblings_attr | 98 | #define ref_thread_siblings_attr |
74 | #endif | 99 | #endif |
@@ -76,7 +101,9 @@ define_one_ro(thread_siblings); | |||
76 | #ifdef topology_core_siblings | 101 | #ifdef topology_core_siblings |
77 | define_siblings_show_func(core_siblings); | 102 | define_siblings_show_func(core_siblings); |
78 | define_one_ro(core_siblings); | 103 | define_one_ro(core_siblings); |
79 | #define ref_core_siblings_attr &attr_core_siblings.attr, | 104 | define_one_ro(core_siblings_list); |
105 | #define ref_core_siblings_attr \ | ||
106 | &attr_core_siblings.attr, &attr_core_siblings_list.attr, | ||
80 | #else | 107 | #else |
81 | #define ref_core_siblings_attr | 108 | #define ref_core_siblings_attr |
82 | #endif | 109 | #endif |