Skip to content

Commit

Permalink
Merge tag 'mlx5-fixes-2022-11-09' of git://git.kernel.org/pub/scm/lin…
Browse files Browse the repository at this point in the history
…ux/kernel/git/saeed/linux

Saeed Mahameed says:

====================
mlx5 fixes 2022-11-02

This series provides bug fixes to mlx5 driver.

* tag 'mlx5-fixes-2022-11-09' of git://git.kernel.org/pub/scm/linux/kernel/git/saeed/linux:
  net/mlx5e: TC, Fix slab-out-of-bounds in parse_tc_actions
  net/mlx5e: E-Switch, Fix comparing termination table instance
  net/mlx5e: TC, Fix wrong rejection of packet-per-second policing
  net/mlx5e: Fix tc acts array not to be dependent on enum order
  net/mlx5e: Fix usage of DMA sync API
  net/mlx5e: Add missing sanity checks for max TX WQE size
  net/mlx5: fw_reset: Don't try to load device in case PCI isn't working
  net/mlx5: E-switch, Set to legacy mode if failed to change switchdev mode
  net/mlx5: Allow async trigger completion execution on single CPU systems
  net/mlx5: Bridge, verify LAG state when adding bond to bridge
====================

Link: https://lore.kernel.org/r/20221109184050.108379-1-saeed@kernel.org
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
  • Loading branch information
Jakub Kicinski committed Nov 11, 2022
2 parents b3bbeba + 7f1a6d4 commit abd5ac1
Show file tree
Hide file tree
Showing 13 changed files with 149 additions and 115 deletions.
11 changes: 8 additions & 3 deletions drivers/net/ethernet/mellanox/mlx5/core/cmd.c
Original file line number Diff line number Diff line change
Expand Up @@ -1770,12 +1770,17 @@ void mlx5_cmd_flush(struct mlx5_core_dev *dev)
struct mlx5_cmd *cmd = &dev->cmd;
int i;

for (i = 0; i < cmd->max_reg_cmds; i++)
while (down_trylock(&cmd->sem))
for (i = 0; i < cmd->max_reg_cmds; i++) {
while (down_trylock(&cmd->sem)) {
mlx5_cmd_trigger_completions(dev);
cond_resched();
}
}

while (down_trylock(&cmd->pages_sem))
while (down_trylock(&cmd->pages_sem)) {
mlx5_cmd_trigger_completions(dev);
cond_resched();
}

/* Unlock cmdif */
up(&cmd->pages_sem);
Expand Down
31 changes: 31 additions & 0 deletions drivers/net/ethernet/mellanox/mlx5/core/en/rep/bridge.c
Original file line number Diff line number Diff line change
Expand Up @@ -164,13 +164,44 @@ static int mlx5_esw_bridge_port_changeupper(struct notifier_block *nb, void *ptr
return err;
}

static int
mlx5_esw_bridge_changeupper_validate_netdev(void *ptr)
{
struct net_device *dev = netdev_notifier_info_to_dev(ptr);
struct netdev_notifier_changeupper_info *info = ptr;
struct net_device *upper = info->upper_dev;
struct net_device *lower;
struct list_head *iter;

if (!netif_is_bridge_master(upper) || !netif_is_lag_master(dev))
return 0;

netdev_for_each_lower_dev(dev, lower, iter) {
struct mlx5_core_dev *mdev;
struct mlx5e_priv *priv;

if (!mlx5e_eswitch_rep(lower))
continue;

priv = netdev_priv(lower);
mdev = priv->mdev;
if (!mlx5_lag_is_active(mdev))
return -EAGAIN;
if (!mlx5_lag_is_shared_fdb(mdev))
return -EOPNOTSUPP;
}

return 0;
}

static int mlx5_esw_bridge_switchdev_port_event(struct notifier_block *nb,
unsigned long event, void *ptr)
{
int err = 0;

switch (event) {
case NETDEV_PRECHANGEUPPER:
err = mlx5_esw_bridge_changeupper_validate_netdev(ptr);
break;

case NETDEV_CHANGEUPPER:
Expand Down
92 changes: 32 additions & 60 deletions drivers/net/ethernet/mellanox/mlx5/core/en/tc/act/act.c
Original file line number Diff line number Diff line change
Expand Up @@ -6,70 +6,42 @@
#include "en/tc_priv.h"
#include "mlx5_core.h"

/* Must be aligned with enum flow_action_id. */
static struct mlx5e_tc_act *tc_acts_fdb[NUM_FLOW_ACTIONS] = {
&mlx5e_tc_act_accept,
&mlx5e_tc_act_drop,
&mlx5e_tc_act_trap,
&mlx5e_tc_act_goto,
&mlx5e_tc_act_mirred,
&mlx5e_tc_act_mirred,
&mlx5e_tc_act_redirect_ingress,
NULL, /* FLOW_ACTION_MIRRED_INGRESS, */
&mlx5e_tc_act_vlan,
&mlx5e_tc_act_vlan,
&mlx5e_tc_act_vlan_mangle,
&mlx5e_tc_act_tun_encap,
&mlx5e_tc_act_tun_decap,
&mlx5e_tc_act_pedit,
&mlx5e_tc_act_pedit,
&mlx5e_tc_act_csum,
NULL, /* FLOW_ACTION_MARK, */
&mlx5e_tc_act_ptype,
NULL, /* FLOW_ACTION_PRIORITY, */
NULL, /* FLOW_ACTION_WAKE, */
NULL, /* FLOW_ACTION_QUEUE, */
&mlx5e_tc_act_sample,
&mlx5e_tc_act_police,
&mlx5e_tc_act_ct,
NULL, /* FLOW_ACTION_CT_METADATA, */
&mlx5e_tc_act_mpls_push,
&mlx5e_tc_act_mpls_pop,
NULL, /* FLOW_ACTION_MPLS_MANGLE, */
NULL, /* FLOW_ACTION_GATE, */
NULL, /* FLOW_ACTION_PPPOE_PUSH, */
NULL, /* FLOW_ACTION_JUMP, */
NULL, /* FLOW_ACTION_PIPE, */
&mlx5e_tc_act_vlan,
&mlx5e_tc_act_vlan,
[FLOW_ACTION_ACCEPT] = &mlx5e_tc_act_accept,
[FLOW_ACTION_DROP] = &mlx5e_tc_act_drop,
[FLOW_ACTION_TRAP] = &mlx5e_tc_act_trap,
[FLOW_ACTION_GOTO] = &mlx5e_tc_act_goto,
[FLOW_ACTION_REDIRECT] = &mlx5e_tc_act_mirred,
[FLOW_ACTION_MIRRED] = &mlx5e_tc_act_mirred,
[FLOW_ACTION_REDIRECT_INGRESS] = &mlx5e_tc_act_redirect_ingress,
[FLOW_ACTION_VLAN_PUSH] = &mlx5e_tc_act_vlan,
[FLOW_ACTION_VLAN_POP] = &mlx5e_tc_act_vlan,
[FLOW_ACTION_VLAN_MANGLE] = &mlx5e_tc_act_vlan_mangle,
[FLOW_ACTION_TUNNEL_ENCAP] = &mlx5e_tc_act_tun_encap,
[FLOW_ACTION_TUNNEL_DECAP] = &mlx5e_tc_act_tun_decap,
[FLOW_ACTION_MANGLE] = &mlx5e_tc_act_pedit,
[FLOW_ACTION_ADD] = &mlx5e_tc_act_pedit,
[FLOW_ACTION_CSUM] = &mlx5e_tc_act_csum,
[FLOW_ACTION_PTYPE] = &mlx5e_tc_act_ptype,
[FLOW_ACTION_SAMPLE] = &mlx5e_tc_act_sample,
[FLOW_ACTION_POLICE] = &mlx5e_tc_act_police,
[FLOW_ACTION_CT] = &mlx5e_tc_act_ct,
[FLOW_ACTION_MPLS_PUSH] = &mlx5e_tc_act_mpls_push,
[FLOW_ACTION_MPLS_POP] = &mlx5e_tc_act_mpls_pop,
[FLOW_ACTION_VLAN_PUSH_ETH] = &mlx5e_tc_act_vlan,
[FLOW_ACTION_VLAN_POP_ETH] = &mlx5e_tc_act_vlan,
};

/* Must be aligned with enum flow_action_id. */
static struct mlx5e_tc_act *tc_acts_nic[NUM_FLOW_ACTIONS] = {
&mlx5e_tc_act_accept,
&mlx5e_tc_act_drop,
NULL, /* FLOW_ACTION_TRAP, */
&mlx5e_tc_act_goto,
&mlx5e_tc_act_mirred_nic,
NULL, /* FLOW_ACTION_MIRRED, */
NULL, /* FLOW_ACTION_REDIRECT_INGRESS, */
NULL, /* FLOW_ACTION_MIRRED_INGRESS, */
NULL, /* FLOW_ACTION_VLAN_PUSH, */
NULL, /* FLOW_ACTION_VLAN_POP, */
NULL, /* FLOW_ACTION_VLAN_MANGLE, */
NULL, /* FLOW_ACTION_TUNNEL_ENCAP, */
NULL, /* FLOW_ACTION_TUNNEL_DECAP, */
&mlx5e_tc_act_pedit,
&mlx5e_tc_act_pedit,
&mlx5e_tc_act_csum,
&mlx5e_tc_act_mark,
NULL, /* FLOW_ACTION_PTYPE, */
NULL, /* FLOW_ACTION_PRIORITY, */
NULL, /* FLOW_ACTION_WAKE, */
NULL, /* FLOW_ACTION_QUEUE, */
NULL, /* FLOW_ACTION_SAMPLE, */
NULL, /* FLOW_ACTION_POLICE, */
&mlx5e_tc_act_ct,
[FLOW_ACTION_ACCEPT] = &mlx5e_tc_act_accept,
[FLOW_ACTION_DROP] = &mlx5e_tc_act_drop,
[FLOW_ACTION_GOTO] = &mlx5e_tc_act_goto,
[FLOW_ACTION_REDIRECT] = &mlx5e_tc_act_mirred_nic,
[FLOW_ACTION_MANGLE] = &mlx5e_tc_act_pedit,
[FLOW_ACTION_ADD] = &mlx5e_tc_act_pedit,
[FLOW_ACTION_CSUM] = &mlx5e_tc_act_csum,
[FLOW_ACTION_MARK] = &mlx5e_tc_act_mark,
[FLOW_ACTION_CT] = &mlx5e_tc_act_ct,
};

/**
Expand Down
24 changes: 23 additions & 1 deletion drivers/net/ethernet/mellanox/mlx5/core/en/txrx.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,27 @@

#define INL_HDR_START_SZ (sizeof(((struct mlx5_wqe_eth_seg *)NULL)->inline_hdr.start))

/* IPSEC inline data includes:
* 1. ESP trailer: up to 255 bytes of padding, 1 byte for pad length, 1 byte for
* next header.
* 2. ESP authentication data: 16 bytes for ICV.
*/
#define MLX5E_MAX_TX_IPSEC_DS DIV_ROUND_UP(sizeof(struct mlx5_wqe_inline_seg) + \
255 + 1 + 1 + 16, MLX5_SEND_WQE_DS)

/* 366 should be big enough to cover all L2, L3 and L4 headers with possible
* encapsulations.
*/
#define MLX5E_MAX_TX_INLINE_DS DIV_ROUND_UP(366 - INL_HDR_START_SZ + VLAN_HLEN, \
MLX5_SEND_WQE_DS)

/* Sync the calculation with mlx5e_sq_calc_wqe_attr. */
#define MLX5E_MAX_TX_WQEBBS DIV_ROUND_UP(MLX5E_TX_WQE_EMPTY_DS_COUNT + \
MLX5E_MAX_TX_INLINE_DS + \
MLX5E_MAX_TX_IPSEC_DS + \
MAX_SKB_FRAGS + 1, \
MLX5_SEND_WQEBB_NUM_DS)

#define MLX5E_RX_ERR_CQE(cqe) (get_cqe_opcode(cqe) != MLX5_CQE_RESP_SEND)

static inline
Expand Down Expand Up @@ -424,6 +445,8 @@ mlx5e_set_eseg_swp(struct sk_buff *skb, struct mlx5_wqe_eth_seg *eseg,

static inline u16 mlx5e_stop_room_for_wqe(struct mlx5_core_dev *mdev, u16 wqe_size)
{
WARN_ON_ONCE(PAGE_SIZE / MLX5_SEND_WQE_BB < mlx5e_get_max_sq_wqebbs(mdev));

/* A WQE must not cross the page boundary, hence two conditions:
* 1. Its size must not exceed the page size.
* 2. If the WQE size is X, and the space remaining in a page is less
Expand All @@ -436,7 +459,6 @@ static inline u16 mlx5e_stop_room_for_wqe(struct mlx5_core_dev *mdev, u16 wqe_si
"wqe_size %u is greater than max SQ WQEBBs %u",
wqe_size, mlx5e_get_max_sq_wqebbs(mdev));


return MLX5E_STOP_ROOM(wqe_size);
}

Expand Down
4 changes: 2 additions & 2 deletions drivers/net/ethernet/mellanox/mlx5/core/en/xdp.c
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ mlx5e_xmit_xdp_buff(struct mlx5e_xdpsq *sq, struct mlx5e_rq *rq,
xdpi.page.rq = rq;

dma_addr = page_pool_get_dma_addr(page) + (xdpf->data - (void *)xdpf);
dma_sync_single_for_device(sq->pdev, dma_addr, xdptxd.len, DMA_TO_DEVICE);
dma_sync_single_for_device(sq->pdev, dma_addr, xdptxd.len, DMA_BIDIRECTIONAL);

if (unlikely(xdp_frame_has_frags(xdpf))) {
sinfo = xdp_get_shared_info_from_frame(xdpf);
Expand All @@ -131,7 +131,7 @@ mlx5e_xmit_xdp_buff(struct mlx5e_xdpsq *sq, struct mlx5e_rq *rq,
skb_frag_off(frag);
len = skb_frag_size(frag);
dma_sync_single_for_device(sq->pdev, addr, len,
DMA_TO_DEVICE);
DMA_BIDIRECTIONAL);
}
}

Expand Down
7 changes: 7 additions & 0 deletions drivers/net/ethernet/mellanox/mlx5/core/en_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -5694,6 +5694,13 @@ int mlx5e_attach_netdev(struct mlx5e_priv *priv)
mlx5e_fs_set_state_destroy(priv->fs,
!test_bit(MLX5E_STATE_DESTROYING, &priv->state));

/* Validate the max_wqe_size_sq capability. */
if (WARN_ON_ONCE(mlx5e_get_max_sq_wqebbs(priv->mdev) < MLX5E_MAX_TX_WQEBBS)) {
mlx5_core_warn(priv->mdev, "MLX5E: Max SQ WQEBBs firmware capability: %u, needed %lu\n",
mlx5e_get_max_sq_wqebbs(priv->mdev), MLX5E_MAX_TX_WQEBBS);
return -EIO;
}

/* max number of channels may have changed */
max_nch = mlx5e_calc_max_nch(priv->mdev, priv->netdev, profile);
if (priv->channels.params.num_channels > max_nch) {
Expand Down
27 changes: 14 additions & 13 deletions drivers/net/ethernet/mellanox/mlx5/core/en_rx.c
Original file line number Diff line number Diff line change
Expand Up @@ -266,7 +266,7 @@ static inline bool mlx5e_rx_cache_get(struct mlx5e_rq *rq, union mlx5e_alloc_uni

addr = page_pool_get_dma_addr(au->page);
/* Non-XSK always uses PAGE_SIZE. */
dma_sync_single_for_device(rq->pdev, addr, PAGE_SIZE, DMA_FROM_DEVICE);
dma_sync_single_for_device(rq->pdev, addr, PAGE_SIZE, rq->buff.map_dir);
return true;
}

Expand All @@ -282,8 +282,7 @@ static inline int mlx5e_page_alloc_pool(struct mlx5e_rq *rq, union mlx5e_alloc_u
return -ENOMEM;

/* Non-XSK always uses PAGE_SIZE. */
addr = dma_map_page_attrs(rq->pdev, au->page, 0, PAGE_SIZE,
rq->buff.map_dir, DMA_ATTR_SKIP_CPU_SYNC);
addr = dma_map_page(rq->pdev, au->page, 0, PAGE_SIZE, rq->buff.map_dir);
if (unlikely(dma_mapping_error(rq->pdev, addr))) {
page_pool_recycle_direct(rq->page_pool, au->page);
au->page = NULL;
Expand Down Expand Up @@ -427,22 +426,24 @@ mlx5e_add_skb_frag(struct mlx5e_rq *rq, struct sk_buff *skb,
{
dma_addr_t addr = page_pool_get_dma_addr(au->page);

dma_sync_single_for_cpu(rq->pdev, addr + frag_offset, len, DMA_FROM_DEVICE);
dma_sync_single_for_cpu(rq->pdev, addr + frag_offset, len,
rq->buff.map_dir);
page_ref_inc(au->page);
skb_add_rx_frag(skb, skb_shinfo(skb)->nr_frags,
au->page, frag_offset, len, truesize);
}

static inline void
mlx5e_copy_skb_header(struct device *pdev, struct sk_buff *skb,
mlx5e_copy_skb_header(struct mlx5e_rq *rq, struct sk_buff *skb,
struct page *page, dma_addr_t addr,
int offset_from, int dma_offset, u32 headlen)
{
const void *from = page_address(page) + offset_from;
/* Aligning len to sizeof(long) optimizes memcpy performance */
unsigned int len = ALIGN(headlen, sizeof(long));

dma_sync_single_for_cpu(pdev, addr + dma_offset, len, DMA_FROM_DEVICE);
dma_sync_single_for_cpu(rq->pdev, addr + dma_offset, len,
rq->buff.map_dir);
skb_copy_to_linear_data(skb, from, len);
}

Expand Down Expand Up @@ -1538,7 +1539,7 @@ mlx5e_skb_from_cqe_linear(struct mlx5e_rq *rq, struct mlx5e_wqe_frag_info *wi,

addr = page_pool_get_dma_addr(au->page);
dma_sync_single_range_for_cpu(rq->pdev, addr, wi->offset,
frag_size, DMA_FROM_DEVICE);
frag_size, rq->buff.map_dir);
net_prefetch(data);

prog = rcu_dereference(rq->xdp_prog);
Expand Down Expand Up @@ -1587,7 +1588,7 @@ mlx5e_skb_from_cqe_nonlinear(struct mlx5e_rq *rq, struct mlx5e_wqe_frag_info *wi

addr = page_pool_get_dma_addr(au->page);
dma_sync_single_range_for_cpu(rq->pdev, addr, wi->offset,
rq->buff.frame0_sz, DMA_FROM_DEVICE);
rq->buff.frame0_sz, rq->buff.map_dir);
net_prefetchw(va); /* xdp_frame data area */
net_prefetch(va + rx_headroom);

Expand All @@ -1608,7 +1609,7 @@ mlx5e_skb_from_cqe_nonlinear(struct mlx5e_rq *rq, struct mlx5e_wqe_frag_info *wi

addr = page_pool_get_dma_addr(au->page);
dma_sync_single_for_cpu(rq->pdev, addr + wi->offset,
frag_consumed_bytes, DMA_FROM_DEVICE);
frag_consumed_bytes, rq->buff.map_dir);

if (!xdp_buff_has_frags(&xdp)) {
/* Init on the first fragment to avoid cold cache access
Expand Down Expand Up @@ -1905,7 +1906,7 @@ mlx5e_skb_from_cqe_mpwrq_nonlinear(struct mlx5e_rq *rq, struct mlx5e_mpw_info *w
mlx5e_fill_skb_data(skb, rq, au, byte_cnt, frag_offset);
/* copy header */
addr = page_pool_get_dma_addr(head_au->page);
mlx5e_copy_skb_header(rq->pdev, skb, head_au->page, addr,
mlx5e_copy_skb_header(rq, skb, head_au->page, addr,
head_offset, head_offset, headlen);
/* skb linear part was allocated with headlen and aligned to long */
skb->tail += headlen;
Expand Down Expand Up @@ -1939,7 +1940,7 @@ mlx5e_skb_from_cqe_mpwrq_linear(struct mlx5e_rq *rq, struct mlx5e_mpw_info *wi,

addr = page_pool_get_dma_addr(au->page);
dma_sync_single_range_for_cpu(rq->pdev, addr, head_offset,
frag_size, DMA_FROM_DEVICE);
frag_size, rq->buff.map_dir);
net_prefetch(data);

prog = rcu_dereference(rq->xdp_prog);
Expand Down Expand Up @@ -1987,7 +1988,7 @@ mlx5e_skb_from_cqe_shampo(struct mlx5e_rq *rq, struct mlx5e_mpw_info *wi,

if (likely(frag_size <= BIT(MLX5E_SHAMPO_LOG_MAX_HEADER_ENTRY_SIZE))) {
/* build SKB around header */
dma_sync_single_range_for_cpu(rq->pdev, head->addr, 0, frag_size, DMA_FROM_DEVICE);
dma_sync_single_range_for_cpu(rq->pdev, head->addr, 0, frag_size, rq->buff.map_dir);
prefetchw(hdr);
prefetch(data);
skb = mlx5e_build_linear_skb(rq, hdr, frag_size, rx_headroom, head_size, 0);
Expand All @@ -2009,7 +2010,7 @@ mlx5e_skb_from_cqe_shampo(struct mlx5e_rq *rq, struct mlx5e_mpw_info *wi,
}

prefetchw(skb->data);
mlx5e_copy_skb_header(rq->pdev, skb, head->page, head->addr,
mlx5e_copy_skb_header(rq, skb, head->page, head->addr,
head_offset + rx_headroom,
rx_headroom, head_size);
/* skb linear part was allocated with headlen and aligned to long */
Expand Down
14 changes: 6 additions & 8 deletions drivers/net/ethernet/mellanox/mlx5/core/en_tc.c
Original file line number Diff line number Diff line change
Expand Up @@ -3633,10 +3633,14 @@ mlx5e_clone_flow_attr_for_post_act(struct mlx5_flow_attr *attr,
attr2->action = 0;
attr2->flags = 0;
attr2->parse_attr = parse_attr;
attr2->esw_attr->out_count = 0;
attr2->esw_attr->split_count = 0;
attr2->dest_chain = 0;
attr2->dest_ft = NULL;

if (ns_type == MLX5_FLOW_NAMESPACE_FDB) {
attr2->esw_attr->out_count = 0;
attr2->esw_attr->split_count = 0;
}

return attr2;
}

Expand Down Expand Up @@ -4758,12 +4762,6 @@ int mlx5e_policer_validate(const struct flow_action *action,
return -EOPNOTSUPP;
}

if (act->police.rate_pkt_ps) {
NL_SET_ERR_MSG_MOD(extack,
"QoS offload not support packets per second");
return -EOPNOTSUPP;
}

return 0;
}

Expand Down
Loading

0 comments on commit abd5ac1

Please sign in to comment.