mlx5: move affinity hints assignments to generic code
authorSagi Grimberg <sagi@grimberg.me>
Thu, 13 Jul 2017 08:09:40 +0000 (11:09 +0300)
committerDoug Ledford <dledford@redhat.com>
Tue, 8 Aug 2017 18:55:56 +0000 (14:55 -0400)
generic api takes care of spreading affinity similar to
what mlx5 open coded (and even handles better asymmetric
configurations). Ask the generic API to spread affinity
for us, and feed him pre_vectors that do not participate
in affinity settings (which is an improvement to what we
had before).

The affinity assignments should match what mlx5 tried to
do earlier but now we do not set affinity to async, cmd
and pages dedicated vectors.

Also, remove mlx5e_get_cpu and introduce mlx5e_get_node
(used for allocation purposes) and mlx5_get_vector_affinity
(for indirection table construction) as they provide the needed
information. Luckily, we have generic helpers to get cpumask
and node given a irq vector. mlx5_get_vector_affinity will
be used by mlx5_ib in a subsequent patch.

Reviewed-by: Christoph Hellwig <hch@lst.de>
Acked-by: Leon Romanovsky <leonro@mellanox.com>
Signed-off-by: Sagi Grimberg <sagi@grimberg.me>
Signed-off-by: Doug Ledford <dledford@redhat.com>
drivers/net/ethernet/mellanox/mlx5/core/en.h
drivers/net/ethernet/mellanox/mlx5/core/en_main.c
drivers/net/ethernet/mellanox/mlx5/core/main.c
include/linux/mlx5/driver.h

index e1b7ddfecd011436c1520edc93eb30e8e15221d4..909123243a85fc1fc7456e680798d6a9aea77bd7 100644 (file)
@@ -587,7 +587,6 @@ struct mlx5e_channel {
        struct mlx5_core_dev      *mdev;
        struct mlx5e_tstamp       *tstamp;
        int                        ix;
-       int                        cpu;
 };
 
 struct mlx5e_channels {
index 2c4e41833e5512f481c61eeb1dd983959dbf88dd..fb647561c5924b771a5befba43881023a8105614 100644 (file)
@@ -71,6 +71,11 @@ struct mlx5e_channel_param {
        struct mlx5e_cq_param      icosq_cq;
 };
 
+static int mlx5e_get_node(struct mlx5e_priv *priv, int ix)
+{
+       return pci_irq_get_node(priv->mdev->pdev, MLX5_EQ_VEC_COMP_BASE + ix);
+}
+
 static bool mlx5e_check_fragmented_striding_rq_cap(struct mlx5_core_dev *mdev)
 {
        return MLX5_CAP_GEN(mdev, striding_rq) &&
@@ -444,16 +449,17 @@ static int mlx5e_rq_alloc_mpwqe_info(struct mlx5e_rq *rq,
        int wq_sz = mlx5_wq_ll_get_size(&rq->wq);
        int mtt_sz = mlx5e_get_wqe_mtt_sz();
        int mtt_alloc = mtt_sz + MLX5_UMR_ALIGN - 1;
+       int node = mlx5e_get_node(c->priv, c->ix);
        int i;
 
        rq->mpwqe.info = kzalloc_node(wq_sz * sizeof(*rq->mpwqe.info),
-                                     GFP_KERNEL, cpu_to_node(c->cpu));
+                                       GFP_KERNEL, node);
        if (!rq->mpwqe.info)
                goto err_out;
 
        /* We allocate more than mtt_sz as we will align the pointer */
-       rq->mpwqe.mtt_no_align = kzalloc_node(mtt_alloc * wq_sz, GFP_KERNEL,
-                                       cpu_to_node(c->cpu));
+       rq->mpwqe.mtt_no_align = kzalloc_node(mtt_alloc * wq_sz,
+                                       GFP_KERNEL, node);
        if (unlikely(!rq->mpwqe.mtt_no_align))
                goto err_free_wqe_info;
 
@@ -561,7 +567,7 @@ static int mlx5e_alloc_rq(struct mlx5e_channel *c,
        int err;
        int i;
 
-       rqp->wq.db_numa_node = cpu_to_node(c->cpu);
+       rqp->wq.db_numa_node = mlx5e_get_node(c->priv, c->ix);
 
        err = mlx5_wq_ll_create(mdev, &rqp->wq, rqc_wq, &rq->wq,
                                &rq->wq_ctrl);
@@ -628,7 +634,8 @@ static int mlx5e_alloc_rq(struct mlx5e_channel *c,
        default: /* MLX5_WQ_TYPE_LINKED_LIST */
                rq->wqe.frag_info =
                        kzalloc_node(wq_sz * sizeof(*rq->wqe.frag_info),
-                                    GFP_KERNEL, cpu_to_node(c->cpu));
+                                    GFP_KERNEL,
+                                    mlx5e_get_node(c->priv, c->ix));
                if (!rq->wqe.frag_info) {
                        err = -ENOMEM;
                        goto err_rq_wq_destroy;
@@ -993,13 +1000,13 @@ static int mlx5e_alloc_xdpsq(struct mlx5e_channel *c,
        sq->uar_map   = mdev->mlx5e_res.bfreg.map;
        sq->min_inline_mode = params->tx_min_inline_mode;
 
-       param->wq.db_numa_node = cpu_to_node(c->cpu);
+       param->wq.db_numa_node = mlx5e_get_node(c->priv, c->ix);
        err = mlx5_wq_cyc_create(mdev, &param->wq, sqc_wq, &sq->wq, &sq->wq_ctrl);
        if (err)
                return err;
        sq->wq.db = &sq->wq.db[MLX5_SND_DBR];
 
-       err = mlx5e_alloc_xdpsq_db(sq, cpu_to_node(c->cpu));
+       err = mlx5e_alloc_xdpsq_db(sq, mlx5e_get_node(c->priv, c->ix));
        if (err)
                goto err_sq_wq_destroy;
 
@@ -1047,13 +1054,13 @@ static int mlx5e_alloc_icosq(struct mlx5e_channel *c,
        sq->channel   = c;
        sq->uar_map   = mdev->mlx5e_res.bfreg.map;
 
-       param->wq.db_numa_node = cpu_to_node(c->cpu);
+       param->wq.db_numa_node = mlx5e_get_node(c->priv, c->ix);
        err = mlx5_wq_cyc_create(mdev, &param->wq, sqc_wq, &sq->wq, &sq->wq_ctrl);
        if (err)
                return err;
        sq->wq.db = &sq->wq.db[MLX5_SND_DBR];
 
-       err = mlx5e_alloc_icosq_db(sq, cpu_to_node(c->cpu));
+       err = mlx5e_alloc_icosq_db(sq, mlx5e_get_node(c->priv, c->ix));
        if (err)
                goto err_sq_wq_destroy;
 
@@ -1119,13 +1126,13 @@ static int mlx5e_alloc_txqsq(struct mlx5e_channel *c,
        if (MLX5_IPSEC_DEV(c->priv->mdev))
                set_bit(MLX5E_SQ_STATE_IPSEC, &sq->state);
 
-       param->wq.db_numa_node = cpu_to_node(c->cpu);
+       param->wq.db_numa_node = mlx5e_get_node(c->priv, c->ix);
        err = mlx5_wq_cyc_create(mdev, &param->wq, sqc_wq, &sq->wq, &sq->wq_ctrl);
        if (err)
                return err;
        sq->wq.db    = &sq->wq.db[MLX5_SND_DBR];
 
-       err = mlx5e_alloc_txqsq_db(sq, cpu_to_node(c->cpu));
+       err = mlx5e_alloc_txqsq_db(sq, mlx5e_get_node(c->priv, c->ix));
        if (err)
                goto err_sq_wq_destroy;
 
@@ -1497,8 +1504,8 @@ static int mlx5e_alloc_cq(struct mlx5e_channel *c,
        struct mlx5_core_dev *mdev = c->priv->mdev;
        int err;
 
-       param->wq.buf_numa_node = cpu_to_node(c->cpu);
-       param->wq.db_numa_node  = cpu_to_node(c->cpu);
+       param->wq.buf_numa_node = mlx5e_get_node(c->priv, c->ix);
+       param->wq.db_numa_node  = mlx5e_get_node(c->priv, c->ix);
        param->eq_ix   = c->ix;
 
        err = mlx5e_alloc_cq_common(mdev, param, cq);
@@ -1597,11 +1604,6 @@ static void mlx5e_close_cq(struct mlx5e_cq *cq)
        mlx5e_free_cq(cq);
 }
 
-static int mlx5e_get_cpu(struct mlx5e_priv *priv, int ix)
-{
-       return cpumask_first(priv->mdev->priv.irq_info[ix].mask);
-}
-
 static int mlx5e_open_tx_cqs(struct mlx5e_channel *c,
                             struct mlx5e_params *params,
                             struct mlx5e_channel_param *cparam)
@@ -1750,11 +1752,10 @@ static int mlx5e_open_channel(struct mlx5e_priv *priv, int ix,
 {
        struct mlx5e_cq_moder icocq_moder = {0, 0};
        struct net_device *netdev = priv->netdev;
-       int cpu = mlx5e_get_cpu(priv, ix);
        struct mlx5e_channel *c;
        int err;
 
-       c = kzalloc_node(sizeof(*c), GFP_KERNEL, cpu_to_node(cpu));
+       c = kzalloc_node(sizeof(*c), GFP_KERNEL, mlx5e_get_node(priv, ix));
        if (!c)
                return -ENOMEM;
 
@@ -1762,7 +1763,6 @@ static int mlx5e_open_channel(struct mlx5e_priv *priv, int ix,
        c->mdev     = priv->mdev;
        c->tstamp   = &priv->tstamp;
        c->ix       = ix;
-       c->cpu      = cpu;
        c->pdev     = &priv->mdev->pdev->dev;
        c->netdev   = priv->netdev;
        c->mkey_be  = cpu_to_be32(priv->mdev->mlx5e_res.mkey.key);
@@ -1848,7 +1848,8 @@ static void mlx5e_activate_channel(struct mlx5e_channel *c)
        for (tc = 0; tc < c->num_tc; tc++)
                mlx5e_activate_txqsq(&c->sq[tc]);
        mlx5e_activate_rq(&c->rq);
-       netif_set_xps_queue(c->netdev, get_cpu_mask(c->cpu), c->ix);
+       netif_set_xps_queue(c->netdev,
+               mlx5_get_vector_affinity(c->priv->mdev, c->ix), c->ix);
 }
 
 static void mlx5e_deactivate_channel(struct mlx5e_channel *c)
index d2fd55e5c68bfd6f327ede5b82d37f6dddb9612c..e464e8179655e0a6c91e4831bb21ded285563bea 100644 (file)
@@ -316,6 +316,9 @@ static int mlx5_alloc_irq_vectors(struct mlx5_core_dev *dev)
 {
        struct mlx5_priv *priv = &dev->priv;
        struct mlx5_eq_table *table = &priv->eq_table;
+       struct irq_affinity irqdesc = {
+               .pre_vectors = MLX5_EQ_VEC_COMP_BASE,
+       };
        int num_eqs = 1 << MLX5_CAP_GEN(dev, log_max_eq);
        int nvec;
 
@@ -329,9 +332,10 @@ static int mlx5_alloc_irq_vectors(struct mlx5_core_dev *dev)
        if (!priv->irq_info)
                goto err_free_msix;
 
-       nvec = pci_alloc_irq_vectors(dev->pdev,
+       nvec = pci_alloc_irq_vectors_affinity(dev->pdev,
                        MLX5_EQ_VEC_COMP_BASE + 1, nvec,
-                       PCI_IRQ_MSIX);
+                       PCI_IRQ_MSIX | PCI_IRQ_AFFINITY,
+                       &irqdesc);
        if (nvec < 0)
                return nvec;
 
@@ -605,63 +609,6 @@ u64 mlx5_read_internal_timer(struct mlx5_core_dev *dev)
        return (u64)timer_l | (u64)timer_h1 << 32;
 }
 
-static int mlx5_irq_set_affinity_hint(struct mlx5_core_dev *mdev, int i)
-{
-       struct mlx5_priv *priv  = &mdev->priv;
-       int irq = pci_irq_vector(mdev->pdev, MLX5_EQ_VEC_COMP_BASE + i);
-
-       if (!zalloc_cpumask_var(&priv->irq_info[i].mask, GFP_KERNEL)) {
-               mlx5_core_warn(mdev, "zalloc_cpumask_var failed");
-               return -ENOMEM;
-       }
-
-       cpumask_set_cpu(cpumask_local_spread(i, priv->numa_node),
-                       priv->irq_info[i].mask);
-
-       if (IS_ENABLED(CONFIG_SMP) &&
-           irq_set_affinity_hint(irq, priv->irq_info[i].mask))
-               mlx5_core_warn(mdev, "irq_set_affinity_hint failed, irq 0x%.4x", irq);
-
-       return 0;
-}
-
-static void mlx5_irq_clear_affinity_hint(struct mlx5_core_dev *mdev, int i)
-{
-       struct mlx5_priv *priv  = &mdev->priv;
-       int irq = pci_irq_vector(mdev->pdev, MLX5_EQ_VEC_COMP_BASE + i);
-
-       irq_set_affinity_hint(irq, NULL);
-       free_cpumask_var(priv->irq_info[i].mask);
-}
-
-static int mlx5_irq_set_affinity_hints(struct mlx5_core_dev *mdev)
-{
-       int err;
-       int i;
-
-       for (i = 0; i < mdev->priv.eq_table.num_comp_vectors; i++) {
-               err = mlx5_irq_set_affinity_hint(mdev, i);
-               if (err)
-                       goto err_out;
-       }
-
-       return 0;
-
-err_out:
-       for (i--; i >= 0; i--)
-               mlx5_irq_clear_affinity_hint(mdev, i);
-
-       return err;
-}
-
-static void mlx5_irq_clear_affinity_hints(struct mlx5_core_dev *mdev)
-{
-       int i;
-
-       for (i = 0; i < mdev->priv.eq_table.num_comp_vectors; i++)
-               mlx5_irq_clear_affinity_hint(mdev, i);
-}
-
 int mlx5_vector2eqn(struct mlx5_core_dev *dev, int vector, int *eqn,
                    unsigned int *irqn)
 {
@@ -1134,12 +1081,6 @@ static int mlx5_load_one(struct mlx5_core_dev *dev, struct mlx5_priv *priv,
                goto err_stop_eqs;
        }
 
-       err = mlx5_irq_set_affinity_hints(dev);
-       if (err) {
-               dev_err(&pdev->dev, "Failed to alloc affinity hint cpumask\n");
-               goto err_affinity_hints;
-       }
-
        err = mlx5_init_fs(dev);
        if (err) {
                dev_err(&pdev->dev, "Failed to init flow steering\n");
@@ -1199,9 +1140,6 @@ err_sriov:
        mlx5_cleanup_fs(dev);
 
 err_fs:
-       mlx5_irq_clear_affinity_hints(dev);
-
-err_affinity_hints:
        free_comp_eqs(dev);
 
 err_stop_eqs:
@@ -1274,7 +1212,6 @@ static int mlx5_unload_one(struct mlx5_core_dev *dev, struct mlx5_priv *priv,
        mlx5_eswitch_detach(dev->priv.eswitch);
 #endif
        mlx5_cleanup_fs(dev);
-       mlx5_irq_clear_affinity_hints(dev);
        free_comp_eqs(dev);
        mlx5_stop_eqs(dev);
        mlx5_put_uars_page(dev, priv->uar);
index 5bac7f53b4f9383866fc6f05e3a21f9599fc07d1..579731842c940d3fdda507d5c9c497c972821e63 100644 (file)
@@ -534,7 +534,6 @@ struct mlx5_core_sriov {
 };
 
 struct mlx5_irq_info {
-       cpumask_var_t mask;
        char name[MLX5_MAX_IRQ_NAME];
 };
 
@@ -1184,4 +1183,10 @@ enum {
        MLX5_TRIGGERED_CMD_COMP = (u64)1 << 32,
 };
 
+static inline const struct cpumask *
+mlx5_get_vector_affinity(struct mlx5_core_dev *dev, int vector)
+{
+       return pci_irq_get_affinity(dev->pdev, MLX5_EQ_VEC_COMP_BASE + vector);
+}
+
 #endif /* MLX5_DRIVER_H */