1 From 7838f994b4fceff24c343f4e26a6cf4393869579 Mon Sep 17 00:00:00 2001
2 From: Robin Holt <holt@sgi.com>
3 Date: Tue, 21 Aug 2012 16:16:02 -0700
4 Subject: drivers/misc/sgi-xp/xpc_uv.c: SGI XPC fails to load when cpu 0 is out of IRQ resources
6 From: Robin Holt <holt@sgi.com>
8 commit 7838f994b4fceff24c343f4e26a6cf4393869579 upstream.
10 On many of our larger systems, CPU 0 has had all of its IRQ resources
11 consumed before XPC loads. Worst cases on machines with multiple 10
12 GigE cards and multiple IB cards have depleted the entire first socket
15 This patch makes selecting the node upon which IRQs are allocated (as
16 well as all the other GRU Message Queue structures) specifiable as a
17 module load param and has a default behavior of searching all nodes/cpus
18 for an available resources.
20 [akpm@linux-foundation.org: fix build: include cpu.h and module.h]
21 Signed-off-by: Robin Holt <holt@sgi.com>
22 Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
23 Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
24 Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
27 drivers/misc/sgi-xp/xpc_uv.c | 84 +++++++++++++++++++++++++++++++++----------
28 1 file changed, 65 insertions(+), 19 deletions(-)
30 --- a/drivers/misc/sgi-xp/xpc_uv.c
31 +++ b/drivers/misc/sgi-xp/xpc_uv.c
33 #include <linux/interrupt.h>
34 #include <linux/delay.h>
35 #include <linux/device.h>
36 +#include <linux/cpu.h>
37 +#include <linux/module.h>
38 #include <linux/err.h>
39 #include <linux/slab.h>
40 #include <asm/uv/uv_hub.h>
41 @@ -59,6 +61,8 @@ static struct xpc_heartbeat_uv *xpc_hear
42 XPC_NOTIFY_MSG_SIZE_UV)
43 #define XPC_NOTIFY_IRQ_NAME "xpc_notify"
45 +static int xpc_mq_node = -1;
47 static struct xpc_gru_mq_uv *xpc_activate_mq_uv;
48 static struct xpc_gru_mq_uv *xpc_notify_mq_uv;
50 @@ -109,11 +113,8 @@ xpc_get_gru_mq_irq_uv(struct xpc_gru_mq_
51 #if defined CONFIG_X86_64
52 mq->irq = uv_setup_irq(irq_name, cpu, mq->mmr_blade, mq->mmr_offset,
55 - dev_err(xpc_part, "uv_setup_irq() returned error=%d\n",
61 mq->mmr_value = uv_read_global_mmr64(mmr_pnode, mq->mmr_offset);
63 @@ -238,8 +239,9 @@ xpc_create_gru_mq_uv(unsigned int mq_siz
64 mq->mmr_blade = uv_cpu_to_blade_id(cpu);
66 nid = cpu_to_node(cpu);
67 - page = alloc_pages_exact_node(nid, GFP_KERNEL | __GFP_ZERO | GFP_THISNODE,
69 + page = alloc_pages_exact_node(nid,
70 + GFP_KERNEL | __GFP_ZERO | GFP_THISNODE,
73 dev_err(xpc_part, "xpc_create_gru_mq_uv() failed to alloc %d "
74 "bytes of memory on nid=%d for GRU mq\n", mq_size, nid);
75 @@ -1731,9 +1733,50 @@ static struct xpc_arch_operations xpc_ar
76 .notify_senders_of_disconnect = xpc_notify_senders_of_disconnect_uv,
80 +xpc_init_mq_node(int nid)
86 + for_each_cpu(cpu, cpumask_of_node(nid)) {
87 + xpc_activate_mq_uv =
88 + xpc_create_gru_mq_uv(XPC_ACTIVATE_MQ_SIZE_UV, nid,
89 + XPC_ACTIVATE_IRQ_NAME,
90 + xpc_handle_activate_IRQ_uv);
91 + if (!IS_ERR(xpc_activate_mq_uv))
94 + if (IS_ERR(xpc_activate_mq_uv)) {
96 + return PTR_ERR(xpc_activate_mq_uv);
99 + for_each_cpu(cpu, cpumask_of_node(nid)) {
101 + xpc_create_gru_mq_uv(XPC_NOTIFY_MQ_SIZE_UV, nid,
102 + XPC_NOTIFY_IRQ_NAME,
103 + xpc_handle_notify_IRQ_uv);
104 + if (!IS_ERR(xpc_notify_mq_uv))
107 + if (IS_ERR(xpc_notify_mq_uv)) {
108 + xpc_destroy_gru_mq_uv(xpc_activate_mq_uv);
110 + return PTR_ERR(xpc_notify_mq_uv);
123 xpc_arch_ops = xpc_arch_ops_uv;
125 if (sizeof(struct xpc_notify_mq_msghdr_uv) > XPC_MSG_HDR_MAX_SIZE) {
126 @@ -1742,21 +1785,21 @@ xpc_init_uv(void)
130 - xpc_activate_mq_uv = xpc_create_gru_mq_uv(XPC_ACTIVATE_MQ_SIZE_UV, 0,
131 - XPC_ACTIVATE_IRQ_NAME,
132 - xpc_handle_activate_IRQ_uv);
133 - if (IS_ERR(xpc_activate_mq_uv))
134 - return PTR_ERR(xpc_activate_mq_uv);
135 + if (xpc_mq_node < 0)
136 + for_each_online_node(nid) {
137 + ret = xpc_init_mq_node(nid);
139 - xpc_notify_mq_uv = xpc_create_gru_mq_uv(XPC_NOTIFY_MQ_SIZE_UV, 0,
140 - XPC_NOTIFY_IRQ_NAME,
141 - xpc_handle_notify_IRQ_uv);
142 - if (IS_ERR(xpc_notify_mq_uv)) {
143 - xpc_destroy_gru_mq_uv(xpc_activate_mq_uv);
144 - return PTR_ERR(xpc_notify_mq_uv);
150 + ret = xpc_init_mq_node(xpc_mq_node);
154 + dev_err(xpc_part, "xpc_init_mq_node() returned error=%d\n",
161 @@ -1765,3 +1808,6 @@ xpc_exit_uv(void)
162 xpc_destroy_gru_mq_uv(xpc_notify_mq_uv);
163 xpc_destroy_gru_mq_uv(xpc_activate_mq_uv);
166 +module_param(xpc_mq_node, int, 0);
167 +MODULE_PARM_DESC(xpc_mq_node, "Node number on which to allocate message queues.");