diff options
author | Thomas Gleixner <tglx@linutronix.de> | 2016-09-01 12:33:46 -0400 |
---|---|---|
committer | Thomas Gleixner <tglx@linutronix.de> | 2016-09-01 12:33:46 -0400 |
commit | 0cb7bf61b1e9f05027de58c80f9b46a714d24e35 (patch) | |
tree | 41fb55cf62d07b425122f9a8b96412c0d8eb99c5 /arch/x86/kernel/apic | |
parent | aa877175e7a9982233ed8f10cb4bfddd78d82741 (diff) | |
parent | 3eab887a55424fc2c27553b7bfe32330df83f7b8 (diff) |
Merge branch 'linus' into smp/hotplug
Apply upstream changes to avoid conflicts with pending patches.
Diffstat (limited to 'arch/x86/kernel/apic')
-rw-r--r-- | arch/x86/kernel/apic/apic.c | 31 | ||||
-rw-r--r-- | arch/x86/kernel/apic/x2apic_cluster.c | 13 | ||||
-rw-r--r-- | arch/x86/kernel/apic/x2apic_uv_x.c | 42 |
3 files changed, 58 insertions, 28 deletions
diff --git a/arch/x86/kernel/apic/apic.c b/arch/x86/kernel/apic/apic.c index 20abd912f0e4..50c95af0f017 100644 --- a/arch/x86/kernel/apic/apic.c +++ b/arch/x86/kernel/apic/apic.c | |||
@@ -313,7 +313,7 @@ int lapic_get_maxlvt(void) | |||
313 | 313 | ||
314 | /* Clock divisor */ | 314 | /* Clock divisor */ |
315 | #define APIC_DIVISOR 16 | 315 | #define APIC_DIVISOR 16 |
316 | #define TSC_DIVISOR 32 | 316 | #define TSC_DIVISOR 8 |
317 | 317 | ||
318 | /* | 318 | /* |
319 | * This function sets up the local APIC timer, with a timeout of | 319 | * This function sets up the local APIC timer, with a timeout of |
@@ -565,13 +565,37 @@ static void setup_APIC_timer(void) | |||
565 | CLOCK_EVT_FEAT_DUMMY); | 565 | CLOCK_EVT_FEAT_DUMMY); |
566 | levt->set_next_event = lapic_next_deadline; | 566 | levt->set_next_event = lapic_next_deadline; |
567 | clockevents_config_and_register(levt, | 567 | clockevents_config_and_register(levt, |
568 | (tsc_khz / TSC_DIVISOR) * 1000, | 568 | tsc_khz * (1000 / TSC_DIVISOR), |
569 | 0xF, ~0UL); | 569 | 0xF, ~0UL); |
570 | } else | 570 | } else |
571 | clockevents_register_device(levt); | 571 | clockevents_register_device(levt); |
572 | } | 572 | } |
573 | 573 | ||
574 | /* | 574 | /* |
575 | * Install the updated TSC frequency from recalibration at the TSC | ||
576 | * deadline clockevent devices. | ||
577 | */ | ||
578 | static void __lapic_update_tsc_freq(void *info) | ||
579 | { | ||
580 | struct clock_event_device *levt = this_cpu_ptr(&lapic_events); | ||
581 | |||
582 | if (!this_cpu_has(X86_FEATURE_TSC_DEADLINE_TIMER)) | ||
583 | return; | ||
584 | |||
585 | clockevents_update_freq(levt, tsc_khz * (1000 / TSC_DIVISOR)); | ||
586 | } | ||
587 | |||
588 | void lapic_update_tsc_freq(void) | ||
589 | { | ||
590 | /* | ||
591 | * The clockevent device's ->mult and ->shift can both be | ||
592 | * changed. In order to avoid races, schedule the frequency | ||
593 | * update code on each CPU. | ||
594 | */ | ||
595 | on_each_cpu(__lapic_update_tsc_freq, NULL, 0); | ||
596 | } | ||
597 | |||
598 | /* | ||
575 | * In this functions we calibrate APIC bus clocks to the external timer. | 599 | * In this functions we calibrate APIC bus clocks to the external timer. |
576 | * | 600 | * |
577 | * We want to do the calibration only once since we want to have local timer | 601 | * We want to do the calibration only once since we want to have local timer |
@@ -1599,6 +1623,9 @@ void __init enable_IR_x2apic(void) | |||
1599 | unsigned long flags; | 1623 | unsigned long flags; |
1600 | int ret, ir_stat; | 1624 | int ret, ir_stat; |
1601 | 1625 | ||
1626 | if (skip_ioapic_setup) | ||
1627 | return; | ||
1628 | |||
1602 | ir_stat = irq_remapping_prepare(); | 1629 | ir_stat = irq_remapping_prepare(); |
1603 | if (ir_stat < 0 && !x2apic_supported()) | 1630 | if (ir_stat < 0 && !x2apic_supported()) |
1604 | return; | 1631 | return; |
diff --git a/arch/x86/kernel/apic/x2apic_cluster.c b/arch/x86/kernel/apic/x2apic_cluster.c index 6368fa69d2af..54f35d988025 100644 --- a/arch/x86/kernel/apic/x2apic_cluster.c +++ b/arch/x86/kernel/apic/x2apic_cluster.c | |||
@@ -155,7 +155,7 @@ static void init_x2apic_ldr(void) | |||
155 | /* | 155 | /* |
156 | * At CPU state changes, update the x2apic cluster sibling info. | 156 | * At CPU state changes, update the x2apic cluster sibling info. |
157 | */ | 157 | */ |
158 | int x2apic_prepare_cpu(unsigned int cpu) | 158 | static int x2apic_prepare_cpu(unsigned int cpu) |
159 | { | 159 | { |
160 | if (!zalloc_cpumask_var(&per_cpu(cpus_in_cluster, cpu), GFP_KERNEL)) | 160 | if (!zalloc_cpumask_var(&per_cpu(cpus_in_cluster, cpu), GFP_KERNEL)) |
161 | return -ENOMEM; | 161 | return -ENOMEM; |
@@ -168,7 +168,7 @@ int x2apic_prepare_cpu(unsigned int cpu) | |||
168 | return 0; | 168 | return 0; |
169 | } | 169 | } |
170 | 170 | ||
171 | int x2apic_dead_cpu(unsigned int this_cpu) | 171 | static int x2apic_dead_cpu(unsigned int this_cpu) |
172 | { | 172 | { |
173 | int cpu; | 173 | int cpu; |
174 | 174 | ||
@@ -186,13 +186,18 @@ int x2apic_dead_cpu(unsigned int this_cpu) | |||
186 | static int x2apic_cluster_probe(void) | 186 | static int x2apic_cluster_probe(void) |
187 | { | 187 | { |
188 | int cpu = smp_processor_id(); | 188 | int cpu = smp_processor_id(); |
189 | int ret; | ||
189 | 190 | ||
190 | if (!x2apic_mode) | 191 | if (!x2apic_mode) |
191 | return 0; | 192 | return 0; |
192 | 193 | ||
194 | ret = cpuhp_setup_state(CPUHP_X2APIC_PREPARE, "X2APIC_PREPARE", | ||
195 | x2apic_prepare_cpu, x2apic_dead_cpu); | ||
196 | if (ret < 0) { | ||
197 | pr_err("Failed to register X2APIC_PREPARE\n"); | ||
198 | return 0; | ||
199 | } | ||
193 | cpumask_set_cpu(cpu, per_cpu(cpus_in_cluster, cpu)); | 200 | cpumask_set_cpu(cpu, per_cpu(cpus_in_cluster, cpu)); |
194 | cpuhp_setup_state(CPUHP_X2APIC_PREPARE, "X2APIC_PREPARE", | ||
195 | x2apic_prepare_cpu, x2apic_dead_cpu); | ||
196 | return 1; | 201 | return 1; |
197 | } | 202 | } |
198 | 203 | ||
diff --git a/arch/x86/kernel/apic/x2apic_uv_x.c b/arch/x86/kernel/apic/x2apic_uv_x.c index 09b59adaea3f..cb0673c1e940 100644 --- a/arch/x86/kernel/apic/x2apic_uv_x.c +++ b/arch/x86/kernel/apic/x2apic_uv_x.c | |||
@@ -223,6 +223,11 @@ static int __init uv_acpi_madt_oem_check(char *oem_id, char *oem_table_id) | |||
223 | if (strncmp(oem_id, "SGI", 3) != 0) | 223 | if (strncmp(oem_id, "SGI", 3) != 0) |
224 | return 0; | 224 | return 0; |
225 | 225 | ||
226 | if (numa_off) { | ||
227 | pr_err("UV: NUMA is off, disabling UV support\n"); | ||
228 | return 0; | ||
229 | } | ||
230 | |||
226 | /* Setup early hub type field in uv_hub_info for Node 0 */ | 231 | /* Setup early hub type field in uv_hub_info for Node 0 */ |
227 | uv_cpu_info->p_uv_hub_info = &uv_hub_info_node0; | 232 | uv_cpu_info->p_uv_hub_info = &uv_hub_info_node0; |
228 | 233 | ||
@@ -325,7 +330,7 @@ static __init void build_uv_gr_table(void) | |||
325 | struct uv_gam_range_entry *gre = uv_gre_table; | 330 | struct uv_gam_range_entry *gre = uv_gre_table; |
326 | struct uv_gam_range_s *grt; | 331 | struct uv_gam_range_s *grt; |
327 | unsigned long last_limit = 0, ram_limit = 0; | 332 | unsigned long last_limit = 0, ram_limit = 0; |
328 | int bytes, i, sid, lsid = -1; | 333 | int bytes, i, sid, lsid = -1, indx = 0, lindx = -1; |
329 | 334 | ||
330 | if (!gre) | 335 | if (!gre) |
331 | return; | 336 | return; |
@@ -356,11 +361,12 @@ static __init void build_uv_gr_table(void) | |||
356 | } | 361 | } |
357 | sid = gre->sockid - _min_socket; | 362 | sid = gre->sockid - _min_socket; |
358 | if (lsid < sid) { /* new range */ | 363 | if (lsid < sid) { /* new range */ |
359 | grt = &_gr_table[sid]; | 364 | grt = &_gr_table[indx]; |
360 | grt->base = lsid; | 365 | grt->base = lindx; |
361 | grt->nasid = gre->nasid; | 366 | grt->nasid = gre->nasid; |
362 | grt->limit = last_limit = gre->limit; | 367 | grt->limit = last_limit = gre->limit; |
363 | lsid = sid; | 368 | lsid = sid; |
369 | lindx = indx++; | ||
364 | continue; | 370 | continue; |
365 | } | 371 | } |
366 | if (lsid == sid && !ram_limit) { /* update range */ | 372 | if (lsid == sid && !ram_limit) { /* update range */ |
@@ -371,7 +377,7 @@ static __init void build_uv_gr_table(void) | |||
371 | } | 377 | } |
372 | if (!ram_limit) { /* non-contiguous ram range */ | 378 | if (!ram_limit) { /* non-contiguous ram range */ |
373 | grt++; | 379 | grt++; |
374 | grt->base = sid - 1; | 380 | grt->base = lindx; |
375 | grt->nasid = gre->nasid; | 381 | grt->nasid = gre->nasid; |
376 | grt->limit = last_limit = gre->limit; | 382 | grt->limit = last_limit = gre->limit; |
377 | continue; | 383 | continue; |
@@ -1155,19 +1161,18 @@ static void __init decode_gam_rng_tbl(unsigned long ptr) | |||
1155 | for (; gre->type != UV_GAM_RANGE_TYPE_UNUSED; gre++) { | 1161 | for (; gre->type != UV_GAM_RANGE_TYPE_UNUSED; gre++) { |
1156 | if (!index) { | 1162 | if (!index) { |
1157 | pr_info("UV: GAM Range Table...\n"); | 1163 | pr_info("UV: GAM Range Table...\n"); |
1158 | pr_info("UV: # %20s %14s %5s %4s %5s %3s %2s %3s\n", | 1164 | pr_info("UV: # %20s %14s %5s %4s %5s %3s %2s\n", |
1159 | "Range", "", "Size", "Type", "NASID", | 1165 | "Range", "", "Size", "Type", "NASID", |
1160 | "SID", "PN", "PXM"); | 1166 | "SID", "PN"); |
1161 | } | 1167 | } |
1162 | pr_info( | 1168 | pr_info( |
1163 | "UV: %2d: 0x%014lx-0x%014lx %5luG %3d %04x %02x %02x %3d\n", | 1169 | "UV: %2d: 0x%014lx-0x%014lx %5luG %3d %04x %02x %02x\n", |
1164 | index++, | 1170 | index++, |
1165 | (unsigned long)lgre << UV_GAM_RANGE_SHFT, | 1171 | (unsigned long)lgre << UV_GAM_RANGE_SHFT, |
1166 | (unsigned long)gre->limit << UV_GAM_RANGE_SHFT, | 1172 | (unsigned long)gre->limit << UV_GAM_RANGE_SHFT, |
1167 | ((unsigned long)(gre->limit - lgre)) >> | 1173 | ((unsigned long)(gre->limit - lgre)) >> |
1168 | (30 - UV_GAM_RANGE_SHFT), /* 64M -> 1G */ | 1174 | (30 - UV_GAM_RANGE_SHFT), /* 64M -> 1G */ |
1169 | gre->type, gre->nasid, gre->sockid, | 1175 | gre->type, gre->nasid, gre->sockid, gre->pnode); |
1170 | gre->pnode, gre->pxm); | ||
1171 | 1176 | ||
1172 | lgre = gre->limit; | 1177 | lgre = gre->limit; |
1173 | if (sock_min > gre->sockid) | 1178 | if (sock_min > gre->sockid) |
@@ -1286,7 +1291,7 @@ static void __init build_socket_tables(void) | |||
1286 | _pnode_to_socket[i] = SOCK_EMPTY; | 1291 | _pnode_to_socket[i] = SOCK_EMPTY; |
1287 | 1292 | ||
1288 | /* fill in pnode/node/addr conversion list values */ | 1293 | /* fill in pnode/node/addr conversion list values */ |
1289 | pr_info("UV: GAM Building socket/pnode/pxm conversion tables\n"); | 1294 | pr_info("UV: GAM Building socket/pnode conversion tables\n"); |
1290 | for (; gre->type != UV_GAM_RANGE_TYPE_UNUSED; gre++) { | 1295 | for (; gre->type != UV_GAM_RANGE_TYPE_UNUSED; gre++) { |
1291 | if (gre->type == UV_GAM_RANGE_TYPE_HOLE) | 1296 | if (gre->type == UV_GAM_RANGE_TYPE_HOLE) |
1292 | continue; | 1297 | continue; |
@@ -1294,20 +1299,18 @@ static void __init build_socket_tables(void) | |||
1294 | if (_socket_to_pnode[i] != SOCK_EMPTY) | 1299 | if (_socket_to_pnode[i] != SOCK_EMPTY) |
1295 | continue; /* duplicate */ | 1300 | continue; /* duplicate */ |
1296 | _socket_to_pnode[i] = gre->pnode; | 1301 | _socket_to_pnode[i] = gre->pnode; |
1297 | _socket_to_node[i] = gre->pxm; | ||
1298 | 1302 | ||
1299 | i = gre->pnode - minpnode; | 1303 | i = gre->pnode - minpnode; |
1300 | _pnode_to_socket[i] = gre->sockid; | 1304 | _pnode_to_socket[i] = gre->sockid; |
1301 | 1305 | ||
1302 | pr_info( | 1306 | pr_info( |
1303 | "UV: sid:%02x type:%d nasid:%04x pn:%02x pxm:%2d pn2s:%2x\n", | 1307 | "UV: sid:%02x type:%d nasid:%04x pn:%02x pn2s:%2x\n", |
1304 | gre->sockid, gre->type, gre->nasid, | 1308 | gre->sockid, gre->type, gre->nasid, |
1305 | _socket_to_pnode[gre->sockid - minsock], | 1309 | _socket_to_pnode[gre->sockid - minsock], |
1306 | _socket_to_node[gre->sockid - minsock], | ||
1307 | _pnode_to_socket[gre->pnode - minpnode]); | 1310 | _pnode_to_socket[gre->pnode - minpnode]); |
1308 | } | 1311 | } |
1309 | 1312 | ||
1310 | /* check socket -> node values */ | 1313 | /* Set socket -> node values */ |
1311 | lnid = -1; | 1314 | lnid = -1; |
1312 | for_each_present_cpu(cpu) { | 1315 | for_each_present_cpu(cpu) { |
1313 | int nid = cpu_to_node(cpu); | 1316 | int nid = cpu_to_node(cpu); |
@@ -1318,14 +1321,9 @@ static void __init build_socket_tables(void) | |||
1318 | lnid = nid; | 1321 | lnid = nid; |
1319 | apicid = per_cpu(x86_cpu_to_apicid, cpu); | 1322 | apicid = per_cpu(x86_cpu_to_apicid, cpu); |
1320 | sockid = apicid >> uv_cpuid.socketid_shift; | 1323 | sockid = apicid >> uv_cpuid.socketid_shift; |
1321 | i = sockid - minsock; | 1324 | _socket_to_node[sockid - minsock] = nid; |
1322 | 1325 | pr_info("UV: sid:%02x: apicid:%04x node:%2d\n", | |
1323 | if (nid != _socket_to_node[i]) { | 1326 | sockid, apicid, nid); |
1324 | pr_warn( | ||
1325 | "UV: %02x: type:%d socket:%02x PXM:%02x != node:%2d\n", | ||
1326 | i, sockid, gre->type, _socket_to_node[i], nid); | ||
1327 | _socket_to_node[i] = nid; | ||
1328 | } | ||
1329 | } | 1327 | } |
1330 | 1328 | ||
1331 | /* Setup physical blade to pnode translation from GAM Range Table */ | 1329 | /* Setup physical blade to pnode translation from GAM Range Table */ |