Commit 14c129e3 authored by Maor Gottlieb's avatar Maor Gottlieb Committed by Leon Romanovsky

{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: default avatarMaor Gottlieb <maorg@mellanox.com>
Reviewed-by: default avatarMark Zhang <markz@mellanox.com>
Reviewed-by: default avatarMark Bloch <markb@mellanox.com>
Signed-off-by: default avatarLeon Romanovsky <leonro@mellanox.com>
parent b6ca09cb
...@@ -3698,12 +3698,13 @@ static struct mlx5_ib_flow_handler *_create_flow_rule(struct mlx5_ib_dev *dev, ...@@ -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, ...@@ -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, ...@@ -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); ...@@ -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, ...@@ -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;
fs_get_obj(prio, ft->node.parent); if (!(sw_action & MLX5_FLOW_CONTEXT_ACTION_FWD_NEXT_PRIO))
if (flow_act->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);
if (num_dest)
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);
}
}
handle = _mlx5_add_flow_rules(ft, spec, flow_act, dest, num_dest); if (!fwd_next_prio_supported(ft))
return ERR_PTR(-EOPNOTSUPP);
if (sw_action == MLX5_FLOW_CONTEXT_ACTION_FWD_NEXT_PRIO) { mutex_lock(&root->chain_lock);
if (!IS_ERR_OR_NULL(handle) && fs_get_obj(prio, ft->node.parent);
(list_empty(&handle->rule[0]->next_ft))) { next_ft = find_next_chained_ft(prio);
mutex_lock(&next_ft->lock); if (!next_ft) {
list_add(&handle->rule[0]->next_ft, handle = ERR_PTR(-EOPNOTSUPP);
&next_ft->fwd_rules); goto unlock;
mutex_unlock(&next_ft->lock); }
handle->rule[0]->sw_action = MLX5_FLOW_CONTEXT_ACTION_FWD_NEXT_PRIO;
} gen_dest = kcalloc(num_dest + 1, sizeof(*dest),
mutex_unlock(&root->chain_lock); 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);
if (IS_ERR(handle))
goto unlock;
if (list_empty(&handle->rule[num_dest - 1]->next_ft)) {
mutex_lock(&next_ft->lock);
list_add(&handle->rule[num_dest - 1]->next_ft,
&next_ft->fwd_rules);
mutex_unlock(&next_ft->lock);
handle->rule[num_dest - 1]->sw_action =
MLX5_FLOW_CONTEXT_ACTION_FWD_NEXT_PRIO;
}
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);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment