Skip to content

Commit

Permalink
[Link event damping] Syncd changes for link event damping.
Browse files Browse the repository at this point in the history
  • Loading branch information
Ashish Singh committed Sep 29, 2023
1 parent c22b76b commit 975ab68
Show file tree
Hide file tree
Showing 45 changed files with 4,892 additions and 12 deletions.
3 changes: 2 additions & 1 deletion lib/ClientSai.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -240,7 +240,8 @@ sai_status_t ClientSai::set(
SWSS_LOG_ENTER();
REDIS_CHECK_API_INITIALIZED();

if (RedisRemoteSaiInterface::isRedisAttribute(objectType, attr))
if (RedisRemoteSaiInterface::isRedisAttribute(objectType, attr) ||
RedisRemoteSaiInterface::isRedisPortAttribute(objectType, attr))
{
SWSS_LOG_ERROR("sairedis extension attributes are not supported in CLIENT mode");

Expand Down
94 changes: 94 additions & 0 deletions lib/RedisRemoteSaiInterface.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -485,6 +485,82 @@ sai_status_t RedisRemoteSaiInterface::setRedisExtensionAttribute(
return SAI_STATUS_FAILURE;
}

sai_status_t RedisRemoteSaiInterface::setLinkEventDampingConfig(
_In_ sai_object_type_t objectType,
_In_ sai_object_id_t objectId,
_In_ const std::vector<swss::FieldValueTuple> &values)
{
SWSS_LOG_ENTER();

std::string key = sai_serialize_object_type(objectType) + ":" + sai_serialize_object_id(objectId);

m_communicationChannel->set(key, values, REDIS_ASIC_STATE_COMMAND_DAMPING_CONFIG_SET);

if (m_syncMode)
{
swss::KeyOpFieldsValuesTuple kco;
auto status = m_communicationChannel->wait(REDIS_ASIC_STATE_COMMAND_DAMPING_CONFIG_SET, kco);

m_recorder->recordGenericSetResponse(status);

return status;
}

return SAI_STATUS_SUCCESS;
}

sai_status_t RedisRemoteSaiInterface::setRedisPortExtensionAttribute(
_In_ sai_object_type_t objectType,
_In_ sai_object_id_t objectId,
_In_ const sai_attribute_t *attr)
{
SWSS_LOG_ENTER();

if (attr == nullptr)
{
SWSS_LOG_ERROR("attr pointer is null");

return SAI_STATUS_INVALID_PARAMETER;
}

std::string str_attr_id = sai_serialize_redis_port_attr_id(
static_cast<sai_redis_port_attr_t>(attr->id));

switch (attr->id)
{
case SAI_REDIS_PORT_ATTR_LINK_EVENT_DAMPING_ALGORITHM:
{
std::string str_attr_value = sai_serialize_link_event_damping_algorithm(
static_cast<sai_link_event_damping_algorithm_t>(attr->value.s32));

return setLinkEventDampingConfig(
objectType, objectId, {swss::FieldValueTuple(str_attr_id, str_attr_value)});
}
case SAI_REDIS_PORT_ATTR_LINK_EVENT_DAMPING_ALGO_AIED_CONFIG:
{
sai_redis_link_event_damping_algo_aied_config_t *config =
(sai_redis_link_event_damping_algo_aied_config_t *)attr->value.ptr;

if (config == NULL)
{
SWSS_LOG_ERROR("invalid link damping config attr value NULL");
return SAI_STATUS_INVALID_PARAMETER;
}

std::string str_attr_value = sai_serialize_link_event_damping_aied_config(*config);

return setLinkEventDampingConfig(
objectType, objectId, {swss::FieldValueTuple(str_attr_id, str_attr_value)});
}
default:
break;
}

SWSS_LOG_ERROR("unknown redis port extension attribute: %d", attr->id);

return SAI_STATUS_INVALID_PARAMETER;
}

sai_status_t RedisRemoteSaiInterface::set(
_In_ sai_object_type_t objectType,
_In_ sai_object_id_t objectId,
Expand All @@ -496,6 +572,10 @@ sai_status_t RedisRemoteSaiInterface::set(
{
return setRedisExtensionAttribute(objectType, objectId, attr);
}
if (RedisRemoteSaiInterface::isRedisPortAttribute(objectType, attr))
{
return setRedisPortExtensionAttribute(objectType, objectId, attr);
}

auto status = set(
objectType,
Expand Down Expand Up @@ -1664,6 +1744,20 @@ bool RedisRemoteSaiInterface::isRedisAttribute(
return true;
}

bool RedisRemoteSaiInterface::isRedisPortAttribute(
_In_ sai_object_id_t objectType,
_In_ const sai_attribute_t* attr)
{
SWSS_LOG_ENTER();

if ((objectType != SAI_OBJECT_TYPE_PORT) || (attr == nullptr) || (attr->id < SAI_PORT_ATTR_CUSTOM_RANGE_START))
{
return false;
}

return true;
}

void RedisRemoteSaiInterface::handleNotification(
_In_ const std::string &name,
_In_ const std::string &serializedNotification,
Expand Down
19 changes: 19 additions & 0 deletions lib/RedisRemoteSaiInterface.h
Original file line number Diff line number Diff line change
Expand Up @@ -207,6 +207,15 @@ namespace sairedis
_In_ sai_object_id_t switchId,
_In_ const sai_attribute_t* attr);

/**
* @brief Checks whether attribute is custom SAI_REDIS_PORT attribute.
*
* This function should only be used on port_api set function.
*/
static bool isRedisPortAttribute(
_In_ sai_object_id_t obejctType,
_In_ const sai_attribute_t* attr);

void setMeta(
_In_ std::weak_ptr<saimeta::Meta> meta);

Expand Down Expand Up @@ -343,12 +352,22 @@ namespace sairedis
_In_ sai_object_id_t objectId,
_In_ const sai_attribute_t *attr);

sai_status_t setRedisPortExtensionAttribute(
_In_ sai_object_type_t objectType,
_In_ sai_object_id_t objectId,
_In_ const sai_attribute_t *attr);

private:

sai_status_t sai_redis_notify_syncd(
_In_ sai_object_id_t switchId,
_In_ const sai_attribute_t *attr);

sai_status_t setLinkEventDampingConfig(
_In_ sai_object_type_t objectType,
_In_ sai_object_id_t objectId,
_In_ const std::vector<swss::FieldValueTuple> &values);

void clear_local_state();

sai_switch_notifications_t processNotification(
Expand Down
6 changes: 6 additions & 0 deletions lib/Sai.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -245,6 +245,12 @@ sai_status_t Sai::set(

REDIS_CHECK_CONTEXT(objectId);

if (RedisRemoteSaiInterface::isRedisPortAttribute(objectType, attr))
{
// skip metadata if attribute is redis extension port attribute.
return context->m_redisSai->set(objectType, objectId, attr);
}

return context->m_meta->set(objectType, objectId, attr);
}

Expand Down
34 changes: 34 additions & 0 deletions lib/Utils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ extern "C" {
#include "meta/sai_serialize.h"
#include "swss/logger.h"

#include <cmath>

using namespace sairedis;

void Utils::clearOidList(
Expand Down Expand Up @@ -80,3 +82,35 @@ void Utils::clearOidValues(

}
}

uint64_t Utils::timeToReachTargetValueUsingHalfLife(
_In_ uint64_t half_life_usec,
_In_ uint32_t initial_value,
_In_ uint32_t target_value)
{
SWSS_LOG_ENTER();

// Check if all the input fields have positive values and targeted value is
// smaller than initial value.
if ((initial_value == 0) || (target_value == 0) ||
(target_value >= initial_value) || (half_life_usec == 0)) {
return 0;
}

return uint64_t(-double(half_life_usec) * (log(double(target_value)/double(initial_value))/log(2.0)));
}

uint32_t Utils::valueAfterDecay(
_In_ uint64_t time_to_decay_usec,
_In_ uint64_t half_life_usec,
_In_ uint32_t initial_value)
{
SWSS_LOG_ENTER();

if ((initial_value == 0) || (time_to_decay_usec == 0) || (half_life_usec == 0)) {
return initial_value;
}
// N(t) = N(0) * 2 ^ (-t / half_life)
double ratio = double(time_to_decay_usec)/double(half_life_usec);
return uint32_t(double(initial_value) * pow(0.5, ratio));
}
11 changes: 11 additions & 0 deletions lib/Utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,5 +33,16 @@ namespace sairedis

static void clearOidList(
_Out_ sai_object_list_t& list);

static uint64_t timeToReachTargetValueUsingHalfLife(
_In_ uint64_t half_life_usec,
_In_ uint32_t initial_value,
_In_ uint32_t target_value);

static uint32_t valueAfterDecay(
_In_ uint64_t time_to_decay_usec,
_In_ uint64_t half_life_usec,
_In_ uint32_t initial_value);

};
}
56 changes: 56 additions & 0 deletions lib/sairedis.h
Original file line number Diff line number Diff line change
Expand Up @@ -250,3 +250,59 @@ typedef enum _sai_redis_switch_attr_t
*/
SAI_REDIS_SWITCH_ATTR_SYNC_OPERATION_RESPONSE_TIMEOUT,
} sai_redis_switch_attr_t;

/**
* @brief Link event damping algorithms.
*/
typedef enum _sai_link_event_damping_algorithm_t
{
/** Link event damping algorithm disabled */
SAI_LINK_EVENT_DAMPING_ALGORITHM_DISABLED = 0,

/** Additive increase exponential decrease based link event damping algorithm */
SAI_LINK_EVENT_DAMPING_ALGORITHM_AIED = 1,

} sai_link_event_damping_algorithm_t;

typedef struct _sai_redis_link_event_damping_algo_aied_config_t
{

/** Max link event damping suppression time (in milliseconds). */
sai_uint32_t max_suppress_time;

/** Link event damping suppress threshold. */
sai_uint32_t suppress_threshold;

/** Link event damping reuse threshold. */
sai_uint32_t reuse_threshold;

/** Link event damping decay half time duration (in milliseconds). */
sai_uint32_t decay_half_life;

/** Link event flap penalty. */
sai_uint32_t flap_penalty;

} sai_redis_link_event_damping_algo_aied_config_t;

typedef enum _sai_redis_port_attr_t
{
/**
* @brief Link event damping algorithm.
*
* @type sai_link_event_damping_algorithm_t
* @flags CREATE_AND_SET
* @default SAI_LINK_EVENT_DAMPING_ALGORITHM_DISABLED
*/
SAI_REDIS_PORT_ATTR_LINK_EVENT_DAMPING_ALGORITHM = SAI_PORT_ATTR_CUSTOM_RANGE_START,

/**
* @brief Link event damping AIED configuration.
*
* @type sai_redis_link_event_damping_algo_aied_config_t
* @flags CREATE_AND_SET
* @validonly SAI_REDIS_PORT_ATTR_LINK_EVENT_DAMPING_ALGORITHM = SAI_LINK_EVENT_DAMPING_ALGORITHM_AIED
* @default internal
*/
SAI_REDIS_PORT_ATTR_LINK_EVENT_DAMPING_ALGO_AIED_CONFIG,

} sai_redis_port_attr_t;
2 changes: 2 additions & 0 deletions lib/sairediscommon.h
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,8 @@
#define REDIS_ASIC_STATE_COMMAND_OBJECT_TYPE_GET_AVAILABILITY_QUERY "object_type_get_availability_query"
#define REDIS_ASIC_STATE_COMMAND_OBJECT_TYPE_GET_AVAILABILITY_RESPONSE "object_type_get_availability_response"

#define REDIS_ASIC_STATE_COMMAND_DAMPING_CONFIG_SET "link_event_damping_config_set"

/**
* @brief Redis virtual object id counter key name.
*
Expand Down
8 changes: 8 additions & 0 deletions meta/Meta.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4593,6 +4593,10 @@ sai_status_t Meta::meta_generic_validation_get(
VALIDATION_LIST(md, value.ipprefixlist);
break;

case SAI_ATTR_VALUE_TYPE_PORT_ERR_STATUS_LIST:
VALIDATION_LIST(md, value.porterror);
break;

default:

// acl capability will is more complex since is in/out we need to check stage
Expand Down Expand Up @@ -4866,6 +4870,10 @@ void Meta::meta_generic_validation_post_get(
VALIDATION_LIST_GET(md, value.ipprefixlist);
break;

case SAI_ATTR_VALUE_TYPE_PORT_ERR_STATUS_LIST:
VALIDATION_LIST_GET(md, value.porterror);
break;

default:

META_LOG_THROW(md, "serialization type is not supported yet FIXME");
Expand Down
Loading

0 comments on commit 975ab68

Please sign in to comment.