Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

ethtool: add support to set/get rx buf len via ethtool

Add support to set rx buf len via ethtool -G parameter and get
rx buf len via ethtool -g parameter.

Signed-off-by: Hao Chen <chenhao288@hisilicon.com>
Signed-off-by: Guangbin Huang <huangguangbin2@huawei.com>
Signed-off-by: David S. Miller <davem@davemloft.net>

authored by

Hao Chen and committed by
David S. Miller
0b70c256 e445f08a

+47 -7
+6 -4
Documentation/networking/ethtool-netlink.rst
··· 849 849 850 850 Kernel response contents: 851 851 852 - ==================================== ====== ========================== 852 + ==================================== ====== =========================== 853 853 ``ETHTOOL_A_RINGS_HEADER`` nested reply header 854 854 ``ETHTOOL_A_RINGS_RX_MAX`` u32 max size of RX ring 855 855 ``ETHTOOL_A_RINGS_RX_MINI_MAX`` u32 max size of RX mini ring ··· 859 859 ``ETHTOOL_A_RINGS_RX_MINI`` u32 size of RX mini ring 860 860 ``ETHTOOL_A_RINGS_RX_JUMBO`` u32 size of RX jumbo ring 861 861 ``ETHTOOL_A_RINGS_TX`` u32 size of TX ring 862 - ==================================== ====== ========================== 862 + ``ETHTOOL_A_RINGS_RX_BUF_LEN`` u32 size of buffers on the ring 863 + ==================================== ====== =========================== 863 864 864 865 865 866 RINGS_SET ··· 870 869 871 870 Request contents: 872 871 873 - ==================================== ====== ========================== 872 + ==================================== ====== =========================== 874 873 ``ETHTOOL_A_RINGS_HEADER`` nested reply header 875 874 ``ETHTOOL_A_RINGS_RX`` u32 size of RX ring 876 875 ``ETHTOOL_A_RINGS_RX_MINI`` u32 size of RX mini ring 877 876 ``ETHTOOL_A_RINGS_RX_JUMBO`` u32 size of RX jumbo ring 878 877 ``ETHTOOL_A_RINGS_TX`` u32 size of TX ring 879 - ==================================== ====== ========================== 878 + ``ETHTOOL_A_RINGS_RX_BUF_LEN`` u32 size of buffers on the ring 879 + ==================================== ====== =========================== 880 880 881 881 Kernel checks that requested ring sizes do not exceed limits reported by 882 882 driver. Driver may impose additional constraints and may not suspport all
+18
include/linux/ethtool.h
··· 67 67 ETH_RSS_HASH_FUNCS_COUNT 68 68 }; 69 69 70 + /** 71 + * struct kernel_ethtool_ringparam - RX/TX ring configuration 72 + * @rx_buf_len: Current length of buffers on the rx ring. 73 + */ 74 + struct kernel_ethtool_ringparam { 75 + u32 rx_buf_len; 76 + }; 77 + 78 + /** 79 + * enum ethtool_supported_ring_param - indicator caps for setting ring params 80 + * @ETHTOOL_RING_USE_RX_BUF_LEN: capture for setting rx_buf_len 81 + */ 82 + enum ethtool_supported_ring_param { 83 + ETHTOOL_RING_USE_RX_BUF_LEN = BIT(0), 84 + }; 85 + 70 86 #define __ETH_RSS_HASH_BIT(bit) ((u32)1 << (bit)) 71 87 #define __ETH_RSS_HASH(name) __ETH_RSS_HASH_BIT(ETH_RSS_HASH_##name##_BIT) 72 88 ··· 448 432 * @cap_link_lanes_supported: indicates if the driver supports lanes 449 433 * parameter. 450 434 * @supported_coalesce_params: supported types of interrupt coalescing. 435 + * @supported_ring_params: supported ring params. 451 436 * @get_drvinfo: Report driver/device information. Should only set the 452 437 * @driver, @version, @fw_version and @bus_info fields. If not 453 438 * implemented, the @driver and @bus_info fields will be filled in ··· 630 613 struct ethtool_ops { 631 614 u32 cap_link_lanes_supported:1; 632 615 u32 supported_coalesce_params; 616 + u32 supported_ring_params; 633 617 void (*get_drvinfo)(struct net_device *, struct ethtool_drvinfo *); 634 618 int (*get_regs_len)(struct net_device *); 635 619 void (*get_regs)(struct net_device *, struct ethtool_regs *, void *);
+1
include/uapi/linux/ethtool_netlink.h
··· 329 329 ETHTOOL_A_RINGS_RX_MINI, /* u32 */ 330 330 ETHTOOL_A_RINGS_RX_JUMBO, /* u32 */ 331 331 ETHTOOL_A_RINGS_TX, /* u32 */ 332 + ETHTOOL_A_RINGS_RX_BUF_LEN, /* u32 */ 332 333 333 334 /* add new constants above here */ 334 335 __ETHTOOL_A_RINGS_CNT,
+1 -1
net/ethtool/netlink.h
··· 356 356 extern const struct nla_policy ethnl_privflags_get_policy[ETHTOOL_A_PRIVFLAGS_HEADER + 1]; 357 357 extern const struct nla_policy ethnl_privflags_set_policy[ETHTOOL_A_PRIVFLAGS_FLAGS + 1]; 358 358 extern const struct nla_policy ethnl_rings_get_policy[ETHTOOL_A_RINGS_HEADER + 1]; 359 - extern const struct nla_policy ethnl_rings_set_policy[ETHTOOL_A_RINGS_TX + 1]; 359 + extern const struct nla_policy ethnl_rings_set_policy[ETHTOOL_A_RINGS_RX_BUF_LEN + 1]; 360 360 extern const struct nla_policy ethnl_channels_get_policy[ETHTOOL_A_CHANNELS_HEADER + 1]; 361 361 extern const struct nla_policy ethnl_channels_set_policy[ETHTOOL_A_CHANNELS_COMBINED_COUNT + 1]; 362 362 extern const struct nla_policy ethnl_coalesce_get_policy[ETHTOOL_A_COALESCE_HEADER + 1];
+21 -2
net/ethtool/rings.c
··· 10 10 struct rings_reply_data { 11 11 struct ethnl_reply_data base; 12 12 struct ethtool_ringparam ringparam; 13 + struct kernel_ethtool_ringparam kernel_ringparam; 13 14 }; 14 15 15 16 #define RINGS_REPDATA(__reply_base) \ ··· 50 49 nla_total_size(sizeof(u32)) + /* _RINGS_RX */ 51 50 nla_total_size(sizeof(u32)) + /* _RINGS_RX_MINI */ 52 51 nla_total_size(sizeof(u32)) + /* _RINGS_RX_JUMBO */ 53 - nla_total_size(sizeof(u32)); /* _RINGS_TX */ 52 + nla_total_size(sizeof(u32)) + /* _RINGS_TX */ 53 + nla_total_size(sizeof(u32)); /* _RINGS_RX_BUF_LEN */ 54 54 } 55 55 56 56 static int rings_fill_reply(struct sk_buff *skb, ··· 59 57 const struct ethnl_reply_data *reply_base) 60 58 { 61 59 const struct rings_reply_data *data = RINGS_REPDATA(reply_base); 60 + const struct kernel_ethtool_ringparam *kernel_ringparam = &data->kernel_ringparam; 62 61 const struct ethtool_ringparam *ringparam = &data->ringparam; 63 62 64 63 if ((ringparam->rx_max_pending && ··· 81 78 (nla_put_u32(skb, ETHTOOL_A_RINGS_TX_MAX, 82 79 ringparam->tx_max_pending) || 83 80 nla_put_u32(skb, ETHTOOL_A_RINGS_TX, 84 - ringparam->tx_pending)))) 81 + ringparam->tx_pending))) || 82 + (kernel_ringparam->rx_buf_len && 83 + (nla_put_u32(skb, ETHTOOL_A_RINGS_RX_BUF_LEN, 84 + kernel_ringparam->rx_buf_len)))) 85 85 return -EMSGSIZE; 86 86 87 87 return 0; ··· 111 105 [ETHTOOL_A_RINGS_RX_MINI] = { .type = NLA_U32 }, 112 106 [ETHTOOL_A_RINGS_RX_JUMBO] = { .type = NLA_U32 }, 113 107 [ETHTOOL_A_RINGS_TX] = { .type = NLA_U32 }, 108 + [ETHTOOL_A_RINGS_RX_BUF_LEN] = NLA_POLICY_MIN(NLA_U32, 1), 114 109 }; 115 110 116 111 int ethnl_set_rings(struct sk_buff *skb, struct genl_info *info) 117 112 { 113 + struct kernel_ethtool_ringparam kernel_ringparam = {}; 118 114 struct ethtool_ringparam ringparam = {}; 119 115 struct ethnl_req_info req_info = {}; 120 116 struct nlattr **tb = info->attrs; ··· 150 142 ethnl_update_u32(&ringparam.rx_jumbo_pending, 151 143 tb[ETHTOOL_A_RINGS_RX_JUMBO], &mod); 152 144 ethnl_update_u32(&ringparam.tx_pending, tb[ETHTOOL_A_RINGS_TX], &mod); 145 + ethnl_update_u32(&kernel_ringparam.rx_buf_len, 146 + tb[ETHTOOL_A_RINGS_RX_BUF_LEN], &mod); 153 147 ret = 0; 154 148 if (!mod) 155 149 goto out_ops; ··· 171 161 ret = -EINVAL; 172 162 NL_SET_ERR_MSG_ATTR(info->extack, err_attr, 173 163 "requested ring size exceeds maximum"); 164 + goto out_ops; 165 + } 166 + 167 + if (kernel_ringparam.rx_buf_len != 0 && 168 + !(ops->supported_ring_params & ETHTOOL_RING_USE_RX_BUF_LEN)) { 169 + ret = -EOPNOTSUPP; 170 + NL_SET_ERR_MSG_ATTR(info->extack, 171 + tb[ETHTOOL_A_RINGS_RX_BUF_LEN], 172 + "setting rx buf len not supported"); 174 173 goto out_ops; 175 174 } 176 175