Skip to content

Commit 45547e6

Browse files
authored
[Buffer Orch] Retry one more time when it fails to set buffer profiles' attributes to SAI (sonic-net#2890)
* Retry one more time when setting buffer profiles' attribute fails Vendor can require attributes to be applied in a certain order
1 parent f938e11 commit 45547e6

File tree

2 files changed

+131
-1
lines changed

2 files changed

+131
-1
lines changed

orchagent/bufferorch.cpp

+13-1
Original file line numberDiff line numberDiff line change
@@ -704,6 +704,7 @@ task_process_status BufferOrch::processBufferProfile(KeyOpFieldsValuesTuple &tup
704704
}
705705
if (SAI_NULL_OBJECT_ID != sai_object)
706706
{
707+
vector<sai_attribute_t> attribs_to_retry;
707708
SWSS_LOG_DEBUG("Modifying existing sai object:%" PRIx64, sai_object);
708709
for (auto &attribute : attribs)
709710
{
@@ -715,7 +716,18 @@ task_process_status BufferOrch::processBufferProfile(KeyOpFieldsValuesTuple &tup
715716
}
716717
else if (SAI_STATUS_SUCCESS != sai_status)
717718
{
718-
SWSS_LOG_ERROR("Failed to modify buffer profile, name:%s, sai object:%" PRIx64 ", status:%d", object_name.c_str(), sai_object, sai_status);
719+
SWSS_LOG_NOTICE("Unable to modify buffer profile, name:%s, sai object:%" PRIx64 ", status:%d, will retry one more time", object_name.c_str(), sai_object, sai_status);
720+
attribs_to_retry.push_back(attribute);
721+
}
722+
}
723+
724+
for (auto &attribute : attribs)
725+
{
726+
sai_status = sai_buffer_api->set_buffer_profile_attribute(sai_object, &attribute);
727+
if (SAI_STATUS_SUCCESS != sai_status)
728+
{
729+
// A retried attribute can not be "not implemented"
730+
SWSS_LOG_ERROR("Failed to modify buffer profile, name:%s, sai object:%" PRIx64 ", status:%d, will retry once", object_name.c_str(), sai_object, sai_status);
719731
task_process_status handle_status = handleSaiSetStatus(SAI_API_BUFFER, sai_status);
720732
if (handle_status != task_process_status::task_success)
721733
{

tests/mock_tests/bufferorch_ut.cpp

+118
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,53 @@ namespace bufferorch_test
6464
return pold_sai_buffer_api->set_ingress_priority_group_attribute(ingress_priority_group_id, attr);
6565
}
6666

67+
sai_uint64_t _ut_stub_buffer_profile_size;
68+
sai_uint64_t _ut_stub_buffer_profile_xon;
69+
sai_uint64_t _ut_stub_buffer_profile_xoff;
70+
bool _ut_stub_buffer_profile_sanity_check = false;
71+
sai_status_t _ut_stub_sai_set_buffer_profile_attribute(
72+
_In_ sai_object_id_t buffer_profile_id,
73+
_In_ const sai_attribute_t *attr)
74+
{
75+
if (_ut_stub_buffer_profile_sanity_check)
76+
{
77+
if (SAI_BUFFER_PROFILE_ATTR_BUFFER_SIZE == attr[0].id)
78+
{
79+
if (attr[0].value.u64 < _ut_stub_buffer_profile_xon + _ut_stub_buffer_profile_xoff)
80+
{
81+
return SAI_STATUS_INVALID_PARAMETER;
82+
}
83+
else
84+
{
85+
_ut_stub_buffer_profile_size = attr[0].value.u64;
86+
}
87+
}
88+
if (SAI_BUFFER_PROFILE_ATTR_XOFF_TH == attr[0].id)
89+
{
90+
if (_ut_stub_buffer_profile_size < _ut_stub_buffer_profile_xon + attr[0].value.u64)
91+
{
92+
return SAI_STATUS_INVALID_PARAMETER;
93+
}
94+
else
95+
{
96+
_ut_stub_buffer_profile_xoff = attr[0].value.u64;
97+
}
98+
}
99+
if (SAI_BUFFER_PROFILE_ATTR_XON_TH == attr[0].id)
100+
{
101+
if (_ut_stub_buffer_profile_size < _ut_stub_buffer_profile_xoff + attr[0].value.u64)
102+
{
103+
return SAI_STATUS_INVALID_PARAMETER;
104+
}
105+
else
106+
{
107+
_ut_stub_buffer_profile_xon = attr[0].value.u64;
108+
}
109+
}
110+
}
111+
return pold_sai_buffer_api->set_buffer_profile_attribute(buffer_profile_id, attr);
112+
}
113+
67114
uint32_t _ut_stub_set_queue_count;
68115
sai_status_t _ut_stub_sai_set_queue_attribute(
69116
_In_ sai_object_id_t queue_id,
@@ -83,6 +130,7 @@ namespace bufferorch_test
83130
ut_sai_buffer_api = *sai_buffer_api;
84131
pold_sai_buffer_api = sai_buffer_api;
85132
ut_sai_buffer_api.set_ingress_priority_group_attribute = _ut_stub_sai_set_ingress_priority_group_attribute;
133+
ut_sai_buffer_api.set_buffer_profile_attribute = _ut_stub_sai_set_buffer_profile_attribute;
86134
sai_buffer_api = &ut_sai_buffer_api;
87135

88136
ut_sai_queue_api = *sai_queue_api;
@@ -674,4 +722,74 @@ namespace bufferorch_test
674722

675723
_unhook_sai_apis();
676724
}
725+
726+
TEST_F(BufferOrchTest, BufferOrchTestSetBufferProfile)
727+
{
728+
_hook_sai_apis();
729+
vector<string> ts;
730+
std::deque<KeyOpFieldsValuesTuple> entries;
731+
Table bufferPoolTable = Table(m_app_db.get(), APP_BUFFER_POOL_TABLE_NAME);
732+
Table bufferProfileTable = Table(m_app_db.get(), APP_BUFFER_PROFILE_TABLE_NAME);
733+
734+
bufferPoolTable.set("ingress_lossless_pool",
735+
{
736+
{"size", "1024000"},
737+
{"mode", "dynamic"},
738+
{"type", "ingress"}
739+
});
740+
bufferProfileTable.set("test_lossless_profile",
741+
{
742+
{"pool", "ingress_lossless_pool"},
743+
{"dynamic_th", "0"},
744+
{"size", "39936"},
745+
{"xon", "19456"},
746+
{"xoff", "20480"}
747+
});
748+
749+
gBufferOrch->addExistingData(&bufferPoolTable);
750+
gBufferOrch->addExistingData(&bufferProfileTable);
751+
752+
static_cast<Orch *>(gBufferOrch)->doTask();
753+
754+
_ut_stub_buffer_profile_size = 39936;
755+
_ut_stub_buffer_profile_xon = 19456;
756+
_ut_stub_buffer_profile_xoff = 20480;
757+
_ut_stub_buffer_profile_sanity_check = true;
758+
759+
// Decrease xoff, size
760+
entries.push_back({"test_lossless_profile", "SET",
761+
{
762+
{"size", "29936"},
763+
{"xon", "19456"},
764+
{"xoff", "10480"}
765+
}});
766+
auto consumer = dynamic_cast<Consumer *>(gBufferOrch->getExecutor(APP_BUFFER_PROFILE_TABLE_NAME));
767+
consumer->addToSync(entries);
768+
entries.clear();
769+
static_cast<Orch *>(gBufferOrch)->doTask();
770+
ASSERT_EQ(_ut_stub_buffer_profile_size, 29936);
771+
ASSERT_EQ(_ut_stub_buffer_profile_xoff, 10480);
772+
ASSERT_EQ(_ut_stub_buffer_profile_xon, 19456);
773+
static_cast<Orch *>(gBufferOrch)->dumpPendingTasks(ts);
774+
ASSERT_TRUE(ts.empty());
775+
776+
// Increase xoff, size
777+
entries.push_back({"test_lossless_profile", "SET",
778+
{
779+
{"xoff", "20480"},
780+
{"size", "39936"},
781+
{"xon", "19456"}
782+
}});
783+
consumer->addToSync(entries);
784+
entries.clear();
785+
static_cast<Orch *>(gBufferOrch)->doTask();
786+
ASSERT_EQ(_ut_stub_buffer_profile_size, 39936);
787+
ASSERT_EQ(_ut_stub_buffer_profile_xoff, 20480);
788+
ASSERT_EQ(_ut_stub_buffer_profile_xon, 19456);
789+
static_cast<Orch *>(gBufferOrch)->dumpPendingTasks(ts);
790+
ASSERT_TRUE(ts.empty());
791+
792+
_ut_stub_buffer_profile_sanity_check = false;
793+
_unhook_sai_apis();
794+
}
677795
}

0 commit comments

Comments
 (0)