diff options
Diffstat (limited to 'arch/x86/kernel/smpboot.c')
-rw-r--r-- | arch/x86/kernel/smpboot.c | 25 |
1 files changed, 16 insertions, 9 deletions
diff --git a/arch/x86/kernel/smpboot.c b/arch/x86/kernel/smpboot.c index 067de612d3fa..26b473dc3f82 100644 --- a/arch/x86/kernel/smpboot.c +++ b/arch/x86/kernel/smpboot.c | |||
@@ -100,10 +100,11 @@ EXPORT_PER_CPU_SYMBOL(cpu_info); | |||
100 | /* Logical package management. We might want to allocate that dynamically */ | 100 | /* Logical package management. We might want to allocate that dynamically */ |
101 | static int *physical_to_logical_pkg __read_mostly; | 101 | static int *physical_to_logical_pkg __read_mostly; |
102 | static unsigned long *physical_package_map __read_mostly;; | 102 | static unsigned long *physical_package_map __read_mostly;; |
103 | static unsigned long *logical_package_map __read_mostly; | ||
104 | static unsigned int max_physical_pkg_id __read_mostly; | 103 | static unsigned int max_physical_pkg_id __read_mostly; |
105 | unsigned int __max_logical_packages __read_mostly; | 104 | unsigned int __max_logical_packages __read_mostly; |
106 | EXPORT_SYMBOL(__max_logical_packages); | 105 | EXPORT_SYMBOL(__max_logical_packages); |
106 | static unsigned int logical_packages __read_mostly; | ||
107 | static bool logical_packages_frozen __read_mostly; | ||
107 | 108 | ||
108 | /* Maximum number of SMT threads on any online core */ | 109 | /* Maximum number of SMT threads on any online core */ |
109 | int __max_smt_threads __read_mostly; | 110 | int __max_smt_threads __read_mostly; |
@@ -277,14 +278,14 @@ int topology_update_package_map(unsigned int apicid, unsigned int cpu) | |||
277 | if (test_and_set_bit(pkg, physical_package_map)) | 278 | if (test_and_set_bit(pkg, physical_package_map)) |
278 | goto found; | 279 | goto found; |
279 | 280 | ||
280 | new = find_first_zero_bit(logical_package_map, __max_logical_packages); | 281 | if (logical_packages_frozen) { |
281 | if (new >= __max_logical_packages) { | ||
282 | physical_to_logical_pkg[pkg] = -1; | 282 | physical_to_logical_pkg[pkg] = -1; |
283 | pr_warn("APIC(%x) Package %u exceeds logical package map\n", | 283 | pr_warn("APIC(%x) Package %u exceeds logical package max\n", |
284 | apicid, pkg); | 284 | apicid, pkg); |
285 | return -ENOSPC; | 285 | return -ENOSPC; |
286 | } | 286 | } |
287 | set_bit(new, logical_package_map); | 287 | |
288 | new = logical_packages++; | ||
288 | pr_info("APIC(%x) Converting physical %u to logical package %u\n", | 289 | pr_info("APIC(%x) Converting physical %u to logical package %u\n", |
289 | apicid, pkg, new); | 290 | apicid, pkg, new); |
290 | physical_to_logical_pkg[pkg] = new; | 291 | physical_to_logical_pkg[pkg] = new; |
@@ -341,6 +342,7 @@ static void __init smp_init_package_map(void) | |||
341 | } | 342 | } |
342 | 343 | ||
343 | __max_logical_packages = DIV_ROUND_UP(total_cpus, ncpus); | 344 | __max_logical_packages = DIV_ROUND_UP(total_cpus, ncpus); |
345 | logical_packages = 0; | ||
344 | 346 | ||
345 | /* | 347 | /* |
346 | * Possibly larger than what we need as the number of apic ids per | 348 | * Possibly larger than what we need as the number of apic ids per |
@@ -352,10 +354,6 @@ static void __init smp_init_package_map(void) | |||
352 | memset(physical_to_logical_pkg, 0xff, size); | 354 | memset(physical_to_logical_pkg, 0xff, size); |
353 | size = BITS_TO_LONGS(max_physical_pkg_id) * sizeof(unsigned long); | 355 | size = BITS_TO_LONGS(max_physical_pkg_id) * sizeof(unsigned long); |
354 | physical_package_map = kzalloc(size, GFP_KERNEL); | 356 | physical_package_map = kzalloc(size, GFP_KERNEL); |
355 | size = BITS_TO_LONGS(__max_logical_packages) * sizeof(unsigned long); | ||
356 | logical_package_map = kzalloc(size, GFP_KERNEL); | ||
357 | |||
358 | pr_info("Max logical packages: %u\n", __max_logical_packages); | ||
359 | 357 | ||
360 | for_each_present_cpu(cpu) { | 358 | for_each_present_cpu(cpu) { |
361 | unsigned int apicid = apic->cpu_present_to_apicid(cpu); | 359 | unsigned int apicid = apic->cpu_present_to_apicid(cpu); |
@@ -369,6 +367,15 @@ static void __init smp_init_package_map(void) | |||
369 | set_cpu_possible(cpu, false); | 367 | set_cpu_possible(cpu, false); |
370 | set_cpu_present(cpu, false); | 368 | set_cpu_present(cpu, false); |
371 | } | 369 | } |
370 | |||
371 | if (logical_packages > __max_logical_packages) { | ||
372 | pr_warn("Detected more packages (%u), then computed by BIOS data (%u).\n", | ||
373 | logical_packages, __max_logical_packages); | ||
374 | logical_packages_frozen = true; | ||
375 | __max_logical_packages = logical_packages; | ||
376 | } | ||
377 | |||
378 | pr_info("Max logical packages: %u\n", __max_logical_packages); | ||
372 | } | 379 | } |
373 | 380 | ||
374 | void __init smp_store_boot_cpu_info(void) | 381 | void __init smp_store_boot_cpu_info(void) |