mlx5-fixes-2022-01-06
-----BEGIN PGP SIGNATURE----- iQEzBAABCAAdFiEEGhZs6bAKwk/OTgTpSD+KveBX+j4FAmHXj44ACgkQSD+KveBX +j4cWggAsenq+AvDHtq2JwolF/IUiNetWiWIrIvnaKLBNcWAL4CvdMU7zNVpjnr5 03xuSn/LnCaCynnF52RSPNWH7RTue2gsVz28pR6cBUMyJ05DL7lxbjpgnu29E/mG vPx8QR/DZjyWYjPt1d46niYKd2FK6egnlGrVrQ911s3zox35R1HHoWPtk+C1/s8i iThuZXTcDBPNPPiwtbANENTPBjTabW9we7F8k5iZNzQiTDkxdH349ojlebNv37Zy Q+BYJJfAxvpMm/kyA4lDAqehKRtbIUqK7n0c8WaF4kxCpA7VKQU7T0osCAa+S7JD R1+juxG3xiZkToKqqMmAu4x0f3mDOw== =KRes -----END PGP SIGNATURE----- Merge tag 'mlx5-fixes-2022-01-06' of git://git.kernel.org/pub/scm/linux/kernel/git/saeed/linux Saeed Mahameed says: ==================== mlx5 fixes 2022-01-06 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
14676c0478
|
@ -148,8 +148,12 @@ static void cmd_ent_put(struct mlx5_cmd_work_ent *ent)
|
|||
if (!refcount_dec_and_test(&ent->refcnt))
|
||||
return;
|
||||
|
||||
if (ent->idx >= 0)
|
||||
cmd_free_index(ent->cmd, ent->idx);
|
||||
if (ent->idx >= 0) {
|
||||
struct mlx5_cmd *cmd = ent->cmd;
|
||||
|
||||
cmd_free_index(cmd, ent->idx);
|
||||
up(ent->page_queue ? &cmd->pages_sem : &cmd->sem);
|
||||
}
|
||||
|
||||
cmd_free_ent(ent);
|
||||
}
|
||||
|
@ -900,25 +904,6 @@ static bool opcode_allowed(struct mlx5_cmd *cmd, u16 opcode)
|
|||
return cmd->allowed_opcode == opcode;
|
||||
}
|
||||
|
||||
static int cmd_alloc_index_retry(struct mlx5_cmd *cmd)
|
||||
{
|
||||
unsigned long alloc_end = jiffies + msecs_to_jiffies(1000);
|
||||
int idx;
|
||||
|
||||
retry:
|
||||
idx = cmd_alloc_index(cmd);
|
||||
if (idx < 0 && time_before(jiffies, alloc_end)) {
|
||||
/* Index allocation can fail on heavy load of commands. This is a temporary
|
||||
* situation as the current command already holds the semaphore, meaning that
|
||||
* another command completion is being handled and it is expected to release
|
||||
* the entry index soon.
|
||||
*/
|
||||
cpu_relax();
|
||||
goto retry;
|
||||
}
|
||||
return idx;
|
||||
}
|
||||
|
||||
bool mlx5_cmd_is_down(struct mlx5_core_dev *dev)
|
||||
{
|
||||
return pci_channel_offline(dev->pdev) ||
|
||||
|
@ -946,7 +931,7 @@ static void cmd_work_handler(struct work_struct *work)
|
|||
sem = ent->page_queue ? &cmd->pages_sem : &cmd->sem;
|
||||
down(sem);
|
||||
if (!ent->page_queue) {
|
||||
alloc_ret = cmd_alloc_index_retry(cmd);
|
||||
alloc_ret = cmd_alloc_index(cmd);
|
||||
if (alloc_ret < 0) {
|
||||
mlx5_core_err_rl(dev, "failed to allocate command entry\n");
|
||||
if (ent->callback) {
|
||||
|
@ -1602,8 +1587,6 @@ static void mlx5_cmd_comp_handler(struct mlx5_core_dev *dev, u64 vec, bool force
|
|||
vector = vec & 0xffffffff;
|
||||
for (i = 0; i < (1 << cmd->log_sz); i++) {
|
||||
if (test_bit(i, &vector)) {
|
||||
struct semaphore *sem;
|
||||
|
||||
ent = cmd->ent_arr[i];
|
||||
|
||||
/* if we already completed the command, ignore it */
|
||||
|
@ -1626,10 +1609,6 @@ static void mlx5_cmd_comp_handler(struct mlx5_core_dev *dev, u64 vec, bool force
|
|||
dev->state == MLX5_DEVICE_STATE_INTERNAL_ERROR)
|
||||
cmd_ent_put(ent);
|
||||
|
||||
if (ent->page_queue)
|
||||
sem = &cmd->pages_sem;
|
||||
else
|
||||
sem = &cmd->sem;
|
||||
ent->ts2 = ktime_get_ns();
|
||||
memcpy(ent->out->first.data, ent->lay->out, sizeof(ent->lay->out));
|
||||
dump_command(dev, ent, 0);
|
||||
|
@ -1683,7 +1662,6 @@ static void mlx5_cmd_comp_handler(struct mlx5_core_dev *dev, u64 vec, bool force
|
|||
*/
|
||||
complete(&ent->done);
|
||||
}
|
||||
up(sem);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1579,6 +1579,8 @@ mlx5e_init_fib_work_ipv4(struct mlx5e_priv *priv,
|
|||
struct net_device *fib_dev;
|
||||
|
||||
fen_info = container_of(info, struct fib_entry_notifier_info, info);
|
||||
if (fen_info->fi->nh)
|
||||
return NULL;
|
||||
fib_dev = fib_info_nh(fen_info->fi, 0)->fib_nh_dev;
|
||||
if (!fib_dev || fib_dev->netdev_ops != &mlx5e_netdev_ops ||
|
||||
fen_info->dst_len != 32)
|
||||
|
|
|
@ -11,13 +11,13 @@ static int mlx5e_xsk_map_pool(struct mlx5e_priv *priv,
|
|||
{
|
||||
struct device *dev = mlx5_core_dma_dev(priv->mdev);
|
||||
|
||||
return xsk_pool_dma_map(pool, dev, 0);
|
||||
return xsk_pool_dma_map(pool, dev, DMA_ATTR_SKIP_CPU_SYNC);
|
||||
}
|
||||
|
||||
static void mlx5e_xsk_unmap_pool(struct mlx5e_priv *priv,
|
||||
struct xsk_buff_pool *pool)
|
||||
{
|
||||
return xsk_pool_dma_unmap(pool, 0);
|
||||
return xsk_pool_dma_unmap(pool, DMA_ATTR_SKIP_CPU_SYNC);
|
||||
}
|
||||
|
||||
static int mlx5e_xsk_get_pools(struct mlx5e_xsk *xsk)
|
||||
|
|
|
@ -4789,15 +4789,22 @@ static void mlx5e_build_nic_netdev(struct net_device *netdev)
|
|||
}
|
||||
|
||||
if (mlx5_vxlan_allowed(mdev->vxlan) || mlx5_geneve_tx_allowed(mdev)) {
|
||||
netdev->hw_features |= NETIF_F_GSO_UDP_TUNNEL;
|
||||
netdev->hw_enc_features |= NETIF_F_GSO_UDP_TUNNEL;
|
||||
netdev->vlan_features |= NETIF_F_GSO_UDP_TUNNEL;
|
||||
netdev->hw_features |= NETIF_F_GSO_UDP_TUNNEL |
|
||||
NETIF_F_GSO_UDP_TUNNEL_CSUM;
|
||||
netdev->hw_enc_features |= NETIF_F_GSO_UDP_TUNNEL |
|
||||
NETIF_F_GSO_UDP_TUNNEL_CSUM;
|
||||
netdev->gso_partial_features = NETIF_F_GSO_UDP_TUNNEL_CSUM;
|
||||
netdev->vlan_features |= NETIF_F_GSO_UDP_TUNNEL |
|
||||
NETIF_F_GSO_UDP_TUNNEL_CSUM;
|
||||
}
|
||||
|
||||
if (mlx5e_tunnel_proto_supported_tx(mdev, IPPROTO_GRE)) {
|
||||
netdev->hw_features |= NETIF_F_GSO_GRE;
|
||||
netdev->hw_enc_features |= NETIF_F_GSO_GRE;
|
||||
netdev->gso_partial_features |= NETIF_F_GSO_GRE;
|
||||
netdev->hw_features |= NETIF_F_GSO_GRE |
|
||||
NETIF_F_GSO_GRE_CSUM;
|
||||
netdev->hw_enc_features |= NETIF_F_GSO_GRE |
|
||||
NETIF_F_GSO_GRE_CSUM;
|
||||
netdev->gso_partial_features |= NETIF_F_GSO_GRE |
|
||||
NETIF_F_GSO_GRE_CSUM;
|
||||
}
|
||||
|
||||
if (mlx5e_tunnel_proto_supported_tx(mdev, IPPROTO_IPIP)) {
|
||||
|
|
|
@ -50,6 +50,7 @@
|
|||
#include "fs_core.h"
|
||||
#include "lib/mlx5.h"
|
||||
#include "lib/devcom.h"
|
||||
#include "lib/vxlan.h"
|
||||
#define CREATE_TRACE_POINTS
|
||||
#include "diag/en_rep_tracepoint.h"
|
||||
#include "en_accel/ipsec.h"
|
||||
|
@ -1027,6 +1028,7 @@ static void mlx5e_uplink_rep_enable(struct mlx5e_priv *priv)
|
|||
rtnl_lock();
|
||||
if (netif_running(netdev))
|
||||
mlx5e_open(netdev);
|
||||
udp_tunnel_nic_reset_ntf(priv->netdev);
|
||||
netif_device_attach(netdev);
|
||||
rtnl_unlock();
|
||||
}
|
||||
|
@ -1048,6 +1050,7 @@ static void mlx5e_uplink_rep_disable(struct mlx5e_priv *priv)
|
|||
mlx5_notifier_unregister(mdev, &priv->events_nb);
|
||||
mlx5e_rep_tc_disable(priv);
|
||||
mlx5_lag_remove_netdev(mdev, priv->netdev);
|
||||
mlx5_vxlan_reset_to_default(mdev->vxlan);
|
||||
}
|
||||
|
||||
static MLX5E_DEFINE_STATS_GRP(sw_rep, 0);
|
||||
|
|
|
@ -278,8 +278,8 @@ static inline int mlx5e_page_alloc_pool(struct mlx5e_rq *rq,
|
|||
if (unlikely(!dma_info->page))
|
||||
return -ENOMEM;
|
||||
|
||||
dma_info->addr = dma_map_page(rq->pdev, dma_info->page, 0,
|
||||
PAGE_SIZE, rq->buff.map_dir);
|
||||
dma_info->addr = dma_map_page_attrs(rq->pdev, dma_info->page, 0, PAGE_SIZE,
|
||||
rq->buff.map_dir, DMA_ATTR_SKIP_CPU_SYNC);
|
||||
if (unlikely(dma_mapping_error(rq->pdev, dma_info->addr))) {
|
||||
page_pool_recycle_direct(rq->page_pool, dma_info->page);
|
||||
dma_info->page = NULL;
|
||||
|
@ -300,7 +300,8 @@ static inline int mlx5e_page_alloc(struct mlx5e_rq *rq,
|
|||
|
||||
void mlx5e_page_dma_unmap(struct mlx5e_rq *rq, struct mlx5e_dma_info *dma_info)
|
||||
{
|
||||
dma_unmap_page(rq->pdev, dma_info->addr, PAGE_SIZE, rq->buff.map_dir);
|
||||
dma_unmap_page_attrs(rq->pdev, dma_info->addr, PAGE_SIZE, rq->buff.map_dir,
|
||||
DMA_ATTR_SKIP_CPU_SYNC);
|
||||
}
|
||||
|
||||
void mlx5e_page_release_dynamic(struct mlx5e_rq *rq,
|
||||
|
|
|
@ -1949,6 +1949,111 @@ u8 mlx5e_tc_get_ip_version(struct mlx5_flow_spec *spec, bool outer)
|
|||
return ip_version;
|
||||
}
|
||||
|
||||
/* Tunnel device follows RFC 6040, see include/net/inet_ecn.h.
|
||||
* And changes inner ip_ecn depending on inner and outer ip_ecn as follows:
|
||||
* +---------+----------------------------------------+
|
||||
* |Arriving | Arriving Outer Header |
|
||||
* | Inner +---------+---------+---------+----------+
|
||||
* | Header | Not-ECT | ECT(0) | ECT(1) | CE |
|
||||
* +---------+---------+---------+---------+----------+
|
||||
* | Not-ECT | Not-ECT | Not-ECT | Not-ECT | <drop> |
|
||||
* | ECT(0) | ECT(0) | ECT(0) | ECT(1) | CE* |
|
||||
* | ECT(1) | ECT(1) | ECT(1) | ECT(1)* | CE* |
|
||||
* | CE | CE | CE | CE | CE |
|
||||
* +---------+---------+---------+---------+----------+
|
||||
*
|
||||
* Tc matches on inner after decapsulation on tunnel device, but hw offload matches
|
||||
* the inner ip_ecn value before hardware decap action.
|
||||
*
|
||||
* Cells marked are changed from original inner packet ip_ecn value during decap, and
|
||||
* so matching those values on inner ip_ecn before decap will fail.
|
||||
*
|
||||
* The following helper allows offload when inner ip_ecn won't be changed by outer ip_ecn,
|
||||
* except for the outer ip_ecn = CE, where in all cases inner ip_ecn will be changed to CE,
|
||||
* and such we can drop the inner ip_ecn=CE match.
|
||||
*/
|
||||
|
||||
static int mlx5e_tc_verify_tunnel_ecn(struct mlx5e_priv *priv,
|
||||
struct flow_cls_offload *f,
|
||||
bool *match_inner_ecn)
|
||||
{
|
||||
u8 outer_ecn_mask = 0, outer_ecn_key = 0, inner_ecn_mask = 0, inner_ecn_key = 0;
|
||||
struct flow_rule *rule = flow_cls_offload_flow_rule(f);
|
||||
struct netlink_ext_ack *extack = f->common.extack;
|
||||
struct flow_match_ip match;
|
||||
|
||||
*match_inner_ecn = true;
|
||||
|
||||
if (flow_rule_match_key(rule, FLOW_DISSECTOR_KEY_ENC_IP)) {
|
||||
flow_rule_match_enc_ip(rule, &match);
|
||||
outer_ecn_key = match.key->tos & INET_ECN_MASK;
|
||||
outer_ecn_mask = match.mask->tos & INET_ECN_MASK;
|
||||
}
|
||||
|
||||
if (flow_rule_match_key(rule, FLOW_DISSECTOR_KEY_IP)) {
|
||||
flow_rule_match_ip(rule, &match);
|
||||
inner_ecn_key = match.key->tos & INET_ECN_MASK;
|
||||
inner_ecn_mask = match.mask->tos & INET_ECN_MASK;
|
||||
}
|
||||
|
||||
if (outer_ecn_mask != 0 && outer_ecn_mask != INET_ECN_MASK) {
|
||||
NL_SET_ERR_MSG_MOD(extack, "Partial match on enc_tos ecn bits isn't supported");
|
||||
netdev_warn(priv->netdev, "Partial match on enc_tos ecn bits isn't supported");
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
if (!outer_ecn_mask) {
|
||||
if (!inner_ecn_mask)
|
||||
return 0;
|
||||
|
||||
NL_SET_ERR_MSG_MOD(extack,
|
||||
"Matching on tos ecn bits without also matching enc_tos ecn bits isn't supported");
|
||||
netdev_warn(priv->netdev,
|
||||
"Matching on tos ecn bits without also matching enc_tos ecn bits isn't supported");
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
if (inner_ecn_mask && inner_ecn_mask != INET_ECN_MASK) {
|
||||
NL_SET_ERR_MSG_MOD(extack,
|
||||
"Partial match on tos ecn bits with match on enc_tos ecn bits isn't supported");
|
||||
netdev_warn(priv->netdev,
|
||||
"Partial match on tos ecn bits with match on enc_tos ecn bits isn't supported");
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
if (!inner_ecn_mask)
|
||||
return 0;
|
||||
|
||||
/* Both inner and outer have full mask on ecn */
|
||||
|
||||
if (outer_ecn_key == INET_ECN_ECT_1) {
|
||||
/* inner ecn might change by DECAP action */
|
||||
|
||||
NL_SET_ERR_MSG_MOD(extack, "Match on enc_tos ecn = ECT(1) isn't supported");
|
||||
netdev_warn(priv->netdev, "Match on enc_tos ecn = ECT(1) isn't supported");
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
if (outer_ecn_key != INET_ECN_CE)
|
||||
return 0;
|
||||
|
||||
if (inner_ecn_key != INET_ECN_CE) {
|
||||
/* Can't happen in software, as packet ecn will be changed to CE after decap */
|
||||
NL_SET_ERR_MSG_MOD(extack,
|
||||
"Match on tos enc_tos ecn = CE while match on tos ecn != CE isn't supported");
|
||||
netdev_warn(priv->netdev,
|
||||
"Match on tos enc_tos ecn = CE while match on tos ecn != CE isn't supported");
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
/* outer ecn = CE, inner ecn = CE, as decap will change inner ecn to CE in anycase,
|
||||
* drop match on inner ecn
|
||||
*/
|
||||
*match_inner_ecn = false;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int parse_tunnel_attr(struct mlx5e_priv *priv,
|
||||
struct mlx5e_tc_flow *flow,
|
||||
struct mlx5_flow_spec *spec,
|
||||
|
@ -2144,6 +2249,7 @@ static int __parse_cls_flower(struct mlx5e_priv *priv,
|
|||
struct flow_rule *rule = flow_cls_offload_flow_rule(f);
|
||||
struct flow_dissector *dissector = rule->match.dissector;
|
||||
enum fs_flow_table_type fs_type;
|
||||
bool match_inner_ecn = true;
|
||||
u16 addr_type = 0;
|
||||
u8 ip_proto = 0;
|
||||
u8 *match_level;
|
||||
|
@ -2197,6 +2303,10 @@ static int __parse_cls_flower(struct mlx5e_priv *priv,
|
|||
headers_c = get_match_inner_headers_criteria(spec);
|
||||
headers_v = get_match_inner_headers_value(spec);
|
||||
}
|
||||
|
||||
err = mlx5e_tc_verify_tunnel_ecn(priv, f, &match_inner_ecn);
|
||||
if (err)
|
||||
return err;
|
||||
}
|
||||
|
||||
err = mlx5e_flower_parse_meta(filter_dev, f);
|
||||
|
@ -2420,10 +2530,12 @@ static int __parse_cls_flower(struct mlx5e_priv *priv,
|
|||
struct flow_match_ip match;
|
||||
|
||||
flow_rule_match_ip(rule, &match);
|
||||
MLX5_SET(fte_match_set_lyr_2_4, headers_c, ip_ecn,
|
||||
match.mask->tos & 0x3);
|
||||
MLX5_SET(fte_match_set_lyr_2_4, headers_v, ip_ecn,
|
||||
match.key->tos & 0x3);
|
||||
if (match_inner_ecn) {
|
||||
MLX5_SET(fte_match_set_lyr_2_4, headers_c, ip_ecn,
|
||||
match.mask->tos & 0x3);
|
||||
MLX5_SET(fte_match_set_lyr_2_4, headers_v, ip_ecn,
|
||||
match.key->tos & 0x3);
|
||||
}
|
||||
|
||||
MLX5_SET(fte_match_set_lyr_2_4, headers_c, ip_dscp,
|
||||
match.mask->tos >> 2);
|
||||
|
|
|
@ -295,26 +295,28 @@ esw_setup_chain_src_port_rewrite(struct mlx5_flow_destination *dest,
|
|||
int *i)
|
||||
{
|
||||
struct mlx5_esw_flow_attr *esw_attr = attr->esw_attr;
|
||||
int j, err;
|
||||
int err;
|
||||
|
||||
if (!(attr->flags & MLX5_ESW_ATTR_FLAG_SRC_REWRITE))
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
for (j = esw_attr->split_count; j < esw_attr->out_count; j++, (*i)++) {
|
||||
err = esw_setup_chain_dest(dest, flow_act, chains, attr->dest_chain, 1, 0, *i);
|
||||
if (err)
|
||||
goto err_setup_chain;
|
||||
/* flow steering cannot handle more than one dest with the same ft
|
||||
* in a single flow
|
||||
*/
|
||||
if (esw_attr->out_count - esw_attr->split_count > 1)
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
if (esw_attr->dests[j].pkt_reformat) {
|
||||
flow_act->action |= MLX5_FLOW_CONTEXT_ACTION_PACKET_REFORMAT;
|
||||
flow_act->pkt_reformat = esw_attr->dests[j].pkt_reformat;
|
||||
}
|
||||
err = esw_setup_chain_dest(dest, flow_act, chains, attr->dest_chain, 1, 0, *i);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
if (esw_attr->dests[esw_attr->split_count].pkt_reformat) {
|
||||
flow_act->action |= MLX5_FLOW_CONTEXT_ACTION_PACKET_REFORMAT;
|
||||
flow_act->pkt_reformat = esw_attr->dests[esw_attr->split_count].pkt_reformat;
|
||||
}
|
||||
return 0;
|
||||
(*i)++;
|
||||
|
||||
err_setup_chain:
|
||||
esw_put_dest_tables_loop(esw, attr, esw_attr->split_count, j);
|
||||
return err;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void esw_cleanup_chain_src_port_rewrite(struct mlx5_eswitch *esw,
|
||||
|
|
|
@ -268,10 +268,8 @@ static int mlx5_lag_fib_event(struct notifier_block *nb,
|
|||
fen_info = container_of(info, struct fib_entry_notifier_info,
|
||||
info);
|
||||
fi = fen_info->fi;
|
||||
if (fi->nh) {
|
||||
NL_SET_ERR_MSG_MOD(info->extack, "IPv4 route with nexthop objects is not supported");
|
||||
return notifier_from_errno(-EINVAL);
|
||||
}
|
||||
if (fi->nh)
|
||||
return NOTIFY_DONE;
|
||||
fib_dev = fib_info_nh(fen_info->fi, 0)->fib_nh_dev;
|
||||
if (fib_dev != ldev->pf[MLX5_LAG_P1].netdev &&
|
||||
fib_dev != ldev->pf[MLX5_LAG_P2].netdev) {
|
||||
|
|
|
@ -30,10 +30,7 @@ bool mlx5_sf_dev_allocated(const struct mlx5_core_dev *dev)
|
|||
{
|
||||
struct mlx5_sf_dev_table *table = dev->priv.sf_dev_table;
|
||||
|
||||
if (!mlx5_sf_dev_supported(dev))
|
||||
return false;
|
||||
|
||||
return !xa_empty(&table->devices);
|
||||
return table && !xa_empty(&table->devices);
|
||||
}
|
||||
|
||||
static ssize_t sfnum_show(struct device *dev, struct device_attribute *attr, char *buf)
|
||||
|
|
Loading…
Reference in New Issue