diff options
author | Susant Sahani <ssahani@vmware.com> | 2019-09-23 16:51:02 +0200 |
---|---|---|
committer | Yu Watanabe <watanabe.yu+github@gmail.com> | 2019-09-24 16:33:35 +0200 |
commit | 224ded670feeb59f7231e6102a5bee5d3b653a8a (patch) | |
tree | 6f7d4645dd9fa5275dc3acaf2b199a9338d98508 /src/shared | |
parent | 68c2b5ddb1881c40201c1d86a7852dd5c5c06a76 (diff) | |
download | systemd-224ded670feeb59f7231e6102a5bee5d3b653a8a.tar.gz |
link: Add support to configure NIC ring buffer size
Diffstat (limited to 'src/shared')
-rw-r--r-- | src/shared/ethtool-util.c | 90 | ||||
-rw-r--r-- | src/shared/ethtool-util.h | 11 |
2 files changed, 101 insertions, 0 deletions
diff --git a/src/shared/ethtool-util.c b/src/shared/ethtool-util.c index b0961df72e..4cab2ef6b0 100644 --- a/src/shared/ethtool-util.c +++ b/src/shared/ethtool-util.c @@ -365,6 +365,54 @@ int ethtool_set_wol(int *fd, const char *ifname, WakeOnLan wol) { return 0; } +int ethtool_set_nic_buffer_size(int *fd, const char *ifname, netdev_ring_param *ring) { + struct ethtool_ringparam ecmd = { + .cmd = ETHTOOL_GRINGPARAM + }; + struct ifreq ifr = { + .ifr_data = (void*) &ecmd + }; + bool need_update = false; + int r; + + if (*fd < 0) { + r = ethtool_connect_or_warn(fd, true); + if (r < 0) + return r; + } + + strscpy(ifr.ifr_name, IFNAMSIZ, ifname); + + r = ioctl(*fd, SIOCETHTOOL, &ifr); + if (r < 0) + return -errno; + + if (ring->rx_pending_set) { + if (ecmd.rx_pending != ring->rx_pending) { + ecmd.rx_pending = ring->rx_pending; + need_update = true; + } + } + + if (ring->tx_pending_set) { + if (ecmd.tx_pending != ring->rx_pending) { + ecmd.tx_pending = ring->tx_pending; + need_update = true; + } + } + + if (need_update) { + ecmd.cmd = ETHTOOL_SRINGPARAM; + + r = ioctl(*fd, SIOCETHTOOL, &ifr); + if (r < 0) + return -errno; + } + + return 0; +} + + static int get_stringset(int fd, struct ifreq *ifr, int stringset_id, struct ethtool_gstrings **gstrings) { _cleanup_free_ struct ethtool_gstrings *strings = NULL; struct { @@ -858,3 +906,45 @@ int config_parse_advertise(const char *unit, return 0; } + +int config_parse_nic_buffer_size(const char *unit, + const char *filename, + unsigned line, + const char *section, + unsigned section_line, + const char *lvalue, + int ltype, + const char *rvalue, + void *data, + void *userdata) { + netdev_ring_param *ring = data; + uint32_t k; + int r; + + assert(filename); + assert(section); + assert(lvalue); + assert(rvalue); + assert(data); + + r = safe_atou32(rvalue, &k); + if (r < 0) { + log_syntax(unit, LOG_ERR, filename, line, r, "Failed to parse interface buffer value, ignoring: %s", rvalue); + return 0; + } + + if (k < 1) { + log_syntax(unit, LOG_ERR, filename, line, 0, "Invalid %s value, ignoring: %s", lvalue, rvalue); + return 0; + } + + if (streq(lvalue, "RxBufferSize")) { + ring->rx_pending = k; + ring->rx_pending_set = true; + } else if (streq(lvalue, "TxBufferSize")) { + ring->tx_pending = k; + ring->tx_pending_set = true; + } + + return 0; +} diff --git a/src/shared/ethtool-util.h b/src/shared/ethtool-util.h index 8b32b243f3..5dd7800852 100644 --- a/src/shared/ethtool-util.h +++ b/src/shared/ethtool-util.h @@ -79,12 +79,22 @@ typedef struct netdev_channels { bool combined_count_set; } netdev_channels; +typedef struct netdev_ring_param { + uint32_t rx_pending; + uint32_t tx_pending; + + bool rx_pending_set; + bool tx_pending_set; +} netdev_ring_param; + + int ethtool_get_driver(int *fd, const char *ifname, char **ret); int ethtool_get_link_info(int *fd, const char *ifname, int *ret_autonegotiation, size_t *ret_speed, Duplex *ret_duplex, NetDevPort *ret_port); int ethtool_set_speed(int *fd, const char *ifname, unsigned speed, Duplex duplex); int ethtool_set_wol(int *fd, const char *ifname, WakeOnLan wol); +int ethtool_set_nic_buffer_size(int *fd, const char *ifname, netdev_ring_param *ring); int ethtool_set_features(int *fd, const char *ifname, int *features); int ethtool_set_glinksettings(int *fd, const char *ifname, int autonegotiation, uint32_t advertise[static N_ADVERTISE], @@ -108,3 +118,4 @@ CONFIG_PARSER_PROTOTYPE(config_parse_wol); CONFIG_PARSER_PROTOTYPE(config_parse_port); CONFIG_PARSER_PROTOTYPE(config_parse_channel); CONFIG_PARSER_PROTOTYPE(config_parse_advertise); +CONFIG_PARSER_PROTOTYPE(config_parse_nic_buffer_size); |