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>pull/1131/head
parent
197258f0ef
commit
eec8359f07
|
|
@ -332,6 +332,12 @@ attribute-sets:
|
||||||
-
|
-
|
||||||
name: tx-push-buf-len-max
|
name: tx-push-buf-len-max
|
||||||
type: u32
|
type: u32
|
||||||
|
-
|
||||||
|
name: hds-thresh
|
||||||
|
type: u32
|
||||||
|
-
|
||||||
|
name: hds-thresh-max
|
||||||
|
type: u32
|
||||||
|
|
||||||
-
|
-
|
||||||
name: mm-stat
|
name: mm-stat
|
||||||
|
|
@ -1777,6 +1783,8 @@ operations:
|
||||||
- rx-push
|
- rx-push
|
||||||
- tx-push-buf-len
|
- tx-push-buf-len
|
||||||
- tx-push-buf-len-max
|
- tx-push-buf-len-max
|
||||||
|
- hds-thresh
|
||||||
|
- hds-thresh-max
|
||||||
dump: *ring-get-op
|
dump: *ring-get-op
|
||||||
-
|
-
|
||||||
name: rings-set
|
name: rings-set
|
||||||
|
|
|
||||||
|
|
@ -899,6 +899,10 @@ Kernel response contents:
|
||||||
``ETHTOOL_A_RINGS_RX_PUSH`` u8 flag of RX 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_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_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
|
``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_RX_JUMBO`` u32 size of RX jumbo ring
|
||||||
``ETHTOOL_A_RINGS_TX`` u32 size of TX 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_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_CQE_SIZE`` u32 Size of TX/RX CQE
|
||||||
``ETHTOOL_A_RINGS_TX_PUSH`` u8 flag of TX Push mode
|
``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_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`` 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
|
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
|
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.
|
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
|
CHANNELS_GET
|
||||||
============
|
============
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -78,6 +78,9 @@ enum {
|
||||||
* @cqe_size: Size of TX/RX completion queue event
|
* @cqe_size: Size of TX/RX completion queue event
|
||||||
* @tx_push_buf_len: Size of TX push buffer
|
* @tx_push_buf_len: Size of TX push buffer
|
||||||
* @tx_push_buf_max_len: Maximum allowed 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 {
|
struct kernel_ethtool_ringparam {
|
||||||
u32 rx_buf_len;
|
u32 rx_buf_len;
|
||||||
|
|
@ -87,6 +90,8 @@ struct kernel_ethtool_ringparam {
|
||||||
u32 cqe_size;
|
u32 cqe_size;
|
||||||
u32 tx_push_buf_len;
|
u32 tx_push_buf_len;
|
||||||
u32 tx_push_buf_max_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_RX_PUSH: capture for setting rx_push
|
||||||
* @ETHTOOL_RING_USE_TX_PUSH_BUF_LEN: capture for setting tx_push_buf_len
|
* @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_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 {
|
enum ethtool_supported_ring_param {
|
||||||
ETHTOOL_RING_USE_RX_BUF_LEN = BIT(0),
|
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_RX_PUSH = BIT(3),
|
||||||
ETHTOOL_RING_USE_TX_PUSH_BUF_LEN = BIT(4),
|
ETHTOOL_RING_USE_TX_PUSH_BUF_LEN = BIT(4),
|
||||||
ETHTOOL_RING_USE_TCP_DATA_SPLIT = BIT(5),
|
ETHTOOL_RING_USE_TCP_DATA_SPLIT = BIT(5),
|
||||||
|
ETHTOOL_RING_USE_HDS_THRS = BIT(6),
|
||||||
};
|
};
|
||||||
|
|
||||||
#define __ETH_RSS_HASH_BIT(bit) ((u32)1 << (bit))
|
#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_ctx: XArray of custom RSS contexts
|
||||||
* @rss_lock: Protects entries in @rss_ctx. May be taken from
|
* @rss_lock: Protects entries in @rss_ctx. May be taken from
|
||||||
* within RTNL.
|
* within RTNL.
|
||||||
|
* @hds_thresh: HDS Threshold value.
|
||||||
* @hds_config: HDS value from userspace.
|
* @hds_config: HDS value from userspace.
|
||||||
* @wol_enabled: Wake-on-LAN is enabled
|
* @wol_enabled: Wake-on-LAN is enabled
|
||||||
* @module_fw_flash_in_progress: Module firmware flashing is in progress.
|
* @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 ethtool_netdev_state {
|
||||||
struct xarray rss_ctx;
|
struct xarray rss_ctx;
|
||||||
struct mutex rss_lock;
|
struct mutex rss_lock;
|
||||||
|
u32 hds_thresh;
|
||||||
u8 hds_config;
|
u8 hds_config;
|
||||||
unsigned wol_enabled:1;
|
unsigned wol_enabled:1;
|
||||||
unsigned module_fw_flash_in_progress:1;
|
unsigned module_fw_flash_in_progress:1;
|
||||||
|
|
|
||||||
|
|
@ -155,6 +155,8 @@ enum {
|
||||||
ETHTOOL_A_RINGS_RX_PUSH,
|
ETHTOOL_A_RINGS_RX_PUSH,
|
||||||
ETHTOOL_A_RINGS_TX_PUSH_BUF_LEN,
|
ETHTOOL_A_RINGS_TX_PUSH_BUF_LEN,
|
||||||
ETHTOOL_A_RINGS_TX_PUSH_BUF_LEN_MAX,
|
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_CNT,
|
||||||
ETHTOOL_A_RINGS_MAX = (__ETHTOOL_A_RINGS_CNT - 1)
|
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_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_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_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_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_channels_set_policy[ETHTOOL_A_CHANNELS_COMBINED_COUNT + 1];
|
||||||
extern const struct nla_policy ethnl_coalesce_get_policy[ETHTOOL_A_COALESCE_HEADER + 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_TX_PUSH */
|
||||||
nla_total_size(sizeof(u8))) + /* _RINGS_RX_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 */
|
||||||
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,
|
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,
|
(nla_put_u32(skb, ETHTOOL_A_RINGS_TX_PUSH_BUF_LEN_MAX,
|
||||||
kr->tx_push_buf_max_len) ||
|
kr->tx_push_buf_max_len) ||
|
||||||
nla_put_u32(skb, ETHTOOL_A_RINGS_TX_PUSH_BUF_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 -EMSGSIZE;
|
||||||
|
|
||||||
return 0;
|
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_TX_PUSH] = NLA_POLICY_MAX(NLA_U8, 1),
|
||||||
[ETHTOOL_A_RINGS_RX_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_TX_PUSH_BUF_LEN] = { .type = NLA_U32 },
|
||||||
|
[ETHTOOL_A_RINGS_HDS_THRESH] = { .type = NLA_U32 },
|
||||||
};
|
};
|
||||||
|
|
||||||
static int
|
static int
|
||||||
|
|
@ -155,6 +163,14 @@ ethnl_set_rings_validate(struct ethnl_req_info *req_info,
|
||||||
return -EOPNOTSUPP;
|
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] &&
|
if (tb[ETHTOOL_A_RINGS_CQE_SIZE] &&
|
||||||
!(ops->supported_ring_params & ETHTOOL_RING_USE_CQE_SIZE)) {
|
!(ops->supported_ring_params & ETHTOOL_RING_USE_CQE_SIZE)) {
|
||||||
NL_SET_ERR_MSG_ATTR(info->extack,
|
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);
|
tb[ETHTOOL_A_RINGS_RX_PUSH], &mod);
|
||||||
ethnl_update_u32(&kernel_ringparam.tx_push_buf_len,
|
ethnl_update_u32(&kernel_ringparam.tx_push_buf_len,
|
||||||
tb[ETHTOOL_A_RINGS_TX_PUSH_BUF_LEN], &mod);
|
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)
|
if (!mod)
|
||||||
return 0;
|
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];
|
err_attr = tb[ETHTOOL_A_RINGS_RX_JUMBO];
|
||||||
else if (ringparam.tx_pending > ringparam.tx_max_pending)
|
else if (ringparam.tx_pending > ringparam.tx_max_pending)
|
||||||
err_attr = tb[ETHTOOL_A_RINGS_TX];
|
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
|
else
|
||||||
err_attr = NULL;
|
err_attr = NULL;
|
||||||
if (err_attr) {
|
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,
|
ret = dev->ethtool_ops->set_ringparam(dev, &ringparam,
|
||||||
&kernel_ringparam, info->extack);
|
&kernel_ringparam, info->extack);
|
||||||
if (!ret)
|
if (!ret) {
|
||||||
dev->ethtool->hds_config = kernel_ringparam.tcp_data_split;
|
dev->ethtool->hds_config = kernel_ringparam.tcp_data_split;
|
||||||
|
dev->ethtool->hds_thresh = kernel_ringparam.hds_thresh;
|
||||||
|
}
|
||||||
|
|
||||||
return ret < 0 ? ret : 1;
|
return ret < 0 ? ret : 1;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue