Skip to content

Commit 509b888

Browse files
authored
[syncd] Comparison logic workaround for empty buffer profile (sonic-net#906)
* [syncd] WIP buffer profile GET * Add object status serialize method * Add buffer profile get test * [syncd] Allow AsicView return dummy created object * Update aspell * [syncd] Transfer not processed objects to temp view Check issue sonic-net/sonic-sairedis#899 for details. * [tests] Add missing recording file for tests
1 parent d8eb0ea commit 509b888

11 files changed

+379
-25
lines changed

syncd/AsicView.cpp

+5-3
Original file line numberDiff line numberDiff line change
@@ -506,7 +506,7 @@ std::vector<std::shared_ptr<SaiObj>> AsicView::getAllNotProcessedObjects() const
506506
* @param[in] rid Real ID
507507
* @param[in] vid Virtual ID
508508
*/
509-
void AsicView::createDummyExistingObject(
509+
std::shared_ptr<SaiObj> AsicView::createDummyExistingObject(
510510
_In_ sai_object_id_t rid,
511511
_In_ sai_object_id_t vid)
512512
{
@@ -540,6 +540,8 @@ void AsicView::createDummyExistingObject(
540540

541541
m_ridToVid[rid] = vid;
542542
m_vidToRid[vid] = rid;
543+
544+
return o;
543545
}
544546

545547
/**
@@ -1289,10 +1291,10 @@ void AsicView::checkObjectsStatus() const
12891291
{
12901292
const auto &o = *p.second;
12911293

1292-
SWSS_LOG_ERROR("object was not processed: %s %s, status: %d (ref: %d)",
1294+
SWSS_LOG_ERROR("object was not processed: %s %s, status: %s (ref: %d)",
12931295
o.m_str_object_type.c_str(),
12941296
o.m_str_object_id.c_str(),
1295-
o.getObjectStatus(),
1297+
ObjectStatus::sai_serialize_object_status(o.getObjectStatus()).c_str(),
12961298
o.isOidObject() ? getVidReferenceCount(o.getVid()): -1);
12971299

12981300
count++;

syncd/AsicView.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -188,7 +188,7 @@ namespace syncd
188188
* @param[in] rid Real ID
189189
* @param[in] vid Virtual ID
190190
*/
191-
void createDummyExistingObject(
191+
std::shared_ptr<SaiObj> createDummyExistingObject(
192192
_In_ sai_object_id_t rid,
193193
_In_ sai_object_id_t vid);
194194

syncd/ComparisonLogic.cpp

+174-11
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,13 @@ void ComparisonLogic::compareViews()
122122

123123
applyViewTransition(current, temp);
124124

125+
transferNotProcessed(current, temp);
126+
127+
// TODO have a method to check for not processed objects
128+
// and maybe add them to list on processing attributes
129+
// and move note processed objects to temporary view as well
130+
// we need to check oid attributes as well
131+
125132
SWSS_LOG_NOTICE("ASIC operations to execute: %zu", current.asicGetOperationsCount());
126133

127134
temp.checkObjectsStatus();
@@ -183,6 +190,8 @@ void ComparisonLogic::matchOids(
183190
{
184191
SWSS_LOG_ENTER();
185192

193+
auto coldBootDiscoveredVids = m_switch->getColdBootDiscoveredVids();
194+
186195
for (const auto &temporaryIt: temporaryView.m_oOids)
187196
{
188197
sai_object_id_t temporaryVid = temporaryIt.first;
@@ -211,6 +220,37 @@ void ComparisonLogic::matchOids(
211220
currentIt->second->m_str_object_type.c_str(),
212221
sai_serialize_object_id(rid).c_str(),
213222
sai_serialize_object_id(vid).c_str());
223+
224+
if (coldBootDiscoveredVids.find(vid) == coldBootDiscoveredVids.end())
225+
{
226+
auto ot = currentIt->second->getObjectType();
227+
228+
switch (ot)
229+
{
230+
case SAI_OBJECT_TYPE_INGRESS_PRIORITY_GROUP:
231+
case SAI_OBJECT_TYPE_SCHEDULER_GROUP:
232+
case SAI_OBJECT_TYPE_QUEUE:
233+
case SAI_OBJECT_TYPE_PORT:
234+
break;
235+
236+
default:
237+
238+
// Should we also add check if also not in removed?
239+
// This is for case of only GET:
240+
// 1. cold boot:
241+
// - OA assigns buffer profile to Queue
242+
// 2. warm boot:
243+
// - OA do GET on Queue and got previous buffer profile
244+
// - OA assigns new buffer profile on Queue
245+
//
246+
// Question: what should happen to old buffer profile? should it be removed?
247+
// No, since OA still hold's the reference to that VID and may use it later.
248+
SWSS_LOG_INFO("matched %s VID %s was not in cold boot, possible only GET?",
249+
sai_serialize_object_id(vid).c_str(),
250+
currentIt->second->m_str_object_type.c_str());
251+
break;
252+
}
253+
}
214254
}
215255

216256
SWSS_LOG_NOTICE("matched oids");
@@ -1125,8 +1165,8 @@ void ComparisonLogic::updateObjectStatus(
11251165
bool ComparisonLogic::performObjectSetTransition(
11261166
_In_ AsicView &currentView,
11271167
_In_ AsicView &temporaryView,
1128-
_In_ const std::shared_ptr<SaiObj> &currentBestMatch,
1129-
_In_ const std::shared_ptr<const SaiObj> &temporaryObj,
1168+
_In_ const std::shared_ptr<SaiObj> currentBestMatch,
1169+
_In_ std::shared_ptr<SaiObj> temporaryObj,
11301170
_In_ bool performTransition)
11311171
{
11321172
SWSS_LOG_ENTER();
@@ -1386,6 +1426,8 @@ bool ComparisonLogic::performObjectSetTransition(
13861426
return false;
13871427
}
13881428

1429+
const bool beginTempSizeZero = temporaryObj->getAllAttributes().size() == 0;
1430+
13891431
/*
13901432
* Current best match can have more attributes than temporary object.
13911433
* let see if we can bring them to default value if possible.
@@ -1530,14 +1572,38 @@ bool ComparisonLogic::performObjectSetTransition(
15301572
continue;
15311573
}
15321574

1533-
// SAI_QUEUE_ATTR_PARENT_SCHEDULER_NODE
1534-
// SAI_SCHEDULER_GROUP_ATTR_SCHEDULER_PROFILE_ID*
1535-
// SAI_SCHEDULER_GROUP_ATTR_PARENT_NODE
1536-
// SAI_BRIDGE_PORT_ATTR_BRIDGE_ID
1537-
//
1538-
// TODO matched by ID (MATCHED state) should always be updatable
1539-
// except those 4 above (at least for those above since they can have
1540-
// default value present after switch creation
1575+
// current best match is MATCHED
1576+
1577+
//auto vid = currentBestMatch->getVid();
1578+
1579+
// TODO don't transfer oid attributes, we don't know how to handle this yet
1580+
// If OA did GET on any attributes, snoop in syncd should catch that and write
1581+
// to database so we would have some attributes here.
1582+
1583+
if (beginTempSizeZero && !meta->isoidattribute)
1584+
{
1585+
SWSS_LOG_WARN("current attr is MoC|CaS and object is MATCHED: %s transferring %s:%s to temp object (was empty)",
1586+
currentBestMatch->m_str_object_id.c_str(),
1587+
meta->attridname,
1588+
currentAttr->getStrAttrValue().c_str());
1589+
1590+
std::shared_ptr<SaiAttr> transferedAttr = std::make_shared<SaiAttr>(
1591+
currentAttr->getStrAttrId(),
1592+
currentAttr->getStrAttrValue());
1593+
1594+
temporaryObj->setAttr(transferedAttr);
1595+
1596+
continue;
1597+
}
1598+
1599+
// SAI_QUEUE_ATTR_PARENT_SCHEDULER_NODE
1600+
// SAI_SCHEDULER_GROUP_ATTR_SCHEDULER_PROFILE_ID*
1601+
// SAI_SCHEDULER_GROUP_ATTR_PARENT_NODE
1602+
// SAI_BRIDGE_PORT_ATTR_BRIDGE_ID
1603+
//
1604+
// TODO matched by ID (MATCHED state) should always be updatable
1605+
// except those 4 above (at least for those above since they can have
1606+
// default value present after switch creation
15411607

15421608
// TODO SAI_SCHEDULER_GROUP_ATTR_SCHEDULER_PROFILE_ID is mandatory on create but also SET
15431609
// if attribute is set we and object is in MATCHED state then that means we are able to
@@ -1571,6 +1637,21 @@ bool ComparisonLogic::performObjectSetTransition(
15711637
meta->attridname,
15721638
currentAttr->getStrAttrValue().c_str());
15731639

1640+
// don't produce too much noise for queues
1641+
if (currentAttr->getStrAttrId() != "SAI_QUEUE_ATTR_TYPE")
1642+
{
1643+
SWSS_LOG_WARN("current attr is CREATE_ONLY and object is MATCHED: %s transferring %s:%s to temp object",
1644+
currentBestMatch->m_str_object_id.c_str(),
1645+
meta->attridname,
1646+
currentAttr->getStrAttrValue().c_str());
1647+
}
1648+
1649+
std::shared_ptr<SaiAttr> transferedAttr = std::make_shared<SaiAttr>(
1650+
currentAttr->getStrAttrId(),
1651+
currentAttr->getStrAttrValue());
1652+
1653+
temporaryObj->setAttr(transferedAttr);
1654+
15741655
continue;
15751656
}
15761657
}
@@ -1709,7 +1790,7 @@ bool ComparisonLogic::performObjectSetTransition(
17091790
void ComparisonLogic::processObjectForViewTransition(
17101791
_In_ AsicView &currentView,
17111792
_In_ AsicView &temporaryView,
1712-
_In_ const std::shared_ptr<SaiObj> &temporaryObj)
1793+
_Inout_ std::shared_ptr<SaiObj> temporaryObj)
17131794
{
17141795
SWSS_LOG_ENTER();
17151796

@@ -2273,6 +2354,10 @@ void ComparisonLogic::populateExistingObjects(
22732354

22742355
if (temporaryView.hasRid(rid))
22752356
{
2357+
SWSS_LOG_INFO("temporary view has existing %s RID %s",
2358+
sai_serialize_object_type(m_vendorSai->objectTypeQuery(rid)).c_str(),
2359+
sai_serialize_object_id(rid).c_str());
2360+
22762361
continue;
22772362
}
22782363

@@ -2295,6 +2380,11 @@ void ComparisonLogic::populateExistingObjects(
22952380
* from current view as well.
22962381
*/
22972382

2383+
SWSS_LOG_INFO("object was removed in init view: %s RID %s VID %s",
2384+
sai_serialize_object_type(m_vendorSai->objectTypeQuery(rid)).c_str(),
2385+
sai_serialize_object_id(rid).c_str(),
2386+
sai_serialize_object_id(vid).c_str());
2387+
22982388
continue;
22992389
}
23002390

@@ -2730,6 +2820,79 @@ void ComparisonLogic::createPreMatchMap(
27302820
count);
27312821
}
27322822

2823+
void ComparisonLogic::transferNotProcessed(
2824+
_In_ AsicView& current,
2825+
_In_ AsicView& temp)
2826+
{
2827+
SWSS_LOG_ENTER();
2828+
2829+
SWSS_LOG_NOTICE("calling transferNotProcessed");
2830+
2831+
/*
2832+
* It may happen that after performing view transition, some objects will
2833+
* not be processed. This may happen is scenario where buffer pool is
2834+
* assigned to buffer profile, and then buffer profile is assigned to
2835+
* queue. If OA will query only for oid for that buffer profile, then
2836+
* buffer pool will not be processed. Normally if it would be removed by
2837+
* comparison logic. More on this issue can be found on github:
2838+
* https://github.com/Azure/sonic-sairedis/issues/899
2839+
*
2840+
* So what we will do, we will transfer all not processed objects to
2841+
* temporary view with the same RID and VID. If nothing will happen to them,
2842+
* they will stay there until next warm boot where they will be removed.
2843+
*/
2844+
2845+
/*
2846+
* We need a loop (or recursion) since not processed objects may have oid
2847+
* attributes as well.
2848+
*/
2849+
2850+
while (current.getAllNotProcessedObjects().size())
2851+
{
2852+
SWSS_LOG_WARN("we have %zu not processed objects on current view, moving to temp view", current.getAllNotProcessedObjects().size());
2853+
2854+
for (const auto& obj: current.getAllNotProcessedObjects())
2855+
{
2856+
auto vid = obj->getVid();
2857+
2858+
auto rid = current.m_vidToRid.at(vid);
2859+
2860+
/*
2861+
* We should have only oid objects here, since all non oid objects
2862+
* are leafs in graph and has been removed.
2863+
*/
2864+
2865+
auto tmp = temp.createDummyExistingObject(rid, vid);
2866+
2867+
/*
2868+
* Move both objects to matched state since match oids was already
2869+
* called, and here we created some new objects that should be matched.
2870+
*/
2871+
2872+
current.m_oOids.at(vid)->setObjectStatus(SAI_OBJECT_STATUS_FINAL);
2873+
temp.m_oOids.at(vid)->setObjectStatus(SAI_OBJECT_STATUS_FINAL);
2874+
2875+
SWSS_LOG_WARN("moved %s VID %s RID %s to temporary view, and marked FINAL",
2876+
obj->m_str_object_type.c_str(),
2877+
obj->m_str_object_id.c_str(),
2878+
sai_serialize_object_id(rid).c_str());
2879+
2880+
for (auto& kvp: obj->getAllAttributes())
2881+
{
2882+
auto& sh = kvp.second;
2883+
2884+
auto attr = std::make_shared<SaiAttr>(sh->getStrAttrId(), sh->getStrAttrValue());
2885+
2886+
tmp->setAttr(attr);
2887+
2888+
SWSS_LOG_WARN(" * with attr: %s: %s",
2889+
sh->getStrAttrId().c_str(),
2890+
sh->getStrAttrValue().c_str());
2891+
}
2892+
2893+
}
2894+
}
2895+
}
27332896

27342897
void ComparisonLogic::applyViewTransition(
27352898
_In_ AsicView &current,

syncd/ComparisonLogic.h

+7-3
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,10 @@ namespace syncd
5858
_In_ AsicView& current,
5959
_In_ AsicView& temp);
6060

61+
void transferNotProcessed(
62+
_In_ AsicView& current,
63+
_In_ AsicView& temp);
64+
6165
void checkInternalObjects(
6266
_In_ const AsicView& cv,
6367
_In_ const AsicView& tv);
@@ -136,8 +140,8 @@ namespace syncd
136140
bool performObjectSetTransition(
137141
_In_ AsicView& currentView,
138142
_In_ AsicView& temporaryView,
139-
_In_ const std::shared_ptr<SaiObj>& currentBestMatch,
140-
_In_ const std::shared_ptr<const SaiObj>& temporaryObj,
143+
_In_ const std::shared_ptr<SaiObj> currentBestMatch,
144+
_In_ const std::shared_ptr<SaiObj> temporaryObj,
141145
_In_ bool performTransition);
142146

143147
void breakBeforeMake(
@@ -154,7 +158,7 @@ namespace syncd
154158
void processObjectForViewTransition(
155159
_In_ AsicView& currentView,
156160
_In_ AsicView& temporaryView,
157-
_In_ const std::shared_ptr<SaiObj>& temporaryObj);
161+
_Inout_ std::shared_ptr<SaiObj> temporaryObj);
158162

159163
void checkSwitch(
160164
_In_ const AsicView& currentView,

syncd/SaiObj.cpp

+24
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,30 @@
44

55
using namespace syncd;
66

7+
std::string ObjectStatus::sai_serialize_object_status(
8+
_In_ sai_object_status_t os)
9+
{
10+
SWSS_LOG_ENTER();
11+
12+
switch (os)
13+
{
14+
case SAI_OBJECT_STATUS_NOT_PROCESSED:
15+
return "not-processed";
16+
17+
case SAI_OBJECT_STATUS_MATCHED:
18+
return "matched";
19+
20+
case SAI_OBJECT_STATUS_REMOVED:
21+
return "removed";
22+
23+
case SAI_OBJECT_STATUS_FINAL:
24+
return "final";
25+
26+
default:
27+
SWSS_LOG_THROW("unknown object status: %d", os);
28+
}
29+
}
30+
731
SaiObj::SaiObj():
832
m_createdObject(false),
933
m_objectStatus(SAI_OBJECT_STATUS_NOT_PROCESSED)

syncd/SaiObj.h

+13
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,19 @@ namespace syncd
5555

5656
} sai_object_status_t;
5757

58+
class ObjectStatus
59+
{
60+
private:
61+
62+
ObjectStatus() = delete;
63+
~ObjectStatus() = delete;
64+
65+
public:
66+
67+
static std::string sai_serialize_object_status(
68+
_In_ sai_object_status_t os);
69+
};
70+
5871
class SaiObj
5972
{
6073
private:

0 commit comments

Comments
 (0)