diff mbox series

[ovs-dev] controller: Fix QoS for ports with undetected or too low link speed.

Message ID 20221101140032.734440-1-i.maximets@ovn.org
State Accepted
Delegated to: Dumitru Ceara
Headers show
Series [ovs-dev] controller: Fix QoS for ports with undetected or too low link speed. | expand

Checks

Context Check Description
ovsrobot/apply-robot success apply and check: success
ovsrobot/github-robot-_Build_and_Test success github build: passed
ovsrobot/github-robot-_ovn-kubernetes fail github build: failed

Commit Message

Ilya Maximets Nov. 1, 2022, 2 p.m. UTC
If netdev_set_qos() is called without specifying max-rate, it will
use reported link speed of that interface instead as a ceil.

If OVS libraries are not able to detect the link speed, the 100 Mbps
will be used.  Also, TAP interfaces do report 10 Mbps as their link
speed by default.

In both cases all the traffic will be unnecessary limited to just
100 or 10 Mpbs regardless of the 'qos_max_rate' configured for that
port in OVN databases, because maximum rate of a single queue can not
be higher than a total maximum rate of a QoS type.

Fix that by always specifying the max-rate as a maximum supported
value - (2^32 - 1) * 8 bits per second.  This way netdev_set_qos()
will not need to check the link speed or guess a value.

Fixes: 8dda482b8059 ("Check and allocate free qdisc queue id for ports with qos parameters")
Reported-at: https://bugzilla.redhat.com/2136716
Signed-off-by: Ilya Maximets <i.maximets@ovn.org>
---
 controller/binding.c | 9 ++++++++-
 tests/system-ovn.at  | 6 +++++-
 2 files changed, 13 insertions(+), 2 deletions(-)

Comments

Ales Musil Nov. 15, 2022, 6:45 a.m. UTC | #1
On Tue, Nov 1, 2022 at 3:01 PM Ilya Maximets <i.maximets@ovn.org> wrote:

> If netdev_set_qos() is called without specifying max-rate, it will
> use reported link speed of that interface instead as a ceil.
>
> If OVS libraries are not able to detect the link speed, the 100 Mbps
> will be used.  Also, TAP interfaces do report 10 Mbps as their link
> speed by default.
>
> In both cases all the traffic will be unnecessary limited to just
> 100 or 10 Mpbs regardless of the 'qos_max_rate' configured for that
> port in OVN databases, because maximum rate of a single queue can not
> be higher than a total maximum rate of a QoS type.
>
> Fix that by always specifying the max-rate as a maximum supported
> value - (2^32 - 1) * 8 bits per second.  This way netdev_set_qos()
> will not need to check the link speed or guess a value.
>
> Fixes: 8dda482b8059 ("Check and allocate free qdisc queue id for ports
> with qos parameters")
> Reported-at: https://bugzilla.redhat.com/2136716
> Signed-off-by: Ilya Maximets <i.maximets@ovn.org>
> ---
>  controller/binding.c | 9 ++++++++-
>  tests/system-ovn.at  | 6 +++++-
>  2 files changed, 13 insertions(+), 2 deletions(-)
>
> diff --git a/controller/binding.c b/controller/binding.c
> index c3d2b2e42..a50379895 100644
> --- a/controller/binding.c
> +++ b/controller/binding.c
> @@ -220,7 +220,14 @@ set_noop_qos(struct ovsdb_idl_txn *ovs_idl_txn,
>  static void
>  set_qos_type(struct netdev *netdev, const char *type)
>  {
> -    int error = netdev_set_qos(netdev, type, NULL);
> +    /* 34359738360 == (2^32 - 1) * 8.  netdev_set_qos() doesn't support
> +     * 64-bit rate netlink attributes, so the maximum value is 2^32 - 1
> bytes.
> +     * The 'max-rate' config option is in bits, so multiplying by 8.
> +     * Without setting max-rate the reported link speed will be used,
> which
> +     * can be unrecognized for certain NICs or reported too low for
> virtual
> +     * interfaces. */
> +    const struct smap conf = SMAP_CONST1(&conf, "max-rate",
> "34359738360");
> +    int error = netdev_set_qos(netdev, type, &conf);
>      if (error) {
>          static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(1, 1);
>          VLOG_WARN_RL(&rl, "%s: could not set qdisc type \"%s\" (%s)",
> diff --git a/tests/system-ovn.at b/tests/system-ovn.at
> index 20c058415..cc267ba25 100644
> --- a/tests/system-ovn.at
> +++ b/tests/system-ovn.at
> @@ -6353,8 +6353,12 @@ OVS_WAIT_UNTIL([tc qdisc show | grep -q 'htb 1: dev
> ovs-public'])
>  OVS_WAIT_UNTIL([tc class show dev ovs-public | \
>                  grep -q 'class htb .* rate 200Kbit ceil 300Kbit burst
> 375000b cburst 375000b'])
>
> -AT_CHECK([ovn-nbctl remove Logical_Switch_Port public options
> qos_min_rate=200000])
> +
>  AT_CHECK([ovn-nbctl remove Logical_Switch_Port public options
> qos_max_rate=300000])
> +OVS_WAIT_UNTIL([tc class show dev ovs-public | \
> +                grep -q 'class htb .* rate 200Kbit ceil 34359Mbit burst
> 375000b .*'])
> +
> +AT_CHECK([ovn-nbctl remove Logical_Switch_Port public options
> qos_min_rate=200000])
>  AT_CHECK([ovn-nbctl remove Logical_Switch_Port public options
> qos_burst=3000000])
>  OVS_WAIT_UNTIL([test "$(tc qdisc show | grep 'htb 1: dev ovs-public')" =
> ""])
>
> --
> 2.37.3
>
> _______________________________________________
> dev mailing list
> dev@openvswitch.org
> https://mail.openvswitch.org/mailman/listinfo/ovs-dev
>
>
Looks good to me, thanks.

Acked-by: Ales Musil <amusil@redhat.com>
Dumitru Ceara Nov. 18, 2022, 4:09 p.m. UTC | #2
On 11/15/22 07:45, Ales Musil wrote:
> On Tue, Nov 1, 2022 at 3:01 PM Ilya Maximets <i.maximets@ovn.org> wrote:
> 
>> If netdev_set_qos() is called without specifying max-rate, it will
>> use reported link speed of that interface instead as a ceil.
>>
>> If OVS libraries are not able to detect the link speed, the 100 Mbps
>> will be used.  Also, TAP interfaces do report 10 Mbps as their link
>> speed by default.
>>
>> In both cases all the traffic will be unnecessary limited to just
>> 100 or 10 Mpbs regardless of the 'qos_max_rate' configured for that
>> port in OVN databases, because maximum rate of a single queue can not
>> be higher than a total maximum rate of a QoS type.
>>
>> Fix that by always specifying the max-rate as a maximum supported
>> value - (2^32 - 1) * 8 bits per second.  This way netdev_set_qos()
>> will not need to check the link speed or guess a value.
>>
>> Fixes: 8dda482b8059 ("Check and allocate free qdisc queue id for ports
>> with qos parameters")
>> Reported-at: https://bugzilla.redhat.com/2136716
>> Signed-off-by: Ilya Maximets <i.maximets@ovn.org>
>> ---
>>  controller/binding.c | 9 ++++++++-
>>  tests/system-ovn.at  | 6 +++++-
>>  2 files changed, 13 insertions(+), 2 deletions(-)
>>
>> diff --git a/controller/binding.c b/controller/binding.c
>> index c3d2b2e42..a50379895 100644
>> --- a/controller/binding.c
>> +++ b/controller/binding.c
>> @@ -220,7 +220,14 @@ set_noop_qos(struct ovsdb_idl_txn *ovs_idl_txn,
>>  static void
>>  set_qos_type(struct netdev *netdev, const char *type)
>>  {
>> -    int error = netdev_set_qos(netdev, type, NULL);
>> +    /* 34359738360 == (2^32 - 1) * 8.  netdev_set_qos() doesn't support
>> +     * 64-bit rate netlink attributes, so the maximum value is 2^32 - 1
>> bytes.
>> +     * The 'max-rate' config option is in bits, so multiplying by 8.
>> +     * Without setting max-rate the reported link speed will be used,
>> which
>> +     * can be unrecognized for certain NICs or reported too low for
>> virtual
>> +     * interfaces. */
>> +    const struct smap conf = SMAP_CONST1(&conf, "max-rate",
>> "34359738360");
>> +    int error = netdev_set_qos(netdev, type, &conf);
>>      if (error) {
>>          static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(1, 1);
>>          VLOG_WARN_RL(&rl, "%s: could not set qdisc type \"%s\" (%s)",
>> diff --git a/tests/system-ovn.at b/tests/system-ovn.at
>> index 20c058415..cc267ba25 100644
>> --- a/tests/system-ovn.at
>> +++ b/tests/system-ovn.at
>> @@ -6353,8 +6353,12 @@ OVS_WAIT_UNTIL([tc qdisc show | grep -q 'htb 1: dev
>> ovs-public'])
>>  OVS_WAIT_UNTIL([tc class show dev ovs-public | \
>>                  grep -q 'class htb .* rate 200Kbit ceil 300Kbit burst
>> 375000b cburst 375000b'])
>>
>> -AT_CHECK([ovn-nbctl remove Logical_Switch_Port public options
>> qos_min_rate=200000])
>> +
>>  AT_CHECK([ovn-nbctl remove Logical_Switch_Port public options
>> qos_max_rate=300000])
>> +OVS_WAIT_UNTIL([tc class show dev ovs-public | \
>> +                grep -q 'class htb .* rate 200Kbit ceil 34359Mbit burst
>> 375000b .*'])
>> +
>> +AT_CHECK([ovn-nbctl remove Logical_Switch_Port public options
>> qos_min_rate=200000])
>>  AT_CHECK([ovn-nbctl remove Logical_Switch_Port public options
>> qos_burst=3000000])
>>  OVS_WAIT_UNTIL([test "$(tc qdisc show | grep 'htb 1: dev ovs-public')" =
>> ""])
>>
>> --
>> 2.37.3
>>
>> _______________________________________________
>> dev mailing list
>> dev@openvswitch.org
>> https://mail.openvswitch.org/mailman/listinfo/ovs-dev
>>
>>
> Looks good to me, thanks.
> 
> Acked-by: Ales Musil <amusil@redhat.com>

Thanks, Ales and Ilya!

I pushed this to the main branch and backported it to all stable
branches down to 22.03.

Regards,
Dumitru
diff mbox series

Patch

diff --git a/controller/binding.c b/controller/binding.c
index c3d2b2e42..a50379895 100644
--- a/controller/binding.c
+++ b/controller/binding.c
@@ -220,7 +220,14 @@  set_noop_qos(struct ovsdb_idl_txn *ovs_idl_txn,
 static void
 set_qos_type(struct netdev *netdev, const char *type)
 {
-    int error = netdev_set_qos(netdev, type, NULL);
+    /* 34359738360 == (2^32 - 1) * 8.  netdev_set_qos() doesn't support
+     * 64-bit rate netlink attributes, so the maximum value is 2^32 - 1 bytes.
+     * The 'max-rate' config option is in bits, so multiplying by 8.
+     * Without setting max-rate the reported link speed will be used, which
+     * can be unrecognized for certain NICs or reported too low for virtual
+     * interfaces. */
+    const struct smap conf = SMAP_CONST1(&conf, "max-rate", "34359738360");
+    int error = netdev_set_qos(netdev, type, &conf);
     if (error) {
         static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(1, 1);
         VLOG_WARN_RL(&rl, "%s: could not set qdisc type \"%s\" (%s)",
diff --git a/tests/system-ovn.at b/tests/system-ovn.at
index 20c058415..cc267ba25 100644
--- a/tests/system-ovn.at
+++ b/tests/system-ovn.at
@@ -6353,8 +6353,12 @@  OVS_WAIT_UNTIL([tc qdisc show | grep -q 'htb 1: dev ovs-public'])
 OVS_WAIT_UNTIL([tc class show dev ovs-public | \
                 grep -q 'class htb .* rate 200Kbit ceil 300Kbit burst 375000b cburst 375000b'])
 
-AT_CHECK([ovn-nbctl remove Logical_Switch_Port public options qos_min_rate=200000])
+
 AT_CHECK([ovn-nbctl remove Logical_Switch_Port public options qos_max_rate=300000])
+OVS_WAIT_UNTIL([tc class show dev ovs-public | \
+                grep -q 'class htb .* rate 200Kbit ceil 34359Mbit burst 375000b .*'])
+
+AT_CHECK([ovn-nbctl remove Logical_Switch_Port public options qos_min_rate=200000])
 AT_CHECK([ovn-nbctl remove Logical_Switch_Port public options qos_burst=3000000])
 OVS_WAIT_UNTIL([test "$(tc qdisc show | grep 'htb 1: dev ovs-public')" = ""])