提交 ed604c5d 编写于 作者: I Ido Schimmel 提交者: David S. Miller

mlxsw: spectrum_router: Free LPM tree upon failure

When a new LPM tree is created, we try to replace the trees in the
existing virtual routers with it. If we fail, the tree needs to be
freed.

Currently, this does not happen in the unlikely case where we fail to
bind the tree to the first virtual router, since its reference count
never transitions from 1 to 0.

Fix that by taking a reference before binding the tree.

Fixes: fc922bb0 ("mlxsw: spectrum_router: Use one LPM tree for all virtual routers")
Signed-off-by: NIdo Schimmel <idosch@mellanox.com>
Signed-off-by: NJiri Pirko <jiri@mellanox.com>
Signed-off-by: NDavid S. Miller <davem@davemloft.net>
上级 d0c081b4
...@@ -821,13 +821,18 @@ static int mlxsw_sp_vr_lpm_tree_replace(struct mlxsw_sp *mlxsw_sp, ...@@ -821,13 +821,18 @@ static int mlxsw_sp_vr_lpm_tree_replace(struct mlxsw_sp *mlxsw_sp,
struct mlxsw_sp_lpm_tree *old_tree = fib->lpm_tree; struct mlxsw_sp_lpm_tree *old_tree = fib->lpm_tree;
int err; int err;
err = mlxsw_sp_vr_lpm_tree_bind(mlxsw_sp, fib, new_tree->id);
if (err)
return err;
fib->lpm_tree = new_tree; fib->lpm_tree = new_tree;
mlxsw_sp_lpm_tree_hold(new_tree); mlxsw_sp_lpm_tree_hold(new_tree);
err = mlxsw_sp_vr_lpm_tree_bind(mlxsw_sp, fib, new_tree->id);
if (err)
goto err_tree_bind;
mlxsw_sp_lpm_tree_put(mlxsw_sp, old_tree); mlxsw_sp_lpm_tree_put(mlxsw_sp, old_tree);
return 0; return 0;
err_tree_bind:
mlxsw_sp_lpm_tree_put(mlxsw_sp, new_tree);
fib->lpm_tree = old_tree;
return err;
} }
static int mlxsw_sp_vrs_lpm_tree_replace(struct mlxsw_sp *mlxsw_sp, static int mlxsw_sp_vrs_lpm_tree_replace(struct mlxsw_sp *mlxsw_sp,
...@@ -868,11 +873,14 @@ static int mlxsw_sp_vrs_lpm_tree_replace(struct mlxsw_sp *mlxsw_sp, ...@@ -868,11 +873,14 @@ static int mlxsw_sp_vrs_lpm_tree_replace(struct mlxsw_sp *mlxsw_sp,
return err; return err;
no_replace: no_replace:
err = mlxsw_sp_vr_lpm_tree_bind(mlxsw_sp, fib, new_tree->id);
if (err)
return err;
fib->lpm_tree = new_tree; fib->lpm_tree = new_tree;
mlxsw_sp_lpm_tree_hold(new_tree); mlxsw_sp_lpm_tree_hold(new_tree);
err = mlxsw_sp_vr_lpm_tree_bind(mlxsw_sp, fib, new_tree->id);
if (err) {
mlxsw_sp_lpm_tree_put(mlxsw_sp, new_tree);
fib->lpm_tree = NULL;
return err;
}
return 0; return 0;
} }
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册