Skip to content

Commit

Permalink
Sairedis support SAI api/object type extenstion rance
Browse files Browse the repository at this point in the history
Extenstions objects can be used on ranges from 0x20000000
(this commit will requires SAI submodule to update as well)
  • Loading branch information
kcudnik committed Jun 13, 2024
1 parent 9574a3c commit 045ab90
Show file tree
Hide file tree
Showing 12 changed files with 417 additions and 329 deletions.
61 changes: 47 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,20 @@ 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 = (sai_object_type_t)(objectType & 0xFF); // get lower part as 1 byte

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 +378,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
50 changes: 18 additions & 32 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 @@ -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 045ab90

Please sign in to comment.