Commit cfa60917 authored by Cliff Wickman's avatar Cliff Wickman Committed by Ingo Molnar

x86, UV, BAU: Extend for more than 16 cpus per socket

Fix a hard-coded limit of a maximum of 16 cpu's per socket.

The UV Broadcast Assist Unit code initializes by scanning the
cpu topology of the system and assigning a master cpu for each
socket and UV hub. That scan had an assumption of a limit of 16
cpus per socket. With Westmere we are going over that limit.
The UV hub hardware will allow up to 32.

If the scan finds the system has gone over that limit it returns
an error and we print a warning and fall back to doing TLB
shootdowns without the BAU.
Signed-off-by: default avatarCliff Wickman <cpw@sgi.com>
Cc: <stable@kernel.org> # .37.x
LKML-Reference: <E1PZol7-0000mM-77@eag09.americas.sgi.com>
Signed-off-by: default avatarIngo Molnar <mingo@elte.hu>
parent d8850ba4
...@@ -26,20 +26,22 @@ ...@@ -26,20 +26,22 @@
* BAU_SB_DESCRIPTOR_BASE register, set 1 is located at BASE + 512, * BAU_SB_DESCRIPTOR_BASE register, set 1 is located at BASE + 512,
* set 2 is at BASE + 2*512, set 3 at BASE + 3*512, and so on. * set 2 is at BASE + 2*512, set 3 at BASE + 3*512, and so on.
* *
* We will use 31 sets, one for sending BAU messages from each of the 32 * We will use one set for sending BAU messages from each of the
* cpu's on the uvhub. * cpu's on the uvhub.
* *
* TLB shootdown will use the first of the 8 descriptors of each set. * TLB shootdown will use the first of the 8 descriptors of each set.
* Each of the descriptors is 64 bytes in size (8*64 = 512 bytes in a set). * Each of the descriptors is 64 bytes in size (8*64 = 512 bytes in a set).
*/ */
#define MAX_CPUS_PER_UVHUB 64
#define MAX_CPUS_PER_SOCKET 32
#define UV_ADP_SIZE 64 /* hardware-provided max. */
#define UV_CPUS_PER_ACT_STATUS 32 /* hardware-provided max. */
#define UV_ITEMS_PER_DESCRIPTOR 8 #define UV_ITEMS_PER_DESCRIPTOR 8
/* the 'throttle' to prevent the hardware stay-busy bug */ /* the 'throttle' to prevent the hardware stay-busy bug */
#define MAX_BAU_CONCURRENT 3 #define MAX_BAU_CONCURRENT 3
#define UV_CPUS_PER_ACT_STATUS 32
#define UV_ACT_STATUS_MASK 0x3 #define UV_ACT_STATUS_MASK 0x3
#define UV_ACT_STATUS_SIZE 2 #define UV_ACT_STATUS_SIZE 2
#define UV_ADP_SIZE 32
#define UV_DISTRIBUTION_SIZE 256 #define UV_DISTRIBUTION_SIZE 256
#define UV_SW_ACK_NPENDING 8 #define UV_SW_ACK_NPENDING 8
#define UV_NET_ENDPOINT_INTD 0x38 #define UV_NET_ENDPOINT_INTD 0x38
...@@ -100,7 +102,6 @@ ...@@ -100,7 +102,6 @@
* number of destination side software ack resources * number of destination side software ack resources
*/ */
#define DEST_NUM_RESOURCES 8 #define DEST_NUM_RESOURCES 8
#define MAX_CPUS_PER_NODE 32
/* /*
* completion statuses for sending a TLB flush message * completion statuses for sending a TLB flush message
*/ */
......
...@@ -1341,7 +1341,7 @@ uv_activation_descriptor_init(int node, int pnode) ...@@ -1341,7 +1341,7 @@ uv_activation_descriptor_init(int node, int pnode)
/* /*
* each bau_desc is 64 bytes; there are 8 (UV_ITEMS_PER_DESCRIPTOR) * each bau_desc is 64 bytes; there are 8 (UV_ITEMS_PER_DESCRIPTOR)
* per cpu; and up to 32 (UV_ADP_SIZE) cpu's per uvhub * per cpu; and one per cpu on the uvhub (UV_ADP_SIZE)
*/ */
bau_desc = kmalloc_node(sizeof(struct bau_desc) * UV_ADP_SIZE bau_desc = kmalloc_node(sizeof(struct bau_desc) * UV_ADP_SIZE
* UV_ITEMS_PER_DESCRIPTOR, GFP_KERNEL, node); * UV_ITEMS_PER_DESCRIPTOR, GFP_KERNEL, node);
...@@ -1490,7 +1490,7 @@ calculate_destination_timeout(void) ...@@ -1490,7 +1490,7 @@ calculate_destination_timeout(void)
/* /*
* initialize the bau_control structure for each cpu * initialize the bau_control structure for each cpu
*/ */
static void __init uv_init_per_cpu(int nuvhubs) static int __init uv_init_per_cpu(int nuvhubs)
{ {
int i; int i;
int cpu; int cpu;
...@@ -1507,7 +1507,7 @@ static void __init uv_init_per_cpu(int nuvhubs) ...@@ -1507,7 +1507,7 @@ static void __init uv_init_per_cpu(int nuvhubs)
struct bau_control *smaster = NULL; struct bau_control *smaster = NULL;
struct socket_desc { struct socket_desc {
short num_cpus; short num_cpus;
short cpu_number[16]; short cpu_number[MAX_CPUS_PER_SOCKET];
}; };
struct uvhub_desc { struct uvhub_desc {
unsigned short socket_mask; unsigned short socket_mask;
...@@ -1540,6 +1540,10 @@ static void __init uv_init_per_cpu(int nuvhubs) ...@@ -1540,6 +1540,10 @@ static void __init uv_init_per_cpu(int nuvhubs)
sdp = &bdp->socket[socket]; sdp = &bdp->socket[socket];
sdp->cpu_number[sdp->num_cpus] = cpu; sdp->cpu_number[sdp->num_cpus] = cpu;
sdp->num_cpus++; sdp->num_cpus++;
if (sdp->num_cpus > MAX_CPUS_PER_SOCKET) {
printk(KERN_EMERG "%d cpus per socket invalid\n", sdp->num_cpus);
return 1;
}
} }
for (uvhub = 0; uvhub < nuvhubs; uvhub++) { for (uvhub = 0; uvhub < nuvhubs; uvhub++) {
if (!(*(uvhub_mask + (uvhub/8)) & (1 << (uvhub%8)))) if (!(*(uvhub_mask + (uvhub/8)) & (1 << (uvhub%8))))
...@@ -1570,6 +1574,12 @@ static void __init uv_init_per_cpu(int nuvhubs) ...@@ -1570,6 +1574,12 @@ static void __init uv_init_per_cpu(int nuvhubs)
bcp->uvhub_master = hmaster; bcp->uvhub_master = hmaster;
bcp->uvhub_cpu = uv_cpu_hub_info(cpu)-> bcp->uvhub_cpu = uv_cpu_hub_info(cpu)->
blade_processor_id; blade_processor_id;
if (bcp->uvhub_cpu >= MAX_CPUS_PER_UVHUB) {
printk(KERN_EMERG
"%d cpus per uvhub invalid\n",
bcp->uvhub_cpu);
return 1;
}
} }
nextsocket: nextsocket:
socket++; socket++;
...@@ -1595,6 +1605,7 @@ static void __init uv_init_per_cpu(int nuvhubs) ...@@ -1595,6 +1605,7 @@ static void __init uv_init_per_cpu(int nuvhubs)
bcp->congested_reps = congested_reps; bcp->congested_reps = congested_reps;
bcp->congested_period = congested_period; bcp->congested_period = congested_period;
} }
return 0;
} }
/* /*
...@@ -1625,7 +1636,10 @@ static int __init uv_bau_init(void) ...@@ -1625,7 +1636,10 @@ static int __init uv_bau_init(void)
spin_lock_init(&disable_lock); spin_lock_init(&disable_lock);
congested_cycles = microsec_2_cycles(congested_response_us); congested_cycles = microsec_2_cycles(congested_response_us);
uv_init_per_cpu(nuvhubs); if (uv_init_per_cpu(nuvhubs)) {
nobau = 1;
return 0;
}
uv_partition_base_pnode = 0x7fffffff; uv_partition_base_pnode = 0x7fffffff;
for (uvhub = 0; uvhub < nuvhubs; uvhub++) for (uvhub = 0; uvhub < nuvhubs; uvhub++)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment