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:
committed by
Ilya Maximets
parent
1ef3f4f78a
commit
6240c0b4c8
@@ -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,
|
||||
|
Reference in New Issue
Block a user