2
0
mirror of https://github.com/openvswitch/ovs synced 2025-08-31 22:35:15 +00:00

netdev: Add netdev_get_speed() to netdev API.

Currently, the netdev's speed is being calculated by taking the link's
feature bits (using netdev_get_features()) and transforming them into
bps.

This mechanism can be both inaccurate and difficult to maintain, mainly
because we currently use the feature bits supported by OpenFlow which
would have to be extended to support all new feature bits of all netdev
implementations while keeping the OpenFlow API intact.

In order to expose the link speed accurately for all current and future
hardware, add a new netdev API call that allows the implementations to
provide the current and maximum link speeds in Mbps.

Internally, the logic to get the maximum supported speed still relies on
feature bits so it might still get out of sync in the future. However,
the maximum configurable speed is not used as much as the current speed
and these feature bits are not exposed through the netdev interface so
it should be easier to add more.

Use this new function instead of netdev_get_features() where the link
speed is needed.

As a consequence of this patch, link speeds of cards is properly
reported (internally in OVSDB) even if not supported by OpenFlow.
A test verifies this behavior using a tap device.

Also, in order to avoid using the old, this patch adds a checkpatch.py
warning if the old API is used.

Reported-at: https://bugzilla.redhat.com/show_bug.cgi?id=2137567
Acked-by: Eelco Chaudron <echaudro@redhat.com>
Signed-off-by: Adrian Moreno <amorenoz@redhat.com>
Signed-off-by: Ilya Maximets <i.maximets@ovn.org>
This commit is contained in:
Adrian Moreno
2023-07-17 10:08:11 +02:00
committed by Ilya Maximets
parent 1ef3f4f78a
commit 6240c0b4c8
14 changed files with 228 additions and 28 deletions

View File

@@ -2382,7 +2382,6 @@ static void
netdev_linux_read_features(struct netdev_linux *netdev)
{
struct ethtool_cmd ecmd;
uint32_t speed;
int error;
if (netdev->cache_valid & VALID_FEATURES) {
@@ -2496,20 +2495,20 @@ netdev_linux_read_features(struct netdev_linux *netdev)
}
/* Current settings. */
speed = ethtool_cmd_speed(&ecmd);
if (speed == SPEED_10) {
netdev->current_speed = ethtool_cmd_speed(&ecmd);
if (netdev->current_speed == SPEED_10) {
netdev->current = ecmd.duplex ? NETDEV_F_10MB_FD : NETDEV_F_10MB_HD;
} else if (speed == SPEED_100) {
} else if (netdev->current_speed == SPEED_100) {
netdev->current = ecmd.duplex ? NETDEV_F_100MB_FD : NETDEV_F_100MB_HD;
} else if (speed == SPEED_1000) {
} else if (netdev->current_speed == SPEED_1000) {
netdev->current = ecmd.duplex ? NETDEV_F_1GB_FD : NETDEV_F_1GB_HD;
} else if (speed == SPEED_10000) {
} else if (netdev->current_speed == SPEED_10000) {
netdev->current = NETDEV_F_10GB_FD;
} else if (speed == 40000) {
} else if (netdev->current_speed == 40000) {
netdev->current = NETDEV_F_40GB_FD;
} else if (speed == 100000) {
} else if (netdev->current_speed == 100000) {
netdev->current = NETDEV_F_100GB_FD;
} else if (speed == 1000000) {
} else if (netdev->current_speed == 1000000) {
netdev->current = NETDEV_F_1TB_FD;
} else {
netdev->current = 0;
@@ -2563,6 +2562,33 @@ exit:
return error;
}
static int
netdev_linux_get_speed(const struct netdev *netdev_, uint32_t *current,
uint32_t *max)
{
struct netdev_linux *netdev = netdev_linux_cast(netdev_);
int error;
ovs_mutex_lock(&netdev->mutex);
if (netdev_linux_netnsid_is_remote(netdev)) {
error = EOPNOTSUPP;
goto exit;
}
netdev_linux_read_features(netdev);
if (!netdev->get_features_error) {
*current = netdev->current_speed == SPEED_UNKNOWN
? 0 : netdev->current_speed;
*max = MIN(UINT32_MAX,
netdev_features_to_bps(netdev->supported, 0) / 1000000ULL);
}
error = netdev->get_features_error;
exit:
ovs_mutex_unlock(&netdev->mutex);
return error;
}
/* Set the features advertised by 'netdev' to 'advertise'. */
static int
netdev_linux_set_advertisements(struct netdev *netdev_,
@@ -3697,6 +3723,7 @@ const struct netdev_class netdev_linux_class = {
.destruct = netdev_linux_destruct,
.get_stats = netdev_linux_get_stats,
.get_features = netdev_linux_get_features,
.get_speed = netdev_linux_get_speed,
.get_status = netdev_linux_get_status,
.get_block_id = netdev_linux_get_block_id,
.send = netdev_linux_send,
@@ -3713,6 +3740,7 @@ const struct netdev_class netdev_tap_class = {
.destruct = netdev_linux_destruct,
.get_stats = netdev_tap_get_stats,
.get_features = netdev_linux_get_features,
.get_speed = netdev_linux_get_speed,
.get_status = netdev_linux_get_status,
.send = netdev_linux_send,
.rxq_construct = netdev_linux_rxq_construct,