Skip to content

Commit

Permalink
[notifications]: Add support for native PFC storm notify (sonic-net#236)
Browse files Browse the repository at this point in the history
Implement notification path and serializattion/deserialization
for event SAI_SWITCH_ATTRIBUTE_QUEUE_PFC_DEADLOCK_NOTIFY

Signed-off-by: marian-pritsak <marianp@mellanox.com>
  • Loading branch information
marian-pritsak authored and lguohan committed Oct 8, 2017
1 parent f43fb01 commit bfe594d
Show file tree
Hide file tree
Showing 4 changed files with 155 additions and 0 deletions.
30 changes: 30 additions & 0 deletions lib/src/sai_redis_notifications.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ sai_switch_shutdown_request_notification_fn on_switch_shutdown_request_notificat
sai_fdb_event_notification_fn on_fdb_event = NULL;
sai_port_state_change_notification_fn on_port_state_change = NULL;
sai_packet_event_notification_fn on_packet_event = NULL;
sai_queue_pfc_deadlock_notification_fn on_queue_deadlock = NULL;

void clear_notifications()
{
Expand All @@ -22,6 +23,7 @@ void clear_notifications()
on_fdb_event = NULL;
on_port_state_change = NULL;
on_packet_event = NULL;
on_queue_deadlock = NULL;
}

void check_notifications_pointers(
Expand Down Expand Up @@ -74,6 +76,10 @@ void check_notifications_pointers(
on_packet_event = (sai_packet_event_notification_fn)attr.value.ptr;
break;

case SAI_SWITCH_ATTR_QUEUE_PFC_DEADLOCK_NOTIFY:
on_queue_deadlock = (sai_queue_pfc_deadlock_notification_fn)attr.value.ptr;
break;

default:
SWSS_LOG_ERROR("pointer for %s is not handled, FIXME!", meta->attridname);
break;
Expand Down Expand Up @@ -182,6 +188,26 @@ void handle_packet_event(
}
}

void handle_queue_deadlock_event(
_In_ const std::string &data)
{
SWSS_LOG_ENTER();

SWSS_LOG_DEBUG("data: %s", data.c_str());

uint32_t count;
sai_queue_deadlock_notification_data_t *ntfData = NULL;

sai_deserialize_queue_deadlock_ntf(data, count, &ntfData);

if (on_queue_deadlock != NULL)
{
on_queue_deadlock(count, ntfData);
}

sai_deserialize_free_queue_deadlock_ntf(count, ntfData);
}

void handle_notification(
_In_ const std::string &notification,
_In_ const std::string &data,
Expand Down Expand Up @@ -214,6 +240,10 @@ void handle_notification(
{
handle_packet_event(data, values);
}
else if (notification == "queue_deadlock")
{
handle_queue_deadlock_event(data);
}
else
{
SWSS_LOG_ERROR("unknow notification: %s", notification.c_str());
Expand Down
76 changes: 76 additions & 0 deletions meta/saiserialize.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1302,6 +1302,14 @@ std::string sai_serialize_port_oper_status(
return sai_serialize_enum(status, &sai_metadata_enum_sai_port_oper_status_t);
}

std::string sai_serialize_queue_deadlock_event(
_In_ sai_queue_pfc_deadlock_event_type_t event)
{
SWSS_LOG_ENTER();

return sai_serialize_enum(event, &sai_metadata_enum_sai_queue_pfc_deadlock_event_type_t);
}

std::string sai_serialize_fdb_event(
_In_ sai_fdb_event_t event)
{
Expand Down Expand Up @@ -1402,6 +1410,34 @@ std::string sai_serialize_port_oper_status_ntf(
return j.dump();
}

std::string sai_serialize_queue_deadlock_ntf(
_In_ uint32_t count,
_In_ const sai_queue_deadlock_notification_data_t* deadlock_data)
{
SWSS_LOG_ENTER();

if (deadlock_data == NULL)
{
SWSS_LOG_ERROR("deadlock_data pointer is null");
throw std::runtime_error("deadlock_data pointer is null");
}

json j = json::array();

for (uint32_t i = 0; i < count; ++i)
{
json item;

item["queue_id"] = sai_serialize_object_id(deadlock_data[i].queue_id);
item["event"] = sai_serialize_queue_deadlock_event(deadlock_data[i].event);

j.push_back(item);
}

// we don't need count since it can be deduced
return j.dump();
}

std::string sai_serialize_object_meta_key(
_In_ const sai_object_meta_key_t& meta_key)
{
Expand Down Expand Up @@ -2280,6 +2316,15 @@ void sai_deserialize_port_oper_status(
sai_deserialize_enum(s, &sai_metadata_enum_sai_port_oper_status_t, (int32_t&)status);
}

void sai_deserialize_queue_deadlock(
_In_ const std::string& s,
_Out_ sai_queue_pfc_deadlock_event_type_t& event)
{
SWSS_LOG_ENTER();

sai_deserialize_enum(s, &sai_metadata_enum_sai_queue_pfc_deadlock_event_type_t, (int32_t&)event);
}

void sai_deserialize_fdb_event(
_In_ const std::string& s,
_Out_ sai_fdb_event_t& event)
Expand Down Expand Up @@ -2540,6 +2585,28 @@ void sai_deserialize_port_oper_status_ntf(
*port_oper_status = data;
}

void sai_deserialize_queue_deadlock_ntf(
_In_ const std::string& s,
_Out_ uint32_t &count,
_Out_ sai_queue_deadlock_notification_data_t** deadlock_data)
{
SWSS_LOG_ENTER();

json j = json::parse(s);

count = (uint32_t)j.size();

auto data = new sai_queue_deadlock_notification_data_t[count];

for (uint32_t i = 0; i < count; ++i)
{
sai_deserialize_object_id(j[i]["queue_id"], data[i].queue_id);
sai_deserialize_queue_deadlock(j[i]["event"], data[i].event);
}

*deadlock_data = data;
}

// deserialize free

void sai_deserialize_free_attribute_value(
Expand Down Expand Up @@ -2710,6 +2777,15 @@ void sai_deserialize_free_port_oper_status_ntf(
delete port_oper_status;
}

void sai_deserialize_free_queue_deadlock_ntf(
_In_ uint32_t count,
_In_ sai_queue_deadlock_notification_data_t* queue_deadlock)
{
SWSS_LOG_ENTER();

delete[] queue_deadlock;
}

void sai_deserialize_port_stat(
_In_ const std::string& s,
_Out_ sai_port_stat_t& stat)
Expand Down
13 changes: 13 additions & 0 deletions meta/saiserialize.h
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,10 @@ std::string sai_serialize_port_oper_status_ntf(
_In_ uint32_t count,
_In_ const sai_port_oper_status_notification_t* port_oper_status);

std::string sai_serialize_queue_deadlock_ntf(
_In_ uint32_t count,
_In_ const sai_queue_deadlock_notification_data_t* deadlock_data);

// deserialize

void sai_deserialize_number(
Expand Down Expand Up @@ -183,6 +187,11 @@ void sai_deserialize_port_oper_status_ntf(
_Out_ uint32_t &count,
_Out_ sai_port_oper_status_notification_t** portoperstatus);

void sai_deserialize_queue_deadlock_ntf(
_In_ const std::string& s,
_Out_ uint32_t &count,
_Out_ sai_queue_deadlock_notification_data_t** deadlock_data);

// free methods

void sai_deserialize_free_attribute_value(
Expand All @@ -199,6 +208,10 @@ void sai_deserialize_free_port_oper_status_ntf(
_In_ uint32_t count,
_In_ sai_port_oper_status_notification_t* portoperstatus);

void sai_deserialize_free_queue_deadlock_ntf(
_In_ uint32_t count,
_In_ sai_queue_deadlock_notification_data_t* deadlock_data);

void sai_deserialize_port_stat(
_In_ const std::string& s,
_Out_ sai_port_stat_t& stat);
Expand Down
36 changes: 36 additions & 0 deletions syncd/syncd_notifications.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -458,11 +458,43 @@ void stopNotificationsProcessingThread()
ntf_process_thread = nullptr;
}

void on_queue_deadlock(
_In_ uint32_t count,
_In_ sai_queue_deadlock_notification_data_t *data)
{
std::lock_guard<std::mutex> lock(g_mutex);

SWSS_LOG_ENTER();

SWSS_LOG_DEBUG("queue deadlock notification count: %u", count);

for (uint32_t i = 0; i < count; i++)
{
sai_queue_deadlock_notification_data_t *deadlock_data = &data[i];

/*
* We are using switch_rid as null, since queue should be already
* defined inside local db after creation.
*
* If this will be faster than return from create queue then we can use
* query switch id and extract rid of switch id and then convert it to
* switch vid.
*/

deadlock_data->queue_id = translate_rid_to_vid(deadlock_data->queue_id, SAI_NULL_OBJECT_ID);
}

std::string s = sai_serialize_queue_deadlock_ntf(count, data);

send_notification("queue_deadlock", s);
}

sai_switch_state_change_notification_fn on_switch_state_change_ntf = on_switch_state_change;
sai_switch_shutdown_request_notification_fn on_switch_shutdown_request_ntf = on_switch_shutdown_request;
sai_fdb_event_notification_fn on_fdb_event_ntf = on_fdb_event;
sai_port_state_change_notification_fn on_port_state_change_ntf = on_port_state_change;
sai_packet_event_notification_fn on_packet_event_ntf = on_packet_event;
sai_queue_pfc_deadlock_notification_fn on_queue_deadlock_ntf = on_queue_deadlock;

void check_notifications_pointers(
_In_ uint32_t attr_count,
Expand Down Expand Up @@ -530,6 +562,10 @@ void check_notifications_pointers(
attr.value.ptr = (void*)on_packet_event_ntf;
break;

case SAI_SWITCH_ATTR_QUEUE_PFC_DEADLOCK_NOTIFY:
attr.value.ptr = (void*)on_queue_deadlock_ntf;
break;

default:

SWSS_LOG_ERROR("pointer for %s is not handled, FIXME!", meta->attridname);
Expand Down

0 comments on commit bfe594d

Please sign in to comment.