Skip to content

Commit 6a06c2f

Browse files
w1ldptrSaeed Mahameed
authored and
Saeed Mahameed
committed
net/mlx5e: Refactor neigh used value update for concurrent execution
In order to remove dependency on rtnl lock and allow neigh used value update workqueue task to execute concurrently with tc, refactor mlx5e_tc_update_neigh_used_value() for concurrent execution: - Lock encap table when accessing encap entry to prevent concurrent changes. - Save offloaded encap flows to temporary list and release them after encap entry is updated. Add mlx5e_put_encap_flow_list() helper which is intended to be shared with neigh update code in following patch in this series. This is necessary because mlx5e_flow_put() can't be called while holding encap_tbl_lock. Signed-off-by: Vlad Buslov <[email protected]> Reviewed-by: Roi Dayan <[email protected]> Signed-off-by: Saeed Mahameed <[email protected]>
1 parent ac0d917 commit 6a06c2f

File tree

1 file changed

+19
-4
lines changed
  • drivers/net/ethernet/mellanox/mlx5/core

1 file changed

+19
-4
lines changed

drivers/net/ethernet/mellanox/mlx5/core/en_tc.c

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,7 @@ struct mlx5e_tc_flow {
126126
struct list_head hairpin; /* flows sharing the same hairpin */
127127
struct list_head peer; /* flows with peer flow */
128128
struct list_head unready; /* flows not ready to be offloaded (e.g due to missing route) */
129+
struct list_head tmp_list; /* temporary flow list used by neigh update */
129130
refcount_t refcnt;
130131
struct rcu_head rcu_head;
131132
union {
@@ -1412,6 +1413,15 @@ static struct mlx5_fc *mlx5e_tc_get_counter(struct mlx5e_tc_flow *flow)
14121413
return flow->nic_attr->counter;
14131414
}
14141415

1416+
/* Iterate over tmp_list of flows attached to flow_list head. */
1417+
static void mlx5e_put_encap_flow_list(struct mlx5e_priv *priv, struct list_head *flow_list)
1418+
{
1419+
struct mlx5e_tc_flow *flow, *tmp;
1420+
1421+
list_for_each_entry_safe(flow, tmp, flow_list, tmp_list)
1422+
mlx5e_flow_put(priv, flow);
1423+
}
1424+
14151425
static struct mlx5e_encap_entry *
14161426
mlx5e_get_next_valid_encap(struct mlx5e_neigh_hash_entry *nhe,
14171427
struct mlx5e_encap_entry *e)
@@ -1481,30 +1491,35 @@ void mlx5e_tc_update_neigh_used_value(struct mlx5e_neigh_hash_entry *nhe)
14811491
* next one.
14821492
*/
14831493
while ((e = mlx5e_get_next_valid_encap(nhe, e)) != NULL) {
1494+
struct mlx5e_priv *priv = netdev_priv(e->out_dev);
14841495
struct encap_flow_item *efi, *tmp;
1496+
struct mlx5_eswitch *esw;
1497+
LIST_HEAD(flow_list);
14851498

1499+
esw = priv->mdev->priv.eswitch;
1500+
mutex_lock(&esw->offloads.encap_tbl_lock);
14861501
list_for_each_entry_safe(efi, tmp, &e->flows, list) {
14871502
flow = container_of(efi, struct mlx5e_tc_flow,
14881503
encaps[efi->index]);
14891504
if (IS_ERR(mlx5e_flow_get(flow)))
14901505
continue;
1506+
list_add(&flow->tmp_list, &flow_list);
14911507

14921508
if (mlx5e_is_offloaded_flow(flow)) {
14931509
counter = mlx5e_tc_get_counter(flow);
14941510
lastuse = mlx5_fc_query_lastuse(counter);
14951511
if (time_after((unsigned long)lastuse, nhe->reported_lastuse)) {
1496-
mlx5e_flow_put(netdev_priv(e->out_dev), flow);
14971512
neigh_used = true;
14981513
break;
14991514
}
15001515
}
1501-
1502-
mlx5e_flow_put(netdev_priv(e->out_dev), flow);
15031516
}
1517+
mutex_unlock(&esw->offloads.encap_tbl_lock);
15041518

1519+
mlx5e_put_encap_flow_list(priv, &flow_list);
15051520
if (neigh_used) {
15061521
/* release current encap before breaking the loop */
1507-
mlx5e_encap_put(netdev_priv(e->out_dev), e);
1522+
mlx5e_encap_put(priv, e);
15081523
break;
15091524
}
15101525
}

0 commit comments

Comments
 (0)