ethtool: add header/data split indication
For applications running on a mix of platforms it's useful to have a clear indication whether host's NIC supports the geometry requirements of TCP zero-copy. TCP zero-copy Rx requires data to be neatly placed into memory pages. Most NICs can't do that. This patch is adding GET support only, since the NICs I work with either always have the feature enabled or enable it whenever MTU is set to jumbo. In other words I don't need SET. But adding set should be trivial. (The only note on SET is that we will likely want the setting to be "sticky" and use 0 / `unknown` to reset it back to driver default.) Signed-off-by: Jakub Kicinski <kuba@kernel.org> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
1a918a32cd
commit
9690ae6042
|
@ -860,8 +860,16 @@ Kernel response 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_TCP_DATA_SPLIT`` indicates whether the device is usable with
|
||||
page-flipping TCP zero-copy receive (``getsockopt(TCP_ZEROCOPY_RECEIVE)``).
|
||||
If enabled the device is configured to place frame headers and data into
|
||||
separate buffers. The device configuration must make it possible to receive
|
||||
full memory pages of data, for example because MTU is high enough or through
|
||||
HW-GRO.
|
||||
|
||||
|
||||
RINGS_SET
|
||||
=========
|
||||
|
|
|
@ -70,9 +70,11 @@ enum {
|
|||
/**
|
||||
* struct kernel_ethtool_ringparam - RX/TX ring configuration
|
||||
* @rx_buf_len: Current length of buffers on the rx ring.
|
||||
* @tcp_data_split: Scatter packet headers and data to separate buffers
|
||||
*/
|
||||
struct kernel_ethtool_ringparam {
|
||||
u32 rx_buf_len;
|
||||
u8 tcp_data_split;
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
@ -318,6 +318,12 @@ enum {
|
|||
|
||||
/* RINGS */
|
||||
|
||||
enum {
|
||||
ETHTOOL_TCP_DATA_SPLIT_UNKNOWN = 0,
|
||||
ETHTOOL_TCP_DATA_SPLIT_DISABLED,
|
||||
ETHTOOL_TCP_DATA_SPLIT_ENABLED,
|
||||
};
|
||||
|
||||
enum {
|
||||
ETHTOOL_A_RINGS_UNSPEC,
|
||||
ETHTOOL_A_RINGS_HEADER, /* nest - _A_HEADER_* */
|
||||
|
@ -330,6 +336,7 @@ enum {
|
|||
ETHTOOL_A_RINGS_RX_JUMBO, /* u32 */
|
||||
ETHTOOL_A_RINGS_TX, /* u32 */
|
||||
ETHTOOL_A_RINGS_RX_BUF_LEN, /* u32 */
|
||||
ETHTOOL_A_RINGS_TCP_DATA_SPLIT, /* u8 */
|
||||
|
||||
/* add new constants above here */
|
||||
__ETHTOOL_A_RINGS_CNT,
|
||||
|
|
|
@ -53,7 +53,8 @@ static int rings_reply_size(const struct ethnl_req_info *req_base,
|
|||
nla_total_size(sizeof(u32)) + /* _RINGS_RX_MINI */
|
||||
nla_total_size(sizeof(u32)) + /* _RINGS_RX_JUMBO */
|
||||
nla_total_size(sizeof(u32)) + /* _RINGS_TX */
|
||||
nla_total_size(sizeof(u32)); /* _RINGS_RX_BUF_LEN */
|
||||
nla_total_size(sizeof(u32)) + /* _RINGS_RX_BUF_LEN */
|
||||
nla_total_size(sizeof(u8)); /* _RINGS_TCP_DATA_SPLIT */
|
||||
}
|
||||
|
||||
static int rings_fill_reply(struct sk_buff *skb,
|
||||
|
@ -61,9 +62,11 @@ static int rings_fill_reply(struct sk_buff *skb,
|
|||
const struct ethnl_reply_data *reply_base)
|
||||
{
|
||||
const struct rings_reply_data *data = RINGS_REPDATA(reply_base);
|
||||
const struct kernel_ethtool_ringparam *kernel_ringparam = &data->kernel_ringparam;
|
||||
const struct kernel_ethtool_ringparam *kr = &data->kernel_ringparam;
|
||||
const struct ethtool_ringparam *ringparam = &data->ringparam;
|
||||
|
||||
WARN_ON(kr->tcp_data_split > ETHTOOL_TCP_DATA_SPLIT_ENABLED);
|
||||
|
||||
if ((ringparam->rx_max_pending &&
|
||||
(nla_put_u32(skb, ETHTOOL_A_RINGS_RX_MAX,
|
||||
ringparam->rx_max_pending) ||
|
||||
|
@ -84,9 +87,11 @@ static int rings_fill_reply(struct sk_buff *skb,
|
|||
ringparam->tx_max_pending) ||
|
||||
nla_put_u32(skb, ETHTOOL_A_RINGS_TX,
|
||||
ringparam->tx_pending))) ||
|
||||
(kernel_ringparam->rx_buf_len &&
|
||||
(nla_put_u32(skb, ETHTOOL_A_RINGS_RX_BUF_LEN,
|
||||
kernel_ringparam->rx_buf_len))))
|
||||
(kr->rx_buf_len &&
|
||||
(nla_put_u32(skb, ETHTOOL_A_RINGS_RX_BUF_LEN, kr->rx_buf_len))) ||
|
||||
(kr->tcp_data_split &&
|
||||
(nla_put_u8(skb, ETHTOOL_A_RINGS_TCP_DATA_SPLIT,
|
||||
kr->tcp_data_split))))
|
||||
return -EMSGSIZE;
|
||||
|
||||
return 0;
|
||||
|
|
Loading…
Reference in New Issue