aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorCliff Wickman <cpw@sgi.com>2010-07-30 15:10:55 -0400
committerIngo Molnar <mingo@elte.hu>2010-08-01 03:18:41 -0400
commitc4026cfd8febcd63dd278894108839f30e525a0e (patch)
tree6eea79fdb39ef80d0eabbd0395d9dc1f93e1361a
parent5edd19af18a36a4e22c570b1b969179e0ca1fe4c (diff)
x86, UV: Initialize BAU hub map
Fix uninitialized uvhub_mask: - An unitialized bit map variable was causing initialization of non-existant hubs (this one causes boot panics). - And the bit map was too small for large machines. This patch makes it dynamic in size. - Fix the case where socket 0 has no enabled cpu's. Don't assume every hub has a socket 0. - uv_init_per_cpu() should be __init. Signed-off-by: Cliff Wickman <cpw@sgi.com> Cc: <stable@kernel.org> # for .35.x LKML-Reference: <E1Oeuyt-0004XS-0y@eag09.americas.sgi.com> Signed-off-by: Ingo Molnar <mingo@elte.hu>
-rw-r--r--arch/x86/kernel/tlb_uv.c26
1 files changed, 14 insertions, 12 deletions
diff --git a/arch/x86/kernel/tlb_uv.c b/arch/x86/kernel/tlb_uv.c
index 59efb5390b37..312ef0292815 100644
--- a/arch/x86/kernel/tlb_uv.c
+++ b/arch/x86/kernel/tlb_uv.c
@@ -1484,15 +1484,16 @@ calculate_destination_timeout(void)
1484/* 1484/*
1485 * initialize the bau_control structure for each cpu 1485 * initialize the bau_control structure for each cpu
1486 */ 1486 */
1487static void uv_init_per_cpu(int nuvhubs) 1487static void __init uv_init_per_cpu(int nuvhubs)
1488{ 1488{
1489 int i; 1489 int i;
1490 int cpu; 1490 int cpu;
1491 int pnode; 1491 int pnode;
1492 int uvhub; 1492 int uvhub;
1493 int have_hmaster;
1493 short socket = 0; 1494 short socket = 0;
1494 unsigned short socket_mask; 1495 unsigned short socket_mask;
1495 unsigned int uvhub_mask; 1496 unsigned char *uvhub_mask;
1496 struct bau_control *bcp; 1497 struct bau_control *bcp;
1497 struct uvhub_desc *bdp; 1498 struct uvhub_desc *bdp;
1498 struct socket_desc *sdp; 1499 struct socket_desc *sdp;
@@ -1516,28 +1517,29 @@ static void uv_init_per_cpu(int nuvhubs)
1516 uvhub_descs = (struct uvhub_desc *) 1517 uvhub_descs = (struct uvhub_desc *)
1517 kmalloc(nuvhubs * sizeof(struct uvhub_desc), GFP_KERNEL); 1518 kmalloc(nuvhubs * sizeof(struct uvhub_desc), GFP_KERNEL);
1518 memset(uvhub_descs, 0, nuvhubs * sizeof(struct uvhub_desc)); 1519 memset(uvhub_descs, 0, nuvhubs * sizeof(struct uvhub_desc));
1520 uvhub_mask = kzalloc((nuvhubs+7)/8, GFP_KERNEL);
1519 for_each_present_cpu(cpu) { 1521 for_each_present_cpu(cpu) {
1520 bcp = &per_cpu(bau_control, cpu); 1522 bcp = &per_cpu(bau_control, cpu);
1521 memset(bcp, 0, sizeof(struct bau_control)); 1523 memset(bcp, 0, sizeof(struct bau_control));
1522 pnode = uv_cpu_hub_info(cpu)->pnode; 1524 pnode = uv_cpu_hub_info(cpu)->pnode;
1523 uvhub = uv_cpu_hub_info(cpu)->numa_blade_id; 1525 uvhub = uv_cpu_hub_info(cpu)->numa_blade_id;
1524 uvhub_mask |= (1 << uvhub); 1526 *(uvhub_mask + (uvhub/8)) |= (1 << (uvhub%8));
1525 bdp = &uvhub_descs[uvhub]; 1527 bdp = &uvhub_descs[uvhub];
1526 bdp->num_cpus++; 1528 bdp->num_cpus++;
1527 bdp->uvhub = uvhub; 1529 bdp->uvhub = uvhub;
1528 bdp->pnode = pnode; 1530 bdp->pnode = pnode;
1529 /* kludge: 'assuming' one node per socket, and assuming that 1531 /* kludge: 'assuming' one node per socket, and assuming that
1530 disabling a socket just leaves a gap in node numbers */ 1532 disabling a socket just leaves a gap in node numbers */
1531 socket = (cpu_to_node(cpu) & 1);; 1533 socket = (cpu_to_node(cpu) & 1);
1532 bdp->socket_mask |= (1 << socket); 1534 bdp->socket_mask |= (1 << socket);
1533 sdp = &bdp->socket[socket]; 1535 sdp = &bdp->socket[socket];
1534 sdp->cpu_number[sdp->num_cpus] = cpu; 1536 sdp->cpu_number[sdp->num_cpus] = cpu;
1535 sdp->num_cpus++; 1537 sdp->num_cpus++;
1536 } 1538 }
1537 uvhub = 0; 1539 for (uvhub = 0; uvhub < nuvhubs; uvhub++) {
1538 while (uvhub_mask) { 1540 if (!(*(uvhub_mask + (uvhub/8)) & (1 << (uvhub%8))))
1539 if (!(uvhub_mask & 1)) 1541 continue;
1540 goto nexthub; 1542 have_hmaster = 0;
1541 bdp = &uvhub_descs[uvhub]; 1543 bdp = &uvhub_descs[uvhub];
1542 socket_mask = bdp->socket_mask; 1544 socket_mask = bdp->socket_mask;
1543 socket = 0; 1545 socket = 0;
@@ -1551,8 +1553,10 @@ static void uv_init_per_cpu(int nuvhubs)
1551 bcp->cpu = cpu; 1553 bcp->cpu = cpu;
1552 if (i == 0) { 1554 if (i == 0) {
1553 smaster = bcp; 1555 smaster = bcp;
1554 if (socket == 0) 1556 if (!have_hmaster) {
1557 have_hmaster++;
1555 hmaster = bcp; 1558 hmaster = bcp;
1559 }
1556 } 1560 }
1557 bcp->cpus_in_uvhub = bdp->num_cpus; 1561 bcp->cpus_in_uvhub = bdp->num_cpus;
1558 bcp->cpus_in_socket = sdp->num_cpus; 1562 bcp->cpus_in_socket = sdp->num_cpus;
@@ -1566,11 +1570,9 @@ nextsocket:
1566 socket++; 1570 socket++;
1567 socket_mask = (socket_mask >> 1); 1571 socket_mask = (socket_mask >> 1);
1568 } 1572 }
1569nexthub:
1570 uvhub++;
1571 uvhub_mask = (uvhub_mask >> 1);
1572 } 1573 }
1573 kfree(uvhub_descs); 1574 kfree(uvhub_descs);
1575 kfree(uvhub_mask);
1574 for_each_present_cpu(cpu) { 1576 for_each_present_cpu(cpu) {
1575 bcp = &per_cpu(bau_control, cpu); 1577 bcp = &per_cpu(bau_control, cpu);
1576 bcp->baudisabled = 0; 1578 bcp->baudisabled = 0;