{IB/net}/mlx5: Simplify don't trap code
The fs_core already supports creation of rules with multiple actions/destinations. Refactor fs_core to handle the case when don't trap rule is created with destination. Adapt the calling code in the driver. Signed-off-by: Maor Gottlieb <maorg@mellanox.com> Reviewed-by: Mark Zhang <markz@mellanox.com> Reviewed-by: Mark Bloch <markb@mellanox.com> Signed-off-by: Leon Romanovsky <leonro@mellanox.com>
This commit is contained in:
parent
b6ca09cb15
commit
14c129e301
|
@ -3698,12 +3698,13 @@ static struct mlx5_ib_flow_handler *_create_flow_rule(struct mlx5_ib_dev *dev,
|
||||||
if (!dest_num)
|
if (!dest_num)
|
||||||
rule_dst = NULL;
|
rule_dst = NULL;
|
||||||
} else {
|
} else {
|
||||||
|
if (flow_attr->flags & IB_FLOW_ATTR_FLAGS_DONT_TRAP)
|
||||||
|
flow_act.action |=
|
||||||
|
MLX5_FLOW_CONTEXT_ACTION_FWD_NEXT_PRIO;
|
||||||
if (is_egress)
|
if (is_egress)
|
||||||
flow_act.action |= MLX5_FLOW_CONTEXT_ACTION_ALLOW;
|
flow_act.action |= MLX5_FLOW_CONTEXT_ACTION_ALLOW;
|
||||||
else
|
else if (dest_num)
|
||||||
flow_act.action |=
|
flow_act.action |= MLX5_FLOW_CONTEXT_ACTION_FWD_DEST;
|
||||||
dest_num ? MLX5_FLOW_CONTEXT_ACTION_FWD_DEST :
|
|
||||||
MLX5_FLOW_CONTEXT_ACTION_FWD_NEXT_PRIO;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((spec->flow_context.flags & FLOW_CONTEXT_HAS_TAG) &&
|
if ((spec->flow_context.flags & FLOW_CONTEXT_HAS_TAG) &&
|
||||||
|
@ -3747,30 +3748,6 @@ static struct mlx5_ib_flow_handler *create_flow_rule(struct mlx5_ib_dev *dev,
|
||||||
return _create_flow_rule(dev, ft_prio, flow_attr, dst, 0, NULL);
|
return _create_flow_rule(dev, ft_prio, flow_attr, dst, 0, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct mlx5_ib_flow_handler *create_dont_trap_rule(struct mlx5_ib_dev *dev,
|
|
||||||
struct mlx5_ib_flow_prio *ft_prio,
|
|
||||||
struct ib_flow_attr *flow_attr,
|
|
||||||
struct mlx5_flow_destination *dst)
|
|
||||||
{
|
|
||||||
struct mlx5_ib_flow_handler *handler_dst = NULL;
|
|
||||||
struct mlx5_ib_flow_handler *handler = NULL;
|
|
||||||
|
|
||||||
handler = create_flow_rule(dev, ft_prio, flow_attr, NULL);
|
|
||||||
if (!IS_ERR(handler)) {
|
|
||||||
handler_dst = create_flow_rule(dev, ft_prio,
|
|
||||||
flow_attr, dst);
|
|
||||||
if (IS_ERR(handler_dst)) {
|
|
||||||
mlx5_del_flow_rules(handler->rule);
|
|
||||||
ft_prio->refcount--;
|
|
||||||
kfree(handler);
|
|
||||||
handler = handler_dst;
|
|
||||||
} else {
|
|
||||||
list_add(&handler_dst->list, &handler->list);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return handler;
|
|
||||||
}
|
|
||||||
enum {
|
enum {
|
||||||
LEFTOVERS_MC,
|
LEFTOVERS_MC,
|
||||||
LEFTOVERS_UC,
|
LEFTOVERS_UC,
|
||||||
|
@ -3974,15 +3951,11 @@ static struct ib_flow *mlx5_ib_create_flow(struct ib_qp *qp,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (flow_attr->type == IB_FLOW_ATTR_NORMAL) {
|
if (flow_attr->type == IB_FLOW_ATTR_NORMAL) {
|
||||||
if (flow_attr->flags & IB_FLOW_ATTR_FLAGS_DONT_TRAP) {
|
underlay_qpn = (mqp->flags & IB_QP_CREATE_SOURCE_QPN) ?
|
||||||
handler = create_dont_trap_rule(dev, ft_prio,
|
mqp->underlay_qpn :
|
||||||
flow_attr, dst);
|
0;
|
||||||
} else {
|
handler = _create_flow_rule(dev, ft_prio, flow_attr, dst,
|
||||||
underlay_qpn = (mqp->flags & MLX5_IB_QP_UNDERLAY) ?
|
underlay_qpn, ucmd);
|
||||||
mqp->underlay_qpn : 0;
|
|
||||||
handler = _create_flow_rule(dev, ft_prio, flow_attr,
|
|
||||||
dst, underlay_qpn, ucmd);
|
|
||||||
}
|
|
||||||
} else if (flow_attr->type == IB_FLOW_ATTR_ALL_DEFAULT ||
|
} else if (flow_attr->type == IB_FLOW_ATTR_ALL_DEFAULT ||
|
||||||
flow_attr->type == IB_FLOW_ATTR_MC_DEFAULT) {
|
flow_attr->type == IB_FLOW_ATTR_MC_DEFAULT) {
|
||||||
handler = create_leftovers_rule(dev, ft_prio, flow_attr,
|
handler = create_leftovers_rule(dev, ft_prio, flow_attr,
|
||||||
|
|
|
@ -254,7 +254,7 @@ static void del_sw_flow_group(struct fs_node *node);
|
||||||
static void del_sw_fte(struct fs_node *node);
|
static void del_sw_fte(struct fs_node *node);
|
||||||
static void del_sw_prio(struct fs_node *node);
|
static void del_sw_prio(struct fs_node *node);
|
||||||
static void del_sw_ns(struct fs_node *node);
|
static void del_sw_ns(struct fs_node *node);
|
||||||
/* Delete rule (destination) is special case that
|
/* Delete rule (destination) is special case that
|
||||||
* requires to lock the FTE for all the deletion process.
|
* requires to lock the FTE for all the deletion process.
|
||||||
*/
|
*/
|
||||||
static void del_sw_hw_rule(struct fs_node *node);
|
static void del_sw_hw_rule(struct fs_node *node);
|
||||||
|
@ -1899,48 +1899,61 @@ mlx5_add_flow_rules(struct mlx5_flow_table *ft,
|
||||||
{
|
{
|
||||||
struct mlx5_flow_root_namespace *root = find_root(&ft->node);
|
struct mlx5_flow_root_namespace *root = find_root(&ft->node);
|
||||||
static const struct mlx5_flow_spec zero_spec = {};
|
static const struct mlx5_flow_spec zero_spec = {};
|
||||||
struct mlx5_flow_destination gen_dest = {};
|
struct mlx5_flow_destination *gen_dest = NULL;
|
||||||
struct mlx5_flow_table *next_ft = NULL;
|
struct mlx5_flow_table *next_ft = NULL;
|
||||||
struct mlx5_flow_handle *handle = NULL;
|
struct mlx5_flow_handle *handle = NULL;
|
||||||
u32 sw_action = flow_act->action;
|
u32 sw_action = flow_act->action;
|
||||||
struct fs_prio *prio;
|
struct fs_prio *prio;
|
||||||
|
int i;
|
||||||
|
|
||||||
if (!spec)
|
if (!spec)
|
||||||
spec = &zero_spec;
|
spec = &zero_spec;
|
||||||
|
|
||||||
|
if (!(sw_action & MLX5_FLOW_CONTEXT_ACTION_FWD_NEXT_PRIO))
|
||||||
|
return _mlx5_add_flow_rules(ft, spec, flow_act, dest, num_dest);
|
||||||
|
|
||||||
|
if (!fwd_next_prio_supported(ft))
|
||||||
|
return ERR_PTR(-EOPNOTSUPP);
|
||||||
|
|
||||||
|
mutex_lock(&root->chain_lock);
|
||||||
fs_get_obj(prio, ft->node.parent);
|
fs_get_obj(prio, ft->node.parent);
|
||||||
if (flow_act->action == MLX5_FLOW_CONTEXT_ACTION_FWD_NEXT_PRIO) {
|
next_ft = find_next_chained_ft(prio);
|
||||||
if (!fwd_next_prio_supported(ft))
|
if (!next_ft) {
|
||||||
return ERR_PTR(-EOPNOTSUPP);
|
handle = ERR_PTR(-EOPNOTSUPP);
|
||||||
if (num_dest)
|
goto unlock;
|
||||||
return ERR_PTR(-EINVAL);
|
|
||||||
mutex_lock(&root->chain_lock);
|
|
||||||
next_ft = find_next_chained_ft(prio);
|
|
||||||
if (next_ft) {
|
|
||||||
gen_dest.type = MLX5_FLOW_DESTINATION_TYPE_FLOW_TABLE;
|
|
||||||
gen_dest.ft = next_ft;
|
|
||||||
dest = &gen_dest;
|
|
||||||
num_dest = 1;
|
|
||||||
flow_act->action = MLX5_FLOW_CONTEXT_ACTION_FWD_DEST;
|
|
||||||
} else {
|
|
||||||
mutex_unlock(&root->chain_lock);
|
|
||||||
return ERR_PTR(-EOPNOTSUPP);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
gen_dest = kcalloc(num_dest + 1, sizeof(*dest),
|
||||||
|
GFP_KERNEL);
|
||||||
|
if (!gen_dest) {
|
||||||
|
handle = ERR_PTR(-ENOMEM);
|
||||||
|
goto unlock;
|
||||||
|
}
|
||||||
|
for (i = 0; i < num_dest; i++)
|
||||||
|
gen_dest[i] = dest[i];
|
||||||
|
gen_dest[i].type =
|
||||||
|
MLX5_FLOW_DESTINATION_TYPE_FLOW_TABLE;
|
||||||
|
gen_dest[i].ft = next_ft;
|
||||||
|
dest = gen_dest;
|
||||||
|
num_dest++;
|
||||||
|
flow_act->action &=
|
||||||
|
~MLX5_FLOW_CONTEXT_ACTION_FWD_NEXT_PRIO;
|
||||||
|
flow_act->action |= MLX5_FLOW_CONTEXT_ACTION_FWD_DEST;
|
||||||
handle = _mlx5_add_flow_rules(ft, spec, flow_act, dest, num_dest);
|
handle = _mlx5_add_flow_rules(ft, spec, flow_act, dest, num_dest);
|
||||||
|
if (IS_ERR(handle))
|
||||||
|
goto unlock;
|
||||||
|
|
||||||
if (sw_action == MLX5_FLOW_CONTEXT_ACTION_FWD_NEXT_PRIO) {
|
if (list_empty(&handle->rule[num_dest - 1]->next_ft)) {
|
||||||
if (!IS_ERR_OR_NULL(handle) &&
|
mutex_lock(&next_ft->lock);
|
||||||
(list_empty(&handle->rule[0]->next_ft))) {
|
list_add(&handle->rule[num_dest - 1]->next_ft,
|
||||||
mutex_lock(&next_ft->lock);
|
&next_ft->fwd_rules);
|
||||||
list_add(&handle->rule[0]->next_ft,
|
mutex_unlock(&next_ft->lock);
|
||||||
&next_ft->fwd_rules);
|
handle->rule[num_dest - 1]->sw_action =
|
||||||
mutex_unlock(&next_ft->lock);
|
MLX5_FLOW_CONTEXT_ACTION_FWD_NEXT_PRIO;
|
||||||
handle->rule[0]->sw_action = MLX5_FLOW_CONTEXT_ACTION_FWD_NEXT_PRIO;
|
|
||||||
}
|
|
||||||
mutex_unlock(&root->chain_lock);
|
|
||||||
}
|
}
|
||||||
|
unlock:
|
||||||
|
mutex_unlock(&root->chain_lock);
|
||||||
|
kfree(gen_dest);
|
||||||
return handle;
|
return handle;
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(mlx5_add_flow_rules);
|
EXPORT_SYMBOL(mlx5_add_flow_rules);
|
||||||
|
|
Loading…
Reference in New Issue