net: ethtool: add support for configuring hds-thresh
The hds-thresh option configures the threshold value of the header-data-split. If a received packet size is larger than this threshold value, a packet will be split into header and payload. The header indicates TCP and UDP header, but it depends on driver spec. The bnxt_en driver supports HDS(Header-Data-Split) configuration at FW level, affecting TCP and UDP too. So, If hds-thresh is set, it affects UDP and TCP packets. Example: # ethtool -G <interface name> hds-thresh <value> # ethtool -G enp14s0f0np0 tcp-data-split on hds-thresh 256 # ethtool -g enp14s0f0np0 Ring parameters for enp14s0f0np0: Pre-set maximums: ... HDS thresh: 1023 Current hardware settings: ... TCP data split: on HDS thresh: 256 The default/min/max values are not defined in the ethtool so the drivers should define themself. The 0 value means that all TCP/UDP packets' header and payload will be split. Tested-by: Stanislav Fomichev <sdf@fomichev.me> Signed-off-by: Taehee Yoo <ap420073@gmail.com> Link: https://patch.msgid.link/20250114142852.3364986-3-ap420073@gmail.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
parent
197258f0ef
commit
eec8359f07
|
@ -332,6 +332,12 @@ attribute-sets:
|
|||
-
|
||||
name: tx-push-buf-len-max
|
||||
type: u32
|
||||
-
|
||||
name: hds-thresh
|
||||
type: u32
|
||||
-
|
||||
name: hds-thresh-max
|
||||
type: u32
|
||||
|
||||
-
|
||||
name: mm-stat
|
||||
|
@ -1777,6 +1783,8 @@ operations:
|
|||
- rx-push
|
||||
- tx-push-buf-len
|
||||
- tx-push-buf-len-max
|
||||
- hds-thresh
|
||||
- hds-thresh-max
|
||||
dump: *ring-get-op
|
||||
-
|
||||
name: rings-set
|
||||
|
|
|
@ -899,6 +899,10 @@ Kernel response contents:
|
|||
``ETHTOOL_A_RINGS_RX_PUSH`` u8 flag of RX Push mode
|
||||
``ETHTOOL_A_RINGS_TX_PUSH_BUF_LEN`` u32 size of TX push buffer
|
||||
``ETHTOOL_A_RINGS_TX_PUSH_BUF_LEN_MAX`` u32 max size of TX push buffer
|
||||
``ETHTOOL_A_RINGS_HDS_THRESH`` u32 threshold of
|
||||
header / data split
|
||||
``ETHTOOL_A_RINGS_HDS_THRESH_MAX`` u32 max threshold of
|
||||
header / data split
|
||||
======================================= ====== ===========================
|
||||
|
||||
``ETHTOOL_A_RINGS_TCP_DATA_SPLIT`` indicates whether the device is usable with
|
||||
|
@ -941,10 +945,12 @@ Request contents:
|
|||
``ETHTOOL_A_RINGS_RX_JUMBO`` u32 size of RX jumbo ring
|
||||
``ETHTOOL_A_RINGS_TX`` u32 size of TX ring
|
||||
``ETHTOOL_A_RINGS_RX_BUF_LEN`` u32 size of buffers on the ring
|
||||
``ETHTOOL_A_RINGS_TCP_DATA_SPLIT`` u8 TCP header / data split
|
||||
``ETHTOOL_A_RINGS_CQE_SIZE`` u32 Size of TX/RX CQE
|
||||
``ETHTOOL_A_RINGS_TX_PUSH`` u8 flag of TX Push mode
|
||||
``ETHTOOL_A_RINGS_RX_PUSH`` u8 flag of RX Push mode
|
||||
``ETHTOOL_A_RINGS_TX_PUSH_BUF_LEN`` u32 size of TX push buffer
|
||||
``ETHTOOL_A_RINGS_HDS_THRESH`` u32 threshold of header / data split
|
||||
==================================== ====== ===========================
|
||||
|
||||
Kernel checks that requested ring sizes do not exceed limits reported by
|
||||
|
@ -961,6 +967,10 @@ A bigger CQE can have more receive buffer pointers, and in turn the NIC can
|
|||
transfer a bigger frame from wire. Based on the NIC hardware, the overall
|
||||
completion queue size can be adjusted in the driver if CQE size is modified.
|
||||
|
||||
``ETHTOOL_A_RINGS_HDS_THRESH`` specifies the threshold value of
|
||||
header / data split feature. If a received packet size is larger than this
|
||||
threshold value, header and data will be split.
|
||||
|
||||
CHANNELS_GET
|
||||
============
|
||||
|
||||
|
|
|
@ -78,6 +78,9 @@ enum {
|
|||
* @cqe_size: Size of TX/RX completion queue event
|
||||
* @tx_push_buf_len: Size of TX push buffer
|
||||
* @tx_push_buf_max_len: Maximum allowed size of TX push buffer
|
||||
* @hds_thresh: Packet size threshold for header data split (HDS)
|
||||
* @hds_thresh_max: Maximum supported setting for @hds_threshold
|
||||
*
|
||||
*/
|
||||
struct kernel_ethtool_ringparam {
|
||||
u32 rx_buf_len;
|
||||
|
@ -87,6 +90,8 @@ struct kernel_ethtool_ringparam {
|
|||
u32 cqe_size;
|
||||
u32 tx_push_buf_len;
|
||||
u32 tx_push_buf_max_len;
|
||||
u32 hds_thresh;
|
||||
u32 hds_thresh_max;
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -97,6 +102,7 @@ struct kernel_ethtool_ringparam {
|
|||
* @ETHTOOL_RING_USE_RX_PUSH: capture for setting rx_push
|
||||
* @ETHTOOL_RING_USE_TX_PUSH_BUF_LEN: capture for setting tx_push_buf_len
|
||||
* @ETHTOOL_RING_USE_TCP_DATA_SPLIT: capture for setting tcp_data_split
|
||||
* @ETHTOOL_RING_USE_HDS_THRS: capture for setting header-data-split-thresh
|
||||
*/
|
||||
enum ethtool_supported_ring_param {
|
||||
ETHTOOL_RING_USE_RX_BUF_LEN = BIT(0),
|
||||
|
@ -105,6 +111,7 @@ enum ethtool_supported_ring_param {
|
|||
ETHTOOL_RING_USE_RX_PUSH = BIT(3),
|
||||
ETHTOOL_RING_USE_TX_PUSH_BUF_LEN = BIT(4),
|
||||
ETHTOOL_RING_USE_TCP_DATA_SPLIT = BIT(5),
|
||||
ETHTOOL_RING_USE_HDS_THRS = BIT(6),
|
||||
};
|
||||
|
||||
#define __ETH_RSS_HASH_BIT(bit) ((u32)1 << (bit))
|
||||
|
@ -1157,6 +1164,7 @@ int ethtool_virtdev_set_link_ksettings(struct net_device *dev,
|
|||
* @rss_ctx: XArray of custom RSS contexts
|
||||
* @rss_lock: Protects entries in @rss_ctx. May be taken from
|
||||
* within RTNL.
|
||||
* @hds_thresh: HDS Threshold value.
|
||||
* @hds_config: HDS value from userspace.
|
||||
* @wol_enabled: Wake-on-LAN is enabled
|
||||
* @module_fw_flash_in_progress: Module firmware flashing is in progress.
|
||||
|
@ -1164,6 +1172,7 @@ int ethtool_virtdev_set_link_ksettings(struct net_device *dev,
|
|||
struct ethtool_netdev_state {
|
||||
struct xarray rss_ctx;
|
||||
struct mutex rss_lock;
|
||||
u32 hds_thresh;
|
||||
u8 hds_config;
|
||||
unsigned wol_enabled:1;
|
||||
unsigned module_fw_flash_in_progress:1;
|
||||
|
|
|
@ -155,6 +155,8 @@ enum {
|
|||
ETHTOOL_A_RINGS_RX_PUSH,
|
||||
ETHTOOL_A_RINGS_TX_PUSH_BUF_LEN,
|
||||
ETHTOOL_A_RINGS_TX_PUSH_BUF_LEN_MAX,
|
||||
ETHTOOL_A_RINGS_HDS_THRESH,
|
||||
ETHTOOL_A_RINGS_HDS_THRESH_MAX,
|
||||
|
||||
__ETHTOOL_A_RINGS_CNT,
|
||||
ETHTOOL_A_RINGS_MAX = (__ETHTOOL_A_RINGS_CNT - 1)
|
||||
|
|
|
@ -456,7 +456,7 @@ extern const struct nla_policy ethnl_features_set_policy[ETHTOOL_A_FEATURES_WANT
|
|||
extern const struct nla_policy ethnl_privflags_get_policy[ETHTOOL_A_PRIVFLAGS_HEADER + 1];
|
||||
extern const struct nla_policy ethnl_privflags_set_policy[ETHTOOL_A_PRIVFLAGS_FLAGS + 1];
|
||||
extern const struct nla_policy ethnl_rings_get_policy[ETHTOOL_A_RINGS_HEADER + 1];
|
||||
extern const struct nla_policy ethnl_rings_set_policy[ETHTOOL_A_RINGS_TX_PUSH_BUF_LEN_MAX + 1];
|
||||
extern const struct nla_policy ethnl_rings_set_policy[ETHTOOL_A_RINGS_HDS_THRESH_MAX + 1];
|
||||
extern const struct nla_policy ethnl_channels_get_policy[ETHTOOL_A_CHANNELS_HEADER + 1];
|
||||
extern const struct nla_policy ethnl_channels_set_policy[ETHTOOL_A_CHANNELS_COMBINED_COUNT + 1];
|
||||
extern const struct nla_policy ethnl_coalesce_get_policy[ETHTOOL_A_COALESCE_HEADER + 1];
|
||||
|
|
|
@ -61,7 +61,9 @@ static int rings_reply_size(const struct ethnl_req_info *req_base,
|
|||
nla_total_size(sizeof(u8)) + /* _RINGS_TX_PUSH */
|
||||
nla_total_size(sizeof(u8))) + /* _RINGS_RX_PUSH */
|
||||
nla_total_size(sizeof(u32)) + /* _RINGS_TX_PUSH_BUF_LEN */
|
||||
nla_total_size(sizeof(u32)); /* _RINGS_TX_PUSH_BUF_LEN_MAX */
|
||||
nla_total_size(sizeof(u32)) + /* _RINGS_TX_PUSH_BUF_LEN_MAX */
|
||||
nla_total_size(sizeof(u32)) + /* _RINGS_HDS_THRESH */
|
||||
nla_total_size(sizeof(u32)); /* _RINGS_HDS_THRESH_MAX*/
|
||||
}
|
||||
|
||||
static int rings_fill_reply(struct sk_buff *skb,
|
||||
|
@ -108,7 +110,12 @@ static int rings_fill_reply(struct sk_buff *skb,
|
|||
(nla_put_u32(skb, ETHTOOL_A_RINGS_TX_PUSH_BUF_LEN_MAX,
|
||||
kr->tx_push_buf_max_len) ||
|
||||
nla_put_u32(skb, ETHTOOL_A_RINGS_TX_PUSH_BUF_LEN,
|
||||
kr->tx_push_buf_len))))
|
||||
kr->tx_push_buf_len))) ||
|
||||
((supported_ring_params & ETHTOOL_RING_USE_HDS_THRS) &&
|
||||
(nla_put_u32(skb, ETHTOOL_A_RINGS_HDS_THRESH,
|
||||
kr->hds_thresh) ||
|
||||
nla_put_u32(skb, ETHTOOL_A_RINGS_HDS_THRESH_MAX,
|
||||
kr->hds_thresh_max))))
|
||||
return -EMSGSIZE;
|
||||
|
||||
return 0;
|
||||
|
@ -130,6 +137,7 @@ const struct nla_policy ethnl_rings_set_policy[] = {
|
|||
[ETHTOOL_A_RINGS_TX_PUSH] = NLA_POLICY_MAX(NLA_U8, 1),
|
||||
[ETHTOOL_A_RINGS_RX_PUSH] = NLA_POLICY_MAX(NLA_U8, 1),
|
||||
[ETHTOOL_A_RINGS_TX_PUSH_BUF_LEN] = { .type = NLA_U32 },
|
||||
[ETHTOOL_A_RINGS_HDS_THRESH] = { .type = NLA_U32 },
|
||||
};
|
||||
|
||||
static int
|
||||
|
@ -155,6 +163,14 @@ ethnl_set_rings_validate(struct ethnl_req_info *req_info,
|
|||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
if (tb[ETHTOOL_A_RINGS_HDS_THRESH] &&
|
||||
!(ops->supported_ring_params & ETHTOOL_RING_USE_HDS_THRS)) {
|
||||
NL_SET_ERR_MSG_ATTR(info->extack,
|
||||
tb[ETHTOOL_A_RINGS_HDS_THRESH],
|
||||
"setting hds-thresh is not supported");
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
if (tb[ETHTOOL_A_RINGS_CQE_SIZE] &&
|
||||
!(ops->supported_ring_params & ETHTOOL_RING_USE_CQE_SIZE)) {
|
||||
NL_SET_ERR_MSG_ATTR(info->extack,
|
||||
|
@ -223,6 +239,8 @@ ethnl_set_rings(struct ethnl_req_info *req_info, struct genl_info *info)
|
|||
tb[ETHTOOL_A_RINGS_RX_PUSH], &mod);
|
||||
ethnl_update_u32(&kernel_ringparam.tx_push_buf_len,
|
||||
tb[ETHTOOL_A_RINGS_TX_PUSH_BUF_LEN], &mod);
|
||||
ethnl_update_u32(&kernel_ringparam.hds_thresh,
|
||||
tb[ETHTOOL_A_RINGS_HDS_THRESH], &mod);
|
||||
if (!mod)
|
||||
return 0;
|
||||
|
||||
|
@ -243,6 +261,8 @@ ethnl_set_rings(struct ethnl_req_info *req_info, struct genl_info *info)
|
|||
err_attr = tb[ETHTOOL_A_RINGS_RX_JUMBO];
|
||||
else if (ringparam.tx_pending > ringparam.tx_max_pending)
|
||||
err_attr = tb[ETHTOOL_A_RINGS_TX];
|
||||
else if (kernel_ringparam.hds_thresh > kernel_ringparam.hds_thresh_max)
|
||||
err_attr = tb[ETHTOOL_A_RINGS_HDS_THRESH];
|
||||
else
|
||||
err_attr = NULL;
|
||||
if (err_attr) {
|
||||
|
@ -261,8 +281,10 @@ ethnl_set_rings(struct ethnl_req_info *req_info, struct genl_info *info)
|
|||
|
||||
ret = dev->ethtool_ops->set_ringparam(dev, &ringparam,
|
||||
&kernel_ringparam, info->extack);
|
||||
if (!ret)
|
||||
if (!ret) {
|
||||
dev->ethtool->hds_config = kernel_ringparam.tcp_data_split;
|
||||
dev->ethtool->hds_thresh = kernel_ringparam.hds_thresh;
|
||||
}
|
||||
|
||||
return ret < 0 ? ret : 1;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue