aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/kernel/apic
diff options
context:
space:
mode:
authorThomas Gleixner <tglx@linutronix.de>2016-09-01 12:33:46 -0400
committerThomas Gleixner <tglx@linutronix.de>2016-09-01 12:33:46 -0400
commit0cb7bf61b1e9f05027de58c80f9b46a714d24e35 (patch)
tree41fb55cf62d07b425122f9a8b96412c0d8eb99c5 /arch/x86/kernel/apic
parentaa877175e7a9982233ed8f10cb4bfddd78d82741 (diff)
parent3eab887a55424fc2c27553b7bfe32330df83f7b8 (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.c31
-rw-r--r--arch/x86/kernel/apic/x2apic_cluster.c13
-rw-r--r--arch/x86/kernel/apic/x2apic_uv_x.c42
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 */
578static 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
588void 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 */
158int x2apic_prepare_cpu(unsigned int cpu) 158static 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
171int x2apic_dead_cpu(unsigned int this_cpu) 171static 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)
186static int x2apic_cluster_probe(void) 186static 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 */