[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