From 406041b7de767316674eb6a2f98ad466577ce8a4 Mon Sep 17 00:00:00 2001 From: Daan De Meyer Date: Wed, 18 Aug 2021 07:59:13 +0100 Subject: [PATCH] udev: Support "max" string for BufferSize options (#20458) "max" indicates the hardware advertised maximum queue buffer size should be used. The max sizes can be checked by running `ethtool -g ` (Preset maximums). Since the buffer sizes can't be set to 0 by users, internally we use 0 to indicate that the hardware advertised maximum should be used. --- man/systemd.link.xml | 20 ++++++++++++-------- src/shared/ethtool-util.c | 40 +++++++++++++++++++++++++-------------- src/shared/ethtool-util.h | 2 ++ 3 files changed, 40 insertions(+), 22 deletions(-) diff --git a/man/systemd.link.xml b/man/systemd.link.xml index ee4356ac3d6..d72533b1625 100644 --- a/man/systemd.link.xml +++ b/man/systemd.link.xml @@ -735,29 +735,33 @@ RxBufferSize= - Takes an integer. Specifies the maximum number of pending packets in the NIC receive buffer. - When unset, the kernel's default will be used. + Takes an integer or max. Specifies the maximum number of pending packets + in the NIC receive buffer. When unset, the kernel's default will be used. If set to + max, the hardware's advertised maximum size will be used. RxMiniBufferSize= - Takes an integer. Specifies the maximum number of pending packets in the NIC mini receive buffer. - When unset, the kernel's default will be used. + Takes an integer or max. Specifies the maximum number of pending packets + in the NIC mini receive buffer. When unset, the kernel's default will be used. If set to + max, the hardware's advertised maximum size will be used. RxJumboBufferSize= - Takes an integer. Specifies the maximum number of pending packets in the NIC jumbo receive buffer. - When unset, the kernel's default will be used. + Takes an integer or max. Specifies the maximum number of pending packets + in the NIC jumbo receive buffer. When unset, the kernel's default will be used. If set to + max, the hardware's advertised maximum size will be used. TxBufferSize= - Takes an integer. Specifies the maximum number of pending packets in the NIC transmit buffer. - When unset, the kernel's default will be used. + Takes an integer or max. Specifies the maximum number of pending packets + in the NIC transmit buffer. When unset, the kernel's default will be used. If set to + max, the hardware's advertised maximum size will be used. diff --git a/src/shared/ethtool-util.c b/src/shared/ethtool-util.c index 4ca90615f3c..4e81e027b22 100644 --- a/src/shared/ethtool-util.c +++ b/src/shared/ethtool-util.c @@ -399,16 +399,24 @@ int ethtool_set_nic_buffer_size(int *ethtool_fd, const char *ifname, const netde return -errno; if (ring->rx_pending_set) - UPDATE(ecmd.rx_pending, ring->rx_pending, need_update); + UPDATE(ecmd.rx_pending, + ring->rx_pending == 0 ? ecmd.rx_max_pending : ring->rx_pending, + need_update); if (ring->rx_mini_pending_set) - UPDATE(ecmd.rx_mini_pending, ring->rx_mini_pending, need_update); + UPDATE(ecmd.rx_mini_pending, + ring->rx_mini_pending == 0 ? ecmd.rx_mini_max_pending : ring->rx_mini_pending, + need_update); if (ring->rx_jumbo_pending_set) - UPDATE(ecmd.rx_jumbo_pending, ring->rx_jumbo_pending, need_update); + UPDATE(ecmd.rx_jumbo_pending, + ring->rx_jumbo_pending == 0 ? ecmd.rx_jumbo_max_pending : ring->rx_jumbo_pending, + need_update); if (ring->tx_pending_set) - UPDATE(ecmd.tx_pending, ring->tx_pending, need_update); + UPDATE(ecmd.tx_pending, + ring->tx_pending == 0 ? ecmd.tx_max_pending : ring->tx_pending, + need_update); if (!need_update) return 0; @@ -1047,16 +1055,20 @@ int config_parse_nic_buffer_size( assert(rvalue); assert(data); - r = safe_atou32(rvalue, &k); - if (r < 0) { - log_syntax(unit, LOG_WARNING, filename, line, r, - "Failed to parse interface buffer value, ignoring: %s", rvalue); - return 0; - } - if (k < 1) { - log_syntax(unit, LOG_WARNING, filename, line, 0, - "Invalid %s= value, ignoring: %s", lvalue, rvalue); - return 0; + if (streq(rvalue, "max")) + k = 0; + else { + r = safe_atou32(rvalue, &k); + if (r < 0) { + log_syntax(unit, LOG_WARNING, filename, line, r, + "Failed to parse interface buffer value, ignoring: %s", rvalue); + return 0; + } + if (k < 1) { + log_syntax(unit, LOG_WARNING, filename, line, 0, + "Invalid %s= value, ignoring: %s", lvalue, rvalue); + return 0; + } } if (streq(lvalue, "RxBufferSize")) { diff --git a/src/shared/ethtool-util.h b/src/shared/ethtool-util.h index f0fc40b0595..f392a1cf42a 100644 --- a/src/shared/ethtool-util.h +++ b/src/shared/ethtool-util.h @@ -70,6 +70,8 @@ typedef struct netdev_channels { } netdev_channels; typedef struct netdev_ring_param { + /* For any of the 4 following settings, a value of 0 indicates the hardware advertised maximum should + * be used. */ uint32_t rx_pending; uint32_t rx_mini_pending; uint32_t rx_jumbo_pending;