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 */ 1548 static void uv_init_per_cpu(int nuvhubs) 1549 { 1550 - int i, j, k; 1551 int cpu; 1552 int pnode; 1553 int uvhub; 1554 short socket = 0; 1555 struct bau_control *bcp; 1556 struct uvhub_desc *bdp; 1557 struct socket_desc *sdp; ··· 1564 short cpu_number[16]; 1565 }; 1566 struct uvhub_desc { 1567 - short num_sockets; 1568 short num_cpus; 1569 short uvhub; 1570 short pnode; ··· 1583 spin_lock_init(&bcp->masks_lock); 1584 pnode = uv_cpu_hub_info(cpu)->pnode; 1585 uvhub = uv_cpu_hub_info(cpu)->numa_blade_id; 1586 bdp = &uvhub_descs[uvhub]; 1587 bdp->num_cpus++; 1588 bdp->uvhub = uvhub; 1589 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; 1594 sdp = &bdp->socket[socket]; 1595 sdp->cpu_number[sdp->num_cpus] = cpu; 1596 sdp->num_cpus++; 1597 } 1598 - socket = 0; 1599 - for_each_possible_blade(uvhub) { 1600 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]; 1605 bcp = &per_cpu(bau_control, cpu); 1606 bcp->cpu = cpu; 1607 - if (j == 0) { 1608 smaster = bcp; 1609 - if (i == 0) 1610 hmaster = bcp; 1611 } 1612 bcp->cpus_in_uvhub = bdp->num_cpus; 1613 bcp->cpus_in_socket = sdp->num_cpus; 1614 bcp->socket_master = smaster; 1615 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; 1620 } 1621 socket++; 1622 } 1623 } 1624 kfree(uvhub_descs); 1625 for_each_present_cpu(cpu) {
··· 1547 */ 1548 static void uv_init_per_cpu(int nuvhubs) 1549 { 1550 + int i; 1551 int cpu; 1552 int pnode; 1553 int uvhub; 1554 short socket = 0; 1555 + unsigned short socket_mask; 1556 + unsigned int uvhub_mask; 1557 struct bau_control *bcp; 1558 struct uvhub_desc *bdp; 1559 struct socket_desc *sdp; ··· 1562 short cpu_number[16]; 1563 }; 1564 struct uvhub_desc { 1565 + unsigned short socket_mask; 1566 short num_cpus; 1567 short uvhub; 1568 short pnode; ··· 1581 spin_lock_init(&bcp->masks_lock); 1582 pnode = uv_cpu_hub_info(cpu)->pnode; 1583 uvhub = uv_cpu_hub_info(cpu)->numa_blade_id; 1584 + uvhub_mask |= (1 << uvhub); 1585 bdp = &uvhub_descs[uvhub]; 1586 bdp->num_cpus++; 1587 bdp->uvhub = uvhub; 1588 bdp->pnode = pnode; 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); 1593 sdp = &bdp->socket[socket]; 1594 sdp->cpu_number[sdp->num_cpus] = cpu; 1595 sdp->num_cpus++; 1596 } 1597 + uvhub = 0; 1598 + while (uvhub_mask) { 1599 + if (!(uvhub_mask & 1)) 1600 + goto nexthub; 1601 bdp = &uvhub_descs[uvhub]; 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]; 1610 bcp = &per_cpu(bau_control, cpu); 1611 bcp->cpu = cpu; 1612 + if (i == 0) { 1613 smaster = bcp; 1614 + if (socket == 0) 1615 hmaster = bcp; 1616 } 1617 bcp->cpus_in_uvhub = bdp->num_cpus; 1618 bcp->cpus_in_socket = sdp->num_cpus; 1619 bcp->socket_master = smaster; 1620 + bcp->uvhub = bdp->uvhub; 1621 bcp->uvhub_master = hmaster; 1622 + bcp->uvhub_cpu = uv_cpu_hub_info(cpu)-> 1623 + blade_processor_id; 1624 } 1625 + nextsocket: 1626 socket++; 1627 + socket_mask = (socket_mask >> 1); 1628 } 1629 + nexthub: 1630 + uvhub++; 1631 + uvhub_mask = (uvhub_mask >> 1); 1632 } 1633 kfree(uvhub_descs); 1634 for_each_present_cpu(cpu) {