Skip to content

Commit

Permalink
Merge tag 'mlx5-fixes-2019-04-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:

====================
Mellanox, mlx5 fixes 2019-04-09

This series provides some fixes to mlx5 driver.

I've cc'ed some of the checksum fixes to Eric Dumazet and i would like to get
his feedback before you pull.

For -stable v4.19
('net/mlx5: FPGA, tls, idr remove on flow delete')
('net/mlx5: FPGA, tls, hold rcu read lock a bit longer')

For -stable v4.20
('net/mlx5e: Rx, Check ip headers sanity')
('Revert "net/mlx5e: Enable reporting checksum unnecessary also for L3 packets"')
('net/mlx5e: Rx, Fixup skb checksum for packets with tail padding')

For -stable v5.0
('net/mlx5e: Switch to Toeplitz RSS hash by default')
('net/mlx5e: Protect against non-uplink representor for encap')
('net/mlx5e: XDP, Avoid checksum complete when XDP prog is loaded')
====================

Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
David S. Miller committed Apr 14, 2019
2 parents 69f23a0 + 7ee2ace commit 7324880
Show file tree
Hide file tree
Showing 9 changed files with 140 additions and 65 deletions.
1 change: 1 addition & 0 deletions drivers/net/ethernet/mellanox/mlx5/core/en.h
Original file line number Diff line number Diff line change
Expand Up @@ -858,6 +858,7 @@ void mlx5e_close_channels(struct mlx5e_channels *chs);
* switching channels
*/
typedef int (*mlx5e_fp_hw_modify)(struct mlx5e_priv *priv);
int mlx5e_safe_reopen_channels(struct mlx5e_priv *priv);
int mlx5e_safe_switch_channels(struct mlx5e_priv *priv,
struct mlx5e_channels *new_chs,
mlx5e_fp_hw_modify hw_modify);
Expand Down
11 changes: 8 additions & 3 deletions drivers/net/ethernet/mellanox/mlx5/core/en/reporter_tx.c
Original file line number Diff line number Diff line change
Expand Up @@ -186,12 +186,17 @@ static int mlx5e_tx_reporter_recover_from_ctx(struct mlx5e_tx_err_ctx *err_ctx)

static int mlx5e_tx_reporter_recover_all(struct mlx5e_priv *priv)
{
int err;
int err = 0;

rtnl_lock();
mutex_lock(&priv->state_lock);
mlx5e_close_locked(priv->netdev);
err = mlx5e_open_locked(priv->netdev);

if (!test_bit(MLX5E_STATE_OPENED, &priv->state))
goto out;

err = mlx5e_safe_reopen_channels(priv);

out:
mutex_unlock(&priv->state_lock);
rtnl_unlock();

Expand Down
4 changes: 4 additions & 0 deletions drivers/net/ethernet/mellanox/mlx5/core/en/tc_tun.c
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,10 @@ static int get_route_and_out_devs(struct mlx5e_priv *priv,
return -EOPNOTSUPP;
}

if (!(mlx5e_eswitch_rep(*out_dev) &&
mlx5e_is_uplink_rep(netdev_priv(*out_dev))))
return -EOPNOTSUPP;

return 0;
}

Expand Down
3 changes: 2 additions & 1 deletion drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c
Original file line number Diff line number Diff line change
Expand Up @@ -1768,7 +1768,8 @@ static int set_pflag_rx_no_csum_complete(struct net_device *netdev, bool enable)
struct mlx5e_channel *c;
int i;

if (!test_bit(MLX5E_STATE_OPENED, &priv->state))
if (!test_bit(MLX5E_STATE_OPENED, &priv->state) ||
priv->channels.params.xdp_prog)
return 0;

for (i = 0; i < channels->num; i++) {
Expand Down
21 changes: 16 additions & 5 deletions drivers/net/ethernet/mellanox/mlx5/core/en_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -951,7 +951,11 @@ static int mlx5e_open_rq(struct mlx5e_channel *c,
if (params->rx_dim_enabled)
__set_bit(MLX5E_RQ_STATE_AM, &c->rq.state);

if (MLX5E_GET_PFLAG(params, MLX5E_PFLAG_RX_NO_CSUM_COMPLETE))
/* We disable csum_complete when XDP is enabled since
* XDP programs might manipulate packets which will render
* skb->checksum incorrect.
*/
if (MLX5E_GET_PFLAG(params, MLX5E_PFLAG_RX_NO_CSUM_COMPLETE) || c->xdp)
__set_bit(MLX5E_RQ_STATE_NO_CSUM_COMPLETE, &c->rq.state);

return 0;
Expand Down Expand Up @@ -2937,6 +2941,14 @@ int mlx5e_safe_switch_channels(struct mlx5e_priv *priv,
return 0;
}

int mlx5e_safe_reopen_channels(struct mlx5e_priv *priv)
{
struct mlx5e_channels new_channels = {};

new_channels.params = priv->channels.params;
return mlx5e_safe_switch_channels(priv, &new_channels, NULL);
}

void mlx5e_timestamp_init(struct mlx5e_priv *priv)
{
priv->tstamp.tx_type = HWTSTAMP_TX_OFF;
Expand Down Expand Up @@ -4161,11 +4173,10 @@ static void mlx5e_tx_timeout_work(struct work_struct *work)
if (!report_failed)
goto unlock;

mlx5e_close_locked(priv->netdev);
err = mlx5e_open_locked(priv->netdev);
err = mlx5e_safe_reopen_channels(priv);
if (err)
netdev_err(priv->netdev,
"mlx5e_open_locked failed recovering from a tx_timeout, err(%d).\n",
"mlx5e_safe_reopen_channels failed recovering from a tx_timeout, err(%d).\n",
err);

unlock:
Expand Down Expand Up @@ -4553,7 +4564,7 @@ void mlx5e_build_rss_params(struct mlx5e_rss_params *rss_params,
{
enum mlx5e_traffic_types tt;

rss_params->hfunc = ETH_RSS_HASH_XOR;
rss_params->hfunc = ETH_RSS_HASH_TOP;
netdev_rss_key_fill(rss_params->toeplitz_hash_key,
sizeof(rss_params->toeplitz_hash_key));
mlx5e_build_default_indir_rqt(rss_params->indirection_rqt,
Expand Down
94 changes: 75 additions & 19 deletions drivers/net/ethernet/mellanox/mlx5/core/en_rx.c
Original file line number Diff line number Diff line change
Expand Up @@ -692,7 +692,14 @@ static inline bool is_last_ethertype_ip(struct sk_buff *skb, int *network_depth,
{
*proto = ((struct ethhdr *)skb->data)->h_proto;
*proto = __vlan_get_protocol(skb, *proto, network_depth);
return (*proto == htons(ETH_P_IP) || *proto == htons(ETH_P_IPV6));

if (*proto == htons(ETH_P_IP))
return pskb_may_pull(skb, *network_depth + sizeof(struct iphdr));

if (*proto == htons(ETH_P_IPV6))
return pskb_may_pull(skb, *network_depth + sizeof(struct ipv6hdr));

return false;
}

static inline void mlx5e_enable_ecn(struct mlx5e_rq *rq, struct sk_buff *skb)
Expand All @@ -712,17 +719,6 @@ static inline void mlx5e_enable_ecn(struct mlx5e_rq *rq, struct sk_buff *skb)
rq->stats->ecn_mark += !!rc;
}

static u32 mlx5e_get_fcs(const struct sk_buff *skb)
{
const void *fcs_bytes;
u32 _fcs_bytes;

fcs_bytes = skb_header_pointer(skb, skb->len - ETH_FCS_LEN,
ETH_FCS_LEN, &_fcs_bytes);

return __get_unaligned_cpu32(fcs_bytes);
}

static u8 get_ip_proto(struct sk_buff *skb, int network_depth, __be16 proto)
{
void *ip_p = skb->data + network_depth;
Expand All @@ -733,6 +729,68 @@ static u8 get_ip_proto(struct sk_buff *skb, int network_depth, __be16 proto)

#define short_frame(size) ((size) <= ETH_ZLEN + ETH_FCS_LEN)

#define MAX_PADDING 8

static void
tail_padding_csum_slow(struct sk_buff *skb, int offset, int len,
struct mlx5e_rq_stats *stats)
{
stats->csum_complete_tail_slow++;
skb->csum = csum_block_add(skb->csum,
skb_checksum(skb, offset, len, 0),
offset);
}

static void
tail_padding_csum(struct sk_buff *skb, int offset,
struct mlx5e_rq_stats *stats)
{
u8 tail_padding[MAX_PADDING];
int len = skb->len - offset;
void *tail;

if (unlikely(len > MAX_PADDING)) {
tail_padding_csum_slow(skb, offset, len, stats);
return;
}

tail = skb_header_pointer(skb, offset, len, tail_padding);
if (unlikely(!tail)) {
tail_padding_csum_slow(skb, offset, len, stats);
return;
}

stats->csum_complete_tail++;
skb->csum = csum_block_add(skb->csum, csum_partial(tail, len, 0), offset);
}

static void
mlx5e_skb_padding_csum(struct sk_buff *skb, int network_depth, __be16 proto,
struct mlx5e_rq_stats *stats)
{
struct ipv6hdr *ip6;
struct iphdr *ip4;
int pkt_len;

switch (proto) {
case htons(ETH_P_IP):
ip4 = (struct iphdr *)(skb->data + network_depth);
pkt_len = network_depth + ntohs(ip4->tot_len);
break;
case htons(ETH_P_IPV6):
ip6 = (struct ipv6hdr *)(skb->data + network_depth);
pkt_len = network_depth + sizeof(*ip6) + ntohs(ip6->payload_len);
break;
default:
return;
}

if (likely(pkt_len >= skb->len))
return;

tail_padding_csum(skb, pkt_len, stats);
}

static inline void mlx5e_handle_csum(struct net_device *netdev,
struct mlx5_cqe64 *cqe,
struct mlx5e_rq *rq,
Expand All @@ -752,7 +810,8 @@ static inline void mlx5e_handle_csum(struct net_device *netdev,
return;
}

if (unlikely(test_bit(MLX5E_RQ_STATE_NO_CSUM_COMPLETE, &rq->state)))
/* True when explicitly set via priv flag, or XDP prog is loaded */
if (test_bit(MLX5E_RQ_STATE_NO_CSUM_COMPLETE, &rq->state))
goto csum_unnecessary;

/* CQE csum doesn't cover padding octets in short ethernet
Expand Down Expand Up @@ -780,18 +839,15 @@ static inline void mlx5e_handle_csum(struct net_device *netdev,
skb->csum = csum_partial(skb->data + ETH_HLEN,
network_depth - ETH_HLEN,
skb->csum);
if (unlikely(netdev->features & NETIF_F_RXFCS))
skb->csum = csum_block_add(skb->csum,
(__force __wsum)mlx5e_get_fcs(skb),
skb->len - ETH_FCS_LEN);

mlx5e_skb_padding_csum(skb, network_depth, proto, stats);
stats->csum_complete++;
return;
}

csum_unnecessary:
if (likely((cqe->hds_ip_ext & CQE_L3_OK) &&
((cqe->hds_ip_ext & CQE_L4_OK) ||
(get_cqe_l4_hdr_type(cqe) == CQE_L4_HDR_TYPE_NONE)))) {
(cqe->hds_ip_ext & CQE_L4_OK))) {
skb->ip_summed = CHECKSUM_UNNECESSARY;
if (cqe_is_tunneled(cqe)) {
skb->csum_level = 1;
Expand Down
6 changes: 6 additions & 0 deletions drivers/net/ethernet/mellanox/mlx5/core/en_stats.c
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,8 @@ static const struct counter_desc sw_stats_desc[] = {
{ MLX5E_DECLARE_STAT(struct mlx5e_sw_stats, rx_csum_unnecessary) },
{ MLX5E_DECLARE_STAT(struct mlx5e_sw_stats, rx_csum_none) },
{ MLX5E_DECLARE_STAT(struct mlx5e_sw_stats, rx_csum_complete) },
{ MLX5E_DECLARE_STAT(struct mlx5e_sw_stats, rx_csum_complete_tail) },
{ MLX5E_DECLARE_STAT(struct mlx5e_sw_stats, rx_csum_complete_tail_slow) },
{ MLX5E_DECLARE_STAT(struct mlx5e_sw_stats, rx_csum_unnecessary_inner) },
{ MLX5E_DECLARE_STAT(struct mlx5e_sw_stats, rx_xdp_drop) },
{ MLX5E_DECLARE_STAT(struct mlx5e_sw_stats, rx_xdp_redirect) },
Expand Down Expand Up @@ -151,6 +153,8 @@ static void mlx5e_grp_sw_update_stats(struct mlx5e_priv *priv)
s->rx_removed_vlan_packets += rq_stats->removed_vlan_packets;
s->rx_csum_none += rq_stats->csum_none;
s->rx_csum_complete += rq_stats->csum_complete;
s->rx_csum_complete_tail += rq_stats->csum_complete_tail;
s->rx_csum_complete_tail_slow += rq_stats->csum_complete_tail_slow;
s->rx_csum_unnecessary += rq_stats->csum_unnecessary;
s->rx_csum_unnecessary_inner += rq_stats->csum_unnecessary_inner;
s->rx_xdp_drop += rq_stats->xdp_drop;
Expand Down Expand Up @@ -1190,6 +1194,8 @@ static const struct counter_desc rq_stats_desc[] = {
{ MLX5E_DECLARE_RX_STAT(struct mlx5e_rq_stats, packets) },
{ MLX5E_DECLARE_RX_STAT(struct mlx5e_rq_stats, bytes) },
{ MLX5E_DECLARE_RX_STAT(struct mlx5e_rq_stats, csum_complete) },
{ MLX5E_DECLARE_RX_STAT(struct mlx5e_rq_stats, csum_complete_tail) },
{ MLX5E_DECLARE_RX_STAT(struct mlx5e_rq_stats, csum_complete_tail_slow) },
{ MLX5E_DECLARE_RX_STAT(struct mlx5e_rq_stats, csum_unnecessary) },
{ MLX5E_DECLARE_RX_STAT(struct mlx5e_rq_stats, csum_unnecessary_inner) },
{ MLX5E_DECLARE_RX_STAT(struct mlx5e_rq_stats, csum_none) },
Expand Down
4 changes: 4 additions & 0 deletions drivers/net/ethernet/mellanox/mlx5/core/en_stats.h
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,8 @@ struct mlx5e_sw_stats {
u64 rx_csum_unnecessary;
u64 rx_csum_none;
u64 rx_csum_complete;
u64 rx_csum_complete_tail;
u64 rx_csum_complete_tail_slow;
u64 rx_csum_unnecessary_inner;
u64 rx_xdp_drop;
u64 rx_xdp_redirect;
Expand Down Expand Up @@ -181,6 +183,8 @@ struct mlx5e_rq_stats {
u64 packets;
u64 bytes;
u64 csum_complete;
u64 csum_complete_tail;
u64 csum_complete_tail_slow;
u64 csum_unnecessary;
u64 csum_unnecessary_inner;
u64 csum_none;
Expand Down
Loading

0 comments on commit 7324880

Please sign in to comment.