Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit f39c6b29 authored by David S. Miller's avatar David S. Miller
Browse files

Merge tag 'mlx5e-updates-2018-06-01' of git://git.kernel.org/pub/scm/linux/kernel/git/saeed/linux



Saeed Mahameed says:

====================
mlx5e-updates-2018-06-01

1) From Tariq, Two patches to Fix IPoIB issues introduced in
   "net/mlx5e: TX, Use actual WQE size for SQ edge fill"

2) From Eran, Additional improvements to mlx5e statistics reporting

3) From Maor, Increase aRFS flow tables size

4) From Adi, Support MTU change for ethernet representors

5) From Ilan and Adi, Handle QP error events in FPGA

6) From Tariq, last 10 patches mainly deals with RX buffer scheme improvements for legacy RQ
   to use only order-0 pages and fragmented SKBs for large MTUs.

-  Tariq starts with some refactoring and removing HW LRO support from traditional
   (legacy) RQ, since it complicates the buffer scheme and removing it makes it smoother
   to move to cyclic descriptor buffer for traditional RQ.

- Use cyclic WQ in legacy RQ, which has many benefits and paves the way for fragmented SKBs
  for large MTUs.

- Enhance legacy Receive Queue memory scheme, such that only order-0 pages are used.
  Whenever possible, prefer using a linear SKB, and build it wrapping the WQE buffer.
  Otherwise (for example, jumbo frames on x86), use non-linear SKB, with as many frags
  as needed. In this case, multiple WQE scatter entries are used, up to a maximum of 4
  frags and 10KB of MTU.

- TX statistics access improvements.
====================

Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 21ad1173 f65a59ff
Loading
Loading
Loading
Loading
+47 −15
Original line number Diff line number Diff line
@@ -101,18 +101,22 @@ struct page_pool;
	(MLX5E_PARAMS_MAXIMUM_LOG_RQ_SIZE_MPW + \
	 (MLX5_MPWRQ_LOG_WQE_SZ - MLX5E_ORDER2_MAX_PACKET_MTU))

#define MLX5E_MIN_SKB_FRAG_SZ		(MLX5_SKB_FRAG_SZ(MLX5_RX_HEADROOM))
#define MLX5E_LOG_MAX_RX_WQE_BULK	\
	(ilog2(PAGE_SIZE / roundup_pow_of_two(MLX5E_MIN_SKB_FRAG_SZ)))

#define MLX5E_PARAMS_MINIMUM_LOG_SQ_SIZE                0x6
#define MLX5E_PARAMS_DEFAULT_LOG_SQ_SIZE                0xa
#define MLX5E_PARAMS_MAXIMUM_LOG_SQ_SIZE                0xd

#define MLX5E_PARAMS_MINIMUM_LOG_RQ_SIZE                0x1
#define MLX5E_PARAMS_MINIMUM_LOG_RQ_SIZE (1 + MLX5E_LOG_MAX_RX_WQE_BULK)
#define MLX5E_PARAMS_DEFAULT_LOG_RQ_SIZE                0xa
#define MLX5E_PARAMS_MAXIMUM_LOG_RQ_SIZE min_t(u8, 0xd,	\
					       MLX5E_LOG_MAX_RQ_NUM_PACKETS_MPW)

#define MLX5E_PARAMS_MINIMUM_LOG_RQ_SIZE_MPW            0x2

#define MLX5_MPWRQ_SMALL_PACKET_THRESHOLD	(256)
#define MLX5E_RX_MAX_HEAD (256)

#define MLX5E_PARAMS_DEFAULT_LRO_WQE_SZ                 (64 * 1024)
#define MLX5E_DEFAULT_LRO_TIMEOUT                       32
@@ -186,9 +190,13 @@ struct mlx5e_tx_wqe {
	struct mlx5_wqe_data_seg data[0];
};

struct mlx5e_rx_wqe {
struct mlx5e_rx_wqe_ll {
	struct mlx5_wqe_srq_next_seg  next;
	struct mlx5_wqe_data_seg      data;
	struct mlx5_wqe_data_seg      data[0];
};

struct mlx5e_rx_wqe_cyc {
	struct mlx5_wqe_data_seg      data[0];
};

struct mlx5e_umr_wqe {
@@ -458,8 +466,9 @@ struct mlx5e_dma_info {
};

struct mlx5e_wqe_frag_info {
	struct mlx5e_dma_info di;
	struct mlx5e_dma_info *di;
	u32 offset;
	bool last_in_page;
};

struct mlx5e_umr_dma_info {
@@ -472,6 +481,8 @@ struct mlx5e_mpw_info {
	DECLARE_BITMAP(xdp_xmit_bitmap, MLX5_MPWRQ_PAGES_PER_WQE);
};

#define MLX5E_MAX_RX_FRAGS 4

/* a single cache unit is capable to serve one napi call (for non-striding rq)
 * or a MPWQE (for striding rq).
 */
@@ -489,6 +500,9 @@ typedef void (*mlx5e_fp_handle_rx_cqe)(struct mlx5e_rq*, struct mlx5_cqe64*);
typedef struct sk_buff *
(*mlx5e_fp_skb_from_cqe_mpwrq)(struct mlx5e_rq *rq, struct mlx5e_mpw_info *wi,
			       u16 cqe_bcnt, u32 head_offset, u32 page_idx);
typedef struct sk_buff *
(*mlx5e_fp_skb_from_cqe)(struct mlx5e_rq *rq, struct mlx5_cqe64 *cqe,
			 struct mlx5e_wqe_frag_info *wi, u32 cqe_bcnt);
typedef bool (*mlx5e_fp_post_rx_wqes)(struct mlx5e_rq *rq);
typedef void (*mlx5e_fp_dealloc_wqe)(struct mlx5e_rq*, u16);

@@ -496,19 +510,30 @@ enum mlx5e_rq_flag {
	MLX5E_RQ_FLAG_XDP_XMIT = BIT(0),
};

struct mlx5e_rq_frag_info {
	int frag_size;
	int frag_stride;
};

struct mlx5e_rq_frags_info {
	struct mlx5e_rq_frag_info arr[MLX5E_MAX_RX_FRAGS];
	u8 num_frags;
	u8 log_num_frags;
	u8 wqe_bulk;
};

struct mlx5e_rq {
	/* data path */
	struct mlx5_wq_ll      wq;

	union {
		struct {
			struct mlx5e_wqe_frag_info *frag_info;
			u32 frag_sz;	/* max possible skb frag_sz */
			union {
				bool page_reuse;
			};
			struct mlx5_wq_cyc          wq;
			struct mlx5e_wqe_frag_info *frags;
			struct mlx5e_dma_info      *di;
			struct mlx5e_rq_frags_info  info;
			mlx5e_fp_skb_from_cqe       skb_from_cqe;
		} wqe;
		struct {
			struct mlx5_wq_ll      wq;
			struct mlx5e_umr_wqe   umr_wqe;
			struct mlx5e_mpw_info *info;
			mlx5e_fp_skb_from_cqe_mpwrq skb_from_cqe_mpwrq;
@@ -519,7 +544,6 @@ struct mlx5e_rq {
	};
	struct {
		u16            headroom;
		u8             page_order;
		u8             map_dir;   /* dma map direction */
	} buff;

@@ -777,8 +801,6 @@ struct mlx5e_priv {
	struct mutex               state_lock; /* Protects Interface state */
	struct mlx5e_rq            drop_rq;

	rwlock_t                   stats_lock; /* Protects channels SW stats updates */
	bool                       channels_active;
	struct mlx5e_channels      channels;
	u32                        tisn[MLX5E_MAX_NUM_TC];
	struct mlx5e_rqt           indir_rqt;
@@ -877,6 +899,12 @@ mlx5e_skb_from_cqe_mpwrq_linear(struct mlx5e_rq *rq, struct mlx5e_mpw_info *wi,
struct sk_buff *
mlx5e_skb_from_cqe_mpwrq_nonlinear(struct mlx5e_rq *rq, struct mlx5e_mpw_info *wi,
				   u16 cqe_bcnt, u32 head_offset, u32 page_idx);
struct sk_buff *
mlx5e_skb_from_cqe_linear(struct mlx5e_rq *rq, struct mlx5_cqe64 *cqe,
			  struct mlx5e_wqe_frag_info *wi, u32 cqe_bcnt);
struct sk_buff *
mlx5e_skb_from_cqe_nonlinear(struct mlx5e_rq *rq, struct mlx5_cqe64 *cqe,
			     struct mlx5e_wqe_frag_info *wi, u32 cqe_bcnt);

void mlx5e_update_stats(struct mlx5e_priv *priv);

@@ -1104,6 +1132,10 @@ void mlx5e_update_stats_work(struct work_struct *work);

int mlx5e_bits_invert(unsigned long a, int size);

typedef int (*change_hw_mtu_cb)(struct mlx5e_priv *priv);
int mlx5e_change_mtu(struct net_device *netdev, int new_mtu,
		     change_hw_mtu_cb set_mtu_cb);

/* ethtool helpers */
void mlx5e_ethtool_get_drvinfo(struct mlx5e_priv *priv,
			       struct ethtool_drvinfo *drvinfo);
+1 −1
Original line number Diff line number Diff line
@@ -213,7 +213,7 @@ static int arfs_add_default_rule(struct mlx5e_priv *priv,
}

#define MLX5E_ARFS_NUM_GROUPS	2
#define MLX5E_ARFS_GROUP1_SIZE	BIT(12)
#define MLX5E_ARFS_GROUP1_SIZE	(BIT(16) - 1)
#define MLX5E_ARFS_GROUP2_SIZE	BIT(0)
#define MLX5E_ARFS_TABLE_SIZE	(MLX5E_ARFS_GROUP1_SIZE +\
				 MLX5E_ARFS_GROUP2_SIZE)
+7 −0
Original line number Diff line number Diff line
@@ -1515,6 +1515,9 @@ static int set_pflag_rx_striding_rq(struct net_device *netdev, bool enable)
			return -EOPNOTSUPP;
		if (!mlx5e_striding_rq_possible(mdev, &priv->channels.params))
			return -EINVAL;
	} else if (priv->channels.params.lro_en) {
		netdev_warn(netdev, "Can't set legacy RQ with LRO, disable LRO first\n");
		return -EINVAL;
	}

	new_channels.params = priv->channels.params;
@@ -1589,6 +1592,10 @@ static int mlx5e_set_priv_flags(struct net_device *netdev, u32 pflags)

out:
	mutex_unlock(&priv->state_lock);

	/* Need to fix some features.. */
	netdev_update_features(netdev);

	return err;
}

+335 −134

File changed.

Preview size limit exceeded, changes collapsed.

+15 −7
Original line number Diff line number Diff line
@@ -130,10 +130,6 @@ static void mlx5e_rep_update_sw_counters(struct mlx5e_priv *priv)
	struct mlx5e_sq_stats *sq_stats;
	int i, j;

	read_lock(&priv->stats_lock);
	if (!priv->channels_active)
	        goto out;

	memset(s, 0, sizeof(*s));
	for (i = 0; i < priv->channels.num; i++) {
		struct mlx5e_channel *c = priv->channels.c[i];
@@ -150,8 +146,6 @@ static void mlx5e_rep_update_sw_counters(struct mlx5e_priv *priv)
			s->tx_bytes		+= sq_stats->bytes;
		}
	}
out:
	read_unlock(&priv->stats_lock);
}

static void mlx5e_rep_get_ethtool_stats(struct net_device *dev,
@@ -906,6 +900,11 @@ static const struct switchdev_ops mlx5e_rep_switchdev_ops = {
	.switchdev_port_attr_get	= mlx5e_attr_get,
};

int mlx5e_change_rep_mtu(struct net_device *netdev, int new_mtu)
{
	return mlx5e_change_mtu(netdev, new_mtu, NULL);
}

static const struct net_device_ops mlx5e_netdev_ops_rep = {
	.ndo_open                = mlx5e_rep_open,
	.ndo_stop                = mlx5e_rep_close,
@@ -915,6 +914,7 @@ static const struct net_device_ops mlx5e_netdev_ops_rep = {
	.ndo_get_stats64         = mlx5e_rep_get_stats,
	.ndo_has_offload_stats	 = mlx5e_has_offload_stats,
	.ndo_get_offload_stats	 = mlx5e_get_offload_stats,
	.ndo_change_mtu          = mlx5e_change_rep_mtu,
};

static void mlx5e_build_rep_params(struct mlx5_core_dev *mdev,
@@ -927,7 +927,7 @@ static void mlx5e_build_rep_params(struct mlx5_core_dev *mdev,
	params->hard_mtu    = MLX5E_ETH_HARD_MTU;
	params->sw_mtu      = mtu;
	params->log_sq_size = MLX5E_REP_PARAMS_LOG_SQ_SIZE;
	params->rq_wq_type  = MLX5_WQ_TYPE_LINKED_LIST;
	params->rq_wq_type  = MLX5_WQ_TYPE_CYCLIC;
	params->log_rq_mtu_frames = MLX5E_REP_PARAMS_LOG_RQ_SIZE;

	params->rx_dim_enabled = MLX5_CAP_GEN(mdev, cq_moderation);
@@ -941,6 +941,10 @@ static void mlx5e_build_rep_params(struct mlx5_core_dev *mdev,

static void mlx5e_build_rep_netdev(struct net_device *netdev)
{
	struct mlx5e_priv *priv = netdev_priv(netdev);
	struct mlx5_core_dev *mdev = priv->mdev;
	u16 max_mtu;

	netdev->netdev_ops = &mlx5e_netdev_ops_rep;

	netdev->watchdog_timeo    = 15 * HZ;
@@ -953,6 +957,10 @@ static void mlx5e_build_rep_netdev(struct net_device *netdev)
	netdev->hw_features      |= NETIF_F_HW_TC;

	eth_hw_addr_random(netdev);

	netdev->min_mtu = ETH_MIN_MTU;
	mlx5_query_port_max_mtu(mdev, &max_mtu, 1);
	netdev->max_mtu = MLX5E_HW2SW_MTU(&priv->channels.params, max_mtu);
}

static void mlx5e_init_rep(struct mlx5_core_dev *mdev,
Loading