x86, UV: Correct BAU discovery of hubs and sockets

Correct the initialization-time assumption of contigous blade
numbers and of sockets numbered from zero.

There may be hubs present with no cpu's enabled.
There may be disabled sockets such that the active socket is not
number zero.

And assign a 'socket master' by assuming that a socket is a
node. (it is not safe to extract socket number from an apicid)

Signed-off-by: Cliff Wickman <cpw@sgi.com>
Cc: gregkh@suse.de
LKML-Reference: <E1OJvNy-0004aW-9S@eag09.americas.sgi.com>
Signed-off-by: Ingo Molnar <mingo@elte.hu>

authored by Cliff Wickman and committed by Ingo Molnar a8328ee5 39847e7f

+31 -18
+31 -18
arch/x86/kernel/tlb_uv.c
··· 1547 1547 */ 1548 1548 static void uv_init_per_cpu(int nuvhubs) 1549 1549 { 1550 - int i, j, k; 1550 + int i; 1551 1551 int cpu; 1552 1552 int pnode; 1553 1553 int uvhub; 1554 1554 short socket = 0; 1555 + unsigned short socket_mask; 1556 + unsigned int uvhub_mask; 1555 1557 struct bau_control *bcp; 1556 1558 struct uvhub_desc *bdp; 1557 1559 struct socket_desc *sdp; ··· 1564 1562 short cpu_number[16]; 1565 1563 }; 1566 1564 struct uvhub_desc { 1567 - short num_sockets; 1565 + unsigned short socket_mask; 1568 1566 short num_cpus; 1569 1567 short uvhub; 1570 1568 short pnode; ··· 1583 1581 spin_lock_init(&bcp->masks_lock); 1584 1582 pnode = uv_cpu_hub_info(cpu)->pnode; 1585 1583 uvhub = uv_cpu_hub_info(cpu)->numa_blade_id; 1584 + uvhub_mask |= (1 << uvhub); 1586 1585 bdp = &uvhub_descs[uvhub]; 1587 1586 bdp->num_cpus++; 1588 1587 bdp->uvhub = uvhub; 1589 1588 bdp->pnode = pnode; 1590 - /* kludge: assume uv_hub.h is constant */ 1591 - socket = (cpu_physical_id(cpu)>>5)&1; 1592 - if (socket >= bdp->num_sockets) 1593 - bdp->num_sockets = socket+1; 1589 + /* kludge: 'assuming' one node per socket, and assuming that 1590 + disabling a socket just leaves a gap in node numbers */ 1591 + socket = (cpu_to_node(cpu) & 1);; 1592 + bdp->socket_mask |= (1 << socket); 1594 1593 sdp = &bdp->socket[socket]; 1595 1594 sdp->cpu_number[sdp->num_cpus] = cpu; 1596 1595 sdp->num_cpus++; 1597 1596 } 1598 - socket = 0; 1599 - for_each_possible_blade(uvhub) { 1597 + uvhub = 0; 1598 + while (uvhub_mask) { 1599 + if (!(uvhub_mask & 1)) 1600 + goto nexthub; 1600 1601 bdp = &uvhub_descs[uvhub]; 1601 - for (i = 0; i < bdp->num_sockets; i++) { 1602 - sdp = &bdp->socket[i]; 1603 - for (j = 0; j < sdp->num_cpus; j++) { 1604 - cpu = sdp->cpu_number[j]; 1602 + socket_mask = bdp->socket_mask; 1603 + socket = 0; 1604 + while (socket_mask) { 1605 + if (!(socket_mask & 1)) 1606 + goto nextsocket; 1607 + sdp = &bdp->socket[socket]; 1608 + for (i = 0; i < sdp->num_cpus; i++) { 1609 + cpu = sdp->cpu_number[i]; 1605 1610 bcp = &per_cpu(bau_control, cpu); 1606 1611 bcp->cpu = cpu; 1607 - if (j == 0) { 1612 + if (i == 0) { 1608 1613 smaster = bcp; 1609 - if (i == 0) 1614 + if (socket == 0) 1610 1615 hmaster = bcp; 1611 1616 } 1612 1617 bcp->cpus_in_uvhub = bdp->num_cpus; 1613 1618 bcp->cpus_in_socket = sdp->num_cpus; 1614 1619 bcp->socket_master = smaster; 1620 + bcp->uvhub = bdp->uvhub; 1615 1621 bcp->uvhub_master = hmaster; 1616 - for (k = 0; k < DEST_Q_SIZE; k++) 1617 - bcp->socket_acknowledge_count[k] = 0; 1618 - bcp->uvhub_cpu = 1619 - uv_cpu_hub_info(cpu)->blade_processor_id; 1622 + bcp->uvhub_cpu = uv_cpu_hub_info(cpu)-> 1623 + blade_processor_id; 1620 1624 } 1625 + nextsocket: 1621 1626 socket++; 1627 + socket_mask = (socket_mask >> 1); 1622 1628 } 1629 + nexthub: 1630 + uvhub++; 1631 + uvhub_mask = (uvhub_mask >> 1); 1623 1632 } 1624 1633 kfree(uvhub_descs); 1625 1634 for_each_present_cpu(cpu) {