These changes are the raw update to linux-4.4.6-rt14. Kernel sources
[kvmfornfv.git] / kernel / drivers / net / ethernet / mellanox / mlx4 / en_cq.c
index 22da4d0..eb8a498 100644 (file)
@@ -66,6 +66,7 @@ int mlx4_en_create_cq(struct mlx4_en_priv *priv,
 
        cq->ring = ring;
        cq->is_tx = mode;
+       cq->vector = mdev->dev->caps.num_comp_vectors;
 
        /* Allocate HW buffers on provided NUMA node.
         * dev->numa_node is used in mtt range allocation flow.
@@ -99,14 +100,8 @@ int mlx4_en_activate_cq(struct mlx4_en_priv *priv, struct mlx4_en_cq *cq,
 {
        struct mlx4_en_dev *mdev = priv->mdev;
        int err = 0;
-       char name[25];
        int timestamp_en = 0;
-       struct cpu_rmap *rmap =
-#ifdef CONFIG_RFS_ACCEL
-               priv->dev->rx_cpu_rmap;
-#else
-               NULL;
-#endif
+       bool assigned_eq = false;
 
        cq->dev = mdev->pndev[priv->port];
        cq->mcq.set_ci_db  = cq->wqres.db.db;
@@ -116,23 +111,19 @@ int mlx4_en_activate_cq(struct mlx4_en_priv *priv, struct mlx4_en_cq *cq,
        memset(cq->buf, 0, cq->buf_size);
 
        if (cq->is_tx == RX) {
-               if (mdev->dev->caps.comp_pool) {
-                       if (!cq->vector) {
-                               sprintf(name, "%s-%d", priv->dev->name,
-                                       cq->ring);
-                               /* Set IRQ for specific name (per ring) */
-                               if (mlx4_assign_eq(mdev->dev, name, rmap,
-                                                  &cq->vector)) {
-                                       cq->vector = (cq->ring + 1 + priv->port)
-                                           % mdev->dev->caps.num_comp_vectors;
-                                       mlx4_warn(mdev, "Failed assigning an EQ to %s, falling back to legacy EQ's\n",
-                                                 name);
-                               }
-
+               if (!mlx4_is_eq_vector_valid(mdev->dev, priv->port,
+                                            cq->vector)) {
+                       cq->vector = cpumask_first(priv->rx_ring[cq->ring]->affinity_mask);
+
+                       err = mlx4_assign_eq(mdev->dev, priv->port,
+                                            &cq->vector);
+                       if (err) {
+                               mlx4_err(mdev, "Failed assigning an EQ to CQ vector %d\n",
+                                        cq->vector);
+                               goto free_eq;
                        }
-               } else {
-                       cq->vector = (cq->ring + 1 + priv->port) %
-                               mdev->dev->caps.num_comp_vectors;
+
+                       assigned_eq = true;
                }
 
                cq->irq_desc =
@@ -159,7 +150,7 @@ int mlx4_en_activate_cq(struct mlx4_en_priv *priv, struct mlx4_en_cq *cq,
                            &mdev->priv_uar, cq->wqres.db.dma, &cq->mcq,
                            cq->vector, 0, timestamp_en);
        if (err)
-               return err;
+               goto free_eq;
 
        cq->mcq.comp  = cq->is_tx ? mlx4_en_tx_irq : mlx4_en_rx_irq;
        cq->mcq.event = mlx4_en_cq_event;
@@ -168,13 +159,6 @@ int mlx4_en_activate_cq(struct mlx4_en_priv *priv, struct mlx4_en_cq *cq,
                netif_napi_add(cq->dev, &cq->napi, mlx4_en_poll_tx_cq,
                               NAPI_POLL_WEIGHT);
        } else {
-               struct mlx4_en_rx_ring *ring = priv->rx_ring[cq->ring];
-
-               err = irq_set_affinity_hint(cq->mcq.irq,
-                                           ring->affinity_mask);
-               if (err)
-                       mlx4_warn(mdev, "Failed setting affinity hint\n");
-
                netif_napi_add(cq->dev, &cq->napi, mlx4_en_poll_rx_cq, 64);
                napi_hash_add(&cq->napi);
        }
@@ -182,6 +166,12 @@ int mlx4_en_activate_cq(struct mlx4_en_priv *priv, struct mlx4_en_cq *cq,
        napi_enable(&cq->napi);
 
        return 0;
+
+free_eq:
+       if (assigned_eq)
+               mlx4_release_eq(mdev->dev, cq->vector);
+       cq->vector = mdev->dev->caps.num_comp_vectors;
+       return err;
 }
 
 void mlx4_en_destroy_cq(struct mlx4_en_priv *priv, struct mlx4_en_cq **pcq)
@@ -191,9 +181,9 @@ void mlx4_en_destroy_cq(struct mlx4_en_priv *priv, struct mlx4_en_cq **pcq)
 
        mlx4_en_unmap_buffer(&cq->wqres.buf);
        mlx4_free_hwq_res(mdev->dev, &cq->wqres, cq->buf_size);
-       if (priv->mdev->dev->caps.comp_pool && cq->vector) {
+       if (mlx4_is_eq_vector_valid(mdev->dev, priv->port, cq->vector) &&
+           cq->is_tx == RX)
                mlx4_release_eq(priv->mdev->dev, cq->vector);
-       }
        cq->vector = 0;
        cq->buf_size = 0;
        cq->buf = NULL;
@@ -207,7 +197,6 @@ void mlx4_en_deactivate_cq(struct mlx4_en_priv *priv, struct mlx4_en_cq *cq)
        if (!cq->is_tx) {
                napi_hash_del(&cq->napi);
                synchronize_rcu();
-               irq_set_affinity_hint(cq->mcq.irq, NULL);
        }
        netif_napi_del(&cq->napi);