From 6f0550e883b0a713ac496eb77bc8fad809c8183f Mon Sep 17 00:00:00 2001 From: Jason Bos Date: Mon, 18 Dec 2023 08:55:57 -0800 Subject: [PATCH] [TAM] Granular counter subscription (#1670) * [TAM] Granular Counter Subscription Enhancements to TAM API to enable a high-speed polling feature to repeatedly poll one or a few counters at short time intervals. A new telemetry type for granular counter subscription to request specific counters at runtime. Introduce SAI_TAM_COUNTER_SUBSCRIPTION object to represent subscribed counters and allow the user to associate a label for the counter in telemetry reports. Add a time units configuration to specify units for the report interval. Default is backwards-compatible to the current units (microseconds). --------- Signed-off-by: Jason Bos --- doc/TAM/Granular-Counter-Subscription.md | 208 +++++++++++++++++ inc/saitam.h | 278 ++++++++++++++++++----- inc/saitypes.h | 1 + 3 files changed, 431 insertions(+), 56 deletions(-) create mode 100644 doc/TAM/Granular-Counter-Subscription.md diff --git a/doc/TAM/Granular-Counter-Subscription.md b/doc/TAM/Granular-Counter-Subscription.md new file mode 100644 index 000000000..6ed7042b6 --- /dev/null +++ b/doc/TAM/Granular-Counter-Subscription.md @@ -0,0 +1,208 @@ +# Telemetry Granular Counter Subscription +------------------------------------------------------------------------------- + Title | Telemetry Granular Counter Subscription +-------------|----------------------------------------------------------------- + Authors | Jason Bos, Cisco + Status | In review + Type | Standards track + Created | 2023-01-11 - Initial Draft + SAI-Version | 1.12 +------------------------------------------------------------------------------- + + +## 1.0 Introduction + +This spec enhances the existing TAM (Telemetry and Monitoring) spec to add granular counter subscription. + +The TAM API allows for predefined telemetry groups, like SAI_TAM_TELEMETRY_TYPE_SWITCH or SAI_TAM_TELEMETRY_TYPE_PORT. This provides extensibility to the API only to define new fixed collections. When collecting counters, all supported counters for the relevant objects are reported. + +However, the user may wish to enable telemetry for a more limited set of counters, selected at runtime. For example, a user may wish to receive only port byte counters, or queue watermarks. Limiting the scope of the telemetry collection permits a device to generate counters samples faster than possible when all counters are collected, and fit many more samples into each network packet, allowing a higher rate of delivery. + +In this mode, the collector may require a meaningful identifier for a counter, which identifies both the object as well as the specific counter on the object. +Depending on the report type, this may be carried directly in the report itself. Or it may be delivered separately, for example as an enterprise-specific +information element ID in an IPFIX template set. + +## 2.0 Configuration + +The subscription is represented by an object of SAI_TAM_COUNTER_SUBSCRIPTION. The creation of this object will indicate that a specific counter should be monitored. + +```c +typedef enum _sai_tam_counter_subscription_attr_t +{ + /** + * @brief Start of Attributes + */ + SAI_TAM_COUNTER_SUBSCRIPTION_ATTR_START, + + /** + * @brief TAM telemetry type object + * + * @type sai_object_id_t + * @flags MANDATORY_ON_CREATE | CREATE_ONLY + * @objects SAI_OBJECT_TYPE_TAM + */ + SAI_TAM_COUNTER_SUBSCRIPTION_ATTR_TEL_TYPE = SAI_TAM_COUNTER_SUBSCRIPTION_ATTR_START, + + /** + * @brief Subscribed object + * + * @type sai_object_id_t + * @flags MANDATORY_ON_CREATE | CREATE_ONLY + */ + SAI_TAM_COUNTER_SUBSCRIPTION_ATTR_OBJECT_ID, + + /** + * @brief Subscribed stat enum + * + * @type sai_uint32_t + * @flags MANDATORY_ON_CREATE | CREATE_ONLY + */ + SAI_TAM_COUNTER_SUBSCRIPTION_ATTR_STAT_ID, + + /** + * @brief Telemetry label + * + * Label to identify the subscribed counter in telemetry reports. + * + * @type sai_uint64_t + * @flags CREATE_ONLY + * @default 0 + */ + SAI_TAM_COUNTER_SUBSCRIPTION_ATTR_LABEL, +``` + +The attribute SAI_TAM_COUNTER_SUBSCRIPTION_ATTR_LABEL configures the application counter ID. + + +## 3 Configuration example + +```c + +// Example: Create a bulk report object +sai_attr_list[0].id = SAI_TAM_REPORT_ATTR_TYPE; +sai_attr_list[0].value.s32 = SAI_TAM_REPORT_TYPE_PROTO; + +sai_attr_list[1].id = SAI_TAM_REPORT_ATTR_REPORT_MODE; +sai_attr_list[1].value.s32 = SAI_TAM_REPORT_MODE_BULK; + +attr_count = 2; + +sai_create_tam_report_fn( + &sai_tam_report_obj, + switch_id, + attr_count, + sai_attr_list); + +// Example: Create telemetry type object to collect object stats +sai_attr_list[0].id = SAI_TAM_TEL_TYPE_ATTR_TAM_TELEMETRY_TYPE; +sai_attr_list[0].value.u32 = SAI_TAM_TELEMETRY_TYPE_OBJECT_STAT; + +sai_attr_list[1].id = SAI_TAM_TEL_TYPE_ATTR_REPORT_ID; +sai_attr_list[1].value.oid = sai_tam_report_obj; + +attr_count = 2; +sai_create_tam_tel_type_fn( + &sai_tam_tel_type_obj, + switch_id, + attr_count, + sai_attr_list); + +// Example: Create counter subscription(s) to collect queue length and watermark +sai_attr_list[0].id = SAI_TAM_COUNTER_SUBSCRIPTION_ATTR_TEL_TYPE; +sai_attr_list[0].value.u32 = sai_tam_tel_type_obj; + +sai_attr_list[1].id = SAI_TAM_COUNTER_SUBSCRIPTION_ATTR_OBJECT_ID; +sai_attr_list[1].value.oid = sai_queue_obj; + +sai_attr_list[2].id = SAI_TAM_COUNTER_SUBSCRIPTION_ATTR_STAT_ID; +sai_attr_list[2].value.u32 = SAI_QUEUE_STAT_CURR_OCCUPANCY_BYTES; + +sai_attr_list[3].id = SAI_TAM_COUNTER_SUBSCRIPTION_ATTR_LABEL; +sai_attr_list[3].value.u64 = 1; + +attr_count = 4; +sai_create_tam_counter_subscription_fn( + &sai_tam_subscription_obj1, + switch_id, + attr_count, + sai_attr_list); + +sai_attr_list[0].id = SAI_TAM_COUNTER_SUBSCRIPTION_ATTR_TEL_TYPE; +sai_attr_list[0].value.u32 = sai_tam_tel_type_obj; + +sai_attr_list[1].id = SAI_TAM_COUNTER_SUBSCRIPTION_ATTR_OBJECT_ID; +sai_attr_list[1].value.oid = sai_queue_obj; + +sai_attr_list[2].id = SAI_TAM_COUNTER_SUBSCRIPTION_ATTR_STAT_ID; +sai_attr_list[2].value.u32 = SAI_QUEUE_STAT_WATERMARK_BYTES; + +sai_attr_list[3].id = SAI_TAM_COUNTER_SUBSCRIPTION_ATTR_LABEL; +sai_attr_list[3].value.u64 = 2; + +attr_count = 4; +sai_create_tam_counter_subscription_fn( + &sai_tam_subscription_obj2, + switch_id, + attr_count, + sai_attr_list); + +// Example: Create Telemetry object +sai_attr_list[0].id = SAI_TAM_TELEMETRY_ATTR_TAM_TYPE_LIST; +sai_attr_list[0].value.objlist.count = 1 +sai_attr_list[0].value.objlist.list[0] = sai_tam_tel_type_obj; + +sai_attr_list[1].id = SAI_TAM_TELEMETRY_ATTR_COLLECTOR_LIST +sai_attr_list[1].value.objlist.count = 1; +sai_attr_list[1].value.objlist.list[0] = collector_obj; + +attr_count = 2; +sai_create_tam_telemetry_fn( + &sai_tam_telemetry_obj, + switch_id, + attr_count, + sai_attr_list); + +// Example: Create TAM object and bind to monitored objects: + +sai_attr_list[0].id = SAI_TAM_ATTR_TAM_TELEMETRY_OBJECTS_LIST; +sai_attr_list[0].value.objlist.count = 1; +sai_attr_list[0].value.objlist.list[0] = sai_tam_telemetry_obj; + +sai_attr_list[1].id = SAI_TAM_ATTR_TAM_BIND_POINT_TYPE_LIST; +sai_attr_list[1].value.objlist.count = 1; +sai_attr_list[1].value.objlist.list[0] = SAI_TAM_BIND_POINT_TYPE_SWITCH; + +attr_count = 2; +sai_create_tam_fn( + &sai_tam_obj, + switch_id, + attr_count, + sai_attr_list); + +// Example: Attach the TAM to the switch + +sai_attr.id = SAI_SWITCH_ATTR_TAM_OBJECT_ID; +sai_attr.value.oid = sai_tam_obj; + +sai_set_queue_attribute_fn( + sai_switch_obj, + sai_attr); +``` + +## 4 Example data export format + +Counter subscription is independent of a specific report format. The format of the report is determined by the report object. In case of protobuf report format, a potential data layout is below: + +``` +message CounterSample { + required uint64 timestamp = 1 [(telemetry_options).is_timestamp = true]; + repeated uint64 counter_values = 2; +} + +message CounterSampleList { + // Counter labels in the order the values will appear in each sample + repeated uint64 counter_labels = 1; + repeated CounterSample samples = 2; +} +``` + diff --git a/inc/saitam.h b/inc/saitam.h index 9ee868d94..d943a71c9 100644 --- a/inc/saitam.h +++ b/inc/saitam.h @@ -896,7 +896,15 @@ typedef enum _sai_tam_telemetry_type_t * @brief INT TAM * All the data relevant on a per packet basis */ - SAI_TAM_TELEMETRY_TYPE_INT + SAI_TAM_TELEMETRY_TYPE_INT, + + /** + * @brief Data based on counter subscriptions + * + * Collect statistics for specific counters, using + * SAI_TAM_COUNTER_SUBSCRIPTION objects + */ + SAI_TAM_TELEMETRY_TYPE_COUNTER_SUBSCRIPTION, } sai_tam_telemetry_type_t; @@ -1057,6 +1065,15 @@ typedef enum _sai_tam_tel_type_attr_t */ SAI_TAM_TEL_TYPE_ATTR_REPORT_ID, + /** + * @brief List of Tam counter subscription objects + * + * @type sai_object_list_t + * @flags READ_ONLY + * @objects SAI_OBJECT_TYPE_TAM_COUNTER_SUBSCRIPTION + */ + SAI_TAM_TEL_TYPE_ATTR_COUNTER_SUBSCRIPTION_LIST, + /** * @brief End of Attributes */ @@ -1180,6 +1197,28 @@ typedef enum _sai_tam_report_mode_t } sai_tam_report_mode_t; +/** + * @brief TAM report interval units + */ +typedef enum _sai_tam_report_interval_unit_t +{ + /** + * @brief Report interval unit nanosecond + */ + SAI_TAM_REPORT_INTERVAL_UNIT_NANOSEC, + + /** + * @brief Report interval unit microsecond + */ + SAI_TAM_REPORT_INTERVAL_UNIT_USEC, + + /** + * @brief Report interval unit millisecond + */ + SAI_TAM_REPORT_INTERVAL_UNIT_MSEC, + +} sai_tam_report_interval_unit_t; + /** * @brief Attributes for TAM report */ @@ -1244,7 +1283,7 @@ typedef enum _sai_tam_report_attr_t SAI_TAM_REPORT_ATTR_REPORT_MODE, /** - * @brief Report Interval in micro seconds + * @brief Report Interval * * @type sai_uint32_t * @flags CREATE_AND_SET @@ -1273,6 +1312,16 @@ typedef enum _sai_tam_report_attr_t */ SAI_TAM_REPORT_ATTR_TEMPLATE_REPORT_INTERVAL, + /** + * @brief Report Interval Units + * + * @type sai_tam_report_interval_unit_t + * @flags CREATE_AND_SET + * @default SAI_TAM_REPORT_INTERVAL_UNIT_USEC + * @validonly SAI_TAM_REPORT_ATTR_REPORT_MODE == SAI_TAM_REPORT_MODE_BULK + */ + SAI_TAM_REPORT_ATTR_REPORT_INTERVAL_UNIT, + /** * @brief End of Attributes */ @@ -2079,6 +2128,118 @@ typedef sai_status_t (*sai_set_tam_event_attribute_fn)( _In_ sai_object_id_t tam_event_id, _In_ const sai_attribute_t *attr); +/** + * @brief Counter Subscription attributes + */ +typedef enum _sai_tam_counter_subscription_attr_t +{ + /** + * @brief Start of Attributes + */ + SAI_TAM_COUNTER_SUBSCRIPTION_ATTR_START, + + /** + * @brief TAM telemetry type object + * + * @type sai_object_id_t + * @flags MANDATORY_ON_CREATE | CREATE_ONLY + * @objects SAI_OBJECT_TYPE_TAM_TEL_TYPE + */ + SAI_TAM_COUNTER_SUBSCRIPTION_ATTR_TEL_TYPE = SAI_TAM_COUNTER_SUBSCRIPTION_ATTR_START, + + /** + * @brief Subscribed object + * + * @type sai_object_id_t + * @flags MANDATORY_ON_CREATE | CREATE_ONLY + * @objects SAI_OBJECT_TYPE_BUFFER_POOL, SAI_OBJECT_TYPE_INGRESS_PRIORITY_GROUP, SAI_OBJECT_TYPE_PORT, SAI_OBJECT_TYPE_QUEUE + */ + SAI_TAM_COUNTER_SUBSCRIPTION_ATTR_OBJECT_ID, + + /** + * @brief Subscribed stat enum + * + * @type sai_uint32_t + * @flags MANDATORY_ON_CREATE | CREATE_ONLY + */ + SAI_TAM_COUNTER_SUBSCRIPTION_ATTR_STAT_ID, + + /** + * @brief Telemetry label + * + * Label to identify this counter in telemetry reports. + * + * @type sai_uint64_t + * @flags CREATE_ONLY + * @default 0 + */ + SAI_TAM_COUNTER_SUBSCRIPTION_ATTR_LABEL, + + /** + * @brief End of Attributes + */ + SAI_TAM_COUNTER_SUBSCRIPTION_ATTR_END, + + /** Custom range base value */ + SAI_TAM_COUNTER_SUBSCRIPTION_ATTR_CUSTOM_RANGE_START = 0x10000000, + + /** End of custom range base */ + SAI_TAM_COUNTER_SUBSCRIPTION_ATTR_CUSTOM_RANGE_END + +} sai_tam_counter_subscription_attr_t; + +/** + * @brief Create a counter subscription + * + * @param[out] tam_counter_subscription_id Counter subscription object Id + * @param[in] switch_id Switch object id + * @param[in] attr_count Number of attributes + * @param[in] attr_list Array of attributes + * + * @return #SAI_STATUS_SUCCESS on success, failure status code on error + */ +typedef sai_status_t (*sai_create_tam_counter_subscription_fn)( + _Out_ sai_object_id_t *tam_counter_subscription_id, + _In_ sai_object_id_t switch_id, + _In_ uint32_t attr_count, + _In_ const sai_attribute_t *attr_list); + +/** + * @brief Delete a specified counter subscription + * + * @param[in] tam_counter_subscription_id Counter Subscription object id + * + * @return #SAI_STATUS_SUCCESS on success, failure status code on error + */ +typedef sai_status_t (*sai_remove_tam_counter_subscription_fn)( + _In_ sai_object_id_t tam_counter_subscription_id); + +/** + * @brief Set value for a specified counter subscription object attribute + * + * @param[in] tam_counter_subscription_id Counter Subscription object id + * @param[in] attr Attribute + * + * @return #SAI_STATUS_SUCCESS on success, failure status code on error + */ +typedef sai_status_t (*sai_set_tam_counter_subscription_attribute_fn)( + _In_ sai_object_id_t tam_counter_subscription_id, + _In_ const sai_attribute_t *attr); + +/** + * @brief Get values for specified event object attributes + * + * @param[in] tam_counter_subscription_id Counter Subscription object id + * @param[in] attr_count Number of attributes + * @param[inout] attr_list Array of attributes + * + * @return #SAI_STATUS_SUCCESS on success, failure status code on error + */ +typedef sai_status_t (*sai_get_tam_counter_subscription_attribute_fn)( + _In_ sai_object_id_t tam_counter_subscription_id, + _In_ uint32_t attr_count, + _Inout_ sai_attribute_t *attr_list); + /** * @brief TAM event callback * @@ -2126,60 +2287,65 @@ typedef struct _sai_tam_api_t /** * @brief SAI TAM v1 API set */ - sai_create_tam_fn create_tam; - sai_remove_tam_fn remove_tam; - sai_set_tam_attribute_fn set_tam_attribute; - sai_get_tam_attribute_fn get_tam_attribute; - - sai_create_tam_math_func_fn create_tam_math_func; - sai_remove_tam_math_func_fn remove_tam_math_func; - sai_set_tam_math_func_attribute_fn set_tam_math_func_attribute; - sai_get_tam_math_func_attribute_fn get_tam_math_func_attribute; - - sai_create_tam_report_fn create_tam_report; - sai_remove_tam_report_fn remove_tam_report; - sai_set_tam_report_attribute_fn set_tam_report_attribute; - sai_get_tam_report_attribute_fn get_tam_report_attribute; - - sai_create_tam_event_threshold_fn create_tam_event_threshold; - sai_remove_tam_event_threshold_fn remove_tam_event_threshold; - sai_set_tam_event_threshold_attribute_fn set_tam_event_threshold_attribute; - sai_get_tam_event_threshold_attribute_fn get_tam_event_threshold_attribute; - - sai_create_tam_int_fn create_tam_int; - sai_remove_tam_int_fn remove_tam_int; - sai_set_tam_int_attribute_fn set_tam_int_attribute; - sai_get_tam_int_attribute_fn get_tam_int_attribute; - - sai_create_tam_tel_type_fn create_tam_tel_type; - sai_remove_tam_tel_type_fn remove_tam_tel_type; - sai_set_tam_tel_type_attribute_fn set_tam_tel_type_attribute; - sai_get_tam_tel_type_attribute_fn get_tam_tel_type_attribute; - - sai_create_tam_transport_fn create_tam_transport; - sai_remove_tam_transport_fn remove_tam_transport; - sai_set_tam_transport_attribute_fn set_tam_transport_attribute; - sai_get_tam_transport_attribute_fn get_tam_transport_attribute; - - sai_create_tam_telemetry_fn create_tam_telemetry; - sai_remove_tam_telemetry_fn remove_tam_telemetry; - sai_set_tam_telemetry_attribute_fn set_tam_telemetry_attribute; - sai_get_tam_telemetry_attribute_fn get_tam_telemetry_attribute; - - sai_create_tam_collector_fn create_tam_collector; - sai_remove_tam_collector_fn remove_tam_collector; - sai_set_tam_collector_attribute_fn set_tam_collector_attribute; - sai_get_tam_collector_attribute_fn get_tam_collector_attribute; - - sai_create_tam_event_action_fn create_tam_event_action; - sai_remove_tam_event_action_fn remove_tam_event_action; - sai_set_tam_event_action_attribute_fn set_tam_event_action_attribute; - sai_get_tam_event_action_attribute_fn get_tam_event_action_attribute; - - sai_create_tam_event_fn create_tam_event; - sai_remove_tam_event_fn remove_tam_event; - sai_set_tam_event_attribute_fn set_tam_event_attribute; - sai_get_tam_event_attribute_fn get_tam_event_attribute; + sai_create_tam_fn create_tam; + sai_remove_tam_fn remove_tam; + sai_set_tam_attribute_fn set_tam_attribute; + sai_get_tam_attribute_fn get_tam_attribute; + + sai_create_tam_math_func_fn create_tam_math_func; + sai_remove_tam_math_func_fn remove_tam_math_func; + sai_set_tam_math_func_attribute_fn set_tam_math_func_attribute; + sai_get_tam_math_func_attribute_fn get_tam_math_func_attribute; + + sai_create_tam_report_fn create_tam_report; + sai_remove_tam_report_fn remove_tam_report; + sai_set_tam_report_attribute_fn set_tam_report_attribute; + sai_get_tam_report_attribute_fn get_tam_report_attribute; + + sai_create_tam_event_threshold_fn create_tam_event_threshold; + sai_remove_tam_event_threshold_fn remove_tam_event_threshold; + sai_set_tam_event_threshold_attribute_fn set_tam_event_threshold_attribute; + sai_get_tam_event_threshold_attribute_fn get_tam_event_threshold_attribute; + + sai_create_tam_int_fn create_tam_int; + sai_remove_tam_int_fn remove_tam_int; + sai_set_tam_int_attribute_fn set_tam_int_attribute; + sai_get_tam_int_attribute_fn get_tam_int_attribute; + + sai_create_tam_tel_type_fn create_tam_tel_type; + sai_remove_tam_tel_type_fn remove_tam_tel_type; + sai_set_tam_tel_type_attribute_fn set_tam_tel_type_attribute; + sai_get_tam_tel_type_attribute_fn get_tam_tel_type_attribute; + + sai_create_tam_transport_fn create_tam_transport; + sai_remove_tam_transport_fn remove_tam_transport; + sai_set_tam_transport_attribute_fn set_tam_transport_attribute; + sai_get_tam_transport_attribute_fn get_tam_transport_attribute; + + sai_create_tam_telemetry_fn create_tam_telemetry; + sai_remove_tam_telemetry_fn remove_tam_telemetry; + sai_set_tam_telemetry_attribute_fn set_tam_telemetry_attribute; + sai_get_tam_telemetry_attribute_fn get_tam_telemetry_attribute; + + sai_create_tam_collector_fn create_tam_collector; + sai_remove_tam_collector_fn remove_tam_collector; + sai_set_tam_collector_attribute_fn set_tam_collector_attribute; + sai_get_tam_collector_attribute_fn get_tam_collector_attribute; + + sai_create_tam_event_action_fn create_tam_event_action; + sai_remove_tam_event_action_fn remove_tam_event_action; + sai_set_tam_event_action_attribute_fn set_tam_event_action_attribute; + sai_get_tam_event_action_attribute_fn get_tam_event_action_attribute; + + sai_create_tam_event_fn create_tam_event; + sai_remove_tam_event_fn remove_tam_event; + sai_set_tam_event_attribute_fn set_tam_event_attribute; + sai_get_tam_event_attribute_fn get_tam_event_attribute; + + sai_create_tam_counter_subscription_fn create_tam_counter_subscription; + sai_remove_tam_counter_subscription_fn remove_tam_counter_subscription; + sai_set_tam_counter_subscription_attribute_fn set_tam_counter_subscription_attribute; + sai_get_tam_counter_subscription_attribute_fn get_tam_counter_subscription_attribute; } sai_tam_api_t; /** diff --git a/inc/saitypes.h b/inc/saitypes.h index 64b163461..dd5d25abc 100644 --- a/inc/saitypes.h +++ b/inc/saitypes.h @@ -294,6 +294,7 @@ typedef enum _sai_object_type_t SAI_OBJECT_TYPE_ARS = 104, SAI_OBJECT_TYPE_ACL_TABLE_CHAIN_GROUP = 105, SAI_OBJECT_TYPE_TWAMP_SESSION = 106, + SAI_OBJECT_TYPE_TAM_COUNTER_SUBSCRIPTION = 107, /** Must remain in last position */ SAI_OBJECT_TYPE_MAX,