udev: make RxChannels= or friends also accept "max"

Follow-up for 406041b7de.

Also, this makes
- the settings accept an empty string,
- if the specified value is too large, also use the advertised maximum
  value.
- mention the range of the value in the man page.
This commit is contained in:
Yu Watanabe
2021-08-18 16:55:03 +02:00
committed by Lennart Poettering
parent bdbb61f69f
commit 0d341eccef
4 changed files with 90 additions and 181 deletions
+59 -111
View File
@@ -329,6 +329,17 @@ int ethtool_get_permanent_macaddr(int *ethtool_fd, const char *ifname, struct et
dest = _v; \
} while(false)
#define UPDATE_WITH_MAX(dest, max, val, updated) \
do { \
typeof(dest) _v = (val); \
typeof(dest) _max = (max); \
if (_v == 0 || _v > _max) \
_v = _max; \
if (dest != _v) \
updated = true; \
dest = _v; \
} while(false)
int ethtool_set_wol(int *ethtool_fd, const char *ifname, uint32_t wolopts) {
struct ethtool_wolinfo ecmd = {
.cmd = ETHTOOL_GWOL,
@@ -382,10 +393,10 @@ int ethtool_set_nic_buffer_size(int *ethtool_fd, const char *ifname, const netde
assert(ifname);
assert(ring);
if (!ring->rx_pending_set &&
!ring->rx_mini_pending_set &&
!ring->rx_jumbo_pending_set &&
!ring->tx_pending_set)
if (!ring->rx.set &&
!ring->rx_mini.set &&
!ring->rx_jumbo.set &&
!ring->tx.set)
return 0;
r = ethtool_connect(ethtool_fd);
@@ -398,25 +409,17 @@ int ethtool_set_nic_buffer_size(int *ethtool_fd, const char *ifname, const netde
if (r < 0)
return -errno;
if (ring->rx_pending_set)
UPDATE(ecmd.rx_pending,
ring->rx_pending == 0 ? ecmd.rx_max_pending : ring->rx_pending,
need_update);
if (ring->rx.set)
UPDATE_WITH_MAX(ecmd.rx_pending, ecmd.rx_max_pending, ring->rx.value, need_update);
if (ring->rx_mini_pending_set)
UPDATE(ecmd.rx_mini_pending,
ring->rx_mini_pending == 0 ? ecmd.rx_mini_max_pending : ring->rx_mini_pending,
need_update);
if (ring->rx_mini.set)
UPDATE_WITH_MAX(ecmd.rx_mini_pending, ecmd.rx_mini_max_pending, ring->rx_mini.value, need_update);
if (ring->rx_jumbo_pending_set)
UPDATE(ecmd.rx_jumbo_pending,
ring->rx_jumbo_pending == 0 ? ecmd.rx_jumbo_max_pending : ring->rx_jumbo_pending,
need_update);
if (ring->rx_jumbo.set)
UPDATE_WITH_MAX(ecmd.rx_jumbo_pending, ecmd.rx_jumbo_max_pending, ring->rx_jumbo.value, need_update);
if (ring->tx_pending_set)
UPDATE(ecmd.tx_pending,
ring->tx_pending == 0 ? ecmd.tx_max_pending : ring->tx_pending,
need_update);
if (ring->tx.set)
UPDATE_WITH_MAX(ecmd.tx_pending, ecmd.tx_max_pending, ring->tx.value, need_update);
if (!need_update)
return 0;
@@ -842,10 +845,10 @@ int ethtool_set_channels(int *fd, const char *ifname, const netdev_channels *cha
assert(ifname);
assert(channels);
if (!channels->rx_count_set &&
!channels->tx_count_set &&
!channels->other_count_set &&
!channels->combined_count_set)
if (!channels->rx.set &&
!channels->tx.set &&
!channels->other.set &&
!channels->combined.set)
return 0;
r = ethtool_connect(fd);
@@ -858,17 +861,17 @@ int ethtool_set_channels(int *fd, const char *ifname, const netdev_channels *cha
if (r < 0)
return -errno;
if (channels->rx_count_set)
UPDATE(ecmd.rx_count, channels->rx_count, need_update);
if (channels->rx.set)
UPDATE_WITH_MAX(ecmd.rx_count, ecmd.max_rx, channels->rx.value, need_update);
if (channels->tx_count_set)
UPDATE(ecmd.tx_count, channels->tx_count, need_update);
if (channels->tx.set)
UPDATE_WITH_MAX(ecmd.tx_count, ecmd.max_tx, channels->tx.value, need_update);
if (channels->other_count_set)
UPDATE(ecmd.other_count, channels->other_count, need_update);
if (channels->other.set)
UPDATE_WITH_MAX(ecmd.other_count, ecmd.max_other, channels->other.value, need_update);
if (channels->combined_count_set)
UPDATE(ecmd.combined_count, channels->combined_count, need_update);
if (channels->combined.set)
UPDATE_WITH_MAX(ecmd.combined_count, ecmd.max_combined, channels->combined.value, need_update);
if (!need_update)
return 0;
@@ -927,57 +930,6 @@ int ethtool_set_flow_control(int *fd, const char *ifname, int rx, int tx, int au
return 0;
}
int config_parse_channel(
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_channels *channels = 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_WARNING, filename, line, r,
"Failed to parse channel value for %s=, ignoring: %s", lvalue, 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, "RxChannels")) {
channels->rx_count = k;
channels->rx_count_set = true;
} else if (streq(lvalue, "TxChannels")) {
channels->tx_count = k;
channels->tx_count_set = true;
} else if (streq(lvalue, "OtherChannels")) {
channels->other_count = k;
channels->other_count_set = true;
} else if (streq(lvalue, "CombinedChannels")) {
channels->combined_count = k;
channels->combined_count_set = true;
}
return 0;
}
int config_parse_advertise(
const char *unit,
const char *filename,
@@ -1033,7 +985,7 @@ int config_parse_advertise(
}
}
int config_parse_nic_buffer_size(
int config_parse_ring_buffer_or_channel(
const char *unit,
const char *filename,
unsigned line,
@@ -1045,7 +997,7 @@ int config_parse_nic_buffer_size(
void *data,
void *userdata) {
netdev_ring_param *ring = data;
u32_opt *dst = data;
uint32_t k;
int r;
@@ -1055,36 +1007,32 @@ int config_parse_nic_buffer_size(
assert(rvalue);
assert(data);
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 (isempty(rvalue)) {
dst->value = 0;
dst->set = false;
return 0;
}
if (streq(lvalue, "RxBufferSize")) {
ring->rx_pending = k;
ring->rx_pending_set = true;
} else if (streq(lvalue, "RxMiniBufferSize")) {
ring->rx_mini_pending = k;
ring->rx_mini_pending_set = true;
} else if (streq(lvalue, "RxJumboBufferSize")) {
ring->rx_jumbo_pending = k;
ring->rx_jumbo_pending_set = true;
} else if (streq(lvalue, "TxBufferSize")) {
ring->tx_pending = k;
ring->tx_pending_set = true;
if (streq(rvalue, "max")) {
dst->value = 0;
dst->set = true;
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;
}
if (k < 1) {
log_syntax(unit, LOG_WARNING, filename, line, 0,
"Invalid %s= value, ignoring: %s", lvalue, rvalue);
return 0;
}
dst->value = k;
dst->set = true;
return 0;
}
+14 -22
View File
@@ -57,30 +57,23 @@ struct ethtool_link_usettings {
} link_modes;
};
typedef struct netdev_channels {
uint32_t rx_count;
uint32_t tx_count;
uint32_t other_count;
uint32_t combined_count;
typedef struct u32_opt {
uint32_t value; /* a value of 0 indicates the hardware advertised maximum should be used.*/
bool set;
} u32_opt;
bool rx_count_set;
bool tx_count_set;
bool other_count_set;
bool combined_count_set;
typedef struct netdev_channels {
u32_opt rx;
u32_opt tx;
u32_opt other;
u32_opt combined;
} 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;
uint32_t tx_pending;
bool rx_pending_set;
bool rx_mini_pending_set;
bool rx_jumbo_pending_set;
bool tx_pending_set;
u32_opt rx;
u32_opt rx_mini;
u32_opt rx_jumbo;
u32_opt tx;
} netdev_ring_param;
int ethtool_get_driver(int *ethtool_fd, const char *ifname, char **ret);
@@ -111,6 +104,5 @@ enum ethtool_link_mode_bit_indices ethtool_link_mode_bit_from_string(const char
CONFIG_PARSER_PROTOTYPE(config_parse_duplex);
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);
CONFIG_PARSER_PROTOTYPE(config_parse_ring_buffer_or_channel);
+8 -8
View File
@@ -58,15 +58,15 @@ Link.TCP6SegmentationOffload, config_parse_tristate, 0,
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_channel, 0, offsetof(LinkConfig, channels)
Link.TxChannels, config_parse_channel, 0, offsetof(LinkConfig, channels)
Link.OtherChannels, config_parse_channel, 0, offsetof(LinkConfig, channels)
Link.CombinedChannels, config_parse_channel, 0, offsetof(LinkConfig, channels)
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_nic_buffer_size, 0, offsetof(LinkConfig, ring)
Link.RxMiniBufferSize, config_parse_nic_buffer_size, 0, offsetof(LinkConfig, ring)
Link.RxJumboBufferSize, config_parse_nic_buffer_size, 0, offsetof(LinkConfig, ring)
Link.TxBufferSize, config_parse_nic_buffer_size, 0, offsetof(LinkConfig, ring)
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)