When stopping a mlx5 device, the flows with non-cached mode will be flushed. So no operation will be done for these flows in the device closing stage. If the device restarts after stopped, no flow with non-cached mode will be reinserted. Operations of flows with cached mode remain the same. And when the flushing is called from user, all the flows will be flushed.
Signed-off-by: Bing Zhao <bi...@mellanox.com> --- drivers/net/mlx5/mlx5.c | 1 + drivers/net/mlx5/mlx5.h | 2 ++ drivers/net/mlx5/mlx5_flow.c | 36 +++++++++++++++++++++++++++++++++--- drivers/net/mlx5/mlx5_trigger.c | 11 ++++++++--- 4 files changed, 44 insertions(+), 6 deletions(-) diff --git a/drivers/net/mlx5/mlx5.c b/drivers/net/mlx5/mlx5.c index dc4fbbc..5114b23 100644 --- a/drivers/net/mlx5/mlx5.c +++ b/drivers/net/mlx5/mlx5.c @@ -1236,6 +1236,7 @@ struct mlx5_flow_id_pool * mlx5_dev_interrupt_handler_uninstall(dev); mlx5_dev_interrupt_handler_devx_uninstall(dev); mlx5_traffic_disable(dev); + /* Only cached flows will be flushed in this stage, if any. */ mlx5_flow_flush(dev, NULL); mlx5_flow_meter_flush(dev, NULL); /* Prevent crashes when queues are still in use. */ diff --git a/drivers/net/mlx5/mlx5.h b/drivers/net/mlx5/mlx5.h index 65bdb3b..d749b29 100644 --- a/drivers/net/mlx5/mlx5.h +++ b/drivers/net/mlx5/mlx5.h @@ -715,6 +715,8 @@ int mlx5_flow_destroy(struct rte_eth_dev *dev, struct rte_flow *flow, struct rte_flow_error *error); void mlx5_flow_list_flush(struct rte_eth_dev *dev, struct mlx5_flows *list); int mlx5_flow_flush(struct rte_eth_dev *dev, struct rte_flow_error *error); +int mlx5_flow_flush_noncached(struct rte_eth_dev *dev, + struct rte_flow_error *error); int mlx5_flow_query(struct rte_eth_dev *dev, struct rte_flow *flow, const struct rte_flow_action *action, void *data, struct rte_flow_error *error); diff --git a/drivers/net/mlx5/mlx5_flow.c b/drivers/net/mlx5/mlx5_flow.c index d7fb094..0560874 100644 --- a/drivers/net/mlx5/mlx5_flow.c +++ b/drivers/net/mlx5/mlx5_flow.c @@ -4453,11 +4453,14 @@ struct rte_flow * struct rte_flow_error error; int ret = 0; - /* Make sure default copy action (reg_c[0] -> reg_b) is created. */ + /* + * Make sure default copy action (reg_c[0] -> reg_b) is created. + * This should always be executed no matter the driver type. + */ ret = flow_mreg_add_default_copy_action(dev, &error); if (ret < 0) return -rte_errno; - /* Apply Flows created by application. */ + /* Apply Flows created by application, only for cached flows. */ TAILQ_FOREACH(flow, list, next) { ret = flow_mreg_start_copy_action(dev, flow); if (ret < 0) @@ -4674,7 +4677,15 @@ struct rte_flow * { struct mlx5_priv *priv = dev->data->dev_private; - flow_list_destroy(dev, &priv->noncached_flows, flow); + /* + * Checking the flow type and then destroying the flows in both lists. + * Flow with DV type is non-cached (most cases) and flow with legacy + * verbs mode is still cached right now. + */ + if (flow->drv_type == MLX5_FLOW_TYPE_DV) + flow_list_destroy(dev, &priv->noncached_flows, flow); + else + flow_list_destroy(dev, &priv->cached_flows, flow); return 0; } @@ -4690,6 +4701,24 @@ struct rte_flow * { struct mlx5_priv *priv = dev->data->dev_private; + /* In most cases, only one tailq list will contain the flows. */ + mlx5_flow_list_flush(dev, &priv->noncached_flows); + mlx5_flow_list_flush(dev, &priv->cached_flows); + return 0; +} + +/** + * Destroy all non-cached flows. + * + * @see rte_flow_flush() + * @see rte_flow_ops + */ +int +mlx5_flow_flush_noncached(struct rte_eth_dev *dev, + struct rte_flow_error *error __rte_unused) +{ + struct mlx5_priv *priv = dev->data->dev_private; + mlx5_flow_list_flush(dev, &priv->noncached_flows); return 0; } @@ -5133,6 +5162,7 @@ struct rte_flow * struct mlx5_priv *priv = dev->data->dev_private; mlx5_flow_list_flush(dev, &priv->noncached_flows); + mlx5_flow_list_flush(dev, &priv->cached_flows); } /** diff --git a/drivers/net/mlx5/mlx5_trigger.c b/drivers/net/mlx5/mlx5_trigger.c index 0053847..26f4863 100644 --- a/drivers/net/mlx5/mlx5_trigger.c +++ b/drivers/net/mlx5/mlx5_trigger.c @@ -320,7 +320,7 @@ dev->data->port_id); goto error; } - ret = mlx5_flow_start(dev, &priv->noncached_flows); + ret = mlx5_flow_start(dev, &priv->cached_flows); if (ret) { DRV_LOG(DEBUG, "port %u failed to set flows", dev->data->port_id); @@ -337,7 +337,7 @@ ret = rte_errno; /* Save rte_errno before cleanup. */ /* Rollback. */ dev->data->dev_started = 0; - mlx5_flow_stop(dev, &priv->noncached_flows); + mlx5_flow_stop(dev, &priv->cached_flows); mlx5_traffic_disable(dev); mlx5_txq_stop(dev); mlx5_rxq_stop(dev); @@ -367,7 +367,12 @@ mlx5_mp_req_stop_rxtx(dev); usleep(1000 * priv->rxqs_n); DRV_LOG(DEBUG, "port %u stopping device", dev->data->port_id); - mlx5_flow_stop(dev, &priv->noncached_flows); + mlx5_flow_stop(dev, &priv->cached_flows); + /* + * Flows flushing is still after deleting default copy action & clearing + * flags of all RX queues. + */ + mlx5_flow_flush_noncached(dev, NULL); mlx5_traffic_disable(dev); mlx5_rx_intr_vec_disable(dev); mlx5_dev_interrupt_handler_uninstall(dev); -- 1.8.3.1