diff options
Diffstat (limited to 'arch/i386/kernel/smpboot.c')
-rw-r--r-- | arch/i386/kernel/smpboot.c | 37 |
1 files changed, 23 insertions, 14 deletions
diff --git a/arch/i386/kernel/smpboot.c b/arch/i386/kernel/smpboot.c index bce5470ecb42..89e7315e539c 100644 --- a/arch/i386/kernel/smpboot.c +++ b/arch/i386/kernel/smpboot.c | |||
@@ -67,12 +67,6 @@ int smp_num_siblings = 1; | |||
67 | EXPORT_SYMBOL(smp_num_siblings); | 67 | EXPORT_SYMBOL(smp_num_siblings); |
68 | #endif | 68 | #endif |
69 | 69 | ||
70 | /* Package ID of each logical CPU */ | ||
71 | int phys_proc_id[NR_CPUS] __read_mostly = {[0 ... NR_CPUS-1] = BAD_APICID}; | ||
72 | |||
73 | /* Core ID of each logical CPU */ | ||
74 | int cpu_core_id[NR_CPUS] __read_mostly = {[0 ... NR_CPUS-1] = BAD_APICID}; | ||
75 | |||
76 | /* Last level cache ID of each logical CPU */ | 70 | /* Last level cache ID of each logical CPU */ |
77 | int cpu_llc_id[NR_CPUS] __cpuinitdata = {[0 ... NR_CPUS-1] = BAD_APICID}; | 71 | int cpu_llc_id[NR_CPUS] __cpuinitdata = {[0 ... NR_CPUS-1] = BAD_APICID}; |
78 | 72 | ||
@@ -454,10 +448,12 @@ cpumask_t cpu_coregroup_map(int cpu) | |||
454 | struct cpuinfo_x86 *c = cpu_data + cpu; | 448 | struct cpuinfo_x86 *c = cpu_data + cpu; |
455 | /* | 449 | /* |
456 | * For perf, we return last level cache shared map. | 450 | * For perf, we return last level cache shared map. |
457 | * TBD: when power saving sched policy is added, we will return | 451 | * And for power savings, we return cpu_core_map |
458 | * cpu_core_map when power saving policy is enabled | ||
459 | */ | 452 | */ |
460 | return c->llc_shared_map; | 453 | if (sched_mc_power_savings || sched_smt_power_savings) |
454 | return cpu_core_map[cpu]; | ||
455 | else | ||
456 | return c->llc_shared_map; | ||
461 | } | 457 | } |
462 | 458 | ||
463 | /* representing cpus for which sibling maps can be computed */ | 459 | /* representing cpus for which sibling maps can be computed */ |
@@ -473,8 +469,8 @@ set_cpu_sibling_map(int cpu) | |||
473 | 469 | ||
474 | if (smp_num_siblings > 1) { | 470 | if (smp_num_siblings > 1) { |
475 | for_each_cpu_mask(i, cpu_sibling_setup_map) { | 471 | for_each_cpu_mask(i, cpu_sibling_setup_map) { |
476 | if (phys_proc_id[cpu] == phys_proc_id[i] && | 472 | if (c[cpu].phys_proc_id == c[i].phys_proc_id && |
477 | cpu_core_id[cpu] == cpu_core_id[i]) { | 473 | c[cpu].cpu_core_id == c[i].cpu_core_id) { |
478 | cpu_set(i, cpu_sibling_map[cpu]); | 474 | cpu_set(i, cpu_sibling_map[cpu]); |
479 | cpu_set(cpu, cpu_sibling_map[i]); | 475 | cpu_set(cpu, cpu_sibling_map[i]); |
480 | cpu_set(i, cpu_core_map[cpu]); | 476 | cpu_set(i, cpu_core_map[cpu]); |
@@ -501,7 +497,7 @@ set_cpu_sibling_map(int cpu) | |||
501 | cpu_set(i, c[cpu].llc_shared_map); | 497 | cpu_set(i, c[cpu].llc_shared_map); |
502 | cpu_set(cpu, c[i].llc_shared_map); | 498 | cpu_set(cpu, c[i].llc_shared_map); |
503 | } | 499 | } |
504 | if (phys_proc_id[cpu] == phys_proc_id[i]) { | 500 | if (c[cpu].phys_proc_id == c[i].phys_proc_id) { |
505 | cpu_set(i, cpu_core_map[cpu]); | 501 | cpu_set(i, cpu_core_map[cpu]); |
506 | cpu_set(cpu, cpu_core_map[i]); | 502 | cpu_set(cpu, cpu_core_map[i]); |
507 | /* | 503 | /* |
@@ -1056,6 +1052,7 @@ static int __cpuinit __smp_prepare_cpu(int cpu) | |||
1056 | struct warm_boot_cpu_info info; | 1052 | struct warm_boot_cpu_info info; |
1057 | struct work_struct task; | 1053 | struct work_struct task; |
1058 | int apicid, ret; | 1054 | int apicid, ret; |
1055 | struct Xgt_desc_struct *cpu_gdt_descr = &per_cpu(cpu_gdt_descr, cpu); | ||
1059 | 1056 | ||
1060 | apicid = x86_cpu_to_apicid[cpu]; | 1057 | apicid = x86_cpu_to_apicid[cpu]; |
1061 | if (apicid == BAD_APICID) { | 1058 | if (apicid == BAD_APICID) { |
@@ -1063,6 +1060,18 @@ static int __cpuinit __smp_prepare_cpu(int cpu) | |||
1063 | goto exit; | 1060 | goto exit; |
1064 | } | 1061 | } |
1065 | 1062 | ||
1063 | /* | ||
1064 | * the CPU isn't initialized at boot time, allocate gdt table here. | ||
1065 | * cpu_init will initialize it | ||
1066 | */ | ||
1067 | if (!cpu_gdt_descr->address) { | ||
1068 | cpu_gdt_descr->address = get_zeroed_page(GFP_KERNEL); | ||
1069 | if (!cpu_gdt_descr->address) | ||
1070 | printk(KERN_CRIT "CPU%d failed to allocate GDT\n", cpu); | ||
1071 | ret = -ENOMEM; | ||
1072 | goto exit; | ||
1073 | } | ||
1074 | |||
1066 | info.complete = &done; | 1075 | info.complete = &done; |
1067 | info.apicid = apicid; | 1076 | info.apicid = apicid; |
1068 | info.cpu = cpu; | 1077 | info.cpu = cpu; |
@@ -1340,8 +1349,8 @@ remove_siblinginfo(int cpu) | |||
1340 | cpu_clear(cpu, cpu_sibling_map[sibling]); | 1349 | cpu_clear(cpu, cpu_sibling_map[sibling]); |
1341 | cpus_clear(cpu_sibling_map[cpu]); | 1350 | cpus_clear(cpu_sibling_map[cpu]); |
1342 | cpus_clear(cpu_core_map[cpu]); | 1351 | cpus_clear(cpu_core_map[cpu]); |
1343 | phys_proc_id[cpu] = BAD_APICID; | 1352 | c[cpu].phys_proc_id = 0; |
1344 | cpu_core_id[cpu] = BAD_APICID; | 1353 | c[cpu].cpu_core_id = 0; |
1345 | cpu_clear(cpu, cpu_sibling_setup_map); | 1354 | cpu_clear(cpu, cpu_sibling_setup_map); |
1346 | } | 1355 | } |
1347 | 1356 | ||