According to Peter, Thomas, Joe and David's advices, try fixing all memory 
allocation 
failure handling in tlb_uv.c

compiled in x86_64
Signed-off-by: Zhouyi Zhou <yizhouz...@ict.ac.cn>
---
 arch/x86/platform/uv/tlb_uv.c |  122 +++++++++++++++++++++++++++++------------
 1 file changed, 87 insertions(+), 35 deletions(-)

diff --git a/arch/x86/platform/uv/tlb_uv.c b/arch/x86/platform/uv/tlb_uv.c
index dfe605a..1a45dfa 100644
--- a/arch/x86/platform/uv/tlb_uv.c
+++ b/arch/x86/platform/uv/tlb_uv.c
@@ -1680,7 +1680,7 @@ static int __init uv_ptc_init(void)
 /*
  * Initialize the sending side's sending buffers.
  */
-static void activation_descriptor_init(int node, int pnode, int base_pnode)
+static int activation_descriptor_init(int node, int pnode, int base_pnode)
 {
        int i;
        int cpu;
@@ -1701,7 +1701,9 @@ static void activation_descriptor_init(int node, int 
pnode, int base_pnode)
         */
        dsize = sizeof(struct bau_desc) * ADP_SZ * ITEMS_PER_DESC;
        bau_desc = kmalloc_node(dsize, GFP_KERNEL, node);
-       BUG_ON(!bau_desc);
+       if (!bau_desc)
+               return -ENOMEM;
+
 
        gpa = uv_gpa(bau_desc);
        n = uv_gpa_to_gnode(gpa);
@@ -1756,6 +1758,8 @@ static void activation_descriptor_init(int node, int 
pnode, int base_pnode)
                bcp = &per_cpu(bau_control, cpu);
                bcp->descriptor_base = bau_desc;
        }
+
+       return 0;
 }
 
 /*
@@ -1764,7 +1768,7 @@ static void activation_descriptor_init(int node, int 
pnode, int base_pnode)
  * - node is first node (kernel memory notion) on the uvhub
  * - pnode is the uvhub's physical identifier
  */
-static void pq_init(int node, int pnode)
+static int pq_init(int node, int pnode)
 {
        int cpu;
        size_t plsize;
@@ -1776,12 +1780,16 @@ static void pq_init(int node, int pnode)
        unsigned long last;
        struct bau_pq_entry *pqp;
        struct bau_control *bcp;
+       int ret = 0;
 
        plsize = (DEST_Q_SIZE + 1) * sizeof(struct bau_pq_entry);
        vp = kmalloc_node(plsize, GFP_KERNEL, node);
-       pqp = (struct bau_pq_entry *)vp;
-       BUG_ON(!pqp);
+       if (!vp) {
+               ret =  -ENOMEM;
+               goto fail;
+       }
 
+       pqp = (struct bau_pq_entry *)vp;
        cp = (char *)pqp + 31;
        pqp = (struct bau_pq_entry *)(((unsigned long)cp >> 5) << 5);
 
@@ -1808,29 +1816,40 @@ static void pq_init(int node, int pnode)
 
        /* in effect, all msg_type's are set to MSG_NOOP */
        memset(pqp, 0, sizeof(struct bau_pq_entry) * DEST_Q_SIZE);
+
+       return 0;
+fail:
+       return ret;
 }
 
 /*
  * Initialization of each UV hub's structures
  */
-static void __init init_uvhub(int uvhub, int vector, int base_pnode)
+static int __init init_uvhub(int uvhub, int vector, int base_pnode)
 {
        int node;
        int pnode;
        unsigned long apicid;
+       int ret;
 
        node = uvhub_to_first_node(uvhub);
        pnode = uv_blade_to_pnode(uvhub);
 
-       activation_descriptor_init(node, pnode, base_pnode);
+       ret = activation_descriptor_init(node, pnode, base_pnode);
+       if (ret)
+               return ret;
 
-       pq_init(node, pnode);
+       ret = pq_init(node, pnode);
+       if (ret)
+               return ret;
        /*
         * The below initialization can't be in firmware because the
         * messaging IRQ will be determined by the OS.
         */
        apicid = uvhub_to_first_apicid(uvhub) | uv_apicid_hibits;
        write_mmr_data_config(pnode, ((apicid << 32) | vector));
+
+       return 0;
 }
 
 /*
@@ -1926,7 +1945,7 @@ static int __init get_cpu_topology(int base_pnode,
                        printk(KERN_EMERG
                                "cpu %d pnode %d-%d beyond %d; BAU disabled\n",
                                cpu, pnode, base_pnode, UV_DISTRIBUTION_SIZE);
-                       return 1;
+                       return -EINVAL;
                }
 
                bcp->osnode = cpu_to_node(cpu);
@@ -1950,7 +1969,7 @@ static int __init get_cpu_topology(int base_pnode,
                if (sdp->num_cpus > MAX_CPUS_PER_SOCKET) {
                        printk(KERN_EMERG "%d cpus per socket invalid\n",
                                sdp->num_cpus);
-                       return 1;
+                       return -EINVAL;
                }
        }
        return 0;
@@ -1959,29 +1978,29 @@ static int __init get_cpu_topology(int base_pnode,
 /*
  * Each socket is to get a local array of pnodes/hubs.
  */
-static void make_per_cpu_thp(struct bau_control *smaster)
+static int make_per_cpu_thp(struct bau_control *smaster)
 {
        int cpu;
        size_t hpsz = sizeof(struct hub_and_pnode) * num_possible_cpus();
-
+       int ret;
        smaster->thp = kmalloc_node(hpsz, GFP_KERNEL, smaster->osnode);
+       if (!smaster->thp) {
+               ret = -ENOMEM;
+               goto fail;
+       }
+
        memset(smaster->thp, 0, hpsz);
        for_each_present_cpu(cpu) {
                smaster->thp[cpu].pnode = uv_cpu_hub_info(cpu)->pnode;
                smaster->thp[cpu].uvhub = uv_cpu_hub_info(cpu)->numa_blade_id;
        }
-}
-
-/*
- * Each uvhub is to get a local cpumask.
- */
-static void make_per_hub_cpumask(struct bau_control *hmaster)
-{
-       int sz = sizeof(cpumask_t);
 
-       hmaster->cpumask = kzalloc_node(sz, GFP_KERNEL, hmaster->osnode);
+       return 0;
+fail:
+       return ret;
 }
 
+
 /*
  * Initialize all the per_cpu information for the cpu's on a given socket,
  * given what has been gathered into the socket_desc struct.
@@ -2014,14 +2033,14 @@ static int scan_sock(struct socket_desc *sdp, struct 
uvhub_desc *bdp,
                        bcp->uvhub_version = 2;
                else {
                        printk(KERN_EMERG "uvhub version not 1 or 2\n");
-                       return 1;
+                       return -EINVAL;
                }
                bcp->uvhub_master = *hmasterp;
                bcp->uvhub_cpu = uv_cpu_hub_info(cpu)->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;
+                       return -EINVAL;
                }
        }
        return 0;
@@ -2037,6 +2056,7 @@ static int __init summarize_uvhub_sockets(int nuvhubs,
        int socket;
        int uvhub;
        unsigned short socket_mask;
+       int ret = 0;
 
        for (uvhub = 0; uvhub < nuvhubs; uvhub++) {
                struct uvhub_desc *bdp;
@@ -2053,16 +2073,30 @@ static int __init summarize_uvhub_sockets(int nuvhubs,
                        struct socket_desc *sdp;
                        if ((socket_mask & 1)) {
                                sdp = &bdp->socket[socket];
-                               if (scan_sock(sdp, bdp, &smaster, &hmaster))
-                                       return 1;
-                               make_per_cpu_thp(smaster);
+                               ret = scan_sock(sdp, bdp, &smaster, &hmaster);
+                               if (ret)
+                                       goto fail;
+                               ret = make_per_cpu_thp(smaster);
+                               if (ret)
+                                       goto fail;
                        }
                        socket++;
                        socket_mask = (socket_mask >> 1);
                }
-               make_per_hub_cpumask(hmaster);
+/*
+ * Each uvhub is to get a local cpumask.
+ */
+               hmaster->cpumask = kzalloc_node(
+                       sizeof(cpumask_t), GFP_KERNEL, hmaster->osnode);
+               if (!hmaster->cpumask) {
+                       ret = -ENOMEM;
+                       goto fail;
+               }
        }
        return 0;
+
+fail:
+       return ret;
 }
 
 /*
@@ -2073,15 +2107,25 @@ static int __init init_per_cpu(int nuvhubs, int 
base_part_pnode)
        unsigned char *uvhub_mask;
        void *vp;
        struct uvhub_desc *uvhub_descs;
+       int ret = 0;
 
        timeout_us = calculate_destination_timeout();
 
-       vp = kmalloc(nuvhubs * sizeof(struct uvhub_desc), GFP_KERNEL);
+       vp = kcalloc(nuvhubs, sizeof(struct uvhub_desc), GFP_KERNEL);
+       if (!vp) {
+               ret = -ENOMEM;
+               goto fail_descs;
+       }
        uvhub_descs = (struct uvhub_desc *)vp;
-       memset(uvhub_descs, 0, nuvhubs * sizeof(struct uvhub_desc));
+
        uvhub_mask = kzalloc((nuvhubs+7)/8, GFP_KERNEL);
+       if (!uvhub_mask) {
+               ret = -ENOMEM;
+               goto fail_mask;
+       }
 
-       if (get_cpu_topology(base_part_pnode, uvhub_descs, uvhub_mask))
+       ret = get_cpu_topology(base_part_pnode, uvhub_descs, uvhub_mask);
+       if (ret)
                goto fail;
 
        if (summarize_uvhub_sockets(nuvhubs, uvhub_descs, uvhub_mask))
@@ -2093,9 +2137,11 @@ static int __init init_per_cpu(int nuvhubs, int 
base_part_pnode)
        return 0;
 
 fail:
-       kfree(uvhub_descs);
        kfree(uvhub_mask);
-       return 1;
+fail_mask:
+       kfree(uvhub_descs);
+fail_descs:
+       return ret;
 }
 
 /*
@@ -2110,13 +2156,16 @@ static int __init uv_bau_init(void)
        int cpus;
        int vector;
        cpumask_var_t *mask;
+       int ret;
 
        if (!is_uv_system())
                return 0;
 
        for_each_possible_cpu(cur_cpu) {
                mask = &per_cpu(uv_flush_tlb_mask, cur_cpu);
-               zalloc_cpumask_var_node(mask, GFP_KERNEL, cpu_to_node(cur_cpu));
+               if (!zalloc_cpumask_var_node(
+                           mask, GFP_KERNEL, cpu_to_node(cur_cpu)))
+                       return -ENOMEM;
        }
 
        nuvhubs = uv_num_possible_blades();
@@ -2139,8 +2188,11 @@ static int __init uv_bau_init(void)
 
        vector = UV_BAU_MESSAGE;
        for_each_possible_blade(uvhub)
-               if (uv_blade_nr_possible_cpus(uvhub))
-                       init_uvhub(uvhub, vector, uv_base_pnode);
+               if (uv_blade_nr_possible_cpus(uvhub)) {
+                       ret = init_uvhub(uvhub, vector, uv_base_pnode);
+                       if (ret)
+                               return ret;
+               }
 
        alloc_intr_gate(vector, uv_bau_message_intr1);
 
-- 
1.7.10.4

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Reply via email to