]> www.infradead.org Git - users/jedix/linux-maple.git/commitdiff
IB/mlx4: Scatter CQs to different EQs
authorMajd Dibbiny <majd@mellanox.com>
Mon, 19 Sep 2016 15:32:22 +0000 (18:32 +0300)
committerSantosh Shilimkar <santosh.shilimkar@oracle.com>
Mon, 24 Oct 2016 16:02:46 +0000 (09:02 -0700)
If the user does not request a specific comp vector, use a weight based
algorithm to set the EQ.

Orabug: 24705943

Signed-off-by: Majd Dibbiny <majd@mellanox.com>
Signed-off-by: Santosh Shilimkar <santosh.shilimkar@oracle.com>
drivers/infiniband/hw/mlx4/cq.c
drivers/infiniband/hw/mlx4/mlx4_ib.h
drivers/net/ethernet/mellanox/mlx4/eq.c
drivers/net/ethernet/mellanox/mlx4/mlx4.h
include/linux/mlx4/device.h
include/linux/mlx4/driver.h

index 50418728e6798e6fa93a37b39b8ec7309cea7f4e..e10fa915fb9fdf2cd13005ce3b9ee0d6a4f0ba7e 100644 (file)
@@ -231,8 +231,12 @@ struct ib_cq *mlx4_ib_create_cq(struct ib_device *ibdev, int entries, int vector
                uar = &dev->priv_uar;
        }
 
-       if (dev->eq_table)
-               vector = dev->eq_table[vector % ibdev->num_comp_vectors];
+       if (dev->eq_table) {
+               vector = dev->eq_table[mlx4_choose_vector(dev->dev, vector,
+                                                         ibdev->num_comp_vectors)];
+       }
+
+       cq->vector = vector;
 
        err = mlx4_cq_alloc(dev->dev, entries, &cq->buf.mtt, uar,
                            cq->db.dma, &cq->mcq, vector, 0, 0);
@@ -254,6 +258,8 @@ struct ib_cq *mlx4_ib_create_cq(struct ib_device *ibdev, int entries, int vector
        return &cq->ibcq;
 
 err_dbmap:
+       mlx4_release_vector(dev->dev, cq->vector);
+
        if (context)
                mlx4_ib_db_unmap_user(to_mucontext(context), &cq->db);
 
@@ -481,6 +487,8 @@ int mlx4_ib_destroy_cq(struct ib_cq *cq)
                mlx4_db_free(dev->dev, &mcq->db);
        }
 
+       mlx4_release_vector(dev->dev, mcq->vector);
+
        kfree(mcq);
 
        return 0;
index 31ea8862c2b06bfcdfbfa7330fcf1837360d3895..5c50b4bbe0875946ff62b7a2324d5628a90a5f8b 100644 (file)
@@ -46,6 +46,7 @@
 
 #include <linux/mlx4/device.h>
 #include <linux/mlx4/doorbell.h>
+#include <linux/mlx4/driver.h>
 
 #define MLX4_IB_DRV_NAME       "mlx4_ib"
 
@@ -121,6 +122,7 @@ struct mlx4_ib_cq {
        /* List of qps that it serves.*/
        struct list_head                send_qp_list;
        struct list_head                recv_qp_list;
+       int                     vector;
 };
 
 struct mlx4_ib_mr {
index fba236ee1059971bf9ebab87e3ecc5db42205aa0..f47eb06df9ce75bf46a224a8f3759b78402f0103 100644 (file)
@@ -1147,6 +1147,7 @@ int mlx4_init_eq_table(struct mlx4_dev *dev)
        int err;
        int i;
 
+       spin_lock_init(&dev->eq_accounting_lock);
        priv->eq_table.uar_map = kcalloc(mlx4_num_eq_uar(dev),
                                         sizeof *priv->eq_table.uar_map,
                                         GFP_KERNEL);
@@ -1447,3 +1448,36 @@ void mlx4_release_eq(struct mlx4_dev *dev, int vec)
 }
 EXPORT_SYMBOL(mlx4_release_eq);
 
+int mlx4_choose_vector(struct mlx4_dev *dev, int vector, int num_comp)
+{
+       struct mlx4_eq *chosen;
+       int k;
+
+       if (vector || smp_processor_id() == (vector % num_online_cpus())) {
+               spin_lock(&dev->eq_accounting_lock);
+               mlx4_priv(dev)->eq_table.eq[vector].ncqs++;
+               spin_unlock(&dev->eq_accounting_lock);
+       } else {
+               spin_lock(&dev->eq_accounting_lock);
+               chosen = &mlx4_priv(dev)->eq_table.eq[0];
+               for (k = 0; k < num_comp; k++) {
+                       if (mlx4_priv(dev)->eq_table.eq[k].ncqs < chosen->ncqs) {
+                               chosen = &mlx4_priv(dev)->eq_table.eq[k];
+                               vector = k;
+                       }
+               }
+               chosen->ncqs++;
+               spin_unlock(&dev->eq_accounting_lock);
+       }
+
+       return vector;
+}
+EXPORT_SYMBOL(mlx4_choose_vector);
+
+void mlx4_release_vector(struct mlx4_dev *dev, int vector)
+{
+       spin_lock(&dev->eq_accounting_lock);
+       mlx4_priv(dev)->eq_table.eq[vector].ncqs--;
+       spin_unlock(&dev->eq_accounting_lock);
+}
+EXPORT_SYMBOL(mlx4_release_vector);
index 7370460bebc7da8a4197d3ae136e5a711a5153e8..9cc1a8cee0fd694a9ff079b9badbcff810699a29 100644 (file)
@@ -391,6 +391,7 @@ struct mlx4_eq {
        struct mlx4_buf_list   *page_list;
        struct mlx4_mtt         mtt;
        struct mlx4_eq_tasklet  tasklet_ctx;
+       u32                     ncqs;
 };
 
 struct mlx4_slave_eqe {
index a2d538fff462fad67d5e2f4b16a1f92f6f843b18..76f276ed676a1a713a4e30f74a986e4999d317a5 100644 (file)
@@ -832,6 +832,7 @@ struct mlx4_dev {
        u64                     regid_promisc_array[MLX4_MAX_PORTS + 1];
        u64                     regid_allmulti_array[MLX4_MAX_PORTS + 1];
        struct mlx4_vf_dev     *dev_vfs;
+       spinlock_t              eq_accounting_lock;
 };
 
 struct mlx4_eqe {
index 9553a73d2049e425bc72bf4fbb7c151ffc9bbe43..c6cd046fd5ddcaf651c2770df533340bdffd7ad4 100644 (file)
@@ -95,4 +95,7 @@ static inline u64 mlx4_mac_to_u64(u8 *addr)
        return mac;
 }
 
+int mlx4_choose_vector(struct mlx4_dev *dev, int vector, int num_comp);
+void mlx4_release_vector(struct mlx4_dev *dev, int vector);
+
 #endif /* MLX4_DRIVER_H */