diff options
Diffstat (limited to 'arch/x86/kernel/cpu/intel_cacheinfo.c')
-rw-r--r-- | arch/x86/kernel/cpu/intel_cacheinfo.c | 63 |
1 files changed, 44 insertions, 19 deletions
diff --git a/arch/x86/kernel/cpu/intel_cacheinfo.c b/arch/x86/kernel/cpu/intel_cacheinfo.c index 48533d77be78..58527a9fc404 100644 --- a/arch/x86/kernel/cpu/intel_cacheinfo.c +++ b/arch/x86/kernel/cpu/intel_cacheinfo.c | |||
@@ -132,7 +132,16 @@ struct _cpuid4_info { | |||
132 | union _cpuid4_leaf_ecx ecx; | 132 | union _cpuid4_leaf_ecx ecx; |
133 | unsigned long size; | 133 | unsigned long size; |
134 | unsigned long can_disable; | 134 | unsigned long can_disable; |
135 | cpumask_t shared_cpu_map; /* future?: only cpus/node is needed */ | 135 | DECLARE_BITMAP(shared_cpu_map, NR_CPUS); |
136 | }; | ||
137 | |||
138 | /* subset of above _cpuid4_info w/o shared_cpu_map */ | ||
139 | struct _cpuid4_info_regs { | ||
140 | union _cpuid4_leaf_eax eax; | ||
141 | union _cpuid4_leaf_ebx ebx; | ||
142 | union _cpuid4_leaf_ecx ecx; | ||
143 | unsigned long size; | ||
144 | unsigned long can_disable; | ||
136 | }; | 145 | }; |
137 | 146 | ||
138 | #ifdef CONFIG_PCI | 147 | #ifdef CONFIG_PCI |
@@ -263,7 +272,7 @@ amd_cpuid4(int leaf, union _cpuid4_leaf_eax *eax, | |||
263 | } | 272 | } |
264 | 273 | ||
265 | static void __cpuinit | 274 | static void __cpuinit |
266 | amd_check_l3_disable(int index, struct _cpuid4_info *this_leaf) | 275 | amd_check_l3_disable(int index, struct _cpuid4_info_regs *this_leaf) |
267 | { | 276 | { |
268 | if (index < 3) | 277 | if (index < 3) |
269 | return; | 278 | return; |
@@ -271,7 +280,8 @@ amd_check_l3_disable(int index, struct _cpuid4_info *this_leaf) | |||
271 | } | 280 | } |
272 | 281 | ||
273 | static int | 282 | static int |
274 | __cpuinit cpuid4_cache_lookup(int index, struct _cpuid4_info *this_leaf) | 283 | __cpuinit cpuid4_cache_lookup_regs(int index, |
284 | struct _cpuid4_info_regs *this_leaf) | ||
275 | { | 285 | { |
276 | union _cpuid4_leaf_eax eax; | 286 | union _cpuid4_leaf_eax eax; |
277 | union _cpuid4_leaf_ebx ebx; | 287 | union _cpuid4_leaf_ebx ebx; |
@@ -299,6 +309,15 @@ __cpuinit cpuid4_cache_lookup(int index, struct _cpuid4_info *this_leaf) | |||
299 | return 0; | 309 | return 0; |
300 | } | 310 | } |
301 | 311 | ||
312 | static int | ||
313 | __cpuinit cpuid4_cache_lookup(int index, struct _cpuid4_info *this_leaf) | ||
314 | { | ||
315 | struct _cpuid4_info_regs *leaf_regs = | ||
316 | (struct _cpuid4_info_regs *)this_leaf; | ||
317 | |||
318 | return cpuid4_cache_lookup_regs(index, leaf_regs); | ||
319 | } | ||
320 | |||
302 | static int __cpuinit find_num_cache_leaves(void) | 321 | static int __cpuinit find_num_cache_leaves(void) |
303 | { | 322 | { |
304 | unsigned int eax, ebx, ecx, edx; | 323 | unsigned int eax, ebx, ecx, edx; |
@@ -338,11 +357,10 @@ unsigned int __cpuinit init_intel_cacheinfo(struct cpuinfo_x86 *c) | |||
338 | * parameters cpuid leaf to find the cache details | 357 | * parameters cpuid leaf to find the cache details |
339 | */ | 358 | */ |
340 | for (i = 0; i < num_cache_leaves; i++) { | 359 | for (i = 0; i < num_cache_leaves; i++) { |
341 | struct _cpuid4_info this_leaf; | 360 | struct _cpuid4_info_regs this_leaf; |
342 | |||
343 | int retval; | 361 | int retval; |
344 | 362 | ||
345 | retval = cpuid4_cache_lookup(i, &this_leaf); | 363 | retval = cpuid4_cache_lookup_regs(i, &this_leaf); |
346 | if (retval >= 0) { | 364 | if (retval >= 0) { |
347 | switch(this_leaf.eax.split.level) { | 365 | switch(this_leaf.eax.split.level) { |
348 | case 1: | 366 | case 1: |
@@ -491,17 +509,20 @@ static void __cpuinit cache_shared_cpu_map_setup(unsigned int cpu, int index) | |||
491 | num_threads_sharing = 1 + this_leaf->eax.split.num_threads_sharing; | 509 | num_threads_sharing = 1 + this_leaf->eax.split.num_threads_sharing; |
492 | 510 | ||
493 | if (num_threads_sharing == 1) | 511 | if (num_threads_sharing == 1) |
494 | cpu_set(cpu, this_leaf->shared_cpu_map); | 512 | cpumask_set_cpu(cpu, to_cpumask(this_leaf->shared_cpu_map)); |
495 | else { | 513 | else { |
496 | index_msb = get_count_order(num_threads_sharing); | 514 | index_msb = get_count_order(num_threads_sharing); |
497 | 515 | ||
498 | for_each_online_cpu(i) { | 516 | for_each_online_cpu(i) { |
499 | if (cpu_data(i).apicid >> index_msb == | 517 | if (cpu_data(i).apicid >> index_msb == |
500 | c->apicid >> index_msb) { | 518 | c->apicid >> index_msb) { |
501 | cpu_set(i, this_leaf->shared_cpu_map); | 519 | cpumask_set_cpu(i, |
520 | to_cpumask(this_leaf->shared_cpu_map)); | ||
502 | if (i != cpu && per_cpu(cpuid4_info, i)) { | 521 | if (i != cpu && per_cpu(cpuid4_info, i)) { |
503 | sibling_leaf = CPUID4_INFO_IDX(i, index); | 522 | sibling_leaf = |
504 | cpu_set(cpu, sibling_leaf->shared_cpu_map); | 523 | CPUID4_INFO_IDX(i, index); |
524 | cpumask_set_cpu(cpu, to_cpumask( | ||
525 | sibling_leaf->shared_cpu_map)); | ||
505 | } | 526 | } |
506 | } | 527 | } |
507 | } | 528 | } |
@@ -513,9 +534,10 @@ static void __cpuinit cache_remove_shared_cpu_map(unsigned int cpu, int index) | |||
513 | int sibling; | 534 | int sibling; |
514 | 535 | ||
515 | this_leaf = CPUID4_INFO_IDX(cpu, index); | 536 | this_leaf = CPUID4_INFO_IDX(cpu, index); |
516 | for_each_cpu_mask_nr(sibling, this_leaf->shared_cpu_map) { | 537 | for_each_cpu(sibling, to_cpumask(this_leaf->shared_cpu_map)) { |
517 | sibling_leaf = CPUID4_INFO_IDX(sibling, index); | 538 | sibling_leaf = CPUID4_INFO_IDX(sibling, index); |
518 | cpu_clear(cpu, sibling_leaf->shared_cpu_map); | 539 | cpumask_clear_cpu(cpu, |
540 | to_cpumask(sibling_leaf->shared_cpu_map)); | ||
519 | } | 541 | } |
520 | } | 542 | } |
521 | #else | 543 | #else |
@@ -620,8 +642,9 @@ static ssize_t show_shared_cpu_map_func(struct _cpuid4_info *this_leaf, | |||
620 | int n = 0; | 642 | int n = 0; |
621 | 643 | ||
622 | if (len > 1) { | 644 | if (len > 1) { |
623 | cpumask_t *mask = &this_leaf->shared_cpu_map; | 645 | const struct cpumask *mask; |
624 | 646 | ||
647 | mask = to_cpumask(this_leaf->shared_cpu_map); | ||
625 | n = type? | 648 | n = type? |
626 | cpulist_scnprintf(buf, len-2, mask) : | 649 | cpulist_scnprintf(buf, len-2, mask) : |
627 | cpumask_scnprintf(buf, len-2, mask); | 650 | cpumask_scnprintf(buf, len-2, mask); |
@@ -684,7 +707,8 @@ static struct pci_dev *get_k8_northbridge(int node) | |||
684 | 707 | ||
685 | static ssize_t show_cache_disable(struct _cpuid4_info *this_leaf, char *buf) | 708 | static ssize_t show_cache_disable(struct _cpuid4_info *this_leaf, char *buf) |
686 | { | 709 | { |
687 | int node = cpu_to_node(first_cpu(this_leaf->shared_cpu_map)); | 710 | const struct cpumask *mask = to_cpumask(this_leaf->shared_cpu_map); |
711 | int node = cpu_to_node(cpumask_first(mask)); | ||
688 | struct pci_dev *dev = NULL; | 712 | struct pci_dev *dev = NULL; |
689 | ssize_t ret = 0; | 713 | ssize_t ret = 0; |
690 | int i; | 714 | int i; |
@@ -718,7 +742,8 @@ static ssize_t | |||
718 | store_cache_disable(struct _cpuid4_info *this_leaf, const char *buf, | 742 | store_cache_disable(struct _cpuid4_info *this_leaf, const char *buf, |
719 | size_t count) | 743 | size_t count) |
720 | { | 744 | { |
721 | int node = cpu_to_node(first_cpu(this_leaf->shared_cpu_map)); | 745 | const struct cpumask *mask = to_cpumask(this_leaf->shared_cpu_map); |
746 | int node = cpu_to_node(cpumask_first(mask)); | ||
722 | struct pci_dev *dev = NULL; | 747 | struct pci_dev *dev = NULL; |
723 | unsigned int ret, index, val; | 748 | unsigned int ret, index, val; |
724 | 749 | ||
@@ -863,7 +888,7 @@ err_out: | |||
863 | return -ENOMEM; | 888 | return -ENOMEM; |
864 | } | 889 | } |
865 | 890 | ||
866 | static cpumask_t cache_dev_map = CPU_MASK_NONE; | 891 | static DECLARE_BITMAP(cache_dev_map, NR_CPUS); |
867 | 892 | ||
868 | /* Add/Remove cache interface for CPU device */ | 893 | /* Add/Remove cache interface for CPU device */ |
869 | static int __cpuinit cache_add_dev(struct sys_device * sys_dev) | 894 | static int __cpuinit cache_add_dev(struct sys_device * sys_dev) |
@@ -903,7 +928,7 @@ static int __cpuinit cache_add_dev(struct sys_device * sys_dev) | |||
903 | } | 928 | } |
904 | kobject_uevent(&(this_object->kobj), KOBJ_ADD); | 929 | kobject_uevent(&(this_object->kobj), KOBJ_ADD); |
905 | } | 930 | } |
906 | cpu_set(cpu, cache_dev_map); | 931 | cpumask_set_cpu(cpu, to_cpumask(cache_dev_map)); |
907 | 932 | ||
908 | kobject_uevent(per_cpu(cache_kobject, cpu), KOBJ_ADD); | 933 | kobject_uevent(per_cpu(cache_kobject, cpu), KOBJ_ADD); |
909 | return 0; | 934 | return 0; |
@@ -916,9 +941,9 @@ static void __cpuinit cache_remove_dev(struct sys_device * sys_dev) | |||
916 | 941 | ||
917 | if (per_cpu(cpuid4_info, cpu) == NULL) | 942 | if (per_cpu(cpuid4_info, cpu) == NULL) |
918 | return; | 943 | return; |
919 | if (!cpu_isset(cpu, cache_dev_map)) | 944 | if (!cpumask_test_cpu(cpu, to_cpumask(cache_dev_map))) |
920 | return; | 945 | return; |
921 | cpu_clear(cpu, cache_dev_map); | 946 | cpumask_clear_cpu(cpu, to_cpumask(cache_dev_map)); |
922 | 947 | ||
923 | for (i = 0; i < num_cache_leaves; i++) | 948 | for (i = 0; i < num_cache_leaves; i++) |
924 | kobject_put(&(INDEX_KOBJECT_PTR(cpu,i)->kobj)); | 949 | kobject_put(&(INDEX_KOBJECT_PTR(cpu,i)->kobj)); |