You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
sonic-sairedis #1774 (Smart Counter Poll) does O(ports) per-port getStats at counter init, starving orchagent and crashing it on high port-count switches #28460
Generic — affects any switch with a high number of ports. Root cause is in the vendor-agnostic syncd FlexCounter counter-initialization code.
Importance or Severity
High — orchagent aborts during initialization; ports are never programmed and all interfaces stay oper-down (no data plane). Reproducible on every boot / config reload.
Description of the bug
sonic-sairedis PR #1774 ("Smart Counter Poll to allow counters to work properly on Broadcom platforms") changed FlexCounter counter initialization from "assume all ports support the same counters" to per-port capability discovery:
Runs a capability check (queryStatsCapability) to get the set of counters the object type supports — this is cheap and done once.
Then, for every port, issues individual getStats calls to empirically determine which of those counters that specific port actually supports (a getStats of the candidate counter set per port, and per-counter getStats in the fallback). Ports are then bucketed into "counter groups" by what they support.
Why it breaks on high port-count switches:
The per-port getStats step turns counter init into an O(number-of-ports) loop of live hardware reads.
A single getStats call costs on the order of ~136 ms, and on a 512-port switch that is 512 such calls ≈ ~70 seconds just to discover per-port capability.
While this loop runs, syncd holds vendor SAI/SDK access serialized. orchagent's concurrent synchronous SAI calls (e.g. the sai_query_stats_capability it issues during counter setup) cannot be serviced — they starve behind the discovery loop.
Those synchronous calls hit the 60 s getresponse timeout, which desynchronizes the request/response channel; orchagent then throws an uncaught exception and aborts (SIGABRT) in its FLEX_COUNTER_TABLE drain. Ports are never programmed.
Note this is the best case (uniform ports, one getStats per port); heterogeneous ports fall back to per-counter probing and are even more expensive.
Confirmed on a 512-port switch (instrumented syncd/orchagent): the entire per-port discovery runs inside a singlesyncd event. syncd processes its request queue with one thread, in order, so that one event holds the queue at the head for ~74 s (elapsed_ms=74220, 514 ports) and blocks everything behind it. orchagent's next synchronous call therefore waits past its 60 sgetresponse timeout → gets 0 values → aborts:
discovery START t=0
orchagent TIMEOUT t=+60.06 s (60 s sync-op timeout)
discovery DONE t=+74.2 s
orchagent -> 0 values -> std::runtime_error -> SIGABRT (FLEX_COUNTER_TABLE drain)
The failure condition is simply ports × per-port getStats > 60 s, so it is not platform specific: invisible at low port counts, hit by any platform carrying #1774 once the count is high enough (empirically > ~256 ports).
Watch syncd counter init and orchagent in the logs, and show interface status.
Actual Behavior and Expected Behavior
Actual: During counter init, syncd spends tens of seconds in the per-port getStats discovery loop; orchagent's synchronous SAI call times out at 60 s, and orchagent aborts (exception in the FLEX_COUNTER_TABLE drain) and hangs. All interfaces remain oper-down.
Expected: Counter init completes within the SAI response-timeout window; orchagent stays up and programs ports; interfaces come up.
Relevant log output
# orchagent - synchronous SAI call to syncd times out during counter init, then aborts
ERR swss#orchagent: wait: SELECT operation result: TIMEOUT on getresponse
ERR swss#orchagent: waitForGetResponse: logic error, get response returned 0 values!
ERR swss#orchagent: drain: Exception caught: table=FLEX_COUNTER_TABLE, error=...0 values!
swss#orchagent: terminate called after throwing an instance of 'std::runtime_error' # SIGABRT
# syncd - per-port counter-init discovery: one getStats per port, ~136 ms each, ~512 ports
# bulkAdd START group=PORT nports=512
# ... 512 x [ per-port getStats, ~136 ms each ] ...
# grouping DONE group=PORT nports=512 elapsed_ms=~70000
Output of show version, show techsupport
Image includes sonic-sairedis #1774. show techsupport available on request / to be attached.
Attach files (if any)
(attach generate_dump techsupport with the orchagent core + syncd/swss logs)
Is it platform specific
Generic — affects any switch with a high number of ports. Root cause is in the vendor-agnostic
syncdFlexCounter counter-initialization code.Importance or Severity
High —
orchagentaborts during initialization; ports are never programmed and all interfaces stayoper-down(no data plane). Reproducible on every boot /config reload.Description of the bug
sonic-sairedis PR #1774 ("Smart Counter Poll to allow counters to work properly on Broadcom platforms") changed FlexCounter counter initialization from "assume all ports support the same counters" to per-port capability discovery:
What the change does at counter init (in
syncd):queryStatsCapability) to get the set of counters the object type supports — this is cheap and done once.getStatscalls to empirically determine which of those counters that specific port actually supports (agetStatsof the candidate counter set per port, and per-countergetStatsin the fallback). Ports are then bucketed into "counter groups" by what they support.Why it breaks on high port-count switches:
getStatsstep turns counter init into an O(number-of-ports) loop of live hardware reads.getStatscall costs on the order of ~136 ms, and on a 512-port switch that is 512 such calls ≈ ~70 seconds just to discover per-port capability.syncdholds vendor SAI/SDK access serialized.orchagent's concurrent synchronous SAI calls (e.g. thesai_query_stats_capabilityit issues during counter setup) cannot be serviced — they starve behind the discovery loop.getresponsetimeout, which desynchronizes the request/response channel;orchagentthen throws an uncaught exception and aborts (SIGABRT) in itsFLEX_COUNTER_TABLEdrain. Ports are never programmed.Note this is the best case (uniform ports, one
getStatsper port); heterogeneous ports fall back to per-counter probing and are even more expensive.Confirmed on a 512-port switch (instrumented
syncd/orchagent): the entire per-port discovery runs inside a singlesyncdevent.syncdprocesses its request queue with one thread, in order, so that one event holds the queue at the head for ~74 s (elapsed_ms=74220, 514 ports) and blocks everything behind it.orchagent's next synchronous call therefore waits past its 60 sgetresponsetimeout → gets 0 values → aborts:The failure condition is simply
ports × per-port getStats > 60 s, so it is not platform specific: invisible at low port counts, hit by any platform carrying #1774 once the count is high enough (empirically > ~256 ports).Steps to Reproduce
sudo config reload -y) an image that includes sonic-sairedis [vs-test]: not forward routes with no-export community #1774, on a switch with a high port count.syncdcounter init andorchagentin the logs, andshow interface status.Actual Behavior and Expected Behavior
Actual: During counter init,
syncdspends tens of seconds in the per-portgetStatsdiscovery loop;orchagent's synchronous SAI call times out at 60 s, andorchagentaborts (exception in theFLEX_COUNTER_TABLEdrain) and hangs. All interfaces remainoper-down.Expected: Counter init completes within the SAI response-timeout window;
orchagentstays up and programs ports; interfaces come up.Relevant log output
Output of
show version,show techsupportImage includes sonic-sairedis #1774.
show techsupportavailable on request / to be attached.Attach files (if any)
(attach
generate_dumptechsupport with the orchagent core + syncd/swss logs)