link: Add support to configure NIC ring buffer size

This commit is contained in:
Susant Sahani
2019-09-24 16:33:35 +02:00
committed by Yu Watanabe
parent 68c2b5ddb1
commit 224ded670f
7 changed files with 125 additions and 0 deletions
+90
View File
@@ -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;
}
+11
View File
@@ -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);