Add "max-rate" value to minimum bandwidth rules

OVS translates the QoS and associated queue registers,
attached to a port, into "tc" linux-htb classfull traffic
shaper, applied on the port.

OVS creates a "tc" root class on the port device. On top of
this root class, the queues are represented as child "tc"
classes. In order to define a "min-rate" value ("tc rate"),
a "max-rate" value ("tc ceil") must be provided and higher than
"min-rate".

By default, OVS agent QoS minimum rules do not have a "max-rate"
defined. Before this patch, any minimum bandwidth rule was
limiting the maximum rate to 100Mbit/s, that is the default value
set in "tc ceil". This patch provides the maximum "max-rate" value
for any minimum bandwidth rule.

Closes-Bug: #1977752

Change-Id: I2c6f09548f39cadfe85e57032091a70a5bc978e5
(cherry picked from commit a575dbc4a1)
This commit is contained in:
Rodolfo Alonso Hernandez 2022-05-18 03:43:40 +00:00
parent bfcc39e660
commit 1d2dd010af
3 changed files with 13 additions and 5 deletions

View File

@ -73,6 +73,7 @@ _SENTINEL = object()
CTRL_RATE_LIMIT_MIN = 100
CTRL_BURST_LIMIT_MIN = 25
OVS_MAX_RATE = 2 ** 35 - 1
# TODO(slaweq): move this to neutron_lib.constants
TYPE_GRE_IP6 = 'ip6gre'
@ -1045,14 +1046,17 @@ class OVSBridge(BaseOVS):
def _update_queue(self, port_id, queue_num, queue_type, max_kbps=None,
max_burst_kbps=None, min_kbps=None):
other_config = {}
queue = self._find_queue(port_id, _type=queue_type)
other_config = dict(queue['other_config']) if queue else {}
if max_kbps:
other_config['max-rate'] = str(int(max_kbps) * p_const.SI_BASE)
other_config['burst'] = str(int(max_burst_kbps) * p_const.SI_BASE)
if min_kbps:
other_config['min-rate'] = str(min_kbps * p_const.SI_BASE)
if 'max-rate' not in other_config:
other_config['max-rate'] = str(OVS_MAX_RATE)
queue = self._find_queue(port_id, _type=queue_type)
if queue and queue['_uuid']:
if queue['other_config'] != other_config:
self.set_db_attribute('Queue', queue['_uuid'], 'other_config',
@ -1125,11 +1129,13 @@ class OVSBridge(BaseOVS):
if not qos_id:
external_ids = {'id': rule_type_id,
'_type': rule_type}
other_config = {'max-rate': str(OVS_MAX_RATE)}
self.ovsdb.db_create(
'QoS',
type='linux-htb',
queues=queues,
external_ids=external_ids).execute(check_error=True)
external_ids=external_ids,
other_config=other_config).execute(check_error=True)
qos_id, _ = self._find_qos(rule_type_id, rule_type)
else:
self.clear_db_attribute('QoS', qos_id, 'queues')

View File

@ -768,7 +768,8 @@ class TestMinBwQoSOvs(_TestMinBwQoS, base.BaseFullStackTestCase):
# Check QoS policy and Queue rule.
qos, queue = self._find_agent_qos_and_queue(vm_qos)
self.assertEqual({'min-rate': str(MIN_BANDWIDTH * 1000)},
self.assertEqual({'min-rate': str(MIN_BANDWIDTH * 1000),
'max-rate': str(ovs_lib.OVS_MAX_RATE)},
queue.other_config)
queues = vm_qos.bridge._list_queues(port=vm_qos.neutron_port['id'])
self.assertEqual(1, len(queues))

View File

@ -487,7 +487,8 @@ class BaseOVSTestCase(base.BaseSudoTestCase):
external_ids = {'port': str(self.port_id),
'type': qos_constants.RULE_TYPE_MINIMUM_BANDWIDTH,
'queue-num': str(queue_num)}
other_config = {'min-rate': '1700000'}
other_config = {'min-rate': '1700000',
'max-rate': str(ovs_lib.OVS_MAX_RATE)}
expected = {'_uuid': queue_id,
'external_ids': external_ids,
'other_config': other_config}