[clear] Add 'sonic-clear pfcwdstats' to clear PFC watchdog counters#4634
[clear] Add 'sonic-clear pfcwdstats' to clear PFC watchdog counters#4634pinky-nexthop wants to merge 1 commit into
Conversation
There is currently no CLI to clear PFC watchdog statistics. Clearing them is needed when troubleshooting PFC storms, where stale counts from a prior event make it hard to tell whether a storm is ongoing. This adds: - scripts/pfcwdstat: a new tool that zeroes the PFC_WD_QUEUE_STATS_* fields in COUNTERS_DB, following the standard counter-clear pattern (pfcstat -c, queuestat -c, ...). It enumerates queues via COUNTERS_QUEUE_NAME_MAP -- the same source 'show pfcwd stats' uses -- so stale stats from queues that are no longer actively monitored (STATUS=N/A) are also cleared. - Queues with an active storm (PFC_WD_STATUS == 'stormed') are skipped, so the in-flight DEADLOCK_DETECTED/RESTORED pair is not split (which would otherwise leave RESTORED > DETECTED once the storm ends). - clear/main.py: 'sonic-clear pfcwdstats', invoking 'pfcwdstat -c'. - setup.py: install scripts/pfcwdstat. - tests for the clear command and the pfcwdstat clear logic. Signed-off-by: Pinky Agrawal <pinky@nexthop.ai>
|
/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
|
|
This PR has backport request for branch(es): 202605. ---Powered by SONiC BuildBot
|
|
|
||
| Queues with an active storm (PFC_WD_STATUS == 'stormed') are skipped. | ||
| """ | ||
| db = SonicV2Connector() |
There was a problem hiding this comment.
sonicV2connector() handles only global namespace and does not work in multi asic. Please add support for multi-asic also
| db = SonicV2Connector() | ||
| db.connect(db.COUNTERS_DB) | ||
|
|
||
| queue_name_map = db.get_all(db.COUNTERS_DB, 'COUNTERS_QUEUE_NAME_MAP') |
There was a problem hiding this comment.
Usually all the clear commands take the snapshot of the stats from COUNTER_DB and saves it in /tmp/cache . Then show commands shows the diff between stats COUNTER_DB and /tmp/cache. Why are you clearing it from COUNTER_DB. Is this the requirement?
|
|
||
| @cli.command() | ||
| def pfcwdstats(): | ||
| """Clear PFC Watchdog stats counters""" |
There was a problem hiding this comment.
Please update doc/Command-Reference.md
| skipped.append(queue_name) | ||
| continue | ||
| for field in PFC_WD_STATS_FIELDS: | ||
| db.set(db.COUNTERS_DB, counter_key, field, '0') |
There was a problem hiding this comment.
Even if you have to clear from COUNTERS_DB, can't you use hmset and clear all stats at once instead of clearing 1 by 1
vmittal-msft
left a comment
There was a problem hiding this comment.
Thanks for the PR! I reviewed the change end-to-end against the current sources. It works on a single-ASIC box, but two items I'd treat as blocking:
- No multi-ASIC / chassis support —
SonicV2Connector()only touches the global DB, so nothing is cleared on multi-ASIC whileshow pfcwd statsstill shows counts. - Destructive
COUNTERS_DBmutation — every sibling clear command uses the non-destructiveUserCachesnapshot+diff pattern instead of writing into the shared counters DB.
Plus a doc/Command-Reference.md update. Details inline — these corroborate and extend @saksarav-nokia's review. Nice touch skipping actively-stormed queues to keep the DEADLOCK_DETECTED/RESTORED pair intact.
|
|
||
| Queues with an active storm (PFC_WD_STATUS == 'stormed') are skipped. | ||
| """ | ||
| db = SonicV2Connector() |
There was a problem hiding this comment.
Multi-ASIC: this won't clear anything on a multi-ASIC/VOQ chassis (+1 to @saksarav-nokia, confirming it's a functional gap, not style).
SonicV2Connector() with no namespace binds only to the global DB. But the reader show pfcwd stats (pfcwd/main.py) walks each ASIC via the @multi_asic_util.run_on_multi_asic decorator, and the sibling clear tools (pfcstat, queuestat) and even pg-drop -c clear all iterate multi_asic.get_namespace_list().
So on a multi-ASIC box, COUNTERS_QUEUE_NAME_MAP in the global DB is empty → this prints No PFC Watchdog stats found. and clears nothing, while show pfcwd stats still shows per-ASIC counts. Please wrap clear_stats() in a namespace loop (MultiAsic / run_on_multi_asic) or add -n/--namespace like pg-drop.
| skipped.append(queue_name) | ||
| continue | ||
| for field in PFC_WD_STATS_FIELDS: | ||
| db.set(db.COUNTERS_DB, counter_key, field, '0') |
There was a problem hiding this comment.
Directly zeroing COUNTERS_DB diverges from the standard clear pattern (this is the crux of @saksarav-nokia's question).
Every other stats-clear in this repo is non-destructive: pfcstat -c, queuestat -c, portstat -c, and pg-drop -c clear snapshot COUNTERS_DB into UserCache (/tmp/...) and the show command renders current - cached. They never mutate COUNTERS_DB.
Writing '0' straight into the shared COUNTERS_DB is a different contract: any other consumer of these counters (telemetry / gNMI streaming, rate calculators) will observe a reset / negative delta, and the clear is global + irreversible rather than per-user. It only works here because you skip stormed queues (no active producer to overwrite the zeros).
Preferred: the cache+diff approach (which also means teaching show pfcwd stats to subtract the baseline). If a hard reset is genuinely required, please call that out and justify it in the PR description.
Minor (also @saksarav-nokia): if you keep the DB write, one hmset/pipeline per queue avoids the per-field round-trips.
| """ | ||
|
|
||
| import argparse | ||
| import sys |
There was a problem hiding this comment.
Nit: sys is imported but unused (F401). Also clear_stats (L27), main (L69), and the __main__ guard (L82) are separated by a single blank line — PEP8 wants two (E302/E305).
Heads-up: the repo's pre-commit runs flake8==4.0.1 in --diff mode, which does not flag these on a brand-new file (I reproduced it locally — that's why the Static Analysis check is green), so they'll silently slip through unless cleaned up by hand.
|
|
||
|
|
||
| @cli.command() | ||
| def pfcwdstats(): |
There was a problem hiding this comment.
+1 to @saksarav-nokia on docs. Please add sonic-clear pfcwdstats to doc/Command-Reference.md — there's already a show pfcwd stats section and a NOTE: PFC counters ... sonic-clear pfccounters blurb, so a parallel note under the PFC watchdog section keeps the new command discoverable.
| importlib.reload(pfcwd.main) | ||
|
|
||
|
|
||
| class TestPfcwdstatClear(object): |
There was a problem hiding this comment.
These tests fully mock SonicV2Connector, so they pass regardless of the multi-ASIC gap flagged in scripts/pfcwdstat — a single mocked DB hides the fact that only the global namespace is cleared.
Once namespace handling is added, please add a multi-ASIC case (e.g. UTILITIES_UNIT_TESTING_TOPOLOGY=multi_asic with per-namespace mock DBs) asserting each namespace's counters are cleared. Tests for the -c arg path in main() and for the Skipped queue(s) ... / No PFC Watchdog stats found. output would also lock in the behavior.
What I did
There is currently no CLI to clear PFC watchdog statistics. Clearing them is needed when troubleshooting PFC storms — stale counts from a prior event make it hard to tell whether a storm is currently ongoing.
show pfcwd statsdisplays the counters, but there is no corresponding clear command. This PR addssonic-clear pfcwdstats.Addresses the PFC-watchdog-counter-clear item in #4595.
How I did it
scripts/pfcwdstat: new tool that zeroes thePFC_WD_QUEUE_STATS_*fields inCOUNTERS_DB, following the standard counter-clear pattern (pfcstat -c,queuestat -c, …). It enumerates queues viaCOUNTERS_QUEUE_NAME_MAP— the same sourceshow pfcwd statsuses — so stale stats from queues that are no longer actively monitored (STATUS=N/A) are also cleared.PFC_WD_STATUS == 'stormed') are skipped, so the in-flightDEADLOCK_DETECTED/DEADLOCK_RESTOREDpair is not split (which would otherwise leaveRESTORED > DETECTEDonce the storm ends).clear/main.py: addssonic-clear pfcwdstats, invokingpfcwdstat -c.setup.py: installsscripts/pfcwdstat.pfcwdstatclear logic (including the stale-stats and active-storm cases).How to verify it
Manually:
show pfcwd statsto see counts,sonic-clear pfcwdstatsto clear them; an actively storming queue is left untouched (and reported as skipped) until the storm ends.Previous command output (if the output of a command-line utility has changed)
New command output (if the output of a command-line utility has changed)
Which release branch to backport (provide reason below if selected)