Topics で読み物として読む
この HLD は実装詳細を含みます。機能の概念・設定・運用を読み物として読みたい場合は Topics 14 章: Platform / Port / Optics を参照。
裏取りステータス: code-verified
sonic-sairedis/syncd/FlexCounter.cpp master に querySupportedCounters() 実装と use_sai_stats_capa_query フラグ、sai_stat_capability_list_t を使った 2 段呼び出し(count 取得 → list 取り直し)パターン、SAI_STATUS_NOT_IMPLEMENTED フォールバックを確認。Port / Queue / PG / RIF / BufferPool で同パターン。HLD の改修は master 取り込み済み。
sai_query_stats_capability による Counter Capability 一括取得¶
概要¶
SONiC syncd の FlexCounter は、各オブジェクト(Port / Queue / Priority Group / RIF / Buffer Pool)について 「どの統計 ID が SAI でサポートされているか」を getStats() を 1 ID ずつ叩いて確認 していた。Port だけでも数十個の counter ID をループで試すため、起動・fast-reboot 時のオーバーヘッドが大きい1。
本機能は SAI に追加された sai_query_stats_capability() API を使って オブジェクトの全 counter capability を 1 コールで取得 するように FlexCounter を改修する。fast-reboot のような時間制約のあるパスで特に効果が大きい1。
動作仕様¶
既存実装¶
for (int id = SAI_PORT_STAT_IF_IN_OCTETS; id <= SAI_PORT_STAT_IF_OUT_FABRIC_DATA_UNITS; ++id) {
sai_port_stat_t counter = static_cast<sai_port_stat_t>(id);
sai_status_t status = m_vendorSai->getStats(SAI_OBJECT_TYPE_PORT, portRid, 1,
(sai_stat_id_t *)&counter, &value);
if (status != SAI_STATUS_SUCCESS) continue;
m_supportedPortCounters.insert(counter);
}
各 ID について実際に値を取得しに行き、SUCCESS なら supported とみなす。失敗ログも 1 ID ずつ出る1。
新実装(2 段呼び出し)¶
sai_query_stats_capability は標準的な「サイズ問い合わせ → 実取得」の 2 段パターンを取る1:
sai_stat_capability_list_t stats_capability {0, nullptr};
sai_status_t status = m_vendorSai->queryStatsCapability(portRid, SAI_OBJECT_TYPE_PORT, &stats_capability);
// status == BUFFER_OVERFLOW で count に必要要素数がセットされる
if (status == SAI_STATUS_BUFFER_OVERFLOW) {
std::vector<sai_stat_capability_t> statCapabilityList(stats_capability.count);
stats_capability.list = statCapabilityList.data();
status = m_vendorSai->queryStatsCapability(portRid, SAI_OBJECT_TYPE_PORT, &stats_capability);
if (status == SAI_STATUS_SUCCESS) {
for (auto& cap : statCapabilityList)
m_supportedPortCounters.insert(static_cast<sai_port_stat_t>(cap.stat_enum));
}
}
ベンダ SAI が SAI_STATUS_NOT_IMPLEMENTED を返した場合は 既存の per-ID 取得方式にフォールバック する。これにより SAI 未対応ベンダでも互換性を維持する1。
SAI ヘッダ定義¶
/**
* @brief Query statistics capability for statistics bound at object level
*
* @param[in] switch_id SAI Switch object id
* @param[in] object_type SAI object type
* @param[inout] stats_capability List of implemented enum values, and the statistics modes (bit mask) supported per value
*
* @return #SAI_STATUS_SUCCESS on success, #SAI_STATUS_BUFFER_OVERFLOW if lists size insufficient,
* failure status code on error
*/
sai_status_t sai_query_stats_capability(
_In_ sai_object_id_t switch_id,
_In_ sai_object_type_t object_type,
_Inout_ sai_stat_capability_list_t *stats_capability);
各エントリ sai_stat_capability_t は stat_enum(counter ID)と stats mode のビットマスク(READ / READ_AND_CLEAR 等)を持つ1。
改修対象関数¶
syncd の FlexCounter.cpp で次の関数が新 API を使うよう書き換わる1:
| 関数 | 対象 |
|---|---|
updateSupportedPortCounters(portRid) |
Port |
updateSupportedQueueCounters(queueRid, counterIds) |
Queue |
updateSupportedPriorityGroupCounters(priorityGroupRid, counterIds) |
PG |
updateSupportedRifCounters(rifRid) |
RIF |
updateSupportedBufferPoolCounters(bufferPoolRid, counterIds, statsMode) |
Buffer Pool |
📋 検証エビデンス: sonic-net/SONiC/doc/Query_Stats_Capability/Query_Stats_Capability_HLD.md#L20-L30 (sha: 49bab5b5ff0e924f1ea52b3d9db0dfa4191a7c06)
出典:
sonic-net/SONiC/doc/Query_Stats_Capability/Query_Stats_Capability_HLD.md#L20-L30 (sha: 49bab5b5ff0e924f1ea52b3d9db0dfa4191a7c06)
抜粋:
The affected functions with this new API will take place on FlexCounter.cpp:
- void updateSupportedPortCounters(_In_ sai_object_id_t portRid)
- void updateSupportedQueueCounters(...)
...
The implementation will support backwards compatibility, so if a SAI vendor is currently not supporting this API it will fall back to the legacy approach.
判断根拠: 改修対象関数とフォールバック動作の根拠。
設定¶
関連する CONFIG_DB / CLI / YANG¶
外部設定表面は無い。SAI capability の検出方式が変わるだけで、ユーザに見える挙動は「起動時間が短くなる」のみ。
関連する SAI 属性¶
該当なし(API そのものの追加)。sai_stat_capability_t.stat_enum と stats_modes ビットマスクが個別 counter の能力情報を返す。
制限事項¶
- SAI ベンダ実装依存: 新 API を実装するか、
SAI_STATUS_NOT_IMPLEMENTEDを返すかのいずれかが要求される1。誤った status を返すベンダではフォールバックが働かない可能性。 - 互換のためのコードパス二重化: 旧 per-ID ループ実装も残す必要があり、メンテナンスコストは増える。
- mode 情報の扱い: 新 API は stats mode のビットマスクも返すが、SONiC
FlexCounter側でどこまで活用するかは HLD では明記されていない(counter 集合判定のみ言及)1。
干渉する機能¶
- Fast-reboot / Warm-reboot: 起動経路で counter capability 検出を含むため、本改修は時間制約のある reboot シーケンスで特に意味がある1。
FlexCounter/FlexCounterManager: 統計収集の中核。同 cpp 内の他関数と連動するため、メンバ変数m_supportedPortCounters等の読み出し側もそのまま使える設計。- 個別 vendor SAI: 実装状況がバラつくと本機能の有効性も差が出る。
SAI_STATUS_NOT_IMPLEMENTEDを正しく返さないベンダはエラー扱いされる可能性。
トラブルシューティング¶
- 起動が依然遅い: vendor SAI が新 API を実装していない可能性。
syncdログでqueryStatsCapabilityの status を確認。SAI_STATUS_NOT_IMPLEMENTEDならフォールバック動作中。 - 一部 counter が認識されない: 新 API が返す
stat_enum集合と旧 per-ID 列挙の差が無いか、SAI バージョン依存を疑う。
コマンド例¶
SAI stats capability を確認する。
# SAI stats
docker exec syncd saidump 2>&1 | head -40
redis-cli -n 1 keys 'COUNTERS_*' | head
counterpoll show