From 328bf8e5a3975b2f4bdf74e1541be6392d5f553f Mon Sep 17 00:00:00 2001 From: Adrien Mazarguil Date: Thu, 12 Oct 2017 14:19:26 +0200 Subject: [PATCH] net/mlx4: relax check on missing flow rule target Creating a flow rule targeting a missing (unconfigured) queue is not possible. However, nothing really prevents the destruction of a queue with existing flow rules still pointing at it, except currently the port must be in a stopped state in order to avoid crashing. Problem is that the port cannot be restarted if flow rules cannot be re-applied due to missing queues. This flexibility will be needed by subsequent work on this PMD. Given that a PMD cannot decide on its own to remove problematic user-defined flow rules in order to restart a port, work around this restriction by making the affected ones drop-like, i.e. rules targeting nonexistent queues drop packets instead. Signed-off-by: Adrien Mazarguil Acked-by: Nelio Laranjeiro --- drivers/net/mlx4/mlx4_flow.c | 28 +++++++++++++++++----------- 1 file changed, 17 insertions(+), 11 deletions(-) diff --git a/drivers/net/mlx4/mlx4_flow.c b/drivers/net/mlx4/mlx4_flow.c index 8f4898b7a0..669eba20fe 100644 --- a/drivers/net/mlx4/mlx4_flow.c +++ b/drivers/net/mlx4/mlx4_flow.c @@ -850,20 +850,24 @@ mlx4_flow_toggle(struct priv *priv, mlx4_drop_put(priv->drop); return 0; } - if (flow->ibv_flow) - return 0; - assert(flow->queue ^ flow->drop); if (flow->queue) { - struct rxq *rxq; + struct rxq *rxq = NULL; - assert(flow->queue_id < priv->dev->data->nb_rx_queues); - rxq = priv->dev->data->rx_queues[flow->queue_id]; - if (!rxq) { - err = EINVAL; - msg = "target queue must be configured first"; - goto error; + if (flow->queue_id < priv->dev->data->nb_rx_queues) + rxq = priv->dev->data->rx_queues[flow->queue_id]; + if (flow->ibv_flow) { + if (!rxq ^ !flow->drop) + return 0; + /* Verbs flow needs updating. */ + claim_zero(ibv_destroy_flow(flow->ibv_flow)); + flow->ibv_flow = NULL; + if (flow->drop) + mlx4_drop_put(priv->drop); } - qp = rxq->qp; + if (rxq) + qp = rxq->qp; + /* A missing target queue drops traffic implicitly. */ + flow->drop = !rxq; } if (flow->drop) { mlx4_drop_get(priv); @@ -876,6 +880,8 @@ mlx4_flow_toggle(struct priv *priv, } assert(qp); assert(flow->ibv_attr); + if (flow->ibv_flow) + return 0; flow->ibv_flow = ibv_create_flow(qp, flow->ibv_attr); if (flow->ibv_flow) return 0; -- 2.20.1