From 57a0b4124d3fec95070e0d29a22324b322e412b1 Mon Sep 17 00:00:00 2001 From: Neetha John Date: Wed, 9 Dec 2020 09:41:03 -0800 Subject: [PATCH] Add show and clear commands for headroom pool watermark (#1144) Depends on Azure/sonic-swss#1453 - What I did Added support to query and clear headroom pool watermark counters Added unit test for the headroom pool watermark counters - How I did it Modified watermarkstat script to query/clear headroom pool watermark counters Added show and clear commands - How to verify it Send traffic such that it treks into the headroom pool and check for the headroom pool usage using the show command below Set polling interval to 30s and issue clear commands mentioned below and verify that counters are cleared - New command output (if the output of a command-line utility has changed) Show commands admin@sonic:~$ show headroom-pool watermark Headroom pool maximum occupancy: Pool Bytes --------------------- ------- ingress_lossless_pool 12480 admin@sonic:~$ show headroom-pool persistent-watermark Headroom pool maximum occupancy: Pool Bytes --------------------- ------- ingress_lossless_pool 12480 Clear commands admin@sonic:~$ sudo sonic-clear headroom-pool watermark admin@sonic:~$ sudo sonic-clear headroom-pool persistent-watermark Signed-off-by: Neetha John --- clear/main.py | 24 ++++++++++++++++++++++++ scripts/watermarkstat | 14 ++++++++++---- show/main.py | 21 +++++++++++++++++++++ tests/mock_tables/counters_db.json | 6 ++++-- tests/watermarkstat_test.py | 6 ++++++ tests/wm_input/wm_test_vectors.py | 24 +++++++++++++++++++++++- 6 files changed, 88 insertions(+), 7 deletions(-) diff --git a/clear/main.py b/clear/main.py index 9d762322069b..ff0bc0d6cb8b 100755 --- a/clear/main.py +++ b/clear/main.py @@ -277,6 +277,30 @@ def clear_pwm_q_multi(): command = 'watermarkstat -c -p -t q_shared_multi' run_command(command) + +@cli.group(name='headroom-pool') +def headroom_pool(): + """Clear headroom pool WM""" + pass + +@headroom_pool.command('watermark') +def watermark(): + """Clear headroom pool user WM. One does not simply clear WM, root is required""" + if os.geteuid() != 0: + exit("Root privileges are required for this operation") + + command = 'watermarkstat -c -t headroom_pool' + run_command(command) + +@headroom_pool.command('persistent-watermark') +def persistent_watermark(): + """Clear headroom pool persistent WM. One does not simply clear WM, root is required""" + if os.geteuid() != 0: + exit("Root privileges are required for this operation") + + command = 'watermarkstat -c -p -t headroom_pool' + run_command(command) + # # 'arp' command #### # diff --git a/scripts/watermarkstat b/scripts/watermarkstat index 2f086b9a9506..b9df56ca897e 100755 --- a/scripts/watermarkstat +++ b/scripts/watermarkstat @@ -167,6 +167,9 @@ class Watermarkstat(object): "header_prefix": "MC"}, "buffer_pool" : {"message": "Shared pool maximum occupancy:", "wm_name": "SAI_BUFFER_POOL_STAT_WATERMARK_BYTES", + "header" : headerBufferPool}, + "headroom_pool" : {"message": "Headroom pool maximum occupancy:", + "wm_name": "SAI_BUFFER_POOL_STAT_XOFF_ROOM_WATERMARK_BYTES", "header" : headerBufferPool} } @@ -226,12 +229,15 @@ class Watermarkstat(object): def print_all_stat(self, table_prefix, key): table = [] type = self.watermark_types[key] - if key == 'buffer_pool': + if key in ['buffer_pool', 'headroom_pool']: self.header_list = type['header'] # Get stats for each buffer pool for buf_pool, bp_oid in natsorted(self.buffer_pool_name_to_oid_map.items()): - key = table_prefix + bp_oid - data = self.counters_db.get(self.counters_db.COUNTERS_DB, key, type["wm_name"]) + if key == 'headroom_pool' and 'ingress_lossless' not in buf_pool: + continue + + db_key = table_prefix + bp_oid + data = self.counters_db.get(self.counters_db.COUNTERS_DB, db_key, type["wm_name"]) if data is None: data = STATUS_NA table.append((buf_pool, data)) @@ -275,7 +281,7 @@ Examples: parser.add_argument('-c', '--clear', action='store_true', help='Clear watermarks request') parser.add_argument('-p', '--persistent', action='store_true', help='Do the operations on the persistent watermark') parser.add_argument('-t', '--type', required=True, action='store', - choices=['pg_headroom', 'pg_shared', 'q_shared_uni', 'q_shared_multi', 'buffer_pool'], + choices=['pg_headroom', 'pg_shared', 'q_shared_uni', 'q_shared_multi', 'buffer_pool', 'headroom_pool'], help='The type of watermark') parser.add_argument('-v', '--version', action='version', version='%(prog)s 1.0') args = parser.parse_args() diff --git a/show/main.py b/show/main.py index d163ac930a59..087a67958bb4 100755 --- a/show/main.py +++ b/show/main.py @@ -634,6 +634,27 @@ def pwm_buffer_pool(): run_command(command) +# +# 'headroom-pool' group ("show headroom-pool ...") +# + +@cli.group(name='headroom-pool', cls=clicommon.AliasedGroup) +def headroom_pool(): + """Show details of headroom pool""" + +@headroom_pool.command('watermark') +def wm_headroom_pool(): + """Show user WM for headroom pool""" + command = 'watermarkstat -t headroom_pool' + run_command(command) + +@headroom_pool.command('persistent-watermark') +def pwm_headroom_pool(): + """Show persistent WM for headroom pool""" + command = 'watermarkstat -p -t headroom_pool' + run_command(command) + + # # 'mac' command ("show mac ...") # diff --git a/tests/mock_tables/counters_db.json b/tests/mock_tables/counters_db.json index 96be3b5fc579..dfc344672baf 100644 --- a/tests/mock_tables/counters_db.json +++ b/tests/mock_tables/counters_db.json @@ -990,7 +990,8 @@ "SAI_BUFFER_POOL_STAT_WATERMARK_BYTES": "2000" }, "USER_WATERMARKS:oid:0x18000000000b66": { - "SAI_BUFFER_POOL_STAT_WATERMARK_BYTES": "3000" + "SAI_BUFFER_POOL_STAT_WATERMARK_BYTES": "3000", + "SAI_BUFFER_POOL_STAT_XOFF_ROOM_WATERMARK_BYTES": "432640" }, "PERSISTENT_WATERMARKS:oid:0x18000000000b64": { "SAI_BUFFER_POOL_STAT_WATERMARK_BYTES": "2000" @@ -999,7 +1000,8 @@ "SAI_BUFFER_POOL_STAT_WATERMARK_BYTES": "3000" }, "PERSISTENT_WATERMARKS:oid:0x18000000000b66": { - "SAI_BUFFER_POOL_STAT_WATERMARK_BYTES": "4000" + "SAI_BUFFER_POOL_STAT_WATERMARK_BYTES": "4000", + "SAI_BUFFER_POOL_STAT_XOFF_ROOM_WATERMARK_BYTES": "863616" }, "CRM:ACL_STATS:INGRESS:VLAN":{ "crm_stats_acl_table_used":"0", diff --git a/tests/watermarkstat_test.py b/tests/watermarkstat_test.py index faf3be11d443..b7c9eadb6b12 100644 --- a/tests/watermarkstat_test.py +++ b/tests/watermarkstat_test.py @@ -36,6 +36,9 @@ def test_show_queue_multicast_wm(self): def test_show_buffer_pool_wm(self): self.executor(testData['show_buffer_pool_wm']) + def test_show_headroom_pool_wm(self): + self.executor(testData['show_hdrm_pool_wm']) + def test_show_pg_shared_peristent_wm(self): self.executor(testData['show_pg_pwm_shared']) @@ -51,6 +54,9 @@ def test_show_queue_multicast_persistent_wm(self): def test_show_buffer_pool_persistent_wm(self): self.executor(testData['show_buffer_pool_pwm']) + def test_show_headroom_pool_persistent_wm(self): + self.executor(testData['show_hdrm_pool_pwm']) + def executor(self, testcase): runner = CliRunner() diff --git a/tests/wm_input/wm_test_vectors.py b/tests/wm_input/wm_test_vectors.py index 98ccb2eaa32c..a5314b1fe6ed 100644 --- a/tests/wm_input/wm_test_vectors.py +++ b/tests/wm_input/wm_test_vectors.py @@ -79,6 +79,20 @@ ingress_lossless_pool 4000 """ +show_hdrm_pool_wm_output="""\ +Headroom pool maximum occupancy: + Pool Bytes +--------------------- ------- +ingress_lossless_pool 432640 +""" + +show_hdrm_pool_persistent_wm_output="""\ +Headroom pool maximum occupancy: + Pool Bytes +--------------------- ------- +ingress_lossless_pool 863616 +""" + testData = { 'show_pg_wm_shared' : [ {'cmd' : ['priority-group', 'watermark', 'shared'], 'rc_output': show_pg_wm_shared_output @@ -119,5 +133,13 @@ 'show_buffer_pool_pwm' : [ {'cmd' : ['buffer_pool', 'persistent-watermark'], 'rc_output': show_buffer_pool_persistent_wm_output } - ] + ], + 'show_hdrm_pool_wm' : [ {'cmd' : ['headroom-pool', 'watermark'], + 'rc_output': show_hdrm_pool_wm_output + } + ], + 'show_hdrm_pool_pwm' : [ {'cmd' : ['headroom-pool', 'persistent-watermark'], + 'rc_output': show_hdrm_pool_persistent_wm_output + } + ] }