Skip to content

Commit

Permalink
Sairedis support SAI api/object type extenstion range (#1390)
Browse files Browse the repository at this point in the history
Extensions objects can be used on ranges from 0x20000000 (this commit will requires SAI submodule to update as well)
  • Loading branch information
kcudnik authored and JunhongMao committed Jul 25, 2024
1 parent a06f8ad commit effaf8c
Show file tree
Hide file tree
Showing 13 changed files with 422 additions and 331 deletions.
63 changes: 49 additions & 14 deletions lib/VirtualObjectIdManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,13 +25,18 @@ static_assert(sizeof(sai_object_id_t) == sizeof(uint64_t), "SAI object ID size s
#define SAI_REDIS_OBJECT_TYPE_MAX ( (1ULL << SAI_REDIS_OBJECT_TYPE_BITS_SIZE) - 1 )
#define SAI_REDIS_OBJECT_TYPE_MASK (SAI_REDIS_OBJECT_TYPE_MAX)

#define SAI_REDIS_OBJECT_INDEX_BITS_SIZE ( 40 )
#define SAI_REDIS_OBJECT_TYPE_EXTENSIONS_FLAG_BITS_SIZE ( 1 )
#define SAI_REDIS_OBJECT_TYPE_EXTENSIONS_FLAG_MAX ( (1ULL << SAI_REDIS_OBJECT_TYPE_EXTENSIONS_FLAG_BITS_SIZE) - 1 )
#define SAI_REDIS_OBJECT_TYPE_EXTENSIONS_FLAG_MASK (SAI_REDIS_OBJECT_TYPE_EXTENSIONS_FLAG_MAX)

#define SAI_REDIS_OBJECT_INDEX_BITS_SIZE ( 39 )
#define SAI_REDIS_OBJECT_INDEX_MAX ( (1ULL << SAI_REDIS_OBJECT_INDEX_BITS_SIZE) - 1 )
#define SAI_REDIS_OBJECT_INDEX_MASK (SAI_REDIS_OBJECT_INDEX_MAX)

#define SAI_REDIS_OBJECT_ID_BITS_SIZE ( \
SAI_REDIS_SWITCH_INDEX_BITS_SIZE + \
SAI_REDIS_GLOBAL_CONTEXT_BITS_SIZE + \
SAI_REDIS_OBJECT_TYPE_EXTENSIONS_FLAG_BITS_SIZE + \
SAI_REDIS_OBJECT_TYPE_BITS_SIZE + \
SAI_REDIS_OBJECT_INDEX_BITS_SIZE )

Expand All @@ -41,38 +46,52 @@ static_assert(SAI_REDIS_OBJECT_ID_BITS_SIZE == SAI_OBJECT_ID_BITS_SIZE, "redis o
* This condition must be met, since we need to be able to encode SAI object
* type in object id on defined number of bits.
*/
static_assert(SAI_OBJECT_TYPE_EXTENSIONS_MAX < SAI_REDIS_OBJECT_TYPE_MAX, "redis max object type value must be greater than supported SAI max object type value");
static_assert(SAI_OBJECT_TYPE_MAX < 256, "object type must be possible to encode on 1 byte");
static_assert((SAI_OBJECT_TYPE_EXTENSIONS_RANGE_END - SAI_OBJECT_TYPE_EXTENSIONS_RANGE_START) < 256,
"extensions object type must be possible to encode on 1 byte");

/*
* Current OBJECT ID format:
*
* bits 63..56 - switch index
* bits 55..48 - SAI object type
* bits 47..40 - global context
* bits 40..0 - object index
* bits 39..39 - object type extensions flag
* bits 38..0 - object index
*
* So large number of bits is required, otherwise we would need to have map of
* OID to some struct that will have all those values. But having all this
* information in OID itself is more convenient.
*
* To be backward compatible with previous sairedis, we will still encode base
* object type on bit's 55..48, and extensions which will now start from range
* 0x20000000, will be encoded from 0x0, but extensions flag will be set to 1.
*
* For example SAI_OBJECT_TYPE_VIRTUAL_ROUTER oid will be encoded as 0x0003000000000001,
* SAI_OBJECT_TYPE_DASH_ACL_GROUP oid will be encoded as 0x0003008000000001.
*/

#define SAI_REDIS_GET_OBJECT_INDEX(oid) \
( ((uint64_t)oid) & ( SAI_REDIS_OBJECT_INDEX_MASK ) )

#define SAI_REDIS_GET_OBJECT_TYPE_EXTENSIONS_FLAG(oid) \
( (((uint64_t)oid) >> (SAI_REDIS_OBJECT_INDEX_BITS_SIZE) ) & ( SAI_REDIS_OBJECT_TYPE_EXTENSIONS_FLAG_MAX ) )

#define SAI_REDIS_GET_GLOBAL_CONTEXT(oid) \
( (((uint64_t)oid) >> (SAI_REDIS_OBJECT_INDEX_BITS_SIZE) ) & ( SAI_REDIS_GLOBAL_CONTEXT_MASK ) )
( (((uint64_t)oid) >> (SAI_REDIS_OBJECT_TYPE_EXTENSIONS_FLAG_BITS_SIZE + SAI_REDIS_OBJECT_INDEX_BITS_SIZE) ) & ( SAI_REDIS_GLOBAL_CONTEXT_MASK ) )

#define SAI_REDIS_GET_OBJECT_TYPE(oid) \
( (((uint64_t)oid) >> ( SAI_REDIS_GLOBAL_CONTEXT_BITS_SIZE + SAI_REDIS_OBJECT_INDEX_BITS_SIZE) ) & ( SAI_REDIS_OBJECT_TYPE_MASK ) )
( (((uint64_t)oid) >> ( SAI_REDIS_GLOBAL_CONTEXT_BITS_SIZE + SAI_REDIS_OBJECT_TYPE_EXTENSIONS_FLAG_BITS_SIZE + SAI_REDIS_OBJECT_INDEX_BITS_SIZE) ) & ( SAI_REDIS_OBJECT_TYPE_MASK ) )

#define SAI_REDIS_GET_SWITCH_INDEX(oid) \
( (((uint64_t)oid) >> ( SAI_REDIS_OBJECT_TYPE_BITS_SIZE + SAI_REDIS_GLOBAL_CONTEXT_BITS_SIZE + SAI_REDIS_OBJECT_INDEX_BITS_SIZE) ) & ( SAI_REDIS_SWITCH_INDEX_MASK ) )
( (((uint64_t)oid) >> ( SAI_REDIS_OBJECT_TYPE_BITS_SIZE + SAI_REDIS_GLOBAL_CONTEXT_BITS_SIZE + SAI_REDIS_OBJECT_TYPE_EXTENSIONS_FLAG_BITS_SIZE + SAI_REDIS_OBJECT_INDEX_BITS_SIZE) ) & ( SAI_REDIS_SWITCH_INDEX_MASK ) )

#define SAI_REDIS_TEST_OID (0x0123456789abcdef)
#define SAI_REDIS_TEST_OID (0x012345e789abcdef)

static_assert(SAI_REDIS_GET_SWITCH_INDEX(SAI_REDIS_TEST_OID) == 0x01, "test switch index");
static_assert(SAI_REDIS_GET_OBJECT_TYPE(SAI_REDIS_TEST_OID) == 0x23, "test object type");
static_assert(SAI_REDIS_GET_GLOBAL_CONTEXT(SAI_REDIS_TEST_OID) == 0x45, "test global context");
static_assert(SAI_REDIS_GET_OBJECT_TYPE_EXTENSIONS_FLAG(SAI_REDIS_TEST_OID) == 0x1, "test object type extensions flag");
static_assert(SAI_REDIS_GET_OBJECT_INDEX(SAI_REDIS_TEST_OID) == 0x6789abcdef, "test object index");

using namespace sairedis;
Expand Down Expand Up @@ -143,9 +162,11 @@ sai_object_type_t VirtualObjectIdManager::saiObjectTypeQuery(
return SAI_OBJECT_TYPE_NULL;
}

sai_object_type_t objectType = (sai_object_type_t)(SAI_REDIS_GET_OBJECT_TYPE(objectId));
sai_object_type_t objectType = SAI_REDIS_GET_OBJECT_TYPE_EXTENSIONS_FLAG(objectId)
? (sai_object_type_t)(SAI_REDIS_GET_OBJECT_TYPE(objectId) + SAI_OBJECT_TYPE_EXTENSIONS_RANGE_START)
: (sai_object_type_t)(SAI_REDIS_GET_OBJECT_TYPE(objectId));

if (objectType == SAI_OBJECT_TYPE_NULL || objectType >= SAI_OBJECT_TYPE_EXTENSIONS_MAX)
if (sai_metadata_is_object_type_valid(objectType) == false)
{
SWSS_LOG_ERROR("invalid object id %s",
sai_serialize_object_id(objectId).c_str());
Expand Down Expand Up @@ -198,7 +219,7 @@ sai_object_id_t VirtualObjectIdManager::allocateNewObjectId(
{
SWSS_LOG_ENTER();

if ((objectType <= SAI_OBJECT_TYPE_NULL) || (objectType >= SAI_OBJECT_TYPE_EXTENSIONS_MAX))
if (sai_metadata_is_object_type_valid(objectType) == false)
{
SWSS_LOG_THROW("invalid object type: %d", objectType);
}
Expand Down Expand Up @@ -299,10 +320,22 @@ sai_object_id_t VirtualObjectIdManager::constructObjectId(
{
SWSS_LOG_ENTER();

if (sai_metadata_is_object_type_valid(objectType) == false)
{
SWSS_LOG_THROW("FATAL: invalid object type (0x%x), logic error, this is a bug!", objectType);
}

uint64_t extensionsFlag = (uint64_t)objectType >= SAI_OBJECT_TYPE_EXTENSIONS_RANGE_START;

objectType = extensionsFlag
? (sai_object_type_t)(objectType - SAI_OBJECT_TYPE_EXTENSIONS_RANGE_START)
: objectType;

return (sai_object_id_t)(
((uint64_t)switchIndex << (SAI_REDIS_OBJECT_TYPE_BITS_SIZE + SAI_REDIS_GLOBAL_CONTEXT_BITS_SIZE + SAI_REDIS_OBJECT_INDEX_BITS_SIZE)) |
((uint64_t)objectType << (SAI_REDIS_GLOBAL_CONTEXT_BITS_SIZE + SAI_REDIS_OBJECT_INDEX_BITS_SIZE)) |
((uint64_t)globalContext << (SAI_REDIS_OBJECT_INDEX_BITS_SIZE)) |
((uint64_t)switchIndex << (SAI_REDIS_OBJECT_TYPE_BITS_SIZE + SAI_REDIS_GLOBAL_CONTEXT_BITS_SIZE + SAI_REDIS_OBJECT_TYPE_EXTENSIONS_FLAG_BITS_SIZE + SAI_REDIS_OBJECT_INDEX_BITS_SIZE)) |
((uint64_t)objectType << (SAI_REDIS_GLOBAL_CONTEXT_BITS_SIZE + SAI_REDIS_OBJECT_TYPE_EXTENSIONS_FLAG_BITS_SIZE + SAI_REDIS_OBJECT_INDEX_BITS_SIZE)) |
((uint64_t)globalContext << (SAI_REDIS_OBJECT_TYPE_EXTENSIONS_FLAG_BITS_SIZE + SAI_REDIS_OBJECT_INDEX_BITS_SIZE)) |
((uint64_t)extensionsFlag << (SAI_REDIS_OBJECT_INDEX_BITS_SIZE)) |
objectIndex);
}

Expand Down Expand Up @@ -347,7 +380,9 @@ sai_object_type_t VirtualObjectIdManager::objectTypeQuery(
return SAI_OBJECT_TYPE_NULL;
}

sai_object_type_t objectType = (sai_object_type_t)(SAI_REDIS_GET_OBJECT_TYPE(objectId));
sai_object_type_t objectType = SAI_REDIS_GET_OBJECT_TYPE_EXTENSIONS_FLAG(objectId)
? (sai_object_type_t)(SAI_REDIS_GET_OBJECT_TYPE(objectId) + SAI_OBJECT_TYPE_EXTENSIONS_RANGE_START)
: (sai_object_type_t)(SAI_REDIS_GET_OBJECT_TYPE(objectId));

if (!sai_metadata_is_object_type_valid(objectType))
{
Expand Down
9 changes: 4 additions & 5 deletions meta/Meta.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1711,16 +1711,15 @@ sai_status_t Meta::meta_sai_validate_oid(
{
SWSS_LOG_ENTER();

if (object_type <= SAI_OBJECT_TYPE_NULL ||
object_type >= SAI_OBJECT_TYPE_EXTENSIONS_MAX)
auto info = sai_metadata_get_object_type_info(object_type);

if (!info)
{
SWSS_LOG_ERROR("invalid object type specified: %d, FIXME", object_type);
return SAI_STATUS_INVALID_PARAMETER;
}

const char* otname = sai_metadata_get_enum_value_name(&sai_metadata_enum_sai_object_type_t, object_type);

auto info = sai_metadata_get_object_type_info(object_type);
const char* otname = info->objecttypename;

if (info->isnonobjectid)
{
Expand Down
1 change: 0 additions & 1 deletion saidump/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ saidump_LDADD = -lhiredis -lswsscommon -lpthread -L$(top_srcdir)/meta/.libs -lsa
-L$(top_srcdir)/lib/.libs -lsairedis -lzmq $(CODE_COVERAGE_LIBS)

noinst_LIBRARIES = libsaidump.a

libsaidump_a_SOURCES = SaiDump.cpp
libsaidump_a_CPPFLAGS = $(CODE_COVERAGE_CPPFLAGS)
libsaidump_a_CXXFLAGS = $(DBGFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS_COMMON) $(CODE_COVERAGE_CXXFLAGS)
52 changes: 19 additions & 33 deletions stub.pl
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ sub GetData
sub SanitizeData
{
$DATA =~ s/SAI_OBJECT_TYPE_\w*(START|END|NULL|MAX)//gms;
$DATA =~ s/SAI_API_\w*(START|END|UNSPECIFIED|MAX)//gms;
$DATA =~ s/SAI_API_\w*(START|END|UNSPECIFIED|MAX|EXTENSIONS_RANGE_BASE)//gms;
}

sub ExtractData
Expand Down Expand Up @@ -197,7 +197,7 @@ sub GetFunctionName
elsif ($fun =~ /(create|remove|set|get)_(\w+)(_attribute)?/ and defined $objectTypes{$2})
{
$OT = $objectTypes{$2};
$fun = $1;
$fun = "$1";
}
else
{
Expand Down Expand Up @@ -270,7 +270,7 @@ ()
Write "";
}

Write "static const sai_${api}_api_t ${STUB}_${api} = {";
Write "static sai_${api}_api_t ${STUB}_${api} = {";

while ($struct =~ /(sai_\w+_fn)\s+(\w+)/gms)
{
Expand Down Expand Up @@ -303,35 +303,13 @@ sub CreateHeader
Write ""
}

sub CreateApiStruct
{
Write "";
Write "/* ==== API STRUCTS === */";
Write "";

Write "static sai_apis_t ${STUB}_apis = {";

for my $API (@APIS)
{
my $api = lc $API;

Write " .${api}_api = const_cast<sai_${api}_api_t*>(&${STUB}_${api}),";
}

Write "};";
Write "";
}

sub CreateApiQuery
{
Write "";
Write "/* ==== API QUERY === */";
Write "";

Write "static_assert((sizeof(sai_apis_t)/sizeof(void*)) == (SAI_API_EXTENSIONS_MAX - 1));";
Write "";
Write "sai_status_t sai_api_query(";
Write " _In_ sai_api_t sai_api_id,";
Write " _In_ sai_api_t api,";
Write " _Out_ void** api_method_table)";
Write "{";
Write " SWSS_LOG_ENTER();";
Expand All @@ -343,21 +321,30 @@ sub CreateApiQuery
Write " return SAI_STATUS_INVALID_PARAMETER;";
Write " }";
Write "";
Write " if (sai_api_id == SAI_API_UNSPECIFIED)";
Write " if (api == SAI_API_UNSPECIFIED)";
Write " {";
Write " SWSS_LOG_ERROR(\"api ID is unspecified api\");";
Write "";
Write " return SAI_STATUS_INVALID_PARAMETER;";
Write " }";
Write "";
Write " if (sai_metadata_get_enum_value_name(&sai_metadata_enum_sai_api_t, sai_api_id))";
Write " switch((int)api)";
Write " {";
Write " *api_method_table = ((void**)&${STUB}_apis)[sai_api_id - 1];";
Write "";
Write " return SAI_STATUS_SUCCESS;";

for my $API (@APIS)
{
my $api = lc $API;

Write " case SAI_API_$API:";
Write " *api_method_table = (void**)&${STUB}_${api};";
Write " return SAI_STATUS_SUCCESS;";
}

Write " default:";
Write " break;";
Write " }";
Write "";
Write " SWSS_LOG_ERROR(\"Invalid API type %d\", sai_api_id);";
Write " SWSS_LOG_ERROR(\"Invalid API type %d\", api);";
Write "";
Write " return SAI_STATUS_INVALID_PARAMETER;";
Write "}";
Expand Down Expand Up @@ -427,7 +414,6 @@ sub CreateGlobalApis
ExtractData();
CreateHeader();
CreateApiStricts();
CreateApiStruct();
CreateApiQuery();
CreateGlobalApis();
WriteFile($optionFileName,$SOURCE_CONTENT);
6 changes: 4 additions & 2 deletions syncd/ComparisonLogic.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3281,9 +3281,11 @@ void ComparisonLogic::logViewObjectCount(

bool asic_changes = false;

for (int i = SAI_OBJECT_TYPE_NULL + 1; i < SAI_OBJECT_TYPE_EXTENSIONS_MAX; i++)
// skip null object type

for (size_t i = 1; i < sai_metadata_enum_sai_object_type_t.valuescount; ++i)
{
sai_object_type_t ot = (sai_object_type_t)i;
sai_object_type_t ot = (sai_object_type_t)sai_metadata_enum_sai_object_type_t.values[i];

size_t c = currentView.getObjectsByObjectType(ot).size();
size_t t = temporaryView.getObjectsByObjectType(ot).size();
Expand Down
18 changes: 9 additions & 9 deletions syncd/SaiDiscovery.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -309,15 +309,15 @@ void SaiDiscovery::setApiLogLevel(

// We start from 1 since 0 is SAI_API_UNSPECIFIED.

for (uint32_t api = 1; api < sai_metadata_enum_sai_api_t.valuescount; ++api)
for (uint32_t idx = 1; idx < sai_metadata_enum_sai_api_t.valuescount; ++idx)
{
sai_status_t status = m_sai->logSet((sai_api_t)api, logLevel);
sai_status_t status = m_sai->logSet((sai_api_t)sai_metadata_enum_sai_api_t.values[idx], logLevel);

if (status == SAI_STATUS_SUCCESS)
{
SWSS_LOG_INFO("setting SAI loglevel %s on %s",
sai_serialize_log_level(logLevel).c_str(),
sai_serialize_api((sai_api_t)api).c_str());
sai_serialize_api((sai_api_t)sai_metadata_enum_sai_api_t.values[idx]).c_str());
}
else
{
Expand All @@ -333,19 +333,19 @@ void SaiDiscovery::setApiLogLevel(

// We start from 1 since 0 is SAI_API_UNSPECIFIED.

for (uint32_t api = 1; api < sai_metadata_enum_sai_api_t.valuescount; ++api)
for (uint32_t idx = 1; idx < sai_metadata_enum_sai_api_t.valuescount; ++idx)
{
auto it = levels.find((sai_api_t)api);
auto it = levels.find((sai_api_t)sai_metadata_enum_sai_api_t.values[idx]);

sai_log_level_t logLevel = (it == levels.end()) ? SAI_LOG_LEVEL_NOTICE : it->second;

sai_status_t status = m_sai->logSet((sai_api_t)api, logLevel);
sai_status_t status = m_sai->logSet((sai_api_t)sai_metadata_enum_sai_api_t.values[idx], logLevel);

if (status == SAI_STATUS_SUCCESS)
{
SWSS_LOG_INFO("setting SAI loglevel %s on %s",
sai_serialize_log_level(logLevel).c_str(),
sai_serialize_api((sai_api_t)api).c_str());
sai_serialize_api((sai_api_t)sai_metadata_enum_sai_api_t.values[idx]).c_str());
}
else
{
Expand All @@ -362,9 +362,9 @@ std::map<sai_api_t, sai_log_level_t> SaiDiscovery::getApiLogLevel()

// We start from 1 since 0 is SAI_API_UNSPECIFIED.

for (uint32_t api = 1; api < sai_metadata_enum_sai_api_t.valuescount; ++api)
for (uint32_t idx = 1; idx < sai_metadata_enum_sai_api_t.valuescount; ++idx)
{
levels[(sai_api_t)api] = m_sai->logGet((sai_api_t)api);
levels[(sai_api_t)sai_metadata_enum_sai_api_t.values[idx]] = m_sai->logGet((sai_api_t)sai_metadata_enum_sai_api_t.values[idx]);
}

return levels;
Expand Down
Loading

0 comments on commit effaf8c

Please sign in to comment.