mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-09-29 13:53:33 +00:00
mlx5-fixes-2023-06-16
-----BEGIN PGP SIGNATURE----- iQEzBAABCAAdFiEEGhZs6bAKwk/OTgTpSD+KveBX+j4FAmSMvxkACgkQSD+KveBX +j42zQf+NxeAf0VYlNTUuAh/I5Zr4oi97SI/bexjOLvrQmN8+7Z1blKiaXAgCudY ot3r2ySg3IL2nM/UhCIMd56qkYPJVxNwLOtfe+DYDU0pGXmrh6Fsn/QXNR2DLw/e tQ/4KYQjC0t6kwfDKmEUOnNLg60E3CNCvodG7u7t75N7gmkR323ZFhTXIw5RRXu0 03UjgJm3y8Mkd7YK8e64UOJksTIJ2tOVZeMAtuNyrDUg2IC9LDlDmumDfsjm9ZBe RFZQi03szjQLi5gXX6NaDh9eI5+HGclvsoygTDJF2Oe4jVx+vmVjiVhmvDOjFjSC kT10AJuqwiB4tHqkxoWM0JDwp66zUA== =/hiQ -----END PGP SIGNATURE----- Merge tag 'mlx5-fixes-2023-06-16' of git://git.kernel.org/pub/scm/linux/kernel/git/saeed/linux Saeed Mahameed says: ==================== mlx5-fixes-2023-06-16 This series provides bug fixes to mlx5 driver. Please pull and let me know if there is any problem. ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
commit
0dbcac3a6d
15 changed files with 163 additions and 36 deletions
|
@ -732,7 +732,8 @@ static void mlx5e_rx_compute_wqe_bulk_params(struct mlx5e_params *params,
|
||||||
static int mlx5e_build_rq_frags_info(struct mlx5_core_dev *mdev,
|
static int mlx5e_build_rq_frags_info(struct mlx5_core_dev *mdev,
|
||||||
struct mlx5e_params *params,
|
struct mlx5e_params *params,
|
||||||
struct mlx5e_xsk_param *xsk,
|
struct mlx5e_xsk_param *xsk,
|
||||||
struct mlx5e_rq_frags_info *info)
|
struct mlx5e_rq_frags_info *info,
|
||||||
|
u32 *xdp_frag_size)
|
||||||
{
|
{
|
||||||
u32 byte_count = MLX5E_SW2HW_MTU(params, params->sw_mtu);
|
u32 byte_count = MLX5E_SW2HW_MTU(params, params->sw_mtu);
|
||||||
int frag_size_max = DEFAULT_FRAG_SIZE;
|
int frag_size_max = DEFAULT_FRAG_SIZE;
|
||||||
|
@ -845,6 +846,8 @@ static int mlx5e_build_rq_frags_info(struct mlx5_core_dev *mdev,
|
||||||
|
|
||||||
info->log_num_frags = order_base_2(info->num_frags);
|
info->log_num_frags = order_base_2(info->num_frags);
|
||||||
|
|
||||||
|
*xdp_frag_size = info->num_frags > 1 && params->xdp_prog ? PAGE_SIZE : 0;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -989,7 +992,8 @@ int mlx5e_build_rq_param(struct mlx5_core_dev *mdev,
|
||||||
}
|
}
|
||||||
default: /* MLX5_WQ_TYPE_CYCLIC */
|
default: /* MLX5_WQ_TYPE_CYCLIC */
|
||||||
MLX5_SET(wq, wq, log_wq_sz, params->log_rq_mtu_frames);
|
MLX5_SET(wq, wq, log_wq_sz, params->log_rq_mtu_frames);
|
||||||
err = mlx5e_build_rq_frags_info(mdev, params, xsk, ¶m->frags_info);
|
err = mlx5e_build_rq_frags_info(mdev, params, xsk, ¶m->frags_info,
|
||||||
|
¶m->xdp_frag_size);
|
||||||
if (err)
|
if (err)
|
||||||
return err;
|
return err;
|
||||||
ndsegs = param->frags_info.num_frags;
|
ndsegs = param->frags_info.num_frags;
|
||||||
|
|
|
@ -24,6 +24,7 @@ struct mlx5e_rq_param {
|
||||||
u32 rqc[MLX5_ST_SZ_DW(rqc)];
|
u32 rqc[MLX5_ST_SZ_DW(rqc)];
|
||||||
struct mlx5_wq_param wq;
|
struct mlx5_wq_param wq;
|
||||||
struct mlx5e_rq_frags_info frags_info;
|
struct mlx5e_rq_frags_info frags_info;
|
||||||
|
u32 xdp_frag_size;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct mlx5e_sq_param {
|
struct mlx5e_sq_param {
|
||||||
|
|
|
@ -2021,6 +2021,8 @@ void
|
||||||
mlx5_tc_ct_delete_flow(struct mlx5_tc_ct_priv *priv,
|
mlx5_tc_ct_delete_flow(struct mlx5_tc_ct_priv *priv,
|
||||||
struct mlx5_flow_attr *attr)
|
struct mlx5_flow_attr *attr)
|
||||||
{
|
{
|
||||||
|
if (!attr->ct_attr.ft) /* no ct action, return */
|
||||||
|
return;
|
||||||
if (!attr->ct_attr.nf_ft) /* means only ct clear action, and not ct_clear,ct() */
|
if (!attr->ct_attr.nf_ft) /* means only ct clear action, and not ct_clear,ct() */
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
|
|
@ -86,7 +86,7 @@ static int mlx5e_init_xsk_rq(struct mlx5e_channel *c,
|
||||||
if (err)
|
if (err)
|
||||||
return err;
|
return err;
|
||||||
|
|
||||||
return xdp_rxq_info_reg(&rq->xdp_rxq, rq->netdev, rq_xdp_ix, 0);
|
return xdp_rxq_info_reg(&rq->xdp_rxq, rq->netdev, rq_xdp_ix, c->napi.napi_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int mlx5e_open_xsk_rq(struct mlx5e_channel *c, struct mlx5e_params *params,
|
static int mlx5e_open_xsk_rq(struct mlx5e_channel *c, struct mlx5e_params *params,
|
||||||
|
|
|
@ -61,16 +61,19 @@ static void mlx5e_ipsec_handle_tx_limit(struct work_struct *_work)
|
||||||
struct mlx5e_ipsec_sa_entry *sa_entry = dwork->sa_entry;
|
struct mlx5e_ipsec_sa_entry *sa_entry = dwork->sa_entry;
|
||||||
struct xfrm_state *x = sa_entry->x;
|
struct xfrm_state *x = sa_entry->x;
|
||||||
|
|
||||||
spin_lock(&x->lock);
|
if (sa_entry->attrs.drop)
|
||||||
|
return;
|
||||||
|
|
||||||
|
spin_lock_bh(&x->lock);
|
||||||
xfrm_state_check_expire(x);
|
xfrm_state_check_expire(x);
|
||||||
if (x->km.state == XFRM_STATE_EXPIRED) {
|
if (x->km.state == XFRM_STATE_EXPIRED) {
|
||||||
sa_entry->attrs.drop = true;
|
sa_entry->attrs.drop = true;
|
||||||
mlx5e_accel_ipsec_fs_modify(sa_entry);
|
spin_unlock_bh(&x->lock);
|
||||||
}
|
|
||||||
spin_unlock(&x->lock);
|
|
||||||
|
|
||||||
if (sa_entry->attrs.drop)
|
mlx5e_accel_ipsec_fs_modify(sa_entry);
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
spin_unlock_bh(&x->lock);
|
||||||
|
|
||||||
queue_delayed_work(sa_entry->ipsec->wq, &dwork->dwork,
|
queue_delayed_work(sa_entry->ipsec->wq, &dwork->dwork,
|
||||||
MLX5_IPSEC_RESCHED);
|
MLX5_IPSEC_RESCHED);
|
||||||
|
@ -1040,11 +1043,17 @@ static int mlx5e_xfrm_add_policy(struct xfrm_policy *x,
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void mlx5e_xfrm_free_policy(struct xfrm_policy *x)
|
static void mlx5e_xfrm_del_policy(struct xfrm_policy *x)
|
||||||
{
|
{
|
||||||
struct mlx5e_ipsec_pol_entry *pol_entry = to_ipsec_pol_entry(x);
|
struct mlx5e_ipsec_pol_entry *pol_entry = to_ipsec_pol_entry(x);
|
||||||
|
|
||||||
mlx5e_accel_ipsec_fs_del_pol(pol_entry);
|
mlx5e_accel_ipsec_fs_del_pol(pol_entry);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void mlx5e_xfrm_free_policy(struct xfrm_policy *x)
|
||||||
|
{
|
||||||
|
struct mlx5e_ipsec_pol_entry *pol_entry = to_ipsec_pol_entry(x);
|
||||||
|
|
||||||
kfree(pol_entry);
|
kfree(pol_entry);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1065,6 +1074,7 @@ static const struct xfrmdev_ops mlx5e_ipsec_packet_xfrmdev_ops = {
|
||||||
|
|
||||||
.xdo_dev_state_update_curlft = mlx5e_xfrm_update_curlft,
|
.xdo_dev_state_update_curlft = mlx5e_xfrm_update_curlft,
|
||||||
.xdo_dev_policy_add = mlx5e_xfrm_add_policy,
|
.xdo_dev_policy_add = mlx5e_xfrm_add_policy,
|
||||||
|
.xdo_dev_policy_delete = mlx5e_xfrm_del_policy,
|
||||||
.xdo_dev_policy_free = mlx5e_xfrm_free_policy,
|
.xdo_dev_policy_free = mlx5e_xfrm_free_policy,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -305,7 +305,17 @@ static void mlx5e_ipsec_update_esn_state(struct mlx5e_ipsec_sa_entry *sa_entry,
|
||||||
}
|
}
|
||||||
|
|
||||||
mlx5e_ipsec_build_accel_xfrm_attrs(sa_entry, &attrs);
|
mlx5e_ipsec_build_accel_xfrm_attrs(sa_entry, &attrs);
|
||||||
|
|
||||||
|
/* It is safe to execute the modify below unlocked since the only flows
|
||||||
|
* that could affect this HW object, are create, destroy and this work.
|
||||||
|
*
|
||||||
|
* Creation flow can't co-exist with this modify work, the destruction
|
||||||
|
* flow would cancel this work, and this work is a single entity that
|
||||||
|
* can't conflict with it self.
|
||||||
|
*/
|
||||||
|
spin_unlock_bh(&sa_entry->x->lock);
|
||||||
mlx5_accel_esp_modify_xfrm(sa_entry, &attrs);
|
mlx5_accel_esp_modify_xfrm(sa_entry, &attrs);
|
||||||
|
spin_lock_bh(&sa_entry->x->lock);
|
||||||
|
|
||||||
data.data_offset_condition_operand =
|
data.data_offset_condition_operand =
|
||||||
MLX5_IPSEC_ASO_REMOVE_FLOW_PKT_CNT_OFFSET;
|
MLX5_IPSEC_ASO_REMOVE_FLOW_PKT_CNT_OFFSET;
|
||||||
|
@ -431,7 +441,7 @@ static void mlx5e_ipsec_handle_event(struct work_struct *_work)
|
||||||
aso = sa_entry->ipsec->aso;
|
aso = sa_entry->ipsec->aso;
|
||||||
attrs = &sa_entry->attrs;
|
attrs = &sa_entry->attrs;
|
||||||
|
|
||||||
spin_lock(&sa_entry->x->lock);
|
spin_lock_bh(&sa_entry->x->lock);
|
||||||
ret = mlx5e_ipsec_aso_query(sa_entry, NULL);
|
ret = mlx5e_ipsec_aso_query(sa_entry, NULL);
|
||||||
if (ret)
|
if (ret)
|
||||||
goto unlock;
|
goto unlock;
|
||||||
|
@ -447,7 +457,7 @@ static void mlx5e_ipsec_handle_event(struct work_struct *_work)
|
||||||
mlx5e_ipsec_handle_limits(sa_entry);
|
mlx5e_ipsec_handle_limits(sa_entry);
|
||||||
|
|
||||||
unlock:
|
unlock:
|
||||||
spin_unlock(&sa_entry->x->lock);
|
spin_unlock_bh(&sa_entry->x->lock);
|
||||||
kfree(work);
|
kfree(work);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -596,7 +606,8 @@ int mlx5e_ipsec_aso_query(struct mlx5e_ipsec_sa_entry *sa_entry,
|
||||||
do {
|
do {
|
||||||
ret = mlx5_aso_poll_cq(aso->aso, false);
|
ret = mlx5_aso_poll_cq(aso->aso, false);
|
||||||
if (ret)
|
if (ret)
|
||||||
usleep_range(2, 10);
|
/* We are in atomic context */
|
||||||
|
udelay(10);
|
||||||
} while (ret && time_is_after_jiffies(expires));
|
} while (ret && time_is_after_jiffies(expires));
|
||||||
spin_unlock_bh(&aso->lock);
|
spin_unlock_bh(&aso->lock);
|
||||||
return ret;
|
return ret;
|
||||||
|
|
|
@ -641,7 +641,7 @@ static void mlx5e_free_mpwqe_rq_drop_page(struct mlx5e_rq *rq)
|
||||||
}
|
}
|
||||||
|
|
||||||
static int mlx5e_init_rxq_rq(struct mlx5e_channel *c, struct mlx5e_params *params,
|
static int mlx5e_init_rxq_rq(struct mlx5e_channel *c, struct mlx5e_params *params,
|
||||||
struct mlx5e_rq *rq)
|
u32 xdp_frag_size, struct mlx5e_rq *rq)
|
||||||
{
|
{
|
||||||
struct mlx5_core_dev *mdev = c->mdev;
|
struct mlx5_core_dev *mdev = c->mdev;
|
||||||
int err;
|
int err;
|
||||||
|
@ -665,7 +665,8 @@ static int mlx5e_init_rxq_rq(struct mlx5e_channel *c, struct mlx5e_params *param
|
||||||
if (err)
|
if (err)
|
||||||
return err;
|
return err;
|
||||||
|
|
||||||
return xdp_rxq_info_reg(&rq->xdp_rxq, rq->netdev, rq->ix, c->napi.napi_id);
|
return __xdp_rxq_info_reg(&rq->xdp_rxq, rq->netdev, rq->ix, c->napi.napi_id,
|
||||||
|
xdp_frag_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int mlx5_rq_shampo_alloc(struct mlx5_core_dev *mdev,
|
static int mlx5_rq_shampo_alloc(struct mlx5_core_dev *mdev,
|
||||||
|
@ -2240,7 +2241,7 @@ static int mlx5e_open_rxq_rq(struct mlx5e_channel *c, struct mlx5e_params *param
|
||||||
{
|
{
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
err = mlx5e_init_rxq_rq(c, params, &c->rq);
|
err = mlx5e_init_rxq_rq(c, params, rq_params->xdp_frag_size, &c->rq);
|
||||||
if (err)
|
if (err)
|
||||||
return err;
|
return err;
|
||||||
|
|
||||||
|
|
|
@ -1439,6 +1439,7 @@ static void mlx5e_tc_del_nic_flow(struct mlx5e_priv *priv,
|
||||||
mlx5e_hairpin_flow_del(priv, flow);
|
mlx5e_hairpin_flow_del(priv, flow);
|
||||||
|
|
||||||
free_flow_post_acts(flow);
|
free_flow_post_acts(flow);
|
||||||
|
mlx5_tc_ct_delete_flow(get_ct_priv(flow->priv), attr);
|
||||||
|
|
||||||
kvfree(attr->parse_attr);
|
kvfree(attr->parse_attr);
|
||||||
kfree(flow->attr);
|
kfree(flow->attr);
|
||||||
|
|
|
@ -511,10 +511,11 @@ static int mlx5_cmd_set_fte(struct mlx5_core_dev *dev,
|
||||||
struct mlx5_flow_rule *dst;
|
struct mlx5_flow_rule *dst;
|
||||||
void *in_flow_context, *vlan;
|
void *in_flow_context, *vlan;
|
||||||
void *in_match_value;
|
void *in_match_value;
|
||||||
|
int reformat_id = 0;
|
||||||
unsigned int inlen;
|
unsigned int inlen;
|
||||||
int dst_cnt_size;
|
int dst_cnt_size;
|
||||||
|
u32 *in, action;
|
||||||
void *in_dests;
|
void *in_dests;
|
||||||
u32 *in;
|
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
if (mlx5_set_extended_dest(dev, fte, &extended_dest))
|
if (mlx5_set_extended_dest(dev, fte, &extended_dest))
|
||||||
|
@ -553,22 +554,42 @@ static int mlx5_cmd_set_fte(struct mlx5_core_dev *dev,
|
||||||
|
|
||||||
MLX5_SET(flow_context, in_flow_context, extended_destination,
|
MLX5_SET(flow_context, in_flow_context, extended_destination,
|
||||||
extended_dest);
|
extended_dest);
|
||||||
if (extended_dest) {
|
|
||||||
u32 action;
|
|
||||||
|
|
||||||
action = fte->action.action &
|
action = fte->action.action;
|
||||||
~MLX5_FLOW_CONTEXT_ACTION_PACKET_REFORMAT;
|
if (extended_dest)
|
||||||
|
action &= ~MLX5_FLOW_CONTEXT_ACTION_PACKET_REFORMAT;
|
||||||
|
|
||||||
MLX5_SET(flow_context, in_flow_context, action, action);
|
MLX5_SET(flow_context, in_flow_context, action, action);
|
||||||
} else {
|
|
||||||
MLX5_SET(flow_context, in_flow_context, action,
|
if (!extended_dest && fte->action.pkt_reformat) {
|
||||||
fte->action.action);
|
struct mlx5_pkt_reformat *pkt_reformat = fte->action.pkt_reformat;
|
||||||
if (fte->action.pkt_reformat)
|
|
||||||
MLX5_SET(flow_context, in_flow_context, packet_reformat_id,
|
if (pkt_reformat->owner == MLX5_FLOW_RESOURCE_OWNER_SW) {
|
||||||
fte->action.pkt_reformat->id);
|
reformat_id = mlx5_fs_dr_action_get_pkt_reformat_id(pkt_reformat);
|
||||||
|
if (reformat_id < 0) {
|
||||||
|
mlx5_core_err(dev,
|
||||||
|
"Unsupported SW-owned pkt_reformat type (%d) in FW-owned table\n",
|
||||||
|
pkt_reformat->reformat_type);
|
||||||
|
err = reformat_id;
|
||||||
|
goto err_out;
|
||||||
}
|
}
|
||||||
if (fte->action.modify_hdr)
|
} else {
|
||||||
|
reformat_id = fte->action.pkt_reformat->id;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
MLX5_SET(flow_context, in_flow_context, packet_reformat_id, (u32)reformat_id);
|
||||||
|
|
||||||
|
if (fte->action.modify_hdr) {
|
||||||
|
if (fte->action.modify_hdr->owner == MLX5_FLOW_RESOURCE_OWNER_SW) {
|
||||||
|
mlx5_core_err(dev, "Can't use SW-owned modify_hdr in FW-owned table\n");
|
||||||
|
err = -EOPNOTSUPP;
|
||||||
|
goto err_out;
|
||||||
|
}
|
||||||
|
|
||||||
MLX5_SET(flow_context, in_flow_context, modify_header_id,
|
MLX5_SET(flow_context, in_flow_context, modify_header_id,
|
||||||
fte->action.modify_hdr->id);
|
fte->action.modify_hdr->id);
|
||||||
|
}
|
||||||
|
|
||||||
MLX5_SET(flow_context, in_flow_context, encrypt_decrypt_type,
|
MLX5_SET(flow_context, in_flow_context, encrypt_decrypt_type,
|
||||||
fte->action.crypto.type);
|
fte->action.crypto.type);
|
||||||
|
@ -885,6 +906,8 @@ static int mlx5_cmd_packet_reformat_alloc(struct mlx5_flow_root_namespace *ns,
|
||||||
|
|
||||||
pkt_reformat->id = MLX5_GET(alloc_packet_reformat_context_out,
|
pkt_reformat->id = MLX5_GET(alloc_packet_reformat_context_out,
|
||||||
out, packet_reformat_id);
|
out, packet_reformat_id);
|
||||||
|
pkt_reformat->owner = MLX5_FLOW_RESOURCE_OWNER_FW;
|
||||||
|
|
||||||
kfree(in);
|
kfree(in);
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
@ -969,6 +992,7 @@ static int mlx5_cmd_modify_header_alloc(struct mlx5_flow_root_namespace *ns,
|
||||||
err = mlx5_cmd_exec(dev, in, inlen, out, sizeof(out));
|
err = mlx5_cmd_exec(dev, in, inlen, out, sizeof(out));
|
||||||
|
|
||||||
modify_hdr->id = MLX5_GET(alloc_modify_header_context_out, out, modify_header_id);
|
modify_hdr->id = MLX5_GET(alloc_modify_header_context_out, out, modify_header_id);
|
||||||
|
modify_hdr->owner = MLX5_FLOW_RESOURCE_OWNER_FW;
|
||||||
kfree(in);
|
kfree(in);
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
|
@ -54,8 +54,14 @@ struct mlx5_flow_definer {
|
||||||
u32 id;
|
u32 id;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum mlx5_flow_resource_owner {
|
||||||
|
MLX5_FLOW_RESOURCE_OWNER_FW,
|
||||||
|
MLX5_FLOW_RESOURCE_OWNER_SW,
|
||||||
|
};
|
||||||
|
|
||||||
struct mlx5_modify_hdr {
|
struct mlx5_modify_hdr {
|
||||||
enum mlx5_flow_namespace_type ns_type;
|
enum mlx5_flow_namespace_type ns_type;
|
||||||
|
enum mlx5_flow_resource_owner owner;
|
||||||
union {
|
union {
|
||||||
struct mlx5_fs_dr_action action;
|
struct mlx5_fs_dr_action action;
|
||||||
u32 id;
|
u32 id;
|
||||||
|
@ -65,6 +71,7 @@ struct mlx5_modify_hdr {
|
||||||
struct mlx5_pkt_reformat {
|
struct mlx5_pkt_reformat {
|
||||||
enum mlx5_flow_namespace_type ns_type;
|
enum mlx5_flow_namespace_type ns_type;
|
||||||
int reformat_type; /* from mlx5_ifc */
|
int reformat_type; /* from mlx5_ifc */
|
||||||
|
enum mlx5_flow_resource_owner owner;
|
||||||
union {
|
union {
|
||||||
struct mlx5_fs_dr_action action;
|
struct mlx5_fs_dr_action action;
|
||||||
u32 id;
|
u32 id;
|
||||||
|
|
|
@ -126,14 +126,22 @@ int mlx5_set_msix_vec_count(struct mlx5_core_dev *dev, int function_id,
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void irq_release(struct mlx5_irq *irq)
|
/* mlx5_system_free_irq - Free an IRQ
|
||||||
|
* @irq: IRQ to free
|
||||||
|
*
|
||||||
|
* Free the IRQ and other resources such as rmap from the system.
|
||||||
|
* BUT doesn't free or remove reference from mlx5.
|
||||||
|
* This function is very important for the shutdown flow, where we need to
|
||||||
|
* cleanup system resoruces but keep mlx5 objects alive,
|
||||||
|
* see mlx5_irq_table_free_irqs().
|
||||||
|
*/
|
||||||
|
static void mlx5_system_free_irq(struct mlx5_irq *irq)
|
||||||
{
|
{
|
||||||
struct mlx5_irq_pool *pool = irq->pool;
|
struct mlx5_irq_pool *pool = irq->pool;
|
||||||
#ifdef CONFIG_RFS_ACCEL
|
#ifdef CONFIG_RFS_ACCEL
|
||||||
struct cpu_rmap *rmap;
|
struct cpu_rmap *rmap;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
xa_erase(&pool->irqs, irq->pool_index);
|
|
||||||
/* free_irq requires that affinity_hint and rmap will be cleared before
|
/* free_irq requires that affinity_hint and rmap will be cleared before
|
||||||
* calling it. To satisfy this requirement, we call
|
* calling it. To satisfy this requirement, we call
|
||||||
* irq_cpu_rmap_remove() to remove the notifier
|
* irq_cpu_rmap_remove() to remove the notifier
|
||||||
|
@ -145,10 +153,18 @@ static void irq_release(struct mlx5_irq *irq)
|
||||||
irq_cpu_rmap_remove(rmap, irq->map.virq);
|
irq_cpu_rmap_remove(rmap, irq->map.virq);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
free_cpumask_var(irq->mask);
|
|
||||||
free_irq(irq->map.virq, &irq->nh);
|
free_irq(irq->map.virq, &irq->nh);
|
||||||
if (irq->map.index && pci_msix_can_alloc_dyn(pool->dev->pdev))
|
if (irq->map.index && pci_msix_can_alloc_dyn(pool->dev->pdev))
|
||||||
pci_msix_free_irq(pool->dev->pdev, irq->map);
|
pci_msix_free_irq(pool->dev->pdev, irq->map);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void irq_release(struct mlx5_irq *irq)
|
||||||
|
{
|
||||||
|
struct mlx5_irq_pool *pool = irq->pool;
|
||||||
|
|
||||||
|
xa_erase(&pool->irqs, irq->pool_index);
|
||||||
|
mlx5_system_free_irq(irq);
|
||||||
|
free_cpumask_var(irq->mask);
|
||||||
kfree(irq);
|
kfree(irq);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -565,15 +581,21 @@ void mlx5_irqs_release_vectors(struct mlx5_irq **irqs, int nirqs)
|
||||||
int mlx5_irqs_request_vectors(struct mlx5_core_dev *dev, u16 *cpus, int nirqs,
|
int mlx5_irqs_request_vectors(struct mlx5_core_dev *dev, u16 *cpus, int nirqs,
|
||||||
struct mlx5_irq **irqs, struct cpu_rmap **rmap)
|
struct mlx5_irq **irqs, struct cpu_rmap **rmap)
|
||||||
{
|
{
|
||||||
|
struct mlx5_irq_table *table = mlx5_irq_table_get(dev);
|
||||||
|
struct mlx5_irq_pool *pool = table->pcif_pool;
|
||||||
struct irq_affinity_desc af_desc;
|
struct irq_affinity_desc af_desc;
|
||||||
struct mlx5_irq *irq;
|
struct mlx5_irq *irq;
|
||||||
|
int offset = 1;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
|
if (!pool->xa_num_irqs.max)
|
||||||
|
offset = 0;
|
||||||
|
|
||||||
af_desc.is_managed = false;
|
af_desc.is_managed = false;
|
||||||
for (i = 0; i < nirqs; i++) {
|
for (i = 0; i < nirqs; i++) {
|
||||||
cpumask_clear(&af_desc.mask);
|
cpumask_clear(&af_desc.mask);
|
||||||
cpumask_set_cpu(cpus[i], &af_desc.mask);
|
cpumask_set_cpu(cpus[i], &af_desc.mask);
|
||||||
irq = mlx5_irq_request(dev, i + 1, &af_desc, rmap);
|
irq = mlx5_irq_request(dev, i + offset, &af_desc, rmap);
|
||||||
if (IS_ERR(irq))
|
if (IS_ERR(irq))
|
||||||
break;
|
break;
|
||||||
irqs[i] = irq;
|
irqs[i] = irq;
|
||||||
|
@ -699,7 +721,8 @@ static void mlx5_irq_pool_free_irqs(struct mlx5_irq_pool *pool)
|
||||||
unsigned long index;
|
unsigned long index;
|
||||||
|
|
||||||
xa_for_each(&pool->irqs, index, irq)
|
xa_for_each(&pool->irqs, index, irq)
|
||||||
free_irq(irq->map.virq, &irq->nh);
|
mlx5_system_free_irq(irq);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void mlx5_irq_pools_free_irqs(struct mlx5_irq_table *table)
|
static void mlx5_irq_pools_free_irqs(struct mlx5_irq_table *table)
|
||||||
|
|
|
@ -1421,9 +1421,13 @@ dr_action_create_reformat_action(struct mlx5dr_domain *dmn,
|
||||||
}
|
}
|
||||||
case DR_ACTION_TYP_TNL_L3_TO_L2:
|
case DR_ACTION_TYP_TNL_L3_TO_L2:
|
||||||
{
|
{
|
||||||
u8 hw_actions[DR_ACTION_CACHE_LINE_SIZE] = {};
|
u8 *hw_actions;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
|
hw_actions = kzalloc(DR_ACTION_CACHE_LINE_SIZE, GFP_KERNEL);
|
||||||
|
if (!hw_actions)
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
ret = mlx5dr_ste_set_action_decap_l3_list(dmn->ste_ctx,
|
ret = mlx5dr_ste_set_action_decap_l3_list(dmn->ste_ctx,
|
||||||
data, data_sz,
|
data, data_sz,
|
||||||
hw_actions,
|
hw_actions,
|
||||||
|
@ -1431,6 +1435,7 @@ dr_action_create_reformat_action(struct mlx5dr_domain *dmn,
|
||||||
&action->rewrite->num_of_actions);
|
&action->rewrite->num_of_actions);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
mlx5dr_dbg(dmn, "Failed creating decap l3 action list\n");
|
mlx5dr_dbg(dmn, "Failed creating decap l3 action list\n");
|
||||||
|
kfree(hw_actions);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1440,6 +1445,7 @@ dr_action_create_reformat_action(struct mlx5dr_domain *dmn,
|
||||||
ret = mlx5dr_ste_alloc_modify_hdr(action);
|
ret = mlx5dr_ste_alloc_modify_hdr(action);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
mlx5dr_dbg(dmn, "Failed preparing reformat data\n");
|
mlx5dr_dbg(dmn, "Failed preparing reformat data\n");
|
||||||
|
kfree(hw_actions);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -2129,6 +2135,11 @@ mlx5dr_action_create_aso(struct mlx5dr_domain *dmn, u32 obj_id,
|
||||||
return action;
|
return action;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
u32 mlx5dr_action_get_pkt_reformat_id(struct mlx5dr_action *action)
|
||||||
|
{
|
||||||
|
return action->reformat->id;
|
||||||
|
}
|
||||||
|
|
||||||
int mlx5dr_action_destroy(struct mlx5dr_action *action)
|
int mlx5dr_action_destroy(struct mlx5dr_action *action)
|
||||||
{
|
{
|
||||||
if (WARN_ON_ONCE(refcount_read(&action->refcount) > 1))
|
if (WARN_ON_ONCE(refcount_read(&action->refcount) > 1))
|
||||||
|
|
|
@ -331,7 +331,15 @@ static int mlx5_cmd_dr_create_fte(struct mlx5_flow_root_namespace *ns,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fte->action.action & MLX5_FLOW_CONTEXT_ACTION_PACKET_REFORMAT) {
|
if (fte->action.action & MLX5_FLOW_CONTEXT_ACTION_PACKET_REFORMAT) {
|
||||||
bool is_decap = fte->action.pkt_reformat->reformat_type ==
|
bool is_decap;
|
||||||
|
|
||||||
|
if (fte->action.pkt_reformat->owner == MLX5_FLOW_RESOURCE_OWNER_FW) {
|
||||||
|
err = -EINVAL;
|
||||||
|
mlx5dr_err(domain, "FW-owned reformat can't be used in SW rule\n");
|
||||||
|
goto free_actions;
|
||||||
|
}
|
||||||
|
|
||||||
|
is_decap = fte->action.pkt_reformat->reformat_type ==
|
||||||
MLX5_REFORMAT_TYPE_L3_TUNNEL_TO_L2;
|
MLX5_REFORMAT_TYPE_L3_TUNNEL_TO_L2;
|
||||||
|
|
||||||
if (is_decap)
|
if (is_decap)
|
||||||
|
@ -661,6 +669,7 @@ static int mlx5_cmd_dr_packet_reformat_alloc(struct mlx5_flow_root_namespace *ns
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pkt_reformat->owner = MLX5_FLOW_RESOURCE_OWNER_SW;
|
||||||
pkt_reformat->action.dr_action = action;
|
pkt_reformat->action.dr_action = action;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -691,6 +700,7 @@ static int mlx5_cmd_dr_modify_header_alloc(struct mlx5_flow_root_namespace *ns,
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
modify_hdr->owner = MLX5_FLOW_RESOURCE_OWNER_SW;
|
||||||
modify_hdr->action.dr_action = action;
|
modify_hdr->action.dr_action = action;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -816,6 +826,19 @@ static u32 mlx5_cmd_dr_get_capabilities(struct mlx5_flow_root_namespace *ns,
|
||||||
return steering_caps;
|
return steering_caps;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int mlx5_fs_dr_action_get_pkt_reformat_id(struct mlx5_pkt_reformat *pkt_reformat)
|
||||||
|
{
|
||||||
|
switch (pkt_reformat->reformat_type) {
|
||||||
|
case MLX5_REFORMAT_TYPE_L2_TO_VXLAN:
|
||||||
|
case MLX5_REFORMAT_TYPE_L2_TO_NVGRE:
|
||||||
|
case MLX5_REFORMAT_TYPE_L2_TO_L2_TUNNEL:
|
||||||
|
case MLX5_REFORMAT_TYPE_L2_TO_L3_TUNNEL:
|
||||||
|
case MLX5_REFORMAT_TYPE_INSERT_HDR:
|
||||||
|
return mlx5dr_action_get_pkt_reformat_id(pkt_reformat->action.dr_action);
|
||||||
|
}
|
||||||
|
return -EOPNOTSUPP;
|
||||||
|
}
|
||||||
|
|
||||||
bool mlx5_fs_dr_is_supported(struct mlx5_core_dev *dev)
|
bool mlx5_fs_dr_is_supported(struct mlx5_core_dev *dev)
|
||||||
{
|
{
|
||||||
return mlx5dr_is_supported(dev);
|
return mlx5dr_is_supported(dev);
|
||||||
|
|
|
@ -38,6 +38,8 @@ struct mlx5_fs_dr_table {
|
||||||
|
|
||||||
bool mlx5_fs_dr_is_supported(struct mlx5_core_dev *dev);
|
bool mlx5_fs_dr_is_supported(struct mlx5_core_dev *dev);
|
||||||
|
|
||||||
|
int mlx5_fs_dr_action_get_pkt_reformat_id(struct mlx5_pkt_reformat *pkt_reformat);
|
||||||
|
|
||||||
const struct mlx5_flow_cmds *mlx5_fs_cmd_get_dr_cmds(void);
|
const struct mlx5_flow_cmds *mlx5_fs_cmd_get_dr_cmds(void);
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
@ -47,6 +49,11 @@ static inline const struct mlx5_flow_cmds *mlx5_fs_cmd_get_dr_cmds(void)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline u32 mlx5_fs_dr_action_get_pkt_reformat_id(struct mlx5_pkt_reformat *pkt_reformat)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static inline bool mlx5_fs_dr_is_supported(struct mlx5_core_dev *dev)
|
static inline bool mlx5_fs_dr_is_supported(struct mlx5_core_dev *dev)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -150,6 +150,8 @@ mlx5dr_action_create_dest_match_range(struct mlx5dr_domain *dmn,
|
||||||
|
|
||||||
int mlx5dr_action_destroy(struct mlx5dr_action *action);
|
int mlx5dr_action_destroy(struct mlx5dr_action *action);
|
||||||
|
|
||||||
|
u32 mlx5dr_action_get_pkt_reformat_id(struct mlx5dr_action *action);
|
||||||
|
|
||||||
int mlx5dr_definer_get(struct mlx5dr_domain *dmn, u16 format_id,
|
int mlx5dr_definer_get(struct mlx5dr_domain *dmn, u16 format_id,
|
||||||
u8 *dw_selectors, u8 *byte_selectors,
|
u8 *dw_selectors, u8 *byte_selectors,
|
||||||
u8 *match_mask, u32 *definer_id);
|
u8 *match_mask, u32 *definer_id);
|
||||||
|
|
Loading…
Reference in a new issue