net/mlx5e: Split open/close ICOSQ into stages
authorAya Levin <ayal@mellanox.com>
Tue, 2 Jul 2019 12:47:29 +0000 (15:47 +0300)
committerSaeed Mahameed <saeedm@mellanox.com>
Tue, 20 Aug 2019 20:08:17 +0000 (13:08 -0700)
Align ICOSQ open/close behaviour with RQ and SQ. Split open flow into
open and activate where open handles creation and activate enables the
queue. Do a symmetric thing in close flow: split into close and
deactivate.

Signed-off-by: Aya Levin <ayal@mellanox.com>
Reviewed-by: Tariq Toukan <tariqt@mellanox.com>
Acked-by: Jiri Pirko <jiri@mellanox.com>
Signed-off-by: Saeed Mahameed <saeedm@mellanox.com>
drivers/net/ethernet/mellanox/mlx5/core/en/xsk/setup.c
drivers/net/ethernet/mellanox/mlx5/core/en/xsk/tx.c
drivers/net/ethernet/mellanox/mlx5/core/en_main.c

index 2c4d1f41596847373e9ef79f4524412ad11977e4..d360750b25b7922f7308413257ec4b3d1408f942 100644 (file)
@@ -150,6 +150,7 @@ void mlx5e_close_xsk(struct mlx5e_channel *c)
 
 void mlx5e_activate_xsk(struct mlx5e_channel *c)
 {
+       mlx5e_activate_icosq(&c->xskicosq);
        set_bit(MLX5E_RQ_STATE_ENABLED, &c->xskrq.state);
        /* TX queue is created active. */
 
@@ -162,6 +163,7 @@ void mlx5e_deactivate_xsk(struct mlx5e_channel *c)
 {
        mlx5e_deactivate_rq(&c->xskrq);
        /* TX queue is disabled on close. */
+       mlx5e_deactivate_icosq(&c->xskicosq);
 }
 
 static int mlx5e_redirect_xsk_rqt(struct mlx5e_priv *priv, u16 ix, u32 rqn)
index 35e188cf4ea4607f7475fbbae48cb838c7e8c6b0..fd2c75b4b519e71fda8a2af052f1aa0afd7639ce 100644 (file)
@@ -26,6 +26,13 @@ int mlx5e_xsk_async_xmit(struct net_device *dev, u32 qid)
                return -ENXIO;
 
        if (!napi_if_scheduled_mark_missed(&c->napi)) {
+               /* To avoid WQE overrun, don't post a NOP if XSKICOSQ is not
+                * active and not polled by NAPI. Return 0, because the upcoming
+                * activate will trigger the IRQ for us.
+                */
+               if (unlikely(!test_bit(MLX5E_SQ_STATE_ENABLED, &c->xskicosq.state)))
+                       return 0;
+
                spin_lock(&c->xskicosq_lock);
                mlx5e_trigger_irq(&c->xskicosq);
                spin_unlock(&c->xskicosq_lock);
index 1cec30627bb0a25bcb84e9c1291bfe7ea187364a..2c4e1cb54402cd4499c403d943109f1bc861173c 100644 (file)
@@ -1375,7 +1375,6 @@ int mlx5e_open_icosq(struct mlx5e_channel *c, struct mlx5e_params *params,
        csp.cqn             = sq->cq.mcq.cqn;
        csp.wq_ctrl         = &sq->wq_ctrl;
        csp.min_inline_mode = params->tx_min_inline_mode;
-       set_bit(MLX5E_SQ_STATE_ENABLED, &sq->state);
        err = mlx5e_create_sq_rdy(c->mdev, param, &csp, &sq->sqn);
        if (err)
                goto err_free_icosq;
@@ -1389,12 +1388,22 @@ err_free_icosq:
        return err;
 }
 
-void mlx5e_close_icosq(struct mlx5e_icosq *sq)
+static void mlx5e_activate_icosq(struct mlx5e_icosq *icosq)
 {
-       struct mlx5e_channel *c = sq->channel;
+       set_bit(MLX5E_SQ_STATE_ENABLED, &icosq->state);
+}
 
-       clear_bit(MLX5E_SQ_STATE_ENABLED, &sq->state);
+static void mlx5e_deactivate_icosq(struct mlx5e_icosq *icosq)
+{
+       struct mlx5e_channel *c = icosq->channel;
+
+       clear_bit(MLX5E_SQ_STATE_ENABLED, &icosq->state);
        napi_synchronize(&c->napi);
+}
+
+void mlx5e_close_icosq(struct mlx5e_icosq *sq)
+{
+       struct mlx5e_channel *c = sq->channel;
 
        mlx5e_destroy_sq(c->mdev, sq->sqn);
        mlx5e_free_icosq(sq);
@@ -1971,6 +1980,7 @@ 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_icosq(&c->icosq);
        mlx5e_activate_rq(&c->rq);
        netif_set_xps_queue(c->netdev, c->xps_cpumask, c->ix);
 
@@ -1986,6 +1996,7 @@ static void mlx5e_deactivate_channel(struct mlx5e_channel *c)
                mlx5e_deactivate_xsk(c);
 
        mlx5e_deactivate_rq(&c->rq);
+       mlx5e_deactivate_icosq(&c->icosq);
        for (tc = 0; tc < c->num_tc; tc++)
                mlx5e_deactivate_txqsq(&c->sq[tc]);
 }