From 3c9d6b342b539b379cf10317e181c9953f57827c Mon Sep 17 00:00:00 2001 From: Stephen Sun <5379172+stephenxs@users.noreply.github.com> Date: Fri, 26 Jul 2024 04:38:01 +0800 Subject: [PATCH] Support allocate buffer pool based on ratio (#3201) Support allocate buffer pool size based on percentage of available memory by percentage field in BUFFER_POOL table. It is used in the dynamic buffer model only and represents the percentage of a buffer pool's size compared to the available memory size. On Nvidia devices, if the percentage is defined, the buffer pool size is available memory * percentage. --- cfgmgr/buffer_pool_mellanox.lua | 17 +++++++++++++---- tests/test_buffer_dynamic.py | 31 +++++++++++++++++++++++++++++++ 2 files changed, 44 insertions(+), 4 deletions(-) diff --git a/cfgmgr/buffer_pool_mellanox.lua b/cfgmgr/buffer_pool_mellanox.lua index 15bb81efb2..f811a1c50d 100644 --- a/cfgmgr/buffer_pool_mellanox.lua +++ b/cfgmgr/buffer_pool_mellanox.lua @@ -417,10 +417,12 @@ local pool_size if shp_size then accumulative_occupied_buffer = accumulative_occupied_buffer + shp_size end + +local available_buffer = mmu_size - accumulative_occupied_buffer if ingress_pool_count == 1 then - pool_size = mmu_size - accumulative_occupied_buffer + pool_size = available_buffer else - pool_size = (mmu_size - accumulative_occupied_buffer) / 2 + pool_size = available_buffer / 2 end if pool_size > ceiling_mmu_size then @@ -429,12 +431,19 @@ end local shp_deployed = false for i = 1, #pools_need_update, 1 do + local percentage = tonumber(redis.call('HGET', pools_need_update[i], 'percentage')) + local effective_pool_size + if percentage ~= nil and percentage >= 0 then + effective_pool_size = available_buffer * percentage / 100 + else + effective_pool_size = pool_size + end local pool_name = string.match(pools_need_update[i], "BUFFER_POOL|([^%s]+)$") if shp_size ~= 0 and pool_name == "ingress_lossless_pool" then - table.insert(result, pool_name .. ":" .. math.ceil(pool_size) .. ":" .. math.ceil(shp_size)) + table.insert(result, pool_name .. ":" .. math.ceil(effective_pool_size) .. ":" .. math.ceil(shp_size)) shp_deployed = true else - table.insert(result, pool_name .. ":" .. math.ceil(pool_size)) + table.insert(result, pool_name .. ":" .. math.ceil(effective_pool_size)) end end diff --git a/tests/test_buffer_dynamic.py b/tests/test_buffer_dynamic.py index 1813ebf430..2737d28d66 100644 --- a/tests/test_buffer_dynamic.py +++ b/tests/test_buffer_dynamic.py @@ -903,3 +903,34 @@ def test_bufferPoolInitWithSHP(self, dvs, testlog): self.config_db.delete_entry('DEFAULT_LOSSLESS_BUFFER_PARAMETER', 'AZURE') self.app_db.delete_entry("BUFFER_PG_TABLE_SET", "") dvs.runcmd("kill -s SIGCONT {}".format(oa_pid)) + + + def test_bufferPoolPercentage(self, dvs, testlog): + self.setup_db(dvs) + + try: + self.config_db.delete_field('BUFFER_POOL', 'ingress_lossless_pool', 'size') + except Exception as e: + pass + + try: + percentage = 75 + margin = 1 + + re_pool_size = "ingress_lossless_pool:([0-9]+)" + _, original_output = dvs.runcmd("redis-cli --eval /usr/share/swss/buffer_pool_vs.lua") + original_size = int(re.match(re_pool_size, original_output).group(1)) + + original_ingress_lossless_pool = self.config_db.get_entry('BUFFER_POOL', 'ingress_lossless_pool') + ingress_lossless_pool = original_ingress_lossless_pool + ingress_lossless_pool['percentage'] = str(percentage) + self.config_db.update_entry('BUFFER_POOL', 'ingress_lossless_pool', ingress_lossless_pool) + + _, percentage_output = dvs.runcmd("redis-cli --eval /usr/share/swss/buffer_pool_vs.lua") + percentage_size = int(re.match(re_pool_size, percentage_output).group(1)) + + real_percentage = percentage_size * 100 / original_size + assert abs(percentage - real_percentage) < margin + finally: + self.config_db.delete_entry('BUFFER_POOL', 'ingress_lossless_pool') + self.config_db.update_entry('BUFFER_POOL', 'ingress_lossless_pool', original_ingress_lossless_pool)