mirror of
https://github.com/systemd/systemd.git
synced 2024-11-24 18:53:33 +08:00
link: Add support to configure NIC ring buffer size
This commit is contained in:
parent
68c2b5ddb1
commit
224ded670f
@ -624,6 +624,19 @@
|
||||
<para>Sets the number of combined set channels (a number between 1 and 4294967295).</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term><varname>RxBufferSize=</varname></term>
|
||||
<listitem>
|
||||
<para>Takes a integer. Specifies the NIC receive ring buffer size. When unset, the kernel's default will be used.</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term><varname>TxBufferSize=</varname></term>
|
||||
<listitem>
|
||||
<para>Takes a integer. Specifies the NIC transmit ring buffer size. When unset, the kernel's default will be used.</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
</variablelist>
|
||||
</refsect1>
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -53,3 +53,5 @@ Link.TxChannels, config_parse_channel, 0,
|
||||
Link.OtherChannels, config_parse_channel, 0, offsetof(link_config, channels)
|
||||
Link.CombinedChannels, config_parse_channel, 0, offsetof(link_config, channels)
|
||||
Link.Advertise, config_parse_advertise, 0, offsetof(link_config, advertise)
|
||||
Link.RxBufferSize, config_parse_nic_buffer_size, 0, offsetof(link_config, ring)
|
||||
Link.TxBufferSize, config_parse_nic_buffer_size, 0, offsetof(link_config, ring)
|
||||
|
@ -381,6 +381,12 @@ int link_config_apply(link_config_ctx *ctx, link_config *config,
|
||||
log_warning_errno(r, "Could not set channels of %s: %m", old_name);
|
||||
}
|
||||
|
||||
if (config->ring.rx_pending_set || config->ring.tx_pending_set) {
|
||||
r = ethtool_set_nic_buffer_size(&ctx->ethtool_fd, old_name, &config->ring);
|
||||
if (r < 0)
|
||||
log_warning_errno(r, "Could not set ring buffer of %s: %m", old_name);
|
||||
}
|
||||
|
||||
r = sd_device_get_ifindex(device, &ifindex);
|
||||
if (r < 0)
|
||||
return log_device_warning_errno(device, r, "Could not find ifindex: %m");
|
||||
|
@ -58,6 +58,7 @@ struct link_config {
|
||||
NetDevPort port;
|
||||
int features[_NET_DEV_FEAT_MAX];
|
||||
netdev_channels channels;
|
||||
netdev_ring_param ring;
|
||||
|
||||
LIST_FIELDS(link_config, links);
|
||||
};
|
||||
|
@ -34,3 +34,5 @@ TxChannels=
|
||||
OtherChannels=
|
||||
CombinedChannels=
|
||||
Advertise=
|
||||
RxBufferSize=
|
||||
TxBufferSize=
|
||||
|
Loading…
Reference in New Issue
Block a user