IB/mlx4: Optimize do_slave_init
[linux-2.6-microblaze.git] / drivers / infiniband / hw / mlx4 / main.c
index 067a691..8be6db8 100644 (file)
@@ -253,14 +253,15 @@ static int mlx4_ib_query_device(struct ib_device *ibdev,
        props->hca_core_clock = dev->dev->caps.hca_core_clock * 1000UL;
        props->timestamp_mask = 0xFFFFFFFFFFFFULL;
 
-       err = mlx4_get_internal_clock_params(dev->dev, &clock_params);
-       if (err)
-               goto out;
+       if (!mlx4_is_slave(dev->dev))
+               err = mlx4_get_internal_clock_params(dev->dev, &clock_params);
 
        if (uhw->outlen >= resp.response_length + sizeof(resp.hca_core_clock_offset)) {
-               resp.hca_core_clock_offset = clock_params.offset % PAGE_SIZE;
                resp.response_length += sizeof(resp.hca_core_clock_offset);
-               resp.comp_mask |= QUERY_DEVICE_RESP_MASK_TIMESTAMP;
+               if (!err && !mlx4_is_slave(dev->dev)) {
+                       resp.comp_mask |= QUERY_DEVICE_RESP_MASK_TIMESTAMP;
+                       resp.hca_core_clock_offset = clock_params.offset % PAGE_SIZE;
+               }
        }
 
        if (uhw->outlen) {
@@ -2669,31 +2670,33 @@ static void do_slave_init(struct mlx4_ib_dev *ibdev, int slave, int do_init)
        dm = kcalloc(ports, sizeof(*dm), GFP_ATOMIC);
        if (!dm) {
                pr_err("failed to allocate memory for tunneling qp update\n");
-               goto out;
+               return;
        }
 
        for (i = 0; i < ports; i++) {
                dm[i] = kmalloc(sizeof (struct mlx4_ib_demux_work), GFP_ATOMIC);
                if (!dm[i]) {
                        pr_err("failed to allocate memory for tunneling qp update work struct\n");
-                       for (i = 0; i < dev->caps.num_ports; i++) {
-                               if (dm[i])
-                                       kfree(dm[i]);
-                       }
+                       while (--i >= 0)
+                               kfree(dm[i]);
                        goto out;
                }
-       }
-       /* initialize or tear down tunnel QPs for the slave */
-       for (i = 0; i < ports; i++) {
                INIT_WORK(&dm[i]->work, mlx4_ib_tunnels_update_work);
                dm[i]->port = first_port + i + 1;
                dm[i]->slave = slave;
                dm[i]->do_init = do_init;
                dm[i]->dev = ibdev;
-               spin_lock_irqsave(&ibdev->sriov.going_down_lock, flags);
-               if (!ibdev->sriov.is_going_down)
+       }
+       /* initialize or tear down tunnel QPs for the slave */
+       spin_lock_irqsave(&ibdev->sriov.going_down_lock, flags);
+       if (!ibdev->sriov.is_going_down) {
+               for (i = 0; i < ports; i++)
                        queue_work(ibdev->sriov.demux[i].ud_wq, &dm[i]->work);
                spin_unlock_irqrestore(&ibdev->sriov.going_down_lock, flags);
+       } else {
+               spin_unlock_irqrestore(&ibdev->sriov.going_down_lock, flags);
+               for (i = 0; i < ports; i++)
+                       kfree(dm[i]);
        }
 out:
        kfree(dm);