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>

authored by Cliff Wickman and committed by Ingo Molnar c4026cfd 5edd19af

+14 -12
+14 -12
arch/x86/kernel/tlb_uv.c
··· 1484 1484 /* 1485 1485 * initialize the bau_control structure for each cpu 1486 1486 */ 1487 - static void uv_init_per_cpu(int nuvhubs) 1487 + static void __init uv_init_per_cpu(int nuvhubs) 1488 1488 { 1489 1489 int i; 1490 1490 int cpu; 1491 1491 int pnode; 1492 1492 int uvhub; 1493 + int have_hmaster; 1493 1494 short socket = 0; 1494 1495 unsigned short socket_mask; 1495 - unsigned int uvhub_mask; 1496 + unsigned char *uvhub_mask; 1496 1497 struct bau_control *bcp; 1497 1498 struct uvhub_desc *bdp; 1498 1499 struct socket_desc *sdp; ··· 1517 1516 uvhub_descs = (struct uvhub_desc *) 1518 1517 kmalloc(nuvhubs * sizeof(struct uvhub_desc), GFP_KERNEL); 1519 1518 memset(uvhub_descs, 0, nuvhubs * sizeof(struct uvhub_desc)); 1519 + uvhub_mask = kzalloc((nuvhubs+7)/8, GFP_KERNEL); 1520 1520 for_each_present_cpu(cpu) { 1521 1521 bcp = &per_cpu(bau_control, cpu); 1522 1522 memset(bcp, 0, sizeof(struct bau_control)); 1523 1523 pnode = uv_cpu_hub_info(cpu)->pnode; 1524 1524 uvhub = uv_cpu_hub_info(cpu)->numa_blade_id; 1525 - uvhub_mask |= (1 << uvhub); 1525 + *(uvhub_mask + (uvhub/8)) |= (1 << (uvhub%8)); 1526 1526 bdp = &uvhub_descs[uvhub]; 1527 1527 bdp->num_cpus++; 1528 1528 bdp->uvhub = uvhub; 1529 1529 bdp->pnode = pnode; 1530 1530 /* kludge: 'assuming' one node per socket, and assuming that 1531 1531 disabling a socket just leaves a gap in node numbers */ 1532 - socket = (cpu_to_node(cpu) & 1);; 1532 + socket = (cpu_to_node(cpu) & 1); 1533 1533 bdp->socket_mask |= (1 << socket); 1534 1534 sdp = &bdp->socket[socket]; 1535 1535 sdp->cpu_number[sdp->num_cpus] = cpu; 1536 1536 sdp->num_cpus++; 1537 1537 } 1538 - uvhub = 0; 1539 - while (uvhub_mask) { 1540 - if (!(uvhub_mask & 1)) 1541 - goto nexthub; 1538 + for (uvhub = 0; uvhub < nuvhubs; uvhub++) { 1539 + if (!(*(uvhub_mask + (uvhub/8)) & (1 << (uvhub%8)))) 1540 + continue; 1541 + have_hmaster = 0; 1542 1542 bdp = &uvhub_descs[uvhub]; 1543 1543 socket_mask = bdp->socket_mask; 1544 1544 socket = 0; ··· 1553 1551 bcp->cpu = cpu; 1554 1552 if (i == 0) { 1555 1553 smaster = bcp; 1556 - if (socket == 0) 1554 + if (!have_hmaster) { 1555 + have_hmaster++; 1557 1556 hmaster = bcp; 1557 + } 1558 1558 } 1559 1559 bcp->cpus_in_uvhub = bdp->num_cpus; 1560 1560 bcp->cpus_in_socket = sdp->num_cpus; ··· 1570 1566 socket++; 1571 1567 socket_mask = (socket_mask >> 1); 1572 1568 } 1573 - nexthub: 1574 - uvhub++; 1575 - uvhub_mask = (uvhub_mask >> 1); 1576 1569 } 1577 1570 kfree(uvhub_descs); 1571 + kfree(uvhub_mask); 1578 1572 for_each_present_cpu(cpu) { 1579 1573 bcp = &per_cpu(bau_control, cpu); 1580 1574 bcp->baudisabled = 0;