Address racey SAI PHY Serdes object causing bad syncd setup - #1945
Address racey SAI PHY Serdes object causing bad syncd setup#1945justin-wong-ce wants to merge 11 commits into
Conversation
Mitigate a race condition in Port PHY Serdes initialization (syncd) where the SAI is still busy with the object from its creation when syncd's intialization attempts to read attributes from the object for syncd's own setup. Do this by allowing 3 retries with 10ms wait intervals in between tries. The retry will only trigger when the failure reason is SAI_STATUS_OBJECT_IN_USE. Signed-off-by: Justin Wong <jvwong@arista.com>
|
/azp run |
|
Azure Pipelines successfully started running 1 pipeline(s). |
Signed-off-by: Justin Wong <jvwong@arista.com>
|
/azp run |
|
Azure Pipelines successfully started running 1 pipeline(s). |
| port_rid = attr.value.oid; | ||
| return true; | ||
| } | ||
| sai_status_t status = Base::m_vendorSai->get(Base::m_objectType, port_serdes_rid, 1, &attr); |
There was a problem hiding this comment.
hey Justin - the fix is a bit of "by-chance".
Also supposedly,
- flex counter should not fail syncd init
- flex counter should work after the objects gets created
so I wonder if we have looked deeper into the failure/race and see what might be happening?
There was a problem hiding this comment.
As mentioned above, the race condition is from the SAI not being able to handle the Port PHY Serdes object creation and accessing of its attribute in extremely quick succession.
Either the SAI needs to be able to delay a request and not return SAI_STATUS_OBJECT_IN_USE, or Sonic (syncd initialization for this case) needs to be able to handle SAI_STATUS_OBJECT_IN_USE properly.
the fix is a bit of "by-chance"
I can change the fix such that it will retry until SAI does not return the SAI_STATUS_OBJECT_IN_USE, rather than just 3 times - this will remove the chance element.
I think it is reasonable to retry when the SAI returns SAI_STATUS_OBJECT_IN_USE since the object is busy and not available for read.
There was a problem hiding this comment.
Please let me know what you think of the latest changes
There was a problem hiding this comment.
what if we just simply skip the failed round and retry in the next pulling interval?
There was a problem hiding this comment.
retrying 3 times is not going to guarantee the fix anyway.
There was a problem hiding this comment.
This error is occuring during the initialization stage and this code that is being edited is for the initialization of Port PHY Serdes.
This will print the following ERR syslog once - during syncd's intialization:
30979 2026 Jun 7 20:56:03.499522 qspf201 ERR syncd#syncd: :- initAttrData: PORT_PHY_SERDES_ATTR: port_serdes_rid:0xb005700000000 has no serdes count attribute information
30980 2026 Jun 7 20:56:03.499522 qspf201 WARNING syncd#syncd: :- collectData: PORT_PHY_SERDES_ATTR: Failed to initialize attribute SAI_PORT_SERDES_ATTR_TX_FIR_TAPS_LIST for RID:0xb005700000000, skipping object
If SAI_STATUS_OBJECT_IN_USE is returned here and we don't retry, this will result missing info (maps) that is used to do other initalization steps later on, as it is treated as a failure.
If the info is missing, it will cause polling to fail all the time.
The following ERR syslog will print at every single poll interval:
26929 2026 Jun 7 20:55:59.007758 qspf201 ERR syncd#syncd: [none] SAI_API_PORT:brcm_sai_get_port_serdes_attribute_cmn:18248 Port 11 hardware lane count get failed with error -17.
26930 2026 Jun 7 20:55:59.007758 qspf201 ERR syncd#syncd: :- updatePortSerdesTapsCountMap: PORT_PHY_SERDES_ATTR: Failed to get port serdes count attr SAI_PORT_SERDES_ATTR_TX_FIR_COUNT for port_serdes RID:0xb005700000000, status:-17
There was a problem hiding this comment.
@justin-wong-ce i see you have removed the retry loop, I dont think this is a right approach.
We should not retry without an upper bound. If we believe a retry of 3 times with a 10ms is not enough we can increase this to 5 retries but we should not leave it unbounded.
@r12f fyi.
There was a problem hiding this comment.
@r12f please advise whether if we can go forward with 5 retries
There was a problem hiding this comment.
Just to check, is it that because flexcounter is running in its own thread and starts as part of syncd initialization, it could be that flexcounter is starting to get port stats before SAI initialization (triggered from the sync main thread) completes? If so, should the flexcounter thread start instead be delayed until after SAI initialization?
There was a problem hiding this comment.
Yes and no - the situaiton with the Port PHY Serdes objects are a bit special.
The Port PHY Serdes objects are first initialized like any other counter during syncd's initialization. There are no problems up to this part.
After a port configuration update, the configuration for these objects also change.
Since these objects only support CREATE, the objects have to be re-created to be reconfigured. What happens in the code is it will re-create these objects, then proceed to read from the objects from SAI so it can instantiate some variables in FlexCounter.cpp for polling - these reads usually happens on the next poll on these objects (which may or may not be the 1st poll).
The time between is not sufficient in some cases since the reconfiguration happens late into initialization or sometimes when polling has already started.
Althought its a rare occurence, it still needs to be accounted for.
Signed-off-by: Justin Wong <jvwong@arista.com>
|
/azp run |
|
Azure Pipelines successfully started running 1 pipeline(s). |
Signed-off-by: Justin Wong <jvwong@arista.com>
|
/azp run |
|
Azure Pipelines successfully started running 1 pipeline(s). |
Signed-off-by: Justin Wong <jvwong@arista.com>
|
/azp run |
|
Azure Pipelines successfully started running 1 pipeline(s). |
Signed-off-by: Justin Wong <jvwong@arista.com>
|
/azp run |
|
Azure Pipelines successfully started running 1 pipeline(s). |
|
/azp run |
|
Azure Pipelines successfully started running 1 pipeline(s). |
|
Hi, there are workflow run(s) waiting for approval, you may be first-time contributor. I will notify maintainers to help approve once PR is approved. Thanks! ---Powered by SONiC BuildBot
|
|
/azp run |
|
Azure Pipelines successfully started running 1 pipeline(s). |
|
Note: I am aware of the cherry-pick conflict to 202511. I have a local branch that addresses this conflict ready and will make a direct backport when this PR is approved. |
| flexCounter->removeCounter(testPortSerdesOid); | ||
| } | ||
|
|
||
| TEST_F(TestPortPhySerdesAttr, RetryOnObjectInUseThenSucceed) |
Signed-off-by: Justin Wong <jvwong@arista.com>
3ac7f55 to
a33c0e8
Compare
|
/azp run |
|
Azure Pipelines successfully started running 1 pipeline(s). |
|
@justin-wong-ce - are these failure logs only seen on a specific platform? |
I do not have access to other platforms - I can only test on Broadcom. I cannot say for sure if it happens on other platforms so I only noted |
|
/azp run |
|
Azure Pipelines: Successfully started running 1 pipeline(s). |
23718ac to
8aa4ae9
Compare
|
/azp run |
|
Azure Pipelines: Successfully started running 1 pipeline(s). |
|
Restarting CI due to failure from: |
|
/azpw retry |
|
Retrying failed(or canceled) jobs... |
|
Retrying failed(or canceled) stages in build 1164893: ✅Stage Test:
|
|
hi @tjchadaga - do you mind to help check this PR? |
|
Hi — this PR is flagged for cherry-pick to the 202605 branch (
This helps us track readiness and ensures we don't cherry-pick untested changes. Thanks! Comment by @vaibhavhd via automated tooling |
|
This PR has backport request label(s) for branch(es): 202511,202605, but is missing required test information. Please make sure you tick the tested branch(es) in the Tested branch section and provide test evidence (e.g., 202511: <test result>) in the Test result section as well in your PR description. ---Powered by SONiC BuildBot
|
There was a problem hiding this comment.
Pull request overview
Mitigates a race during syncd Port PHY Serdes flex-counter initialization where immediate SAI get calls can fail with SAI_STATUS_OBJECT_IN_USE, leaving syncd in a degraded state that later causes continuous polling errors.
Changes:
- Add retry-with-delay logic (10ms backoff) for key SAI
getoperations used to initialize Port PHY Serdes collection (port RID lookup, hardware lane count query, and tap/count attribute reads). - Add unit tests that validate both “eventual success after transient OBJECT_IN_USE” and “failure after retry exhaustion” behaviors.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.
| File | Description |
|---|---|
syncd/FlexCounter.cpp |
Adds OBJECT_IN_USE retry handling during Port PHY Serdes attribute initialization to avoid permanent bad state caused by transient SAI busy responses. |
unittest/syncd/TestPortPhySerdesAttr.cpp |
Adds tests covering retry success and exhaustion scenarios for the Port PHY Serdes initialization path. |
| * and results in a good syncd state such that RX_VGA entries appears in | ||
| * PORT_PHY_ATTR_TABLE after retries. |
| for (uint32_t tries = 1; tries <= 5; tries++) | ||
| { | ||
| port_rid = attr.value.oid; | ||
| return true; | ||
| } | ||
| sai_status_t status = Base::m_vendorSai->get(Base::m_objectType, port_serdes_rid, 1, &attr); |
There was a problem hiding this comment.
Forgot to update the description after applying changes from #1945 (comment)
| // SAI object is busy - retry in 10ms | ||
| SWSS_LOG_WARN("PORT_PHY_SERDES_ATTR: SAI object in use, retry getting port RID for port serdes RID:0x%" PRIx64 "...", | ||
| port_serdes_rid); | ||
| std::this_thread::sleep_for(chrono::milliseconds(10)); |
There was a problem hiding this comment.
@justin-wong-ce this is risky to sleep assuming we have say 256 ports which will result in 256 * 10 * 5 = 12.8 secs.
There was a problem hiding this comment.
The 2.5% chance is the probability of it happening to 1 port on a config-reload or reboot. Of course yes, there is the chance of it happening to all ports at the same time and I agree this is not an optimal solution.
|
|
||
| if (status == SAI_STATUS_SUCCESS) | ||
| break; | ||
| else if (status == SAI_STATUS_OBJECT_IN_USE && tries < 5) |
There was a problem hiding this comment.
@justin-wong-ce I think we need to understand who else is modifying the serdes object to keep it busy in BRCM SDK. Adding a busy retry only mitigates the problem to some extent but there could be other race condition in future where these retries may not be sufficient. Do you know how else is modifying the serdes object?
There was a problem hiding this comment.
To my knowledge, there is just not enough time between creating the object and reading from it.
There was a problem hiding this comment.
Port phy serdes objects are first created in intialization.
Then some time later, a reconfiguration can happen. This can be during intialization or during polling.
To apply the new config, the object has to be recreated.
There is a chance a poll will happen too quickly after the object is created.
There was a problem hiding this comment.
AFAIK, there is no mechanism to partially delay the polling only on the Port PHY Serdes objects, or on object creation. However, I am also not familiar with the orchagent code.
If there is a way to:
- stop polling on certain objects when destroy object
- when an object isc reated, check the object is ready for polling before turning on polling
^then we should use this approach, this will be the ideal fix.
Description of PR
Summary:
Mitigate a race condition in Port PHY Serdes initialization (
syncd) where the SAI is still busy with the object from its creation whensyncd's intialization attempts to read attributes from the object for syncd's own setup.This race condition will cause a failing SAI call that is needed for initializing
syncd, causing polls to the Port PHY Serdes object to fail continuously later on. The chances of this happening is around ~2.5% perconfig reload/reboot.Do this by allowing 5 retries with 10ms wait intervals in between tries. The retry will only trigger when the failure reason is
SAI_STATUS_OBJECT_IN_USE.Fixes #1946
Type of change
Approach
What is the motivation for this PR?
Fix syslog ERRs that logs continuously when this scenario occurs.
Work item tracking
How did you do it?
Added multiple attempts for interacing with Port PHY Serdes object over SAI during setup.
How did you verify/test it?
Continuous syslog ERRs no longer occur. The retry logic can be seen working in the syslogs as well. The most retry attempts observed is 1.
Any platform specific information?
Broadcom.
Documentation