Skip to content

Commit 58d5229

Browse files
Achiad Shochatdavem330
authored andcommitted
net/mlx5e: Support TX packet copy into WQE
AKA inline WQE. A TX latency optimization to save data gather DMA reads. Controlled by ETHTOOL_TX_COPYBREAK. Signed-off-by: Achiad Shochat <achiad@mellanox.com> Signed-off-by: Amir Vadai <amirv@mellanox.com> Signed-off-by: David S. Miller <davem@davemloft.net>
1 parent 311c7c7 commit 58d5229

File tree

4 files changed

+77
-1
lines changed

4 files changed

+77
-1
lines changed

drivers/net/ethernet/mellanox/mlx5/core/en.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -196,6 +196,7 @@ struct mlx5e_params {
196196
bool lro_en;
197197
u32 lro_wqe_sz;
198198
u8 rss_hfunc;
199+
u16 tx_max_inline;
199200
};
200201

201202
enum {
@@ -520,3 +521,4 @@ static inline void mlx5e_cq_arm(struct mlx5e_cq *cq)
520521
}
521522

522523
extern const struct ethtool_ops mlx5e_ethtool_ops;
524+
u16 mlx5e_get_max_inline_cap(struct mlx5_core_dev *mdev);

drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -699,6 +699,57 @@ static int mlx5e_set_rxfh(struct net_device *netdev, const u32 *indir,
699699
return err;
700700
}
701701

702+
static int mlx5e_get_tunable(struct net_device *dev,
703+
const struct ethtool_tunable *tuna,
704+
void *data)
705+
{
706+
const struct mlx5e_priv *priv = netdev_priv(dev);
707+
int err = 0;
708+
709+
switch (tuna->id) {
710+
case ETHTOOL_TX_COPYBREAK:
711+
*(u32 *)data = priv->params.tx_max_inline;
712+
break;
713+
default:
714+
err = -EINVAL;
715+
break;
716+
}
717+
718+
return err;
719+
}
720+
721+
static int mlx5e_set_tunable(struct net_device *dev,
722+
const struct ethtool_tunable *tuna,
723+
const void *data)
724+
{
725+
struct mlx5e_priv *priv = netdev_priv(dev);
726+
struct mlx5_core_dev *mdev = priv->mdev;
727+
struct mlx5e_params new_params;
728+
u32 val;
729+
int err = 0;
730+
731+
switch (tuna->id) {
732+
case ETHTOOL_TX_COPYBREAK:
733+
val = *(u32 *)data;
734+
if (val > mlx5e_get_max_inline_cap(mdev)) {
735+
err = -EINVAL;
736+
break;
737+
}
738+
739+
mutex_lock(&priv->state_lock);
740+
new_params = priv->params;
741+
new_params.tx_max_inline = val;
742+
err = mlx5e_update_priv_params(priv, &new_params);
743+
mutex_unlock(&priv->state_lock);
744+
break;
745+
default:
746+
err = -EINVAL;
747+
break;
748+
}
749+
750+
return err;
751+
}
752+
702753
const struct ethtool_ops mlx5e_ethtool_ops = {
703754
.get_drvinfo = mlx5e_get_drvinfo,
704755
.get_link = ethtool_op_get_link,
@@ -715,4 +766,6 @@ const struct ethtool_ops mlx5e_ethtool_ops = {
715766
.set_settings = mlx5e_set_settings,
716767
.get_rxfh = mlx5e_get_rxfh,
717768
.set_rxfh = mlx5e_set_rxfh,
769+
.get_tunable = mlx5e_get_tunable,
770+
.set_tunable = mlx5e_set_tunable,
718771
};

drivers/net/ethernet/mellanox/mlx5/core/en_main.c

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ struct mlx5e_rq_param {
4141
struct mlx5e_sq_param {
4242
u32 sqc[MLX5_ST_SZ_DW(sqc)];
4343
struct mlx5_wq_param wq;
44+
u16 max_inline;
4445
};
4546

4647
struct mlx5e_cq_param {
@@ -514,6 +515,7 @@ static int mlx5e_create_sq(struct mlx5e_channel *c,
514515
sq->wq.db = &sq->wq.db[MLX5_SND_DBR];
515516
sq->uar_map = sq->uar.map;
516517
sq->bf_buf_size = (1 << MLX5_CAP_GEN(mdev, log_bf_reg_size)) / 2;
518+
sq->max_inline = param->max_inline;
517519

518520
err = mlx5e_alloc_sq_db(sq, cpu_to_node(c->cpu));
519521
if (err)
@@ -1020,6 +1022,7 @@ static void mlx5e_build_sq_param(struct mlx5e_priv *priv,
10201022
MLX5_SET(wq, wq, pd, priv->pdn);
10211023

10221024
param->wq.buf_numa_node = dev_to_node(&priv->mdev->pdev->dev);
1025+
param->max_inline = priv->params.tx_max_inline;
10231026
}
10241027

10251028
static void mlx5e_build_common_cq_param(struct mlx5e_priv *priv,
@@ -1703,6 +1706,15 @@ static int mlx5e_check_required_hca_cap(struct mlx5_core_dev *mdev)
17031706
return 0;
17041707
}
17051708

1709+
u16 mlx5e_get_max_inline_cap(struct mlx5_core_dev *mdev)
1710+
{
1711+
int bf_buf_size = (1 << MLX5_CAP_GEN(mdev, log_bf_reg_size)) / 2;
1712+
1713+
return bf_buf_size -
1714+
sizeof(struct mlx5e_tx_wqe) +
1715+
2 /*sizeof(mlx5e_tx_wqe.inline_hdr_start)*/;
1716+
}
1717+
17061718
static void mlx5e_build_netdev_priv(struct mlx5_core_dev *mdev,
17071719
struct net_device *netdev,
17081720
int num_comp_vectors)
@@ -1721,6 +1733,7 @@ static void mlx5e_build_netdev_priv(struct mlx5_core_dev *mdev,
17211733
MLX5E_PARAMS_DEFAULT_TX_CQ_MODERATION_USEC;
17221734
priv->params.tx_cq_moderation_pkts =
17231735
MLX5E_PARAMS_DEFAULT_TX_CQ_MODERATION_PKTS;
1736+
priv->params.tx_max_inline = mlx5e_get_max_inline_cap(mdev);
17241737
priv->params.min_rx_wqes =
17251738
MLX5E_PARAMS_DEFAULT_MIN_RX_WQES;
17261739
priv->params.rx_hash_log_tbl_sz =

drivers/net/ethernet/mellanox/mlx5/core/en_tx.c

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,15 @@ u16 mlx5e_select_queue(struct net_device *dev, struct sk_buff *skb,
112112
static inline u16 mlx5e_get_inline_hdr_size(struct mlx5e_sq *sq,
113113
struct sk_buff *skb)
114114
{
115-
#define MLX5E_MIN_INLINE 16 /* eth header with vlan (w/o next ethertype) */
115+
/* Some NIC TX decisions, e.g loopback, are based on the packet
116+
* headers and occur before the data gather.
117+
* Therefore these headers must be copied into the WQE
118+
*/
119+
#define MLX5E_MIN_INLINE (ETH_HLEN + 2/*vlan tag*/)
120+
121+
if (skb_headlen(skb) <= sq->max_inline)
122+
return skb_headlen(skb);
123+
116124
return MLX5E_MIN_INLINE;
117125
}
118126

0 commit comments

Comments
 (0)