aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86
diff options
context:
space:
mode:
authorCliff Wickman <cpw@sgi.com>2010-06-02 17:22:02 -0400
committerIngo Molnar <mingo@elte.hu>2010-06-08 15:13:46 -0400
commita8328ee58c15c9d763a67607a35bb987b38950fa (patch)
tree30fd2f8ef13eb8fbc72209237d366b2cddb4f1ca /arch/x86
parent39847e7f3c8198b14102fe7ba4b3a6a1d84bbcfe (diff)
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>
Diffstat (limited to 'arch/x86')
-rw-r--r--arch/x86/kernel/tlb_uv.c49
1 files changed, 31 insertions, 18 deletions
diff --git a/arch/x86/kernel/tlb_uv.c b/arch/x86/kernel/tlb_uv.c
index 295a41122da1..ab929e976502 100644
--- a/arch/x86/kernel/tlb_uv.c
+++ b/arch/x86/kernel/tlb_uv.c
@@ -1547,11 +1547,13 @@ calculate_destination_timeout(void)
1547 */ 1547 */
1548static void uv_init_per_cpu(int nuvhubs) 1548static void uv_init_per_cpu(int nuvhubs)
1549{ 1549{
1550 int i, j, k; 1550 int i;
1551 int cpu; 1551 int cpu;
1552 int pnode; 1552 int pnode;
1553 int uvhub; 1553 int uvhub;
1554 short socket = 0; 1554 short socket = 0;
1555 unsigned short socket_mask;
1556 unsigned int uvhub_mask;
1555 struct bau_control *bcp; 1557 struct bau_control *bcp;
1556 struct uvhub_desc *bdp; 1558 struct uvhub_desc *bdp;
1557 struct socket_desc *sdp; 1559 struct socket_desc *sdp;
@@ -1562,7 +1564,7 @@ static void uv_init_per_cpu(int nuvhubs)
1562 short cpu_number[16]; 1564 short cpu_number[16];
1563 }; 1565 };
1564 struct uvhub_desc { 1566 struct uvhub_desc {
1565 short num_sockets; 1567 unsigned short socket_mask;
1566 short num_cpus; 1568 short num_cpus;
1567 short uvhub; 1569 short uvhub;
1568 short pnode; 1570 short pnode;
@@ -1581,43 +1583,54 @@ static void uv_init_per_cpu(int nuvhubs)
1581 spin_lock_init(&bcp->masks_lock); 1583 spin_lock_init(&bcp->masks_lock);
1582 pnode = uv_cpu_hub_info(cpu)->pnode; 1584 pnode = uv_cpu_hub_info(cpu)->pnode;
1583 uvhub = uv_cpu_hub_info(cpu)->numa_blade_id; 1585 uvhub = uv_cpu_hub_info(cpu)->numa_blade_id;
1586 uvhub_mask |= (1 << uvhub);
1584 bdp = &uvhub_descs[uvhub]; 1587 bdp = &uvhub_descs[uvhub];
1585 bdp->num_cpus++; 1588 bdp->num_cpus++;
1586 bdp->uvhub = uvhub; 1589 bdp->uvhub = uvhub;
1587 bdp->pnode = pnode; 1590 bdp->pnode = pnode;
1588 /* kludge: assume uv_hub.h is constant */ 1591 /* kludge: 'assuming' one node per socket, and assuming that
1589 socket = (cpu_physical_id(cpu)>>5)&1; 1592 disabling a socket just leaves a gap in node numbers */
1590 if (socket >= bdp->num_sockets) 1593 socket = (cpu_to_node(cpu) & 1);;
1591 bdp->num_sockets = socket+1; 1594 bdp->socket_mask |= (1 << socket);
1592 sdp = &bdp->socket[socket]; 1595 sdp = &bdp->socket[socket];
1593 sdp->cpu_number[sdp->num_cpus] = cpu; 1596 sdp->cpu_number[sdp->num_cpus] = cpu;
1594 sdp->num_cpus++; 1597 sdp->num_cpus++;
1595 } 1598 }
1596 socket = 0; 1599 uvhub = 0;
1597 for_each_possible_blade(uvhub) { 1600 while (uvhub_mask) {
1601 if (!(uvhub_mask & 1))
1602 goto nexthub;
1598 bdp = &uvhub_descs[uvhub]; 1603 bdp = &uvhub_descs[uvhub];
1599 for (i = 0; i < bdp->num_sockets; i++) { 1604 socket_mask = bdp->socket_mask;
1600 sdp = &bdp->socket[i]; 1605 socket = 0;
1601 for (j = 0; j < sdp->num_cpus; j++) { 1606 while (socket_mask) {
1602 cpu = sdp->cpu_number[j]; 1607 if (!(socket_mask & 1))
1608 goto nextsocket;
1609 sdp = &bdp->socket[socket];
1610 for (i = 0; i < sdp->num_cpus; i++) {
1611 cpu = sdp->cpu_number[i];
1603 bcp = &per_cpu(bau_control, cpu); 1612 bcp = &per_cpu(bau_control, cpu);
1604 bcp->cpu = cpu; 1613 bcp->cpu = cpu;
1605 if (j == 0) { 1614 if (i == 0) {
1606 smaster = bcp; 1615 smaster = bcp;
1607 if (i == 0) 1616 if (socket == 0)
1608 hmaster = bcp; 1617 hmaster = bcp;
1609 } 1618 }
1610 bcp->cpus_in_uvhub = bdp->num_cpus; 1619 bcp->cpus_in_uvhub = bdp->num_cpus;
1611 bcp->cpus_in_socket = sdp->num_cpus; 1620 bcp->cpus_in_socket = sdp->num_cpus;
1612 bcp->socket_master = smaster; 1621 bcp->socket_master = smaster;
1622 bcp->uvhub = bdp->uvhub;
1613 bcp->uvhub_master = hmaster; 1623 bcp->uvhub_master = hmaster;
1614 for (k = 0; k < DEST_Q_SIZE; k++) 1624 bcp->uvhub_cpu = uv_cpu_hub_info(cpu)->
1615 bcp->socket_acknowledge_count[k] = 0; 1625 blade_processor_id;
1616 bcp->uvhub_cpu =
1617 uv_cpu_hub_info(cpu)->blade_processor_id;
1618 } 1626 }
1627nextsocket:
1619 socket++; 1628 socket++;
1629 socket_mask = (socket_mask >> 1);
1620 } 1630 }
1631nexthub:
1632 uvhub++;
1633 uvhub_mask = (uvhub_mask >> 1);
1621 } 1634 }
1622 kfree(uvhub_descs); 1635 kfree(uvhub_descs);
1623 for_each_present_cpu(cpu) { 1636 for_each_present_cpu(cpu) {