forked from sonic-net/sonic-buildimage
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[orchagent] Adds swss support for drop counters (sonic-net#1075)
* [orchagent] Adds swss support for drop counters - Creates a new orchestrator for managing debug counters - Adds utility functions for managing flex counters - Adds utility functions for managing debug counters Signed-off-by: Danny Allen <daall@microsoft.com> * Fix build issues * Fix log levels * Cast drop reasons before serializing * Fix testing issues * Clean up flex counter utilities * Expose switch ids in redis * Clean-up comments and namespace usage * Add basic drop counter vswitch tests * Add drop reasons * Fix rebase merge conflicts * Move flex counter and switch related work to different PRs * Fix first round of feedback comments * Fix free counters review comments * Reorganize helper classes * Delete extra makefile * Only put useful capabilities in STATE DB * Use new flex counter manager naming * Update mock tests to build with debug counter orch * Add remaining ingress drop reasons * Fix reference style issue * Update tests to match virtual switch implementation * Respond to C++ style issues * Improve documentation for vs tests * Add test case for removing all drop reasons from a counter * Specify exception type being caught * Add range check for drop counter indices * Undo range check
- Loading branch information
Showing
14 changed files
with
2,086 additions
and
5 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,112 @@ | ||
#include "debug_counter.h" | ||
#include "drop_counter.h" | ||
|
||
#include <unordered_set> | ||
#include <unordered_map> | ||
#include <string> | ||
#include <memory> | ||
#include <vector> | ||
#include "rediscommand.h" | ||
#include <exception> | ||
#include "logger.h" | ||
|
||
using std::runtime_error; | ||
using std::string; | ||
using std::unique_ptr; | ||
using std::unordered_map; | ||
using std::unordered_set; | ||
using std::vector; | ||
using swss::FieldValueTuple; | ||
|
||
extern sai_object_id_t gSwitchId; | ||
extern sai_debug_counter_api_t *sai_debug_counter_api; | ||
|
||
// Set of supported attributes to support easy look-up. | ||
const unordered_set<string> DebugCounter::supported_debug_counter_attributes = | ||
{ | ||
COUNTER_ALIAS, | ||
COUNTER_TYPE, | ||
COUNTER_DESCRIPTION, | ||
COUNTER_GROUP | ||
}; | ||
|
||
const std::unordered_map<std::string, sai_debug_counter_type_t> DebugCounter::debug_counter_type_lookup = | ||
{ | ||
{ PORT_INGRESS_DROPS, SAI_DEBUG_COUNTER_TYPE_PORT_IN_DROP_REASONS }, | ||
{ PORT_EGRESS_DROPS, SAI_DEBUG_COUNTER_TYPE_PORT_OUT_DROP_REASONS }, | ||
{ SWITCH_INGRESS_DROPS, SAI_DEBUG_COUNTER_TYPE_SWITCH_IN_DROP_REASONS }, | ||
{ SWITCH_EGRESS_DROPS, SAI_DEBUG_COUNTER_TYPE_SWITCH_OUT_DROP_REASONS } | ||
}; | ||
|
||
// It is expected that derived types populate any relevant fields and | ||
// initialize the counter in the SAI. | ||
// | ||
// If counter_type is not a member of debug_counter_type_lookup then this | ||
// constructor will throw a runtime error. | ||
DebugCounter::DebugCounter( | ||
const string& counter_name, | ||
const string& counter_type) | ||
: name(counter_name) | ||
{ | ||
SWSS_LOG_ENTER(); | ||
|
||
auto counter_type_it = debug_counter_type_lookup.find(counter_type); | ||
if (counter_type_it == debug_counter_type_lookup.end()) { | ||
SWSS_LOG_ERROR("Failed to initialize debug counter of type '%s'", | ||
counter_type.c_str()); | ||
throw runtime_error("Failed to initialize debug counter"); | ||
} | ||
type = counter_type_it->first; | ||
} | ||
|
||
// It is expected that derived types delete the counter from the SAI. | ||
DebugCounter::~DebugCounter() | ||
{ | ||
SWSS_LOG_ENTER(); | ||
} | ||
|
||
void DebugCounter::serializeDebugCounterType(sai_attribute_t& type_attribute) | ||
{ | ||
SWSS_LOG_ENTER(); | ||
|
||
sai_debug_counter_type_t sai_counter_type = debug_counter_type_lookup.at(type); | ||
type_attribute.id = SAI_DEBUG_COUNTER_ATTR_TYPE; | ||
type_attribute.value.s32 = sai_counter_type; | ||
|
||
SWSS_LOG_DEBUG("Serializing debug counter of type '%s'", type.c_str()); | ||
} | ||
|
||
// addDebugCounterToSAI creates a new debug counter object in the SAI given a list of debug counter attributes. | ||
// | ||
// If the SAI returns an error then this method will throw a runtime error. | ||
// | ||
// Behavior is undefined if num_attributes is not equal to the number of | ||
// attributes in debug_counter_attributes. | ||
void DebugCounter::addDebugCounterToSAI(const int num_attributes, const sai_attribute_t *debug_counter_attributes) | ||
{ | ||
SWSS_LOG_ENTER(); | ||
|
||
SWSS_LOG_DEBUG("Adding debug counter '%s' to SAI", name.c_str()); | ||
sai_object_id_t debug_counter_id; | ||
if (sai_debug_counter_api->create_debug_counter(&debug_counter_id, | ||
gSwitchId, | ||
num_attributes, | ||
debug_counter_attributes) != SAI_STATUS_SUCCESS) { | ||
SWSS_LOG_ERROR("Failed to create debug counter '%s'", name.c_str()); | ||
throw std::runtime_error("Failed to create debug counter"); | ||
} | ||
|
||
SWSS_LOG_DEBUG("Created debug counter '%s' with OID=%lu", name.c_str(), debug_counter_id); | ||
counter_id = debug_counter_id; | ||
} | ||
|
||
void DebugCounter::removeDebugCounterFromSAI() | ||
{ | ||
SWSS_LOG_ENTER(); | ||
|
||
SWSS_LOG_DEBUG("Removing debug counter '%s' from SAI", name.c_str()); | ||
if (sai_debug_counter_api->remove_debug_counter(counter_id) != SAI_STATUS_SUCCESS) { | ||
SWSS_LOG_ERROR("Failed to remove debug counter '%s'", name.c_str()); | ||
throw std::runtime_error("Failed to remove debug counter"); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,64 @@ | ||
#ifndef SWSS_UTIL_DEBUG_COUNTER_H_ | ||
#define SWSS_UTIL_DEBUG_COUNTER_H_ | ||
|
||
#include <string> | ||
#include <unordered_map> | ||
#include <unordered_set> | ||
|
||
extern "C" { | ||
#include "sai.h" | ||
} | ||
|
||
// Supported debug counter attributes. | ||
#define COUNTER_ALIAS "alias" | ||
#define COUNTER_TYPE "type" | ||
#define COUNTER_DESCRIPTION "desc" | ||
#define COUNTER_GROUP "group" | ||
|
||
// Supported debug counter types. | ||
#define PORT_INGRESS_DROPS "PORT_INGRESS_DROPS" | ||
#define PORT_EGRESS_DROPS "PORT_EGRESS_DROPS" | ||
#define SWITCH_INGRESS_DROPS "SWITCH_INGRESS_DROPS" | ||
#define SWITCH_EGRESS_DROPS "SWITCH_EGRESS_DROPS" | ||
|
||
// DebugCounter represents a SAI debug counter object. | ||
class DebugCounter | ||
{ | ||
public: | ||
DebugCounter(const std::string& counter_name, const std::string& counter_type) noexcept(false); | ||
DebugCounter(const DebugCounter&) = delete; | ||
DebugCounter& operator=(const DebugCounter&) = delete; | ||
virtual ~DebugCounter(); | ||
|
||
std::string getCounterName() const { return name; } | ||
std::string getCounterType() const { return type; } | ||
|
||
virtual std::string getDebugCounterSAIStat() const noexcept(false) = 0; | ||
|
||
static const std::unordered_set<std::string>& getSupportedDebugCounterAttributes() | ||
{ | ||
return supported_debug_counter_attributes; | ||
} | ||
|
||
// TODO: We should try to neatly abstract this like we've done for the isValid methods in DropCounter. | ||
static const std::unordered_map<std::string, sai_debug_counter_type_t>& getDebugCounterTypeLookup() | ||
{ | ||
return debug_counter_type_lookup; | ||
} | ||
|
||
protected: | ||
// These methods are intended to help with initialization. Dervied types will most likely | ||
// need to define additional helper methods to serialize additional fields (see DropCounter for example). | ||
void serializeDebugCounterType(sai_attribute_t& type_attribute); | ||
void addDebugCounterToSAI(int num_attrs, const sai_attribute_t *counter_attrs) noexcept(false); | ||
void removeDebugCounterFromSAI() noexcept(false); | ||
|
||
std::string name; | ||
std::string type; | ||
sai_object_id_t counter_id = 0; | ||
|
||
static const std::unordered_set<std::string> supported_debug_counter_attributes; | ||
static const std::unordered_map<std::string, sai_debug_counter_type_t> debug_counter_type_lookup; | ||
}; | ||
|
||
#endif // _SWSS_UTIL_DEBUG_COUNTER_H_ |
Oops, something went wrong.