This attribute, which is part of ethtool's ring param configuration allows the user to specify the maximum number of the packet's payload that can be written directly to the device. Example usage: # ethtool -G [interface] tx-push-buf-len [number of bytes]
Unified · Split
| @@ -165,6 +165,12 @@ attribute-sets: · 164 unmodified lines | |||
| 165 | - | 165 | - |
| 166 | name: rx-push | 166 | name: rx-push |
| 167 | type: u8 | 167 | type: u8 |
| 168 | - | ||
| 169 | name: tx-push-buf-len | ||
| 170 | type: u32 | ||
| 171 | - | ||
| 172 | name: tx-push-buf-len-max | ||
| 173 | type: u32 | ||
| 168 | 174 | ||
| 169 | - | 175 | - |
| 170 | name: mm-stat | 176 | name: mm-stat |
| @@ -311,6 +317,8 @@ operations: · 140 unmodified lines | |||
| 311 | - cqe-size | 317 | - cqe-size |
| 312 | - tx-push | 318 | - tx-push |
| 313 | - rx-push | 319 | - rx-push |
| 320 | - tx-push-buf-len | ||
| 321 | - tx-push-buf-len-max | ||
| 314 | dump: *ring-get-op | 322 | dump: *ring-get-op |
| 315 | - | 323 | - |
| 316 | name: rings-set | 324 | name: rings-set |
| @@ -860,22 +860,24 @@ Request contents: · 859 unmodified lines | |||
| 860 | 860 | ||
| 861 | Kernel response contents: | 861 | Kernel response contents: |
| 862 | 862 | ||
| 863 | ==================================== ====== =========================== | 863 | ======================================= ====== =========================== |
| 864 | ``ETHTOOL_A_RINGS_HEADER`` nested reply header | 864 | ``ETHTOOL_A_RINGS_HEADER`` nested reply header |
| 865 | ``ETHTOOL_A_RINGS_RX_MAX`` u32 max size of RX ring | 865 | ``ETHTOOL_A_RINGS_RX_MAX`` u32 max size of RX ring |
| 866 | ``ETHTOOL_A_RINGS_RX_MINI_MAX`` u32 max size of RX mini ring | 866 | ``ETHTOOL_A_RINGS_RX_MINI_MAX`` u32 max size of RX mini ring |
| 867 | ``ETHTOOL_A_RINGS_RX_JUMBO_MAX`` u32 max size of RX jumbo ring | 867 | ``ETHTOOL_A_RINGS_RX_JUMBO_MAX`` u32 max size of RX jumbo ring |
| 868 | ``ETHTOOL_A_RINGS_TX_MAX`` u32 max size of TX ring | 868 | ``ETHTOOL_A_RINGS_TX_MAX`` u32 max size of TX ring |
| 869 | ``ETHTOOL_A_RINGS_RX`` u32 size of RX ring | 869 | ``ETHTOOL_A_RINGS_RX`` u32 size of RX ring |
| 870 | ``ETHTOOL_A_RINGS_RX_MINI`` u32 size of RX mini ring | 870 | ``ETHTOOL_A_RINGS_RX_MINI`` u32 size of RX mini ring |
| 871 | ``ETHTOOL_A_RINGS_RX_JUMBO`` u32 size of RX jumbo ring | 871 | ``ETHTOOL_A_RINGS_RX_JUMBO`` u32 size of RX jumbo ring |
| 872 | ``ETHTOOL_A_RINGS_TX`` u32 size of TX ring | 872 | ``ETHTOOL_A_RINGS_TX`` u32 size of TX ring |
| 873 | ``ETHTOOL_A_RINGS_RX_BUF_LEN`` u32 size of buffers on the ring | 873 | ``ETHTOOL_A_RINGS_RX_BUF_LEN`` u32 size of buffers on the ring |
| 874 | ``ETHTOOL_A_RINGS_TCP_DATA_SPLIT`` u8 TCP header / data split | 874 | ``ETHTOOL_A_RINGS_TCP_DATA_SPLIT`` u8 TCP header / data split |
| 875 | ``ETHTOOL_A_RINGS_CQE_SIZE`` u32 Size of TX/RX CQE | 875 | ``ETHTOOL_A_RINGS_CQE_SIZE`` u32 Size of TX/RX CQE |
| 876 | ``ETHTOOL_A_RINGS_TX_PUSH`` u8 flag of TX Push mode | 876 | ``ETHTOOL_A_RINGS_TX_PUSH`` u8 flag of TX Push mode |
| 877 | ``ETHTOOL_A_RINGS_RX_PUSH`` u8 flag of RX Push mode | 877 | ``ETHTOOL_A_RINGS_RX_PUSH`` u8 flag of RX Push mode |
| 878 | ==================================== ====== =========================== | 878 | ``ETHTOOL_A_RINGS_TX_PUSH_BUF_LEN`` u32 size of TX push buffer |
| 879 | ``ETHTOOL_A_RINGS_TX_PUSH_BUF_LEN_MAX`` u32 max size of TX push buffer | ||
| 880 | ======================================= ====== =========================== | ||
| 879 | 881 | ||
| 880 | ``ETHTOOL_A_RINGS_TCP_DATA_SPLIT`` indicates whether the device is usable with | 882 | ``ETHTOOL_A_RINGS_TCP_DATA_SPLIT`` indicates whether the device is usable with |
| 881 | page-flipping TCP zero-copy receive (``getsockopt(TCP_ZEROCOPY_RECEIVE)``). | 883 | page-flipping TCP zero-copy receive (``getsockopt(TCP_ZEROCOPY_RECEIVE)``). |
| @@ -891,6 +893,18 @@ through MMIO writes, thus reducing the latency. However, enabling this feature · 9 unmodified lines | |||
| 891 | may increase the CPU cost. Drivers may enforce additional per-packet | 893 | may increase the CPU cost. Drivers may enforce additional per-packet |
| 892 | eligibility checks (e.g. on packet size). | 894 | eligibility checks (e.g. on packet size). |
| 893 | 895 | ||
| 896 | ``ETHTOOL_A_RINGS_TX_PUSH_BUF_LEN`` specifies the maximum number of bytes of a | ||
| 897 | transmitted packet a driver can push directly to the underlying device | ||
| 898 | ('push' mode). Pushing some of the payload bytes to the device has the | ||
| 899 | advantages of reducing latency for small packets by avoiding DMA mapping (same | ||
| 900 | as ``ETHTOOL_A_RINGS_TX_PUSH`` parameter) as well as allowing the underlying | ||
| 901 | device to process packet headers ahead of fetching its payload. | ||
| 902 | This can help the device to make fast actions based on the packet's headers. | ||
| 903 | This is similar to the "tx-copybreak" parameter, which copies the packet to a | ||
| 904 | preallocated DMA memory area instead of mapping new memory. However, | ||
| 905 | tx-push-buff parameter copies the packet directly to the device to allow the | ||
| 906 | device to take faster actions on the packet. | ||
| 907 | |||
| 894 | RINGS_SET | 908 | RINGS_SET |
| 895 | ========= | 909 | ========= |
| 896 | 910 | ||
| @@ -908,6 +922,7 @@ Request contents: · 11 unmodified lines | |||
| 908 | ``ETHTOOL_A_RINGS_CQE_SIZE`` u32 Size of TX/RX CQE | 922 | ``ETHTOOL_A_RINGS_CQE_SIZE`` u32 Size of TX/RX CQE |
| 909 | ``ETHTOOL_A_RINGS_TX_PUSH`` u8 flag of TX Push mode | 923 | ``ETHTOOL_A_RINGS_TX_PUSH`` u8 flag of TX Push mode |
| 910 | ``ETHTOOL_A_RINGS_RX_PUSH`` u8 flag of RX Push mode | 924 | ``ETHTOOL_A_RINGS_RX_PUSH`` u8 flag of RX Push mode |
| 925 | ``ETHTOOL_A_RINGS_TX_PUSH_BUF_LEN`` u32 size of TX push buffer | ||
| 911 | ==================================== ====== =========================== | 926 | ==================================== ====== =========================== |
| 912 | 927 | ||
| 913 | Kernel checks that requested ring sizes do not exceed limits reported by | 928 | Kernel checks that requested ring sizes do not exceed limits reported by |
| @@ -75,6 +75,8 @@ enum { · 74 unmodified lines | |||
| 75 | * @tx_push: The flag of tx push mode | 75 | * @tx_push: The flag of tx push mode |
| 76 | * @rx_push: The flag of rx push mode | 76 | * @rx_push: The flag of rx push mode |
| 77 | * @cqe_size: Size of TX/RX completion queue event | 77 | * @cqe_size: Size of TX/RX completion queue event |
| 78 | * @tx_push_buf_len: Size of TX push buffer | ||
| 79 | * @tx_push_buf_max_len: Maximum allowed size of TX push buffer | ||
| 78 | */ | 80 | */ |
| 79 | struct kernel_ethtool_ringparam { | 81 | struct kernel_ethtool_ringparam { |
| 80 | u32 rx_buf_len; | 82 | u32 rx_buf_len; |
| @@ -82,6 +84,8 @@ struct kernel_ethtool_ringparam { · 1 unmodified line | |||
| 82 | u8 tx_push; | 84 | u8 tx_push; |
| 83 | u8 rx_push; | 85 | u8 rx_push; |
| 84 | u32 cqe_size; | 86 | u32 cqe_size; |
| 87 | u32 tx_push_buf_len; | ||
| 88 | u32 tx_push_buf_max_len; | ||
| 85 | }; | 89 | }; |
| 86 | 90 | ||
| 87 | /** | 91 | /** |
| @@ -90,12 +94,14 @@ struct kernel_ethtool_ringparam { · 2 unmodified lines | |||
| 90 | * @ETHTOOL_RING_USE_CQE_SIZE: capture for setting cqe_size | 94 | * @ETHTOOL_RING_USE_CQE_SIZE: capture for setting cqe_size |
| 91 | * @ETHTOOL_RING_USE_TX_PUSH: capture for setting tx_push | 95 | * @ETHTOOL_RING_USE_TX_PUSH: capture for setting tx_push |
| 92 | * @ETHTOOL_RING_USE_RX_PUSH: capture for setting rx_push | 96 | * @ETHTOOL_RING_USE_RX_PUSH: capture for setting rx_push |
| 97 | * @ETHTOOL_RING_USE_TX_PUSH_BUF_LEN: capture for setting tx_push_buf_len | ||
| 93 | */ | 98 | */ |
| 94 | enum ethtool_supported_ring_param { | 99 | enum ethtool_supported_ring_param { |
| 95 | ETHTOOL_RING_USE_RX_BUF_LEN = BIT(0), | 100 | ETHTOOL_RING_USE_RX_BUF_LEN = BIT(0), |
| 96 | ETHTOOL_RING_USE_CQE_SIZE = BIT(1), | 101 | ETHTOOL_RING_USE_CQE_SIZE = BIT(1), |
| 97 | ETHTOOL_RING_USE_TX_PUSH = BIT(2), | 102 | ETHTOOL_RING_USE_TX_PUSH = BIT(2), |
| 98 | ETHTOOL_RING_USE_RX_PUSH = BIT(3), | 103 | ETHTOOL_RING_USE_RX_PUSH = BIT(3), |
| 104 | ETHTOOL_RING_USE_TX_PUSH_BUF_LEN = BIT(4), | ||
| 99 | }; | 105 | }; |
| 100 | 106 | ||
| 101 | #define __ETH_RSS_HASH_BIT(bit) ((u32)1 << (bit)) | 107 | #define __ETH_RSS_HASH_BIT(bit) ((u32)1 << (bit)) |
| @@ -357,6 +357,8 @@ enum { · 356 unmodified lines | |||
| 357 | ETHTOOL_A_RINGS_CQE_SIZE, /* u32 */ | 357 | ETHTOOL_A_RINGS_CQE_SIZE, /* u32 */ |
| 358 | ETHTOOL_A_RINGS_TX_PUSH, /* u8 */ | 358 | ETHTOOL_A_RINGS_TX_PUSH, /* u8 */ |
| 359 | ETHTOOL_A_RINGS_RX_PUSH, /* u8 */ | 359 | ETHTOOL_A_RINGS_RX_PUSH, /* u8 */ |
| 360 | ETHTOOL_A_RINGS_TX_PUSH_BUF_LEN, /* u32 */ | ||
| 361 | ETHTOOL_A_RINGS_TX_PUSH_BUF_LEN_MAX, /* u32 */ | ||
| 360 | 362 | ||
| 361 | /* add new constants above here */ | 363 | /* add new constants above here */ |
| 362 | __ETHTOOL_A_RINGS_CNT, | 364 | __ETHTOOL_A_RINGS_CNT, |
| @@ -413,7 +413,7 @@ extern const struct nla_policy ethnl_features_set_policy[ETHTOOL_A_FEATURES_WANT · 412 unmodified lines | |||
| 413 | extern const struct nla_policy ethnl_privflags_get_policy[ETHTOOL_A_PRIVFLAGS_HEADER + 1]; | 413 | extern const struct nla_policy ethnl_privflags_get_policy[ETHTOOL_A_PRIVFLAGS_HEADER + 1]; |
| 414 | extern const struct nla_policy ethnl_privflags_set_policy[ETHTOOL_A_PRIVFLAGS_FLAGS + 1]; | 414 | extern const struct nla_policy ethnl_privflags_set_policy[ETHTOOL_A_PRIVFLAGS_FLAGS + 1]; |
| 415 | extern const struct nla_policy ethnl_rings_get_policy[ETHTOOL_A_RINGS_HEADER + 1]; | 415 | extern const struct nla_policy ethnl_rings_get_policy[ETHTOOL_A_RINGS_HEADER + 1]; |
| 416 | extern const struct nla_policy ethnl_rings_set_policy[ETHTOOL_A_RINGS_RX_PUSH + 1]; | 416 | extern const struct nla_policy ethnl_rings_set_policy[ETHTOOL_A_RINGS_TX_PUSH_BUF_LEN_MAX + 1]; |
| 417 | extern const struct nla_policy ethnl_channels_get_policy[ETHTOOL_A_CHANNELS_HEADER + 1]; | 417 | extern const struct nla_policy ethnl_channels_get_policy[ETHTOOL_A_CHANNELS_HEADER + 1]; |
| 418 | extern const struct nla_policy ethnl_channels_set_policy[ETHTOOL_A_CHANNELS_COMBINED_COUNT + 1]; | 418 | extern const struct nla_policy ethnl_channels_set_policy[ETHTOOL_A_CHANNELS_COMBINED_COUNT + 1]; |
| 419 | extern const struct nla_policy ethnl_coalesce_get_policy[ETHTOOL_A_COALESCE_HEADER + 1]; | 419 | extern const struct nla_policy ethnl_coalesce_get_policy[ETHTOOL_A_COALESCE_HEADER + 1]; |
| @@ -11,6 +11,7 @@ struct rings_reply_data { · 10 unmodified lines | |||
| 11 | struct ethnl_reply_data base; | 11 | struct ethnl_reply_data base; |
| 12 | struct ethtool_ringparam ringparam; | 12 | struct ethtool_ringparam ringparam; |
| 13 | struct kernel_ethtool_ringparam kernel_ringparam; | 13 | struct kernel_ethtool_ringparam kernel_ringparam; |
| 14 | u32 supported_ring_params; | ||
| 14 | }; | 15 | }; |
| 15 | 16 | ||
| 16 | #define RINGS_REPDATA(__reply_base) \ | 17 | #define RINGS_REPDATA(__reply_base) \ |
| @@ -32,6 +33,8 @@ static int rings_prepare_data(const struct ethnl_req_info *req_base, · 15 unmodified lines | |||
| 32 | 33 | ||
| 33 | if (!dev->ethtool_ops->get_ringparam) | 34 | if (!dev->ethtool_ops->get_ringparam) |
| 34 | return -EOPNOTSUPP; | 35 | return -EOPNOTSUPP; |
| 36 | |||
| 37 | data->supported_ring_params = dev->ethtool_ops->supported_ring_params; | ||
| 35 | ret = ethnl_ops_begin(dev); | 38 | ret = ethnl_ops_begin(dev); |
| 36 | if (ret < 0) | 39 | if (ret < 0) |
| 37 | return ret; | 40 | return ret; |
| @@ -57,7 +60,9 @@ static int rings_reply_size(const struct ethnl_req_info *req_base, · 19 unmodified lines | |||
| 57 | nla_total_size(sizeof(u8)) + /* _RINGS_TCP_DATA_SPLIT */ | 60 | nla_total_size(sizeof(u8)) + /* _RINGS_TCP_DATA_SPLIT */ |
| 58 | nla_total_size(sizeof(u32) + /* _RINGS_CQE_SIZE */ | 61 | nla_total_size(sizeof(u32) + /* _RINGS_CQE_SIZE */ |
| 59 | nla_total_size(sizeof(u8)) + /* _RINGS_TX_PUSH */ | 62 | nla_total_size(sizeof(u8)) + /* _RINGS_TX_PUSH */ |
| 60 | nla_total_size(sizeof(u8))); /* _RINGS_RX_PUSH */ | 63 | nla_total_size(sizeof(u8))) + /* _RINGS_RX_PUSH */ |
| 64 | nla_total_size(sizeof(u32)) + /* _RINGS_TX_PUSH_BUF_LEN */ | ||
| 65 | nla_total_size(sizeof(u32)); /* _RINGS_TX_PUSH_BUF_LEN_MAX */ | ||
| 61 | } | 66 | } |
| 62 | 67 | ||
| 63 | static int rings_fill_reply(struct sk_buff *skb, | 68 | static int rings_fill_reply(struct sk_buff *skb, |
| @@ -67,6 +72,7 @@ static int rings_fill_reply(struct sk_buff *skb, · 3 unmodified lines | |||
| 67 | const struct rings_reply_data *data = RINGS_REPDATA(reply_base); | 72 | const struct rings_reply_data *data = RINGS_REPDATA(reply_base); |
| 68 | const struct kernel_ethtool_ringparam *kr = &data->kernel_ringparam; | 73 | const struct kernel_ethtool_ringparam *kr = &data->kernel_ringparam; |
| 69 | const struct ethtool_ringparam *ringparam = &data->ringparam; | 74 | const struct ethtool_ringparam *ringparam = &data->ringparam; |
| 75 | u32 supported_ring_params = data->supported_ring_params; | ||
| 70 | 76 | ||
| 71 | WARN_ON(kr->tcp_data_split > ETHTOOL_TCP_DATA_SPLIT_ENABLED); | 77 | WARN_ON(kr->tcp_data_split > ETHTOOL_TCP_DATA_SPLIT_ENABLED); |
| 72 | 78 | ||
| @@ -98,7 +104,12 @@ static int rings_fill_reply(struct sk_buff *skb, · 25 unmodified lines | |||
| 98 | (kr->cqe_size && | 104 | (kr->cqe_size && |
| 99 | (nla_put_u32(skb, ETHTOOL_A_RINGS_CQE_SIZE, kr->cqe_size))) || | 105 | (nla_put_u32(skb, ETHTOOL_A_RINGS_CQE_SIZE, kr->cqe_size))) || |
| 100 | nla_put_u8(skb, ETHTOOL_A_RINGS_TX_PUSH, !!kr->tx_push) || | 106 | nla_put_u8(skb, ETHTOOL_A_RINGS_TX_PUSH, !!kr->tx_push) || |
| 101 | nla_put_u8(skb, ETHTOOL_A_RINGS_RX_PUSH, !!kr->rx_push)) | 107 | nla_put_u8(skb, ETHTOOL_A_RINGS_RX_PUSH, !!kr->rx_push) || |
| 108 | ((supported_ring_params & ETHTOOL_RING_USE_TX_PUSH_BUF_LEN) && | ||
| 109 | (nla_put_u32(skb, ETHTOOL_A_RINGS_TX_PUSH_BUF_LEN_MAX, | ||
| 110 | kr->tx_push_buf_max_len) || | ||
| 111 | nla_put_u32(skb, ETHTOOL_A_RINGS_TX_PUSH_BUF_LEN, | ||
| 112 | kr->tx_push_buf_len)))) | ||
| 102 | return -EMSGSIZE; | 113 | return -EMSGSIZE; |
| 103 | 114 | ||
| 104 | return 0; | 115 | return 0; |
| @@ -117,6 +128,7 @@ const struct nla_policy ethnl_rings_set_policy[] = { · 12 unmodified lines | |||
| 117 | [ETHTOOL_A_RINGS_CQE_SIZE] = NLA_POLICY_MIN(NLA_U32, 1), | 128 | [ETHTOOL_A_RINGS_CQE_SIZE] = NLA_POLICY_MIN(NLA_U32, 1), |
| 118 | [ETHTOOL_A_RINGS_TX_PUSH] = NLA_POLICY_MAX(NLA_U8, 1), | 129 | [ETHTOOL_A_RINGS_TX_PUSH] = NLA_POLICY_MAX(NLA_U8, 1), |
| 119 | [ETHTOOL_A_RINGS_RX_PUSH] = NLA_POLICY_MAX(NLA_U8, 1), | 130 | [ETHTOOL_A_RINGS_RX_PUSH] = NLA_POLICY_MAX(NLA_U8, 1), |
| 131 | [ETHTOOL_A_RINGS_TX_PUSH_BUF_LEN] = { .type = NLA_U32 }, | ||
| 120 | }; | 132 | }; |
| 121 | 133 | ||
| 122 | static int | 134 | static int |
| @@ -158,6 +170,14 @@ ethnl_set_rings_validate(struct ethnl_req_info *req_info, · 35 unmodified lines | |||
| 158 | return -EOPNOTSUPP; | 170 | return -EOPNOTSUPP; |
| 159 | } | 171 | } |
| 160 | 172 | ||
| 173 | if (tb[ETHTOOL_A_RINGS_TX_PUSH_BUF_LEN] && | ||
| 174 | !(ops->supported_ring_params & ETHTOOL_RING_USE_TX_PUSH_BUF_LEN)) { | ||
| 175 | NL_SET_ERR_MSG_ATTR(info->extack, | ||
| 176 | tb[ETHTOOL_A_RINGS_TX_PUSH_BUF_LEN], | ||
| 177 | "setting tx push buf len is not supported"); | ||
| 178 | return -EOPNOTSUPP; | ||
| 179 | } | ||
| 180 | |||
| 161 | return ops->get_ringparam && ops->set_ringparam ? 1 : -EOPNOTSUPP; | 181 | return ops->get_ringparam && ops->set_ringparam ? 1 : -EOPNOTSUPP; |
| 162 | } | 182 | } |
| 163 | 183 | ||
| @@ -189,6 +209,8 @@ ethnl_set_rings(struct ethnl_req_info *req_info, struct genl_info *info) · 25 unmodified lines | |||
| 189 | tb[ETHTOOL_A_RINGS_TX_PUSH], &mod); | 209 | tb[ETHTOOL_A_RINGS_TX_PUSH], &mod); |
| 190 | ethnl_update_u8(&kernel_ringparam.rx_push, | 210 | ethnl_update_u8(&kernel_ringparam.rx_push, |
| 191 | tb[ETHTOOL_A_RINGS_RX_PUSH], &mod); | 211 | tb[ETHTOOL_A_RINGS_RX_PUSH], &mod); |
| 212 | ethnl_update_u32(&kernel_ringparam.tx_push_buf_len, | ||
| 213 | tb[ETHTOOL_A_RINGS_TX_PUSH_BUF_LEN], &mod); | ||
| 192 | if (!mod) | 214 | if (!mod) |
| 193 | return 0; | 215 | return 0; |
| 194 | 216 | ||
| @@ -209,6 +231,14 @@ ethnl_set_rings(struct ethnl_req_info *req_info, struct genl_info *info) · 14 unmodified lines | |||
| 209 | return -EINVAL; | 231 | return -EINVAL; |
| 210 | } | 232 | } |
| 211 | 233 | ||
| 234 | if (kernel_ringparam.tx_push_buf_len > kernel_ringparam.tx_push_buf_max_len) { | ||
| 235 | NL_SET_ERR_MSG_ATTR_FMT(info->extack, tb[ETHTOOL_A_RINGS_TX_PUSH_BUF_LEN], | ||
| 236 | "Requested TX push buffer exceeds the maximum of %u", | ||
| 237 | kernel_ringparam.tx_push_buf_max_len); | ||
| 238 | |||
| 239 | return -EINVAL; | ||
| 240 | } | ||
| 241 | |||
| 212 | ret = dev->ethtool_ops->set_ringparam(dev, &ringparam, | 242 | ret = dev->ethtool_ops->set_ringparam(dev, &ringparam, |
| 213 | &kernel_ringparam, info->extack); | 243 | &kernel_ringparam, info->extack); |
| 214 | return ret < 0 ? ret : 1; | 244 | return ret < 0 ? ret : 1; |