Skip to content

Commit ebf45d6

Browse files
kcudnikShuotian Cheng
authored and
Shuotian Cheng
committed
[syncd]: Refactor mutexes (sonic-net#221)
1 parent a2e58cf commit ebf45d6

File tree

5 files changed

+272
-56
lines changed

5 files changed

+272
-56
lines changed

syncd/syncd.cpp

+22-10
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,19 @@
77
#include <iostream>
88
#include <map>
99

10-
std::mutex g_db_mutex;
10+
/**
11+
* @brief Global mutex for thread synchronization
12+
*
13+
* Purpose of this mutex is to synchronize multiple threads like main thread,
14+
* counters and notifications as well as all operations which require multiple
15+
* Redis DB access.
16+
*
17+
* For example: query DB for next VID id number, and then put map RID and VID
18+
* to Redis. From syncd point of view this entire operation should be atomic
19+
* and no other thread should access DB or make assumption on previous
20+
* information until entire operation will finish.
21+
*/
22+
std::mutex g_mutex;
1123

1224
std::shared_ptr<swss::RedisClient> g_redisClient;
1325
std::shared_ptr<swss::ProducerTable> getResponse;
@@ -41,7 +53,7 @@ std::map<sai_object_id_t, std::shared_ptr<SaiSwitch>> switches;
4153
* could be vlan members, bridge ports etc.
4254
*
4355
* We need this list to later on not put them back to temp view mode when doing
44-
* populate existing obejcts in apply view mode.
56+
* populate existing objects in apply view mode.
4557
*
4658
* Object ids here a VIDs.
4759
*/
@@ -327,8 +339,6 @@ sai_object_id_t translate_rid_to_vid(
327339
_In_ sai_object_id_t rid,
328340
_In_ sai_object_id_t switch_vid)
329341
{
330-
std::lock_guard<std::mutex> lock(g_db_mutex);
331-
332342
SWSS_LOG_ENTER();
333343

334344
/*
@@ -516,7 +526,6 @@ void translate_rid_to_vid_list(
516526
sai_object_id_t translate_vid_to_rid(
517527
_In_ sai_object_id_t vid)
518528
{
519-
std::lock_guard<std::mutex> lock(g_db_mutex);
520529

521530
SWSS_LOG_ENTER();
522531

@@ -679,7 +688,6 @@ void snoop_get_attr(
679688

680689
SWSS_LOG_DEBUG("%s", key.c_str());
681690

682-
std::lock_guard<std::mutex> lock(g_db_mutex);
683691

684692
g_redisClient->hset(key, attr_id, attr_value);
685693
}
@@ -1208,7 +1216,6 @@ sai_status_t handle_generic(
12081216
*/
12091217

12101218
{
1211-
std::lock_guard<std::mutex> lock(g_db_mutex);
12121219

12131220
g_redisClient->hset(VIDTORID, str_vid, str_rid);
12141221
g_redisClient->hset(RIDTOVID, str_rid, str_vid);
@@ -1246,7 +1253,6 @@ sai_status_t handle_generic(
12461253
*/
12471254

12481255
{
1249-
std::lock_guard<std::mutex> lock(g_db_mutex);
12501256

12511257
g_redisClient->hdel(VIDTORID, str_vid);
12521258
g_redisClient->hdel(RIDTOVID, str_rid);
@@ -1411,7 +1417,6 @@ void clearTempView()
14111417
* We need to expose api to execute user lua script not only predefined.
14121418
*/
14131419

1414-
std::lock_guard<std::mutex> lock(g_db_mutex);
14151420

14161421
for (const auto &key: g_redisClient->keys(pattern))
14171422
{
@@ -2107,6 +2112,8 @@ sai_status_t processBulkEvent(
21072112
sai_status_t processEvent(
21082113
_In_ swss::ConsumerTable &consumer)
21092114
{
2115+
std::lock_guard<std::mutex> lock(g_mutex);
2116+
21102117
SWSS_LOG_ENTER();
21112118

21122119
swss::KeyOpFieldsValuesTuple kco;
@@ -2613,7 +2620,6 @@ bool handleRestartQuery(swss::NotificationConsumer &restartQuery)
26132620

26142621
bool isVeryFirstRun()
26152622
{
2616-
std::lock_guard<std::mutex> lock(g_db_mutex);
26172623

26182624
SWSS_LOG_ENTER();
26192625

@@ -2761,6 +2767,8 @@ void performWarmRestart()
27612767

27622768
void onSyncdStart(bool warmStart)
27632769
{
2770+
std::lock_guard<std::mutex> lock(g_mutex);
2771+
27642772
/*
27652773
* It may happen that after initialize we will receive some port
27662774
* notifications with port'ids that are not in redis db yet, so after
@@ -2987,6 +2995,8 @@ int main(int argc, char **argv)
29872995
startCountersThread(options.countersThreadIntervalInSeconds);
29882996
}
29892997

2998+
startNotificationsProcessingThread();
2999+
29903000
SWSS_LOG_NOTICE("syncd listening for events");
29913001

29923002
swss::Select s;
@@ -3056,6 +3066,8 @@ int main(int argc, char **argv)
30563066
SWSS_LOG_ERROR("failed to uninitialize api: %s", sai_serialize_status(status).c_str());
30573067
}
30583068

3069+
stopNotificationsProcessingThread();
3070+
30593071
SWSS_LOG_NOTICE("uninitialize finished");
30603072

30613073
exit(EXIT_SUCCESS);

syncd/syncd.h

+4-1
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ extern "C" {
5858
#define SWITCH_SAI_THRIFT_RPC_SERVER_PORT 9092
5959
#endif // SAITHRIFT
6060

61-
extern std::mutex g_db_mutex;
61+
extern std::mutex g_mutex;
6262

6363
extern std::map<sai_object_id_t, std::shared_ptr<SaiSwitch>> switches;
6464

@@ -110,4 +110,7 @@ bool is_set_attribute_workaround(
110110
_In_ sai_attr_id_t attrid,
111111
_In_ sai_status_t status);
112112

113+
void startNotificationsProcessingThread();
114+
void stopNotificationsProcessingThread();
115+
113116
#endif // __SYNCD_H__

syncd/syncd_counters.cpp

+3-1
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,10 @@ void collectCountersThread(
2929

3030
for (auto sw: switches)
3131
{
32+
std::lock_guard<std::mutex> lock(g_mutex);
33+
3234
/*
33-
* Collect counters should be under mutex sice configuration can
35+
* Collect counters should be under mutex since configuration can
3436
* change and we don't want that during counters collection.
3537
*/
3638

0 commit comments

Comments
 (0)