[ovs-dev] [ovsdb-server multithreading RFC 5/9] ovsdb: Add a 'big lock' to serialize all OVSDB operations
Andy Zhou
azhou at ovn.org
Thu Mar 3 08:13:24 UTC 2016
Add a global lock to serialize all OVSDB operations. It is a simple
locking scheme to implement and to reason about correctness, without
much changes to core of OVSDB implementation.
Signed-off-by: Andy Zhou <azhou at ovn.org>
---
ovsdb/jsonrpc-server.c | 31 ++++++++++++++++++++++++++-----
1 file changed, 26 insertions(+), 5 deletions(-)
diff --git a/ovsdb/jsonrpc-server.c b/ovsdb/jsonrpc-server.c
index 5a323e0..ed76192 100644
--- a/ovsdb/jsonrpc-server.c
+++ b/ovsdb/jsonrpc-server.c
@@ -51,6 +51,9 @@ struct ovsdb_jsonrpc_session;
* method with an error. */
static bool monitor2_enable__ = true;
+/* A global lock to serilize just about all OVSDB operations. */
+static struct ovs_mutex mutex = OVS_MUTEX_INITIALIZER;
+
/* Message rate-limiting. */
static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(1, 5);
@@ -92,7 +95,7 @@ static struct ovsdb_jsonrpc_trigger *ovsdb_jsonrpc_trigger_find(
static void ovsdb_jsonrpc_trigger_complete(struct ovsdb_jsonrpc_trigger *);
static void ovsdb_jsonrpc_trigger_complete_all(struct ovsdb_jsonrpc_session *);
static void ovsdb_jsonrpc_trigger_complete_done(
- struct ovsdb_jsonrpc_session *);
+ struct ovsdb_jsonrpc_session *) OVS_EXCLUDED(mutex);
/* Monitors. */
static struct jsonrpc_msg *ovsdb_jsonrpc_monitor_create(
@@ -471,14 +474,16 @@ ovsdb_jsonrpc_server_use_threads(struct ovsdb_jsonrpc_server *svr) {
struct ovsdb_jsonrpc_session {
struct ovs_list node; /* Element in remote's sessions list. */
- struct ovsdb_session up;
+ struct ovsdb_session up OVS_GUARDED_BY(mutex);
const void *remote;
/* Triggers. */
- struct hmap triggers; /* Hmap of "struct ovsdb_jsonrpc_trigger"s. */
+ /* Hmap of "struct ovsdb_jsonrpc_trigger"s. */
+ struct hmap triggers OVS_GUARDED_BY(mutex);
/* Monitors. */
- struct hmap monitors; /* Hmap of "struct ovsdb_jsonrpc_monitor"s. */
+ /* Hmap of "struct ovsdb_jsonrpc_monitor"s. */
+ struct hmap monitors OVS_GUARDED_BY(mutex);
/* Network connectivity. */
struct jsonrpc_session *js; /* JSON-RPC session. */
@@ -486,7 +491,8 @@ struct ovsdb_jsonrpc_session {
};
static void ovsdb_jsonrpc_session_close(struct ovsdb_jsonrpc_session *);
-static int ovsdb_jsonrpc_session_run(struct ovsdb_jsonrpc_session *);
+static int ovsdb_jsonrpc_session_run(struct ovsdb_jsonrpc_session *)
+ OVS_EXCLUDED(mutex);
static void ovsdb_jsonrpc_session_wait(struct ovsdb_jsonrpc_session *);
static void ovsdb_jsonrpc_session_get_memory_usage(
const struct ovsdb_jsonrpc_session *, struct simap *usage);
@@ -521,6 +527,8 @@ ovsdb_jsonrpc_session_close(struct ovsdb_jsonrpc_session *s)
{
struct ovsdb_jsonrpc_server *server;
+ ovs_mutex_lock(&mutex);
+
ovsdb_jsonrpc_monitor_remove_all(s);
ovsdb_jsonrpc_session_unlock_all(s);
ovsdb_jsonrpc_trigger_complete_all(s);
@@ -533,11 +541,14 @@ ovsdb_jsonrpc_session_close(struct ovsdb_jsonrpc_session *s)
server = ovsdb_jsonrpc_server_cast(s->up.server);
atomic_count_dec(&server->n_sessions);
ovsdb_session_destroy(&s->up);
+
+ ovs_mutex_unlock(&mutex);
free(s);
}
static int
ovsdb_jsonrpc_session_run(struct ovsdb_jsonrpc_session *s)
+ OVS_EXCLUDED(mutex)
{
jsonrpc_session_run(s->js);
if (s->js_seqno != jsonrpc_session_get_seqno(s->js)) {
@@ -549,6 +560,7 @@ ovsdb_jsonrpc_session_run(struct ovsdb_jsonrpc_session *s)
ovsdb_jsonrpc_trigger_complete_done(s);
+ ovs_mutex_lock(&mutex);
if (!jsonrpc_session_get_backlog(s->js)) {
struct jsonrpc_msg *msg;
@@ -569,6 +581,7 @@ ovsdb_jsonrpc_session_run(struct ovsdb_jsonrpc_session *s)
}
}
}
+ ovs_mutex_unlock(&mutex);
return jsonrpc_session_is_alive(s->js) ? 0 : ETIMEDOUT;
}
@@ -586,11 +599,13 @@ ovsdb_jsonrpc_session_wait(struct ovsdb_jsonrpc_session *s)
{
jsonrpc_session_wait(s->js);
if (!jsonrpc_session_get_backlog(s->js)) {
+ ovs_mutex_lock(&mutex);
if (ovsdb_jsonrpc_monitor_needs_flush(s)) {
poll_immediate_wake();
} else {
jsonrpc_session_recv_wait(s->js);
}
+ ovs_mutex_unlock(&mutex);
}
}
@@ -686,6 +701,7 @@ static struct ovsdb *
ovsdb_jsonrpc_lookup_db(const struct ovsdb_jsonrpc_session *s,
const struct jsonrpc_msg *request,
struct jsonrpc_msg **replyp)
+ OVS_REQUIRES(mutex)
{
struct json_array *params;
struct ovsdb_error *error;
@@ -755,6 +771,7 @@ static struct jsonrpc_msg *
ovsdb_jsonrpc_session_lock(struct ovsdb_jsonrpc_session *s,
struct jsonrpc_msg *request,
enum ovsdb_lock_mode mode)
+ OVS_REQUIRES(mutex)
{
struct ovsdb_lock_waiter *waiter;
struct jsonrpc_msg *reply;
@@ -870,6 +887,7 @@ execute_transaction(struct ovsdb_jsonrpc_session *s, struct ovsdb *db,
static void
ovsdb_jsonrpc_session_got_request(struct ovsdb_jsonrpc_session *s,
struct jsonrpc_msg *request)
+ OVS_REQUIRES(mutex)
{
struct jsonrpc_msg *reply;
@@ -1059,13 +1077,16 @@ ovsdb_jsonrpc_trigger_complete_all(struct ovsdb_jsonrpc_session *s)
static void
ovsdb_jsonrpc_trigger_complete_done(struct ovsdb_jsonrpc_session *s)
+ OVS_EXCLUDED(mutex)
{
+ ovs_mutex_lock(&mutex);
while (!list_is_empty(&s->up.completions)) {
struct ovsdb_jsonrpc_trigger *t
= CONTAINER_OF(s->up.completions.next,
struct ovsdb_jsonrpc_trigger, trigger.node);
ovsdb_jsonrpc_trigger_complete(t);
}
+ ovs_mutex_unlock(&mutex);
}
/* Jsonrpc front end monitor. */
--
1.9.1
More information about the dev
mailing list