diff --git a/cfgmgr/buffermgr.cpp b/cfgmgr/buffermgr.cpp index c051d681b397..0fb39a862a0f 100644 --- a/cfgmgr/buffermgr.cpp +++ b/cfgmgr/buffermgr.cpp @@ -30,6 +30,17 @@ BufferMgr::BufferMgr(DBConnector *cfgDb, DBConnector *applDb, string pg_lookup_f m_applBufferEgressProfileListTable(applDb, APP_BUFFER_PORT_EGRESS_PROFILE_LIST_NAME) { readPgProfileLookupFile(pg_lookup_file); + + char *platform = getenv("ASIC_VENDOR"); + if (NULL == platform) + { + SWSS_LOG_WARN("Platform environment variable is not defined"); + } + else + { + m_platform = platform; + } + dynamic_buffer_model = false; } @@ -122,9 +133,9 @@ Create/update two tables: profile (in m_cfgBufferProfileTable) and port buffer ( } } */ -task_process_status BufferMgr::doSpeedUpdateTask(string port) +task_process_status BufferMgr::doSpeedUpdateTask(string port, bool admin_up) { - vector fvVector; + vector fvVectorPg, fvVectorProfile; string cable; string speed; @@ -142,6 +153,39 @@ task_process_status BufferMgr::doSpeedUpdateTask(string port) } speed = m_speedLookup[port]; + + string buffer_pg_key = port + m_cfgBufferPgTable.getTableNameSeparator() + LOSSLESS_PGS; + // key format is pg_lossless___profile + string buffer_profile_key = "pg_lossless_" + speed + "_" + cable + "_profile"; + string profile_ref = buffer_profile_key; + + m_cfgBufferPgTable.get(buffer_pg_key, fvVectorPg); + + if (!admin_up && m_platform == "mellanox") + { + // Remove the entry in BUFFER_PG table if any + if (!fvVectorPg.empty()) + { + for (auto &prop : fvVectorPg) + { + if (fvField(prop) == "profile") + { + if (fvValue(prop) == profile_ref) + { + SWSS_LOG_NOTICE("Removing PG %s from port %s which is administrative down", buffer_pg_key.c_str(), port.c_str()); + m_cfgBufferPgTable.del(buffer_pg_key); + } + else + { + SWSS_LOG_NOTICE("Not default profile %s is configured on PG %s, won't reclaim buffer", fvValue(prop).c_str(), buffer_pg_key.c_str()); + } + } + } + } + + return task_process_status::task_success; + } + if (m_pgProfileLookup.count(speed) == 0 || m_pgProfileLookup[speed].count(cable) == 0) { SWSS_LOG_ERROR("Unable to create/update PG profile for port %s. No PG profile configured for speed %s and cable length %s", @@ -149,13 +193,10 @@ task_process_status BufferMgr::doSpeedUpdateTask(string port) return task_process_status::task_invalid_entry; } - // Crete record in BUFFER_PROFILE table - // key format is pg_lossless___profile - string buffer_profile_key = "pg_lossless_" + speed + "_" + cable + "_profile"; - // check if profile already exists - if yes - skip creation - m_cfgBufferProfileTable.get(buffer_profile_key, fvVector); - if (fvVector.size() == 0) + m_cfgBufferProfileTable.get(buffer_profile_key, fvVectorProfile); + // Create record in BUFFER_PROFILE table + if (fvVectorProfile.size() == 0) { SWSS_LOG_NOTICE("Creating new profile '%s'", buffer_profile_key.c_str()); @@ -170,32 +211,24 @@ task_process_status BufferMgr::doSpeedUpdateTask(string port) // profile threshold field name mode += "_th"; - fvVector.push_back(make_pair("pool", INGRESS_LOSSLESS_PG_POOL_NAME)); - fvVector.push_back(make_pair("xon", m_pgProfileLookup[speed][cable].xon)); + fvVectorProfile.push_back(make_pair("pool", INGRESS_LOSSLESS_PG_POOL_NAME)); + fvVectorProfile.push_back(make_pair("xon", m_pgProfileLookup[speed][cable].xon)); if (m_pgProfileLookup[speed][cable].xon_offset.length() > 0) { - fvVector.push_back(make_pair("xon_offset", + fvVectorProfile.push_back(make_pair("xon_offset", m_pgProfileLookup[speed][cable].xon_offset)); } - fvVector.push_back(make_pair("xoff", m_pgProfileLookup[speed][cable].xoff)); - fvVector.push_back(make_pair("size", m_pgProfileLookup[speed][cable].size)); - fvVector.push_back(make_pair(mode, m_pgProfileLookup[speed][cable].threshold)); - m_cfgBufferProfileTable.set(buffer_profile_key, fvVector); + fvVectorProfile.push_back(make_pair("xoff", m_pgProfileLookup[speed][cable].xoff)); + fvVectorProfile.push_back(make_pair("size", m_pgProfileLookup[speed][cable].size)); + fvVectorProfile.push_back(make_pair(mode, m_pgProfileLookup[speed][cable].threshold)); + m_cfgBufferProfileTable.set(buffer_profile_key, fvVectorProfile); } else { SWSS_LOG_NOTICE("Reusing existing profile '%s'", buffer_profile_key.c_str()); } - fvVector.clear(); - - string buffer_pg_key = port + m_cfgBufferPgTable.getTableNameSeparator() + LOSSLESS_PGS; - - string profile_ref = buffer_profile_key; - /* Check if PG Mapping is already then log message and return. */ - m_cfgBufferPgTable.get(buffer_pg_key, fvVector); - - for (auto& prop : fvVector) + for (auto& prop : fvVectorPg) { if ((fvField(prop) == "profile") && (profile_ref == fvValue(prop))) { @@ -204,10 +237,10 @@ task_process_status BufferMgr::doSpeedUpdateTask(string port) } } - fvVector.clear(); + fvVectorPg.clear(); - fvVector.push_back(make_pair("profile", profile_ref)); - m_cfgBufferPgTable.set(buffer_pg_key, fvVector); + fvVectorPg.push_back(make_pair("profile", profile_ref)); + m_cfgBufferPgTable.set(buffer_pg_key, fvVectorPg); return task_process_status::task_success; } @@ -379,26 +412,35 @@ void BufferMgr::doTask(Consumer &consumer) task_process_status task_status = task_process_status::task_success; if (op == SET_COMMAND) { - for (auto i : kfvFieldsValues(t)) + if (table_name == CFG_PORT_CABLE_LEN_TABLE_NAME) { - if (table_name == CFG_PORT_CABLE_LEN_TABLE_NAME) + // receive and cache cable length table + for (auto i : kfvFieldsValues(t)) { - // receive and cache cable length table task_status = doCableTask(fvField(i), fvValue(i)); } - if (m_pgfile_processed && table_name == CFG_PORT_TABLE_NAME && (fvField(i) == "speed" || fvField(i) == "admin_status")) + } + else if (m_pgfile_processed && table_name == CFG_PORT_TABLE_NAME) + { + bool admin_up = false; + for (auto i : kfvFieldsValues(t)) { if (fvField(i) == "speed") { m_speedLookup[port] = fvValue(i); } - - if (m_speedLookup.count(port) != 0) + if (fvField(i) == "admin_status") { - // create/update profile for port - task_status = doSpeedUpdateTask(port); + admin_up = ("up" == fvValue(i)); } } + + if (m_speedLookup.count(port) != 0) + { + // create/update profile for port + task_status = doSpeedUpdateTask(port, admin_up); + } + if (task_status != task_process_status::task_success) { break; diff --git a/cfgmgr/buffermgr.h b/cfgmgr/buffermgr.h index 0c71f1b8c0a6..e7f04465ef7e 100644 --- a/cfgmgr/buffermgr.h +++ b/cfgmgr/buffermgr.h @@ -36,6 +36,8 @@ class BufferMgr : public Orch using Orch::doTask; private: + std::string m_platform; + Table m_cfgPortTable; Table m_cfgCableLenTable; Table m_cfgBufferProfileTable; @@ -58,7 +60,7 @@ class BufferMgr : public Orch std::string getPgPoolMode(); void readPgProfileLookupFile(std::string); task_process_status doCableTask(std::string port, std::string cable_length); - task_process_status doSpeedUpdateTask(std::string port); + task_process_status doSpeedUpdateTask(std::string port, bool admin_up); void doBufferTableTask(Consumer &consumer, ProducerStateTable &applTable); void transformSeperator(std::string &name);