Skip to content

Commit 7a965ca

Browse files
authored
Optimize counter initialization by reducing the number of bulk counter poll calls and communication between swss/sairedis (sonic-net#3504)
* Use flex counter manager for the following counter groups - priority group watermark - priority group drop - queue watermark - port counter group Signed-off-by: Stephen Sun <stephens@nvidia.com> * Fix compiling error Signed-off-by: Stephen Sun <stephens@nvidia.com> * Support bulk create also for WRED/ECN counter groups Signed-off-by: Stephen Sun <stephens@nvidia.com> * Fix review comments Signed-off-by: Stephen Sun <stephens@nvidia.com> --------- Signed-off-by: Stephen Sun <stephens@nvidia.com>
1 parent 1b2a8e6 commit 7a965ca

File tree

11 files changed

+488
-217
lines changed

11 files changed

+488
-217
lines changed

orchagent/bufferorch.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1858,6 +1858,7 @@ void BufferOrch::doTask()
18581858
continue;
18591859
consumer->drain();
18601860
}
1861+
gPortsOrch->flushCounters();
18611862
}
18621863

18631864
void BufferOrch::doTask(Consumer &consumer)
@@ -1921,4 +1922,6 @@ void BufferOrch::doTask(Consumer &consumer)
19211922
{
19221923
(this->*(m_bufferFlushHandlerMap[map_type_name]))(consumer);
19231924
}
1925+
1926+
gPortsOrch->flushCounters();
19241927
}

orchagent/flex_counter/flex_counter_manager.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
#include "schema.h"
66
#include "rediscommand.h"
77
#include "logger.h"
8-
#include "sai_serialize.h"
98

109
#include <macsecorch.h>
1110

@@ -20,14 +19,13 @@ using swss::ProducerTable;
2019

2120
extern sai_switch_api_t *sai_switch_api;
2221

23-
extern sai_object_id_t gSwitchId;
24-
2522
const string FLEX_COUNTER_ENABLE("enable");
2623
const string FLEX_COUNTER_DISABLE("disable");
2724

2825
const unordered_map<StatsMode, string> FlexCounterManager::stats_mode_lookup =
2926
{
3027
{ StatsMode::READ, STATS_MODE_READ },
28+
{ StatsMode::READ_AND_CLEAR, STATS_MODE_READ_AND_CLEAR },
3129
};
3230

3331
const unordered_map<bool, string> FlexCounterManager::status_lookup =
@@ -42,6 +40,8 @@ const unordered_map<CounterType, string> FlexCounterManager::counter_id_field_lo
4240
{ CounterType::SWITCH_DEBUG, SWITCH_DEBUG_COUNTER_ID_LIST },
4341
{ CounterType::PORT, PORT_COUNTER_ID_LIST },
4442
{ CounterType::QUEUE, QUEUE_COUNTER_ID_LIST },
43+
{ CounterType::QUEUE_ATTR, QUEUE_ATTR_ID_LIST },
44+
{ CounterType::PRIORITY_GROUP, PG_COUNTER_ID_LIST },
4545
{ CounterType::MACSEC_SA_ATTR, MACSEC_SA_ATTR_ID_LIST },
4646
{ CounterType::MACSEC_SA, MACSEC_SA_COUNTER_ID_LIST },
4747
{ CounterType::MACSEC_FLOW, MACSEC_FLOW_COUNTER_ID_LIST },
@@ -259,7 +259,7 @@ string FlexCounterManager::getFlexCounterTableKey(
259259

260260
// serializeCounterStats turns a set of stats into a format suitable for FLEX_COUNTER_DB.
261261
string FlexCounterManager::serializeCounterStats(
262-
const unordered_set<string>& counter_stats) const
262+
const unordered_set<string>& counter_stats)
263263
{
264264
SWSS_LOG_ENTER();
265265

orchagent/flex_counter/flex_counter_manager.h

Lines changed: 238 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,20 +9,26 @@
99
#include "producertable.h"
1010
#include "table.h"
1111
#include <inttypes.h>
12+
#include <type_traits>
13+
#include "sai_serialize.h"
14+
#include "saihelper.h"
1215

1316
extern "C" {
1417
#include "sai.h"
1518
}
1619

1720
enum class StatsMode
1821
{
19-
READ
22+
READ,
23+
READ_AND_CLEAR
2024
};
2125

2226
enum class CounterType
2327
{
2428
PORT,
2529
QUEUE,
30+
QUEUE_ATTR,
31+
PRIORITY_GROUP,
2632
PORT_DEBUG,
2733
SWITCH_DEBUG,
2834
MACSEC_SA_ATTR,
@@ -35,13 +41,18 @@ enum class CounterType
3541
ENI
3642
};
3743

44+
extern bool gTraditionalFlexCounter;
45+
extern sai_object_id_t gSwitchId;
46+
47+
struct CachedObjects;
3848
// FlexCounterManager allows users to manage a group of flex counters.
3949
//
4050
// TODO: FlexCounterManager doesn't currently support the full range of
4151
// flex counter features. In particular, support for standard (i.e. non-debug)
4252
// counters and support for plugins needs to be added.
4353
class FlexCounterManager
4454
{
55+
friend struct CachedObjects;
4556
public:
4657
FlexCounterManager(
4758
const std::string& group_name,
@@ -69,12 +80,12 @@ class FlexCounterManager
6980
void enableFlexCounterGroup();
7081
void disableFlexCounterGroup();
7182

72-
void setCounterIdList(
83+
virtual void setCounterIdList(
7384
const sai_object_id_t object_id,
7485
const CounterType counter_type,
7586
const std::unordered_set<std::string>& counter_stats,
7687
const sai_object_id_t switch_id=SAI_NULL_OBJECT_ID);
77-
void clearCounterIdList(const sai_object_id_t object_id);
88+
virtual void clearCounterIdList(const sai_object_id_t object_id);
7889

7990
const std::string& getGroupName() const
8091
{
@@ -99,12 +110,9 @@ class FlexCounterManager
99110
protected:
100111
void applyGroupConfiguration();
101112

102-
private:
103113
std::string getFlexCounterTableKey(
104114
const std::string& group_name,
105115
const sai_object_id_t object_id) const;
106-
std::string serializeCounterStats(
107-
const std::unordered_set<std::string>& counter_stats) const;
108116

109117
std::string group_name;
110118
StatsMode stats_mode;
@@ -114,11 +122,235 @@ class FlexCounterManager
114122
std::unordered_map<sai_object_id_t, sai_object_id_t> installed_counters;
115123
bool is_gearbox;
116124

125+
static std::string serializeCounterStats(
126+
const std::unordered_set<std::string>& counter_stats);
127+
117128
static const std::unordered_map<StatsMode, std::string> stats_mode_lookup;
118129
static const std::unordered_map<bool, std::string> status_lookup;
119130
static const std::unordered_map<CounterType, std::string> counter_id_field_lookup;
120131
};
121132

133+
struct CachedObjects
134+
{
135+
CounterType pending_counter_type;
136+
sai_object_id_t pending_switch_id;
137+
std::unordered_set<std::string> pending_counter_stats;
138+
std::unordered_set<sai_object_id_t> pending_sai_objects;
139+
140+
bool try_cache(const sai_object_id_t object_id,
141+
const CounterType counter_type,
142+
const std::unordered_set<std::string>& counter_stats,
143+
sai_object_id_t switch_id)
144+
{
145+
if (pending_sai_objects.empty())
146+
{
147+
pending_counter_type = counter_type;
148+
pending_switch_id = switch_id;
149+
// Just to avoid recreating counter IDs
150+
if (pending_counter_stats != counter_stats)
151+
{
152+
pending_counter_stats = counter_stats;
153+
}
154+
}
155+
else if (counter_type != pending_counter_type ||
156+
switch_id != pending_switch_id ||
157+
counter_stats != pending_counter_stats)
158+
{
159+
return false;
160+
}
161+
162+
cache(object_id);
163+
164+
return true;
165+
}
166+
167+
bool is_cached(const sai_object_id_t object_id)
168+
{
169+
return pending_sai_objects.find(object_id) != pending_sai_objects.end();
170+
}
171+
172+
void flush(const std::string &group_name)
173+
{
174+
if (pending_sai_objects.empty())
175+
{
176+
return;
177+
}
178+
179+
auto counter_ids = FlexCounterManager::serializeCounterStats(pending_counter_stats);
180+
auto counter_type_it = FlexCounterManager::counter_id_field_lookup.find(pending_counter_type);
181+
182+
auto counter_keys = group_name + ":";
183+
for (const auto& oid: pending_sai_objects)
184+
{
185+
counter_keys += sai_serialize_object_id(oid) + ",";
186+
}
187+
counter_keys.pop_back();
188+
189+
startFlexCounterPolling(pending_switch_id, counter_keys, counter_ids, counter_type_it->second);
190+
191+
pending_sai_objects.clear();
192+
}
193+
194+
void cache(sai_object_id_t object_id)
195+
{
196+
pending_sai_objects.emplace(object_id);
197+
}
198+
};
199+
200+
class FlexCounterCachedManager : public FlexCounterManager
201+
{
202+
public:
203+
FlexCounterCachedManager(
204+
const std::string& group_name,
205+
const StatsMode stats_mode,
206+
const uint polling_interval,
207+
const bool enabled,
208+
swss::FieldValueTuple fv_plugin = std::make_pair("","")) :
209+
FlexCounterManager(group_name, stats_mode, polling_interval, enabled, fv_plugin)
210+
{
211+
}
212+
213+
virtual void flush()
214+
{
215+
}
216+
217+
protected:
218+
void flush(const std::string &group_name, struct CachedObjects &cached_objects)
219+
{
220+
cached_objects.flush(group_name);
221+
}
222+
223+
void setCounterIdList(
224+
struct CachedObjects &cached_objects,
225+
const sai_object_id_t object_id,
226+
const CounterType counter_type,
227+
const std::unordered_set<std::string>& counter_stats,
228+
const sai_object_id_t switch_id=SAI_NULL_OBJECT_ID)
229+
{
230+
if (gTraditionalFlexCounter)
231+
{
232+
// Unable to cache an object and initialize in bulk in traditional flex counter mode
233+
FlexCounterManager::setCounterIdList(object_id, counter_type, counter_stats, switch_id);
234+
return;
235+
}
236+
237+
auto effective_switch_id = switch_id == SAI_NULL_OBJECT_ID ? gSwitchId : switch_id;
238+
installed_counters[object_id] = effective_switch_id;
239+
if (cached_objects.try_cache(object_id, counter_type, counter_stats, effective_switch_id))
240+
{
241+
return;
242+
}
243+
else
244+
{
245+
flush(group_name, cached_objects);
246+
cached_objects.cache(object_id);
247+
}
248+
}
249+
250+
void clearCounterIdList(
251+
struct CachedObjects &cached_objects,
252+
const sai_object_id_t object_id)
253+
{
254+
auto search = cached_objects.pending_sai_objects.find(object_id);
255+
if (search == cached_objects.pending_sai_objects.end())
256+
{
257+
FlexCounterManager::clearCounterIdList(object_id);
258+
}
259+
else
260+
{
261+
installed_counters.erase(object_id);
262+
cached_objects.pending_sai_objects.erase(search);
263+
}
264+
}
265+
};
266+
267+
template <typename TagType, typename Enable=void>
268+
class FlexCounterTaggedCachedManager : public FlexCounterCachedManager
269+
{
270+
public:
271+
FlexCounterTaggedCachedManager(
272+
const std::string& group_name,
273+
const StatsMode stats_mode,
274+
const uint polling_interval,
275+
const bool enabled,
276+
swss::FieldValueTuple fv_plugin = std::make_pair("","")) :
277+
FlexCounterCachedManager(group_name, stats_mode, polling_interval, enabled, fv_plugin)
278+
{
279+
}
280+
281+
void flush()
282+
{
283+
FlexCounterCachedManager::flush(group_name, cached_objects);
284+
}
285+
286+
virtual void setCounterIdList(
287+
const sai_object_id_t object_id,
288+
const CounterType counter_type,
289+
const std::unordered_set<std::string>& counter_stats,
290+
const sai_object_id_t switch_id=SAI_NULL_OBJECT_ID)
291+
{
292+
FlexCounterCachedManager::setCounterIdList(cached_objects,
293+
object_id,
294+
counter_type,
295+
counter_stats);
296+
}
297+
298+
virtual void clearCounterIdList(
299+
const sai_object_id_t object_id)
300+
{
301+
FlexCounterCachedManager::clearCounterIdList(cached_objects, object_id);
302+
}
303+
304+
private:
305+
struct CachedObjects cached_objects;
306+
};
307+
308+
template <typename TagType>
309+
class FlexCounterTaggedCachedManager<TagType, typename std::enable_if_t<std::is_enum<TagType>::value>> : public FlexCounterCachedManager
310+
{
311+
public:
312+
FlexCounterTaggedCachedManager(
313+
const std::string& group_name,
314+
const StatsMode stats_mode,
315+
const uint polling_interval,
316+
const bool enabled,
317+
swss::FieldValueTuple fv_plugin = std::make_pair("","")) :
318+
FlexCounterCachedManager(group_name, stats_mode, polling_interval, enabled, fv_plugin)
319+
{
320+
}
321+
322+
void flush()
323+
{
324+
for(auto &it : cached_objects)
325+
{
326+
FlexCounterCachedManager::flush(group_name, it.second);
327+
}
328+
}
329+
330+
void setCounterIdList(
331+
const sai_object_id_t object_id,
332+
const CounterType counter_type,
333+
const std::unordered_set<std::string>& counter_stats,
334+
const TagType tag,
335+
const sai_object_id_t switch_id=SAI_NULL_OBJECT_ID)
336+
{
337+
FlexCounterCachedManager::setCounterIdList(cached_objects[tag],
338+
object_id,
339+
counter_type,
340+
counter_stats);
341+
}
342+
343+
void clearCounterIdList(
344+
const sai_object_id_t object_id,
345+
const TagType tag)
346+
{
347+
FlexCounterCachedManager::clearCounterIdList(cached_objects[tag], object_id);
348+
}
349+
350+
private:
351+
std::map<TagType, struct CachedObjects> cached_objects;
352+
};
353+
122354
class FlexManagerDirectory
123355
{
124356
public:

orchagent/flexcounterorch.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -271,6 +271,7 @@ void FlexCounterOrch::doTask(Consumer &consumer)
271271
}
272272
}
273273

274+
gPortsOrch->flushCounters();
274275
setFlexCounterGroupOperation(flexCounterGroupMap[key], value);
275276

276277
if (gPortsOrch && gPortsOrch->isGearboxEnabled())

0 commit comments

Comments
 (0)