Skip to content

Commit

Permalink
[orchagent] Adds swss support for drop counters (sonic-net#1075)
Browse files Browse the repository at this point in the history
* [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
daall authored and yxieca committed Nov 19, 2019
1 parent 457ea7e commit c3b8fe1
Show file tree
Hide file tree
Showing 14 changed files with 2,086 additions and 5 deletions.
6 changes: 4 additions & 2 deletions orchagent/Makefile.am
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
INCLUDES = -I $(top_srcdir) -I $(top_srcdir)/warmrestart -I flex_counter
INCLUDES = -I $(top_srcdir) -I $(top_srcdir)/warmrestart -I flex_counter -I debug_counter

CFLAGS_SAI = -I /usr/include/sai

Expand Down Expand Up @@ -54,9 +54,11 @@ orchagent_SOURCES = \
watermarkorch.cpp \
policerorch.cpp \
sfloworch.cpp \
chassisorch.cpp
chassisorch.cpp \
debugcounterorch.cpp

orchagent_SOURCES += flex_counter/flex_counter_manager.cpp flex_counter/flex_counter_stat_manager.cpp
orchagent_SOURCES += debug_counter/debug_counter.cpp debug_counter/drop_counter.cpp

orchagent_CFLAGS = $(DBGFLAGS) $(AM_CFLAGS) $(CFLAGS_COMMON) $(CFLAGS_SAI)
orchagent_CPPFLAGS = $(DBGFLAGS) $(AM_CFLAGS) $(CFLAGS_COMMON) $(CFLAGS_SAI)
Expand Down
112 changes: 112 additions & 0 deletions orchagent/debug_counter/debug_counter.cpp
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");
}
}
64 changes: 64 additions & 0 deletions orchagent/debug_counter/debug_counter.h
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_
Loading

0 comments on commit c3b8fe1

Please sign in to comment.