[ovs-dev] [ovsdb speedup v3 12/19] ovsdb-monitor: stores jsonrpc-monitor in a linked-list

Andy Zhou azhou at nicira.com
Fri Apr 10 01:40:21 UTC 2015


Currently, each ovsdb-monitor points to a single jsonrpc_monitor object.
This means there is 1:1 relationship between them.

In case multiple jsonrpc-monitors need to monitor the same tables and
the columns within them, then can share a single ovsdb-monitor, so the
updates only needs to be maintained once.

This patch, with a few following patches,  will allow for N:1 mapping
between jsonrpc-monitor and ovsdb-monitor.

Maintaining jsonrpc-monitor pointers in a linked-list is essential
in allowing N:1 mapping. The ovsdb-monitor life cycle
is now reference counted. An empty list means zero references.

Signed-off-by: Andy Zhou <azhou at nicira.com>

---
v1->v2: style fixes
v2->v3: no change
---
 ovsdb/jsonrpc-server.c |  2 +-
 ovsdb/monitor.c        | 50 ++++++++++++++++++++++++++++++++++++++++++++++----
 ovsdb/monitor.h        |  5 +++--
 3 files changed, 50 insertions(+), 7 deletions(-)

diff --git a/ovsdb/jsonrpc-server.c b/ovsdb/jsonrpc-server.c
index 48bb640..c7d404f 100644
--- a/ovsdb/jsonrpc-server.c
+++ b/ovsdb/jsonrpc-server.c
@@ -1304,7 +1304,7 @@ ovsdb_jsonrpc_monitor_destroy(struct ovsdb_jsonrpc_monitor *m)
 {
     json_destroy(m->monitor_id);
     hmap_remove(&m->session->monitors, &m->node);
-    ovsdb_monitor_destroy(m->dbmon);
+    ovsdb_monitor_remove_jsonrpc_monitor(m->dbmon, m);
     free(m);
 }
 
diff --git a/ovsdb/monitor.c b/ovsdb/monitor.c
index 6fc459e..415e5c8 100644
--- a/ovsdb/monitor.c
+++ b/ovsdb/monitor.c
@@ -47,10 +47,15 @@ static const struct ovsdb_replica_class ovsdb_jsonrpc_replica_class;
 struct ovsdb_monitor {
     struct ovsdb_replica replica;
     struct shash tables;     /* Holds "struct ovsdb_monitor_table"s. */
-    struct ovsdb_jsonrpc_monitor *jsonrpc_monitor;
+    struct ovs_list jsonrpc_monitors;  /* Contains "jsonrpc_monitor_node"s. */
     struct ovsdb *db;
 };
 
+struct jsonrpc_monitor_node {
+    struct ovsdb_jsonrpc_monitor *jsonrpc_monitor;
+    struct ovs_list node;
+};
+
 /* A particular column being monitored. */
 struct ovsdb_monitor_column {
     const struct ovsdb_column *column;
@@ -82,6 +87,8 @@ struct ovsdb_monitor_table {
     struct hmap changes;
 };
 
+static void ovsdb_monitor_destroy(struct ovsdb_monitor *dbmon);
+
 static int
 compare_ovsdb_monitor_column(const void *a_, const void *b_)
 {
@@ -199,15 +206,20 @@ ovsdb_monitor_create(struct ovsdb *db,
                      struct ovsdb_jsonrpc_monitor *jsonrpc_monitor)
 {
     struct ovsdb_monitor *dbmon;
+    struct jsonrpc_monitor_node *jm;
 
     dbmon = xzalloc(sizeof *dbmon);
 
     ovsdb_replica_init(&dbmon->replica, &ovsdb_jsonrpc_replica_class);
     ovsdb_add_replica(db, &dbmon->replica);
-    dbmon->jsonrpc_monitor = jsonrpc_monitor;
+    list_init(&dbmon->jsonrpc_monitors);
     dbmon->db = db;
     shash_init(&dbmon->tables);
 
+    jm = xzalloc(sizeof *jm);
+    jm->jsonrpc_monitor = jsonrpc_monitor;
+    list_push_back(&dbmon->jsonrpc_monitors, &jm->node);
+
     return dbmon;
 }
 
@@ -526,6 +538,31 @@ ovsdb_monitor_get_initial(const struct ovsdb_monitor *dbmon)
 }
 
 void
+ovsdb_monitor_remove_jsonrpc_monitor(struct ovsdb_monitor *dbmon,
+                   struct ovsdb_jsonrpc_monitor *jsonrpc_monitor)
+{
+    struct jsonrpc_monitor_node *jm;
+
+    /* Find and remove the jsonrpc monitor from the list.  */
+    LIST_FOR_EACH(jm, node, &dbmon->jsonrpc_monitors) {
+        if (jm->jsonrpc_monitor == jsonrpc_monitor) {
+            list_remove(&jm->node);
+            free(jm);
+
+            /* Destory ovsdb monitor if this is the last user.  */
+            if (list_is_empty(&dbmon->jsonrpc_monitors)) {
+                ovsdb_monitor_destroy(dbmon);
+            }
+
+            return;
+        };
+    }
+
+    /* Should never reach here. jsonrpc_monitor should be on the list.  */
+    OVS_NOT_REACHED();
+}
+
+static void
 ovsdb_monitor_destroy(struct ovsdb_monitor *dbmon)
 {
     struct shash_node *node;
@@ -567,9 +604,14 @@ static void
 ovsdb_monitor_destroy_callback(struct ovsdb_replica *replica)
 {
     struct ovsdb_monitor *dbmon = ovsdb_monitor_cast(replica);
-    struct ovsdb_jsonrpc_monitor *m = dbmon->jsonrpc_monitor;
+    struct jsonrpc_monitor_node *jm, *next;
 
-    ovsdb_jsonrpc_monitor_destroy(m);
+    /* Delete all front end monitors. Removing the last front
+     * end monitor will also destroy the corresponding 'ovsdb_monitor'.
+     * ovsdb monitor will also be destroied.  */
+    LIST_FOR_EACH_SAFE(jm, next, node, &dbmon->jsonrpc_monitors) {
+        ovsdb_jsonrpc_monitor_destroy(jm->jsonrpc_monitor);
+    }
 }
 
 static const struct ovsdb_replica_class ovsdb_jsonrpc_replica_class = {
diff --git a/ovsdb/monitor.h b/ovsdb/monitor.h
index 6b7f730..829a135 100644
--- a/ovsdb/monitor.h
+++ b/ovsdb/monitor.h
@@ -30,6 +30,9 @@ enum ovsdb_monitor_selection {
 struct ovsdb_monitor *ovsdb_monitor_create(struct ovsdb *db,
                         struct ovsdb_jsonrpc_monitor *jsonrpc_monitor);
 
+void ovsdb_monitor_remove_jsonrpc_monitor(struct ovsdb_monitor *dbmon,
+                               struct ovsdb_jsonrpc_monitor *jsonrpc_monitor);
+
 void ovsdb_monitor_add_table(struct ovsdb_monitor *m,
                              const struct ovsdb_table *table);
 
@@ -53,6 +56,4 @@ void ovsdb_monitor_table_set_select(struct ovsdb_monitor *dbmon,
 bool ovsdb_monitor_needs_flush(struct ovsdb_monitor *dbmon);
 
 void ovsdb_monitor_get_initial(const struct ovsdb_monitor *dbmon);
-
-void ovsdb_monitor_destroy(struct ovsdb_monitor *dbmon);
 #endif
-- 
1.9.1




More information about the dev mailing list