From c160b59c2089bcfff2e2ac35d0154ac5135f0b2e Mon Sep 17 00:00:00 2001 From: Ze Gan Date: Sun, 5 Oct 2025 11:28:38 +0000 Subject: [PATCH 1/2] Enhance stream telemetry Signed-off-by: Ze Gan --- doc/TAM/SAI-Proposal-TAM-stream-telemetry.md | 66 ++++++++++++ inc/saitam.h | 103 +++++++++++++++++++ inc/saitypes.h | 6 ++ 3 files changed, 175 insertions(+) diff --git a/doc/TAM/SAI-Proposal-TAM-stream-telemetry.md b/doc/TAM/SAI-Proposal-TAM-stream-telemetry.md index 8181c3b16..8d6a3fa1b 100644 --- a/doc/TAM/SAI-Proposal-TAM-stream-telemetry.md +++ b/doc/TAM/SAI-Proposal-TAM-stream-telemetry.md @@ -77,10 +77,12 @@ The existing telemetry solution relies on a process to proactively query stats a - The vendor SDK should support querying the minimal polling interval for each counter. - When reconfiguring any stream settings, whether it is the polling interval or the stats list, the existing stream will be interrupted and regenerated. - If any of monitored objects is deleted, the existing stream will be interrupted and regenerated. +- The collector is designed to handle single-cycle counter rollovers; however, vendors must ensure that the data does not roll over twice between two collection intervals. ### Phase 2 - Supports updating configuration without interrupting the telemetry stream +- Support stats of tam telemetry for debugging purpose ## Architecture Design @@ -971,6 +973,13 @@ typedef struct _sai_stat_st_capability_t */ uint64_t minimal_polling_interval; +/** + * @brief Maximal polling interval in nanoseconds + * + * If polling interval is more than this value, it will be unacceptable. + */ + uint64_t maximal_polling_interval; + } sai_stat_st_capability_t; typedef struct _sai_stat_st_capability_list_t @@ -1007,3 +1016,60 @@ sai_s32_list_t tel_type_mode[2] = {-1, -1}; sai_query_attribute_enum_values_capability(switch_id, SAI_OBJECT_TYPE_TAM_TEL_TYPE, SAI_TAM_TEL_TYPE_ATTR_MODE, tel_type_mode) ``` + +#### Stats for TAM telemetry + +```c++ + +/** + * @brief TAM telemetry counter IDs in sai_get_tam_telemetry_stats_ext() call + */ +typedef enum _sai_tam_telemetry_stat_t +{ + /** Tam telemetry stat range start */ + SAI_TAM_TELEMETRY_STAT_START, + + /** + * @brief Total number of telemetry records successfully ingested + * + * Indicates the cumulative count of telemetry messages received and accepted + * into the telemetry system. + * Unit: Count [uint64_t] + */ + SAI_TAM_TELEMETRY_STAT_INGESTED_RECORDS = SAI_TAM_TELEMETRY_STAT_START, + + /** + * @brief Number of telemetry records pending read or processing + * + * Represents current backlog or pending messages awaiting processing. + * This is a gauge-type value rather than a monotonically increasing counter. + * Unit: Count [uint64_t] + */ + SAI_TAM_TELEMETRY_STAT_PENDING_READ_RECORDS, + + /** + * @brief Total number of telemetry records successfully consumed + * + * Indicates the cumulative count of telemetry records that have been processed + * by the consumer. + * Unit: Count [uint64_t] + */ + SAI_TAM_TELEMETRY_STAT_CONSUMED_RECORDS, + + /** + * @brief Total number of telemetry records dropped + * + * Represents the cumulative number of telemetry messages discarded due to + * buffer overflow, timeout, or internal error. + * Unit: Count [uint64_t] + */ + SAI_TAM_TELEMETRY_STAT_DROPPED_RECORDS, + + /** Tam telemetry stat range end */ + SAI_TAM_TELEMETRY_STAT_END, + + SAI_TAM_TELEMETRY_STAT_CUSTOM_RANGE_BASE = 0x10000000, + +} sai_tam_telemetry_stat_t; + +``` diff --git a/inc/saitam.h b/inc/saitam.h index 651641886..d961cf036 100644 --- a/inc/saitam.h +++ b/inc/saitam.h @@ -1716,6 +1716,57 @@ typedef enum _sai_tam_telemetry_attr_t } sai_tam_telemetry_attr_t; +/** + * @brief TAM telemetry counter IDs in sai_get_tam_telemetry_stats_ext() call + */ +typedef enum _sai_tam_telemetry_stat_t +{ + /** Tam telemetry stat range start */ + SAI_TAM_TELEMETRY_STAT_START, + + /** + * @brief Total number of telemetry records successfully ingested + * + * Indicates the cumulative count of telemetry messages received and accepted + * into the telemetry system. + * Unit: Count [uint64_t] + */ + SAI_TAM_TELEMETRY_STAT_INGESTED_RECORDS = SAI_TAM_TELEMETRY_STAT_START, + + /** + * @brief Number of telemetry records pending read or processing + * + * Represents current backlog or pending messages awaiting processing. + * This is a gauge-type value rather than a monotonically increasing counter. + * Unit: Count [uint64_t] + */ + SAI_TAM_TELEMETRY_STAT_PENDING_READ_RECORDS, + + /** + * @brief Total number of telemetry records successfully consumed + * + * Indicates the cumulative count of telemetry records that have been processed + * by the consumer. + * Unit: Count [uint64_t] + */ + SAI_TAM_TELEMETRY_STAT_CONSUMED_RECORDS, + + /** + * @brief Total number of telemetry records dropped + * + * Represents the cumulative number of telemetry messages discarded due to + * buffer overflow, timeout, or internal error. + * Unit: Count [uint64_t] + */ + SAI_TAM_TELEMETRY_STAT_DROPPED_RECORDS, + + /** Tam telemetry stat range end */ + SAI_TAM_TELEMETRY_STAT_END, + + SAI_TAM_TELEMETRY_STAT_CUSTOM_RANGE_BASE = 0x10000000, + +} sai_tam_telemetry_stat_t; + /** * @brief Create and return a telemetry object * @@ -2593,6 +2644,54 @@ sai_status_t sai_tam_telemetry_get_data( _Inout_ sai_size_t *buffer_size, _Out_ void *buffer); +/** + * @brief Get TAM telemetry statistics counters. Deprecated for backward compatibility. + * + * @param[in] tam_telemetry_id TAM telemetry id + * @param[in] number_of_counters Number of counters in the array + * @param[in] counter_ids Specifies the array of counter ids + * @param[out] counters Array of resulting counter values. + * + * @return #SAI_STATUS_SUCCESS on success, failure status code on error + */ +typedef sai_status_t (*sai_get_tam_telemetry_stats_fn)( + _In_ sai_object_id_t tam_telemetry_id, + _In_ uint32_t number_of_counters, + _In_ const sai_stat_id_t *counter_ids, + _Out_ uint64_t *counters); + +/** + * @brief Get TAM telemetry statistics counters extended. + * + * @param[in] tam_telemetry_id TAM telemetry id + * @param[in] number_of_counters Number of counters in the array + * @param[in] counter_ids Specifies the array of counter ids + * @param[in] mode Statistics mode + * @param[out] counters Array of resulting counter values. + * + * @return #SAI_STATUS_SUCCESS on success, failure status code on error + */ +typedef sai_status_t (*sai_get_tam_telemetry_stats_ext_fn)( + _In_ sai_object_id_t tam_telemetry_id, + _In_ uint32_t number_of_counters, + _In_ const sai_stat_id_t *counter_ids, + _In_ sai_stats_mode_t mode, + _Out_ uint64_t *counters); + +/** + * @brief Clear tam_telemetry statistics counters. + * + * @param[in] tam_telemetry_id TAM telemetry id + * @param[in] number_of_counters Number of counters in the array + * @param[in] counter_ids Specifies the array of counter ids + * + * @return #SAI_STATUS_SUCCESS on success, failure status code on error + */ +typedef sai_status_t (*sai_clear_tam_telemetry_stats_fn)( + _In_ sai_object_id_t tam_telemetry_id, + _In_ uint32_t number_of_counters, + _In_ const sai_stat_id_t *counter_ids); + /** * @brief SAI TAM API set */ @@ -2662,6 +2761,10 @@ typedef struct _sai_tam_api_t sai_get_tam_counter_subscription_attribute_fn get_tam_counter_subscription_attribute; sai_bulk_object_create_fn create_tam_counter_subscriptions; sai_bulk_object_remove_fn remove_tam_counter_subscriptions; + + sai_get_tam_telemetry_stats_fn get_tam_telemetry_stats; + sai_get_tam_telemetry_stats_ext_fn get_tam_telemetry_stats_ext; + sai_clear_tam_telemetry_stats_fn clear_tam_telemetry_stats; } sai_tam_api_t; /** diff --git a/inc/saitypes.h b/inc/saitypes.h index 530d984cc..aa9141458 100644 --- a/inc/saitypes.h +++ b/inc/saitypes.h @@ -1992,6 +1992,12 @@ typedef struct _sai_stat_st_capability_t */ uint64_t minimal_polling_interval; + /** + * @brief Maximal polling interval in nanoseconds + * + * If polling interval is more than this value, it will be unacceptable. + */ + uint64_t maximal_polling_interval; } sai_stat_st_capability_t; typedef struct _sai_stat_st_capability_list_t From a07f7b21783ac5a1a1076db87d19438c16a8d5af Mon Sep 17 00:00:00 2001 From: Ze Gan Date: Mon, 9 Mar 2026 07:22:13 +0000 Subject: [PATCH 2/2] Add sai_stat_st_capability_t to extensible struct allowlist Refactor hardcoded struct exceptions in meta/structs.pl and meta/test.pm into a maintainable extensible struct allowlist. Add sai_stat_st_capability_t to allow appending new members (e.g. maximal_polling_interval) without failing metadata CI checks. Signed-off-by: Ze Gan --- meta/structs.pl | 17 +++++++++++++---- meta/test.pm | 9 ++++++++- 2 files changed, 21 insertions(+), 5 deletions(-) diff --git a/meta/structs.pl b/meta/structs.pl index d8e05bdb2..44077de8d 100755 --- a/meta/structs.pl +++ b/meta/structs.pl @@ -164,18 +164,27 @@ sub BuildCommitHistory # of union may not increase by adding members, and actual union size # check is performed by sai sanity check + # Structs that are allowed to append new members at the end (ABI extension). + # api_t structs are always allowed. Add other structs here as needed. + my @extensible_structs = ( + "sai_switch_health_data_t", + "sai_port_oper_status_notification_t", + "sai_stat_st_capability_t", + ); + + my %extensible = map { $_ => 1 } @extensible_structs; + if ($currCount != $histCount and not $structTypeName =~ /^sai_\w+_api_t$/ - and $structTypeName ne "sai_switch_health_data_t" - and $structTypeName ne "sai_port_oper_status_notification_t") + and not $extensible{$structTypeName}) { LogError "FATAL: struct $structTypeName member count differs, was $histCount but is $currCount on commit $commit" if $type eq "struct"; } if ($histCount > $currCount) { - if ($structTypeName eq "sai_port_oper_status_notification_t") + if ($extensible{$structTypeName}) { - # we allow this to change back backward compatibility + # we allow extensible structs to change for backward compatibility } else { diff --git a/meta/test.pm b/meta/test.pm index 8d0937c0f..c7f34475b 100644 --- a/meta/test.pm +++ b/meta/test.pm @@ -646,7 +646,14 @@ sub CreateStructUnionSizeCheckTest $STRUCTS{$name} = $name; next if $name =~ /^sai_\w+_api_t$/; # skip api structs - next if $name eq "sai_switch_health_data_t"; + + # Skip extensible structs that are allowed to grow (see also structs.pl) + my %extensible_structs = map { $_ => 1 } ( + "sai_switch_health_data_t", + "sai_port_oper_status_notification_t", + "sai_stat_st_capability_t", + ); + next if $extensible_structs{$name}; my $upname = uc($name);