1
0
mirror of https://github.com/systemd/systemd.git synced 2024-12-22 17:35:35 +03:00

udev: Add support for configuring nic coalescing settings

These are configured via the corresponding ethtool ioctl.
This commit is contained in:
Daan De Meyer 2021-08-18 13:52:00 +01:00 committed by Luca Boccassi
parent a622c58993
commit 6c35ea5ef0
7 changed files with 405 additions and 51 deletions

View File

@ -773,6 +773,77 @@
accept. An unsigned integer in the range 1…65535. Defaults to unset.</para>
</listitem>
</varlistentry>
<varlistentry>
<term><varname>UseAdaptiveRxCoalesce=</varname></term>
<term><varname>UseAdaptiveTxCoalesce=</varname></term>
<listitem>
<para>Boolean properties that, when set, enable/disable adaptive Rx/Tx coalescing if the hardware
supports it. When unset, the kernel's default will be used.</para>
</listitem>
</varlistentry>
<varlistentry>
<term><varname>RxCoalesceSec=</varname></term>
<term><varname>RxCoalesceIrqSec=</varname></term>
<term><varname>RxCoalesceLowSec=</varname></term>
<term><varname>RxCoalesceHighSec=</varname></term>
<term><varname>TxCoalesceSec=</varname></term>
<term><varname>TxCoalesceIrqSec=</varname></term>
<term><varname>TxCoalesceLowSec=</varname></term>
<term><varname>TxCoalesceHighSec=</varname></term>
<listitem>
<para>These properties configure the delay before Rx/Tx interrupts are generated after a packet is
sent/received. The <literal>Irq</literal> properties come into effect when the host is servicing an
IRQ. The <literal>Low</literal> and <literal>High</literal> properties come into effect when the
packet rate drops below the low packet rate threshold or exceeds the high packet rate threshold
respectively if adaptive Rx/Tx coalescing is enabled. When unset, the kernel's defaults will be
used.</para>
</listitem>
</varlistentry>
<varlistentry>
<term><varname>RxMaxCoalescedFrames=</varname></term>
<term><varname>RxMaxCoalescedIrqFrames=</varname></term>
<term><varname>RxMaxCoalescedLowFrames=</varname></term>
<term><varname>RxMaxCoalescedHighFrames=</varname></term>
<term><varname>TxMaxCoalescedFrames=</varname></term>
<term><varname>TxMaxCoalescedIrqFrames=</varname></term>
<term><varname>TxMaxCoalescedLowFrames=</varname></term>
<term><varname>TxMaxCoalescedHighFrames=</varname></term>
<listitem>
<para>These properties configure the maximum number of frames that are sent/received before a Rx/Tx
interrupt is generated. The <literal>Irq</literal> properties come into effect when the host is
servicing an IRQ. The <literal>Low</literal> and <literal>High</literal> properties come into
effect when the packet rate drops below the low packet rate threshold or exceeds the high packet
rate threshold respectively if adaptive Rx/Tx coalescing is enabled. When unset, the kernel's
defaults will be used.</para>
</listitem>
</varlistentry>
<varlistentry>
<term><varname>CoalescePacketRateLow=</varname></term>
<term><varname>CoalescePacketRateHigh=</varname></term>
<listitem>
<para>These properties configure the low and high packet rate (expressed in packets per second)
threshold respectively and are used to determine when the corresponding coalescing settings for low
and high packet rates come into effect if adaptive Rx/Tx coalescing is enabled. If unset, the
kernel's defaults will be used.</para>
</listitem>
</varlistentry>
<varlistentry>
<term><varname>CoalescePacketRateSampleIntervalSec=</varname></term>
<listitem>
<para>Configures how often to sample the packet rate used for adaptive Rx/Tx coalescing. This
property cannot be zero. This lowest time granularity supported by this property is seconds.
Partial seconds will be rounded up before being passed to the kernel. If unset, the kernel's
default will be used.</para>
</listitem>
</varlistentry>
<varlistentry>
<term><varname>StatisticsBlockCoalesceSec=</varname></term>
<listitem>
<para>How long to delay driver in-memory statistics block updates. If the driver does not have an
in-memory statistic block, this property is ignored. This property cannot be zero. If unset, the
kernel's default will be used.</para>
</listitem>
</varlistentry>
</variablelist>
</refsect1>

View File

@ -14,6 +14,7 @@
#include "memory-util.h"
#include "socket-util.h"
#include "string-table.h"
#include "strv.h"
#include "strxcpyx.h"
static const char* const duplex_table[_DUP_MAX] = {
@ -1101,3 +1102,207 @@ int config_parse_wol(
return 0;
}
int config_parse_coalesce_u32(
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) {
u32_opt *dst = data;
uint32_t k;
int r;
if (isempty(rvalue)) {
dst->value = 0;
dst->set = false;
return 0;
}
r = safe_atou32(rvalue, &k);
if (r < 0) {
log_syntax(unit, LOG_WARNING, filename, line, r,
"Failed to parse %s=, ignoring: %s", lvalue, rvalue);
return 0;
}
dst->value = k;
dst->set = true;
return 0;
}
int config_parse_coalesce_sec(
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) {
u32_opt *dst = data;
usec_t usec;
int r;
if (isempty(rvalue)) {
dst->value = 0;
dst->set = false;
return 0;
}
r = parse_sec(rvalue, &usec);
if (r < 0) {
log_syntax(unit, LOG_WARNING, filename, line, r,
"Failed to parse coalesce setting value, ignoring: %s", rvalue);
return 0;
}
if (usec > UINT32_MAX) {
log_syntax(unit, LOG_WARNING, filename, line, 0,
"Too large %s= value, ignoring: %s", lvalue, rvalue);
return 0;
}
if (STR_IN_SET(lvalue, "StatisticsBlockCoalesceSec", "CoalescePacketRateSampleIntervalSec") && usec < 1) {
log_syntax(unit, LOG_WARNING, filename, line, 0,
"Invalid %s= value, ignoring: %s", lvalue, rvalue);
return 0;
}
dst->value = (uint32_t) usec;
dst->set = true;
return 0;
}
int ethtool_set_nic_coalesce_settings(int *ethtool_fd, const char *ifname, const netdev_coalesce_param *coalesce) {
struct ethtool_coalesce ecmd = {
.cmd = ETHTOOL_GCOALESCE,
};
struct ifreq ifr = {
.ifr_data = (void*) &ecmd,
};
bool need_update = false;
int r;
assert(ethtool_fd);
assert(ifname);
assert(coalesce);
if (coalesce->use_adaptive_rx_coalesce < 0 &&
coalesce->use_adaptive_tx_coalesce < 0 &&
!coalesce->rx_coalesce_usecs.set &&
!coalesce->rx_max_coalesced_frames.set &&
!coalesce->rx_coalesce_usecs_irq.set &&
!coalesce->rx_max_coalesced_frames_irq.set &&
!coalesce->tx_coalesce_usecs.set &&
!coalesce->tx_max_coalesced_frames.set &&
!coalesce->tx_coalesce_usecs_irq.set &&
!coalesce->tx_max_coalesced_frames_irq.set &&
!coalesce->stats_block_coalesce_usecs.set &&
!coalesce->pkt_rate_low.set &&
!coalesce->rx_coalesce_usecs_low.set &&
!coalesce->rx_max_coalesced_frames_low.set &&
!coalesce->tx_coalesce_usecs_low.set &&
!coalesce->tx_max_coalesced_frames_low.set &&
!coalesce->pkt_rate_high.set &&
!coalesce->rx_coalesce_usecs_high.set &&
!coalesce->rx_max_coalesced_frames_high.set &&
!coalesce->tx_coalesce_usecs_high.set &&
!coalesce->tx_max_coalesced_frames_high.set &&
!coalesce->rate_sample_interval.set)
return 0;
r = ethtool_connect(ethtool_fd);
if (r < 0)
return r;
strscpy(ifr.ifr_name, IFNAMSIZ, ifname);
r = ioctl(*ethtool_fd, SIOCETHTOOL, &ifr);
if (r < 0)
return -errno;
if (coalesce->use_adaptive_rx_coalesce >= 0)
UPDATE(ecmd.use_adaptive_rx_coalesce, (uint32_t) coalesce->use_adaptive_rx_coalesce, need_update);
if (coalesce->use_adaptive_tx_coalesce >= 0)
UPDATE(ecmd.use_adaptive_tx_coalesce, (uint32_t) coalesce->use_adaptive_tx_coalesce, need_update);
if (coalesce->rx_coalesce_usecs.set)
UPDATE(ecmd.rx_coalesce_usecs, coalesce->rx_coalesce_usecs.value, need_update);
if (coalesce->rx_max_coalesced_frames.set)
UPDATE(ecmd.rx_max_coalesced_frames, coalesce->rx_max_coalesced_frames.value, need_update);
if (coalesce->rx_coalesce_usecs_irq.set)
UPDATE(ecmd.rx_coalesce_usecs_irq, coalesce->rx_coalesce_usecs_irq.value, need_update);
if (coalesce->rx_max_coalesced_frames_irq.set)
UPDATE(ecmd.rx_max_coalesced_frames_irq, coalesce->rx_max_coalesced_frames_irq.value, need_update);
if (coalesce->tx_coalesce_usecs.set)
UPDATE(ecmd.tx_coalesce_usecs, coalesce->tx_coalesce_usecs.value, need_update);
if (coalesce->tx_max_coalesced_frames.set)
UPDATE(ecmd.tx_max_coalesced_frames, coalesce->tx_max_coalesced_frames.value, need_update);
if (coalesce->tx_coalesce_usecs_irq.set)
UPDATE(ecmd.tx_coalesce_usecs_irq, coalesce->tx_coalesce_usecs_irq.value, need_update);
if (coalesce->tx_max_coalesced_frames_irq.set)
UPDATE(ecmd.tx_max_coalesced_frames_irq, coalesce->tx_max_coalesced_frames_irq.value, need_update);
if (coalesce->stats_block_coalesce_usecs.set)
UPDATE(ecmd.stats_block_coalesce_usecs, coalesce->stats_block_coalesce_usecs.value, need_update);
if (coalesce->pkt_rate_low.set)
UPDATE(ecmd.pkt_rate_low, coalesce->pkt_rate_low.value, need_update);
if (coalesce->rx_coalesce_usecs_low.set)
UPDATE(ecmd.rx_coalesce_usecs_low, coalesce->rx_coalesce_usecs_low.value, need_update);
if (coalesce->rx_max_coalesced_frames_low.set)
UPDATE(ecmd.rx_max_coalesced_frames_low, coalesce->rx_max_coalesced_frames_low.value, need_update);
if (coalesce->tx_coalesce_usecs_low.set)
UPDATE(ecmd.tx_coalesce_usecs_low, coalesce->tx_coalesce_usecs_low.value, need_update);
if (coalesce->tx_max_coalesced_frames_low.set)
UPDATE(ecmd.tx_max_coalesced_frames_low, coalesce->tx_max_coalesced_frames_low.value, need_update);
if (coalesce->pkt_rate_high.set)
UPDATE(ecmd.pkt_rate_high, coalesce->pkt_rate_high.value, need_update);
if (coalesce->rx_coalesce_usecs_high.set)
UPDATE(ecmd.rx_coalesce_usecs_high, coalesce->rx_coalesce_usecs_high.value, need_update);
if (coalesce->rx_max_coalesced_frames_high.set)
UPDATE(ecmd.rx_max_coalesced_frames_high, coalesce->rx_max_coalesced_frames_high.value, need_update);
if (coalesce->tx_coalesce_usecs_high.set)
UPDATE(ecmd.tx_coalesce_usecs_high, coalesce->tx_coalesce_usecs_high.value, need_update);
if (coalesce->tx_max_coalesced_frames_high.set)
UPDATE(ecmd.tx_max_coalesced_frames_high, coalesce->tx_max_coalesced_frames_high.value, need_update);
if (coalesce->rate_sample_interval.set)
UPDATE(ecmd.rate_sample_interval, DIV_ROUND_UP(coalesce->rate_sample_interval.value, USEC_PER_SEC), need_update);
if (!need_update)
return 0;
ecmd.cmd = ETHTOOL_SCOALESCE;
r = ioctl(*ethtool_fd, SIOCETHTOOL, &ifr);
if (r < 0)
return -errno;
return 0;
}

View File

@ -76,6 +76,31 @@ typedef struct netdev_ring_param {
u32_opt tx;
} netdev_ring_param;
typedef struct netdev_coalesce_param {
u32_opt rx_coalesce_usecs;
u32_opt rx_max_coalesced_frames;
u32_opt rx_coalesce_usecs_irq;
u32_opt rx_max_coalesced_frames_irq;
u32_opt tx_coalesce_usecs;
u32_opt tx_max_coalesced_frames;
u32_opt tx_coalesce_usecs_irq;
u32_opt tx_max_coalesced_frames_irq;
u32_opt stats_block_coalesce_usecs;
int use_adaptive_rx_coalesce;
int use_adaptive_tx_coalesce;
u32_opt pkt_rate_low;
u32_opt rx_coalesce_usecs_low;
u32_opt rx_max_coalesced_frames_low;
u32_opt tx_coalesce_usecs_low;
u32_opt tx_max_coalesced_frames_low;
u32_opt pkt_rate_high;
u32_opt rx_coalesce_usecs_high;
u32_opt rx_max_coalesced_frames_high;
u32_opt tx_coalesce_usecs_high;
u32_opt tx_max_coalesced_frames_high;
u32_opt rate_sample_interval;
} netdev_coalesce_param;
int ethtool_get_driver(int *ethtool_fd, const char *ifname, char **ret);
int ethtool_get_link_info(int *ethtool_fd, const char *ifname,
int *ret_autonegotiation, uint64_t *ret_speed,
@ -89,6 +114,7 @@ int ethtool_set_glinksettings(int *ethtool_fd, const char *ifname,
uint64_t speed, Duplex duplex, NetDevPort port);
int ethtool_set_channels(int *ethtool_fd, const char *ifname, const netdev_channels *channels);
int ethtool_set_flow_control(int *fd, const char *ifname, int rx, int tx, int autoneg);
int ethtool_set_nic_coalesce_settings(int *ethtool_fd, const char *ifname, const netdev_coalesce_param *coalesce);
const char *duplex_to_string(Duplex d) _const_;
Duplex duplex_from_string(const char *d) _pure_;
@ -106,3 +132,6 @@ CONFIG_PARSER_PROTOTYPE(config_parse_wol);
CONFIG_PARSER_PROTOTYPE(config_parse_port);
CONFIG_PARSER_PROTOTYPE(config_parse_advertise);
CONFIG_PARSER_PROTOTYPE(config_parse_ring_buffer_or_channel);
CONFIG_PARSER_PROTOTYPE(config_parse_coalesce_u32);
CONFIG_PARSER_PROTOTYPE(config_parse_coalesce_sec);
CONFIG_PARSER_PROTOTYPE(config_parse_nic_coalesce_setting);

View File

@ -21,54 +21,76 @@ struct ConfigPerfItem;
%struct-type
%includes
%%
Match.MACAddress, config_parse_hwaddrs, 0, offsetof(LinkConfig, match.mac)
Match.PermanentMACAddress, config_parse_hwaddrs, 0, offsetof(LinkConfig, match.permanent_mac)
Match.OriginalName, config_parse_match_ifnames, 0, offsetof(LinkConfig, match.ifname)
Match.Path, config_parse_match_strv, 0, offsetof(LinkConfig, match.path)
Match.Driver, config_parse_match_strv, 0, offsetof(LinkConfig, match.driver)
Match.Type, config_parse_match_strv, 0, offsetof(LinkConfig, match.iftype)
Match.Property, config_parse_match_property, 0, offsetof(LinkConfig, match.property)
Match.Host, config_parse_net_condition, CONDITION_HOST, offsetof(LinkConfig, conditions)
Match.Virtualization, config_parse_net_condition, CONDITION_VIRTUALIZATION, offsetof(LinkConfig, conditions)
Match.KernelCommandLine, config_parse_net_condition, CONDITION_KERNEL_COMMAND_LINE, offsetof(LinkConfig, conditions)
Match.KernelVersion, config_parse_net_condition, CONDITION_KERNEL_VERSION, offsetof(LinkConfig, conditions)
Match.Architecture, config_parse_net_condition, CONDITION_ARCHITECTURE, offsetof(LinkConfig, conditions)
Link.Description, config_parse_string, 0, offsetof(LinkConfig, description)
Link.MACAddressPolicy, config_parse_mac_address_policy, 0, offsetof(LinkConfig, mac_address_policy)
Link.MACAddress, config_parse_hwaddr, 0, offsetof(LinkConfig, mac)
Link.NamePolicy, config_parse_name_policy, 0, offsetof(LinkConfig, name_policy)
Link.Name, config_parse_ifname, 0, offsetof(LinkConfig, name)
Link.AlternativeName, config_parse_ifnames, IFNAME_VALID_ALTERNATIVE, offsetof(LinkConfig, alternative_names)
Link.AlternativeNamesPolicy, config_parse_alternative_names_policy, 0, offsetof(LinkConfig, alternative_names_policy)
Link.Alias, config_parse_ifalias, 0, offsetof(LinkConfig, alias)
Link.TransmitQueues, config_parse_rx_tx_queues, 0, offsetof(LinkConfig, txqueues)
Link.ReceiveQueues, config_parse_rx_tx_queues, 0, offsetof(LinkConfig, rxqueues)
Link.TransmitQueueLength, config_parse_txqueuelen, 0, offsetof(LinkConfig, txqueuelen)
Link.MTUBytes, config_parse_mtu, AF_UNSPEC, offsetof(LinkConfig, mtu)
Link.BitsPerSecond, config_parse_si_uint64, 0, offsetof(LinkConfig, speed)
Link.Duplex, config_parse_duplex, 0, offsetof(LinkConfig, duplex)
Link.AutoNegotiation, config_parse_tristate, 0, offsetof(LinkConfig, autonegotiation)
Link.WakeOnLan, config_parse_wol, 0, offsetof(LinkConfig, wol)
Link.Port, config_parse_port, 0, offsetof(LinkConfig, port)
Link.ReceiveChecksumOffload, config_parse_tristate, 0, offsetof(LinkConfig, features[NET_DEV_FEAT_RX])
Link.TransmitChecksumOffload, config_parse_tristate, 0, offsetof(LinkConfig, features[NET_DEV_FEAT_TX])
Link.GenericSegmentationOffload, config_parse_tristate, 0, offsetof(LinkConfig, features[NET_DEV_FEAT_GSO])
Link.TCPSegmentationOffload, config_parse_tristate, 0, offsetof(LinkConfig, features[NET_DEV_FEAT_TSO])
Link.TCP6SegmentationOffload, config_parse_tristate, 0, offsetof(LinkConfig, features[NET_DEV_FEAT_TSO6])
Link.UDPSegmentationOffload, config_parse_warn_compat, DISABLED_LEGACY, 0
Link.GenericReceiveOffload, config_parse_tristate, 0, offsetof(LinkConfig, features[NET_DEV_FEAT_GRO])
Link.LargeReceiveOffload, config_parse_tristate, 0, offsetof(LinkConfig, features[NET_DEV_FEAT_LRO])
Link.RxChannels, config_parse_ring_buffer_or_channel, 0, offsetof(LinkConfig, channels.rx)
Link.TxChannels, config_parse_ring_buffer_or_channel, 0, offsetof(LinkConfig, channels.tx)
Link.OtherChannels, config_parse_ring_buffer_or_channel, 0, offsetof(LinkConfig, channels.other)
Link.CombinedChannels, config_parse_ring_buffer_or_channel, 0, offsetof(LinkConfig, channels.combined)
Link.Advertise, config_parse_advertise, 0, offsetof(LinkConfig, advertise)
Link.RxBufferSize, config_parse_ring_buffer_or_channel, 0, offsetof(LinkConfig, ring.rx)
Link.RxMiniBufferSize, config_parse_ring_buffer_or_channel, 0, offsetof(LinkConfig, ring.rx_mini)
Link.RxJumboBufferSize, config_parse_ring_buffer_or_channel, 0, offsetof(LinkConfig, ring.rx_jumbo)
Link.TxBufferSize, config_parse_ring_buffer_or_channel, 0, offsetof(LinkConfig, ring.tx)
Link.RxFlowControl, config_parse_tristate, 0, offsetof(LinkConfig, rx_flow_control)
Link.TxFlowControl, config_parse_tristate, 0, offsetof(LinkConfig, tx_flow_control)
Link.AutoNegotiationFlowControl, config_parse_tristate, 0, offsetof(LinkConfig, autoneg_flow_control)
Link.GenericSegmentOffloadMaxBytes, config_parse_iec_size, 0, offsetof(LinkConfig, gso_max_size)
Link.GenericSegmentOffloadMaxSegments, config_parse_uint32, 0, offsetof(LinkConfig, gso_max_segments)
Match.MACAddress, config_parse_hwaddrs, 0, offsetof(LinkConfig, match.mac)
Match.PermanentMACAddress, config_parse_hwaddrs, 0, offsetof(LinkConfig, match.permanent_mac)
Match.OriginalName, config_parse_match_ifnames, 0, offsetof(LinkConfig, match.ifname)
Match.Path, config_parse_match_strv, 0, offsetof(LinkConfig, match.path)
Match.Driver, config_parse_match_strv, 0, offsetof(LinkConfig, match.driver)
Match.Type, config_parse_match_strv, 0, offsetof(LinkConfig, match.iftype)
Match.Property, config_parse_match_property, 0, offsetof(LinkConfig, match.property)
Match.Host, config_parse_net_condition, CONDITION_HOST, offsetof(LinkConfig, conditions)
Match.Virtualization, config_parse_net_condition, CONDITION_VIRTUALIZATION, offsetof(LinkConfig, conditions)
Match.KernelCommandLine, config_parse_net_condition, CONDITION_KERNEL_COMMAND_LINE, offsetof(LinkConfig, conditions)
Match.KernelVersion, config_parse_net_condition, CONDITION_KERNEL_VERSION, offsetof(LinkConfig, conditions)
Match.Architecture, config_parse_net_condition, CONDITION_ARCHITECTURE, offsetof(LinkConfig, conditions)
Link.Description, config_parse_string, 0, offsetof(LinkConfig, description)
Link.MACAddressPolicy, config_parse_mac_address_policy, 0, offsetof(LinkConfig, mac_address_policy)
Link.MACAddress, config_parse_hwaddr, 0, offsetof(LinkConfig, mac)
Link.NamePolicy, config_parse_name_policy, 0, offsetof(LinkConfig, name_policy)
Link.Name, config_parse_ifname, 0, offsetof(LinkConfig, name)
Link.AlternativeName, config_parse_ifnames, IFNAME_VALID_ALTERNATIVE, offsetof(LinkConfig, alternative_names)
Link.AlternativeNamesPolicy, config_parse_alternative_names_policy, 0, offsetof(LinkConfig, alternative_names_policy)
Link.Alias, config_parse_ifalias, 0, offsetof(LinkConfig, alias)
Link.TransmitQueues, config_parse_rx_tx_queues, 0, offsetof(LinkConfig, txqueues)
Link.ReceiveQueues, config_parse_rx_tx_queues, 0, offsetof(LinkConfig, rxqueues)
Link.TransmitQueueLength, config_parse_txqueuelen, 0, offsetof(LinkConfig, txqueuelen)
Link.MTUBytes, config_parse_mtu, AF_UNSPEC, offsetof(LinkConfig, mtu)
Link.BitsPerSecond, config_parse_si_uint64, 0, offsetof(LinkConfig, speed)
Link.Duplex, config_parse_duplex, 0, offsetof(LinkConfig, duplex)
Link.AutoNegotiation, config_parse_tristate, 0, offsetof(LinkConfig, autonegotiation)
Link.WakeOnLan, config_parse_wol, 0, offsetof(LinkConfig, wol)
Link.Port, config_parse_port, 0, offsetof(LinkConfig, port)
Link.ReceiveChecksumOffload, config_parse_tristate, 0, offsetof(LinkConfig, features[NET_DEV_FEAT_RX])
Link.TransmitChecksumOffload, config_parse_tristate, 0, offsetof(LinkConfig, features[NET_DEV_FEAT_TX])
Link.GenericSegmentationOffload, config_parse_tristate, 0, offsetof(LinkConfig, features[NET_DEV_FEAT_GSO])
Link.TCPSegmentationOffload, config_parse_tristate, 0, offsetof(LinkConfig, features[NET_DEV_FEAT_TSO])
Link.TCP6SegmentationOffload, config_parse_tristate, 0, offsetof(LinkConfig, features[NET_DEV_FEAT_TSO6])
Link.UDPSegmentationOffload, config_parse_warn_compat, DISABLED_LEGACY, 0
Link.GenericReceiveOffload, config_parse_tristate, 0, offsetof(LinkConfig, features[NET_DEV_FEAT_GRO])
Link.LargeReceiveOffload, config_parse_tristate, 0, offsetof(LinkConfig, features[NET_DEV_FEAT_LRO])
Link.RxChannels, config_parse_ring_buffer_or_channel, 0, offsetof(LinkConfig, channels.rx)
Link.TxChannels, config_parse_ring_buffer_or_channel, 0, offsetof(LinkConfig, channels.tx)
Link.OtherChannels, config_parse_ring_buffer_or_channel, 0, offsetof(LinkConfig, channels.other)
Link.CombinedChannels, config_parse_ring_buffer_or_channel, 0, offsetof(LinkConfig, channels.combined)
Link.Advertise, config_parse_advertise, 0, offsetof(LinkConfig, advertise)
Link.RxBufferSize, config_parse_ring_buffer_or_channel, 0, offsetof(LinkConfig, ring.rx)
Link.RxMiniBufferSize, config_parse_ring_buffer_or_channel, 0, offsetof(LinkConfig, ring.rx_mini)
Link.RxJumboBufferSize, config_parse_ring_buffer_or_channel, 0, offsetof(LinkConfig, ring.rx_jumbo)
Link.TxBufferSize, config_parse_ring_buffer_or_channel, 0, offsetof(LinkConfig, ring.tx)
Link.RxFlowControl, config_parse_tristate, 0, offsetof(LinkConfig, rx_flow_control)
Link.TxFlowControl, config_parse_tristate, 0, offsetof(LinkConfig, tx_flow_control)
Link.AutoNegotiationFlowControl, config_parse_tristate, 0, offsetof(LinkConfig, autoneg_flow_control)
Link.GenericSegmentOffloadMaxBytes, config_parse_iec_size, 0, offsetof(LinkConfig, gso_max_size)
Link.GenericSegmentOffloadMaxSegments, config_parse_uint32, 0, offsetof(LinkConfig, gso_max_segments)
Link.RxCoalesceSec, config_parse_coalesce_sec, 0, offsetof(LinkConfig, coalesce.rx_coalesce_usecs)
Link.RxMaxCoalescedFrames, config_parse_coalesce_u32, 0, offsetof(LinkConfig, coalesce.rx_max_coalesced_frames)
Link.RxCoalesceIrqSec, config_parse_coalesce_sec, 0, offsetof(LinkConfig, coalesce.rx_coalesce_usecs_irq)
Link.RxMaxCoalescedIrqFrames, config_parse_coalesce_u32, 0, offsetof(LinkConfig, coalesce.rx_max_coalesced_frames_irq)
Link.TxCoalesceSec, config_parse_coalesce_sec, 0, offsetof(LinkConfig, coalesce.tx_coalesce_usecs)
Link.TxMaxCoalescedFrames, config_parse_coalesce_u32, 0, offsetof(LinkConfig, coalesce.tx_max_coalesced_frames)
Link.TxCoalesceIrqSec, config_parse_coalesce_sec, 0, offsetof(LinkConfig, coalesce.tx_coalesce_usecs_irq)
Link.TxMaxCoalescedIrqFrames, config_parse_coalesce_u32, 0, offsetof(LinkConfig, coalesce.tx_max_coalesced_frames_irq)
Link.StatisticsBlockCoalesceSec, config_parse_coalesce_sec, 0, offsetof(LinkConfig, coalesce.stats_block_coalesce_usecs)
Link.UseAdaptiveRxCoalesce, config_parse_tristate, 0, offsetof(LinkConfig, coalesce.use_adaptive_rx_coalesce)
Link.UseAdaptiveTxCoalesce, config_parse_tristate, 0, offsetof(LinkConfig, coalesce.use_adaptive_tx_coalesce)
Link.CoalescePacketRateLow, config_parse_coalesce_u32, 0, offsetof(LinkConfig, coalesce.pkt_rate_low)
Link.RxCoalesceLowSec, config_parse_coalesce_sec, 0, offsetof(LinkConfig, coalesce.rx_coalesce_usecs_low)
Link.RxMaxCoalescedLowFrames, config_parse_coalesce_u32, 0, offsetof(LinkConfig, coalesce.rx_max_coalesced_frames_low)
Link.TxCoalesceLowSec, config_parse_coalesce_sec, 0, offsetof(LinkConfig, coalesce.tx_coalesce_usecs_low)
Link.TxMaxCoalescedLowFrames, config_parse_coalesce_u32, 0, offsetof(LinkConfig, coalesce.tx_max_coalesced_frames_low)
Link.CoalescePacketRateHigh, config_parse_coalesce_u32, 0, offsetof(LinkConfig, coalesce.pkt_rate_high)
Link.RxCoalesceHighSec, config_parse_coalesce_sec, 0, offsetof(LinkConfig, coalesce.rx_coalesce_usecs_high)
Link.RxMaxCoalescedHighFrames, config_parse_coalesce_u32, 0, offsetof(LinkConfig, coalesce.rx_max_coalesced_frames_high)
Link.TxCoalesceHighSec, config_parse_coalesce_sec, 0, offsetof(LinkConfig, coalesce.tx_coalesce_usecs_high)
Link.TxMaxCoalescedHighFrames, config_parse_coalesce_u32, 0, offsetof(LinkConfig, coalesce.tx_max_coalesced_frames_high)
Link.CoalescePacketRateSampleIntervalSec, config_parse_coalesce_sec, 0, offsetof(LinkConfig, coalesce.rate_sample_interval)

View File

@ -353,6 +353,10 @@ static int link_config_apply_ethtool_settings(int *ethtool_fd, const LinkConfig
if (r < 0)
log_device_warning_errno(device, r, "Could not set flow control, ignoring: %m");
r = ethtool_set_nic_coalesce_settings(ethtool_fd, name, &config->coalesce);
if (r < 0)
log_device_warning_errno(device, r, "Could not set coalesce settings, ignoring: %m");
return 0;
}

View File

@ -64,6 +64,7 @@ struct LinkConfig {
int rx_flow_control;
int tx_flow_control;
int autoneg_flow_control;
netdev_coalesce_param coalesce;
LIST_FIELDS(LinkConfig, links);
};

View File

@ -51,3 +51,25 @@ TxFlowControl=
AutoNegotiationFlowControl=
GenericSegmentOffloadMaxBytes=
GenericSegmentOffloadMaxSegments=
RxCoalesceSec=
RxMaxCoalescedFrames=
RxCoalesceIrqSec=
RxMaxCoalescedIrqFrames=
TxCoalesceSec=
TxMaxCoalescedFrames=
TxCoalesceIrqSec=
TxMaxCoalescedIrqFrames=
StatisticsBlockCoalesceSec=
UseAdaptiveRxCoalesce=
UseAdaptiveTxCoalesce=
CoalescePacketRateLow=
RxCoalesceLowSec=
RxMaxCoalescedLowFrames=
TxCoalesceLowSec=
TxMaxCoalescedLowFrames=
CoalescePacketRateHigh=
RxCoalesceHighSec=
RxMaxCoalescedHighFrames=
TxCoalesceHighSec=
TxMaxCoalescedHighFrames=
CoalescePacketRateSampleIntervalSec=