[ovs-dev] [PATCH v4 ovn 3/3] controller: add memory accounting for local_datapath

Lorenzo Bianconi lorenzo.bianconi at redhat.com
Thu Oct 14 15:17:01 UTC 2021


Similar to if-status-mgr, track memory allocated for local_datapath.

Signed-off-by: Lorenzo Bianconi <lorenzo.bianconi at redhat.com>
---
 controller/binding.c        |  6 ++--
 controller/local_data.c     | 66 +++++++++++++++++++++++++++++++++++++
 controller/local_data.h     |  7 ++++
 controller/ovn-controller.c |  1 +
 4 files changed, 77 insertions(+), 3 deletions(-)

diff --git a/controller/binding.c b/controller/binding.c
index c037b2352..329d0d12b 100644
--- a/controller/binding.c
+++ b/controller/binding.c
@@ -374,8 +374,8 @@ update_ld_external_ports(const struct sbrec_port_binding *binding_rec,
     struct local_datapath *ld = get_local_datapath(
         local_datapaths, binding_rec->datapath->tunnel_key);
     if (ld) {
-        shash_replace(&ld->external_ports, binding_rec->logical_port,
-                      binding_rec);
+        add_local_datapath_external_port(ld, binding_rec->logical_port,
+                                         binding_rec);
     }
 }
 
@@ -1756,7 +1756,7 @@ remove_pb_from_local_datapath(const struct sbrec_port_binding *pb,
             ld->localnet_port = NULL;
         }
     } else if (!strcmp(pb->type, "external")) {
-        shash_find_and_delete(&ld->external_ports, pb->logical_port);
+        remove_local_datapath_external_port(ld, pb->logical_port);
     }
 }
 
diff --git a/controller/local_data.c b/controller/local_data.c
index 6efed2de0..48e6958b7 100644
--- a/controller/local_data.c
+++ b/controller/local_data.c
@@ -47,6 +47,30 @@ static struct tracked_datapath *tracked_datapath_create(
     enum en_tracked_resource_type tracked_type,
     struct hmap *tracked_datapaths);
 
+static uint64_t local_datapath_usage;
+
+static void
+local_datapath_peer_ports_mem_add(struct local_datapath *ld,
+                                  size_t n_peer_ports)
+{
+    /* memory accounting - peer_ports. */
+    local_datapath_usage +=
+        (ld->n_allocated_peer_ports - n_peer_ports) * sizeof *ld->peer_ports;
+}
+
+static void
+local_datapath_ext_port_mem_update(struct local_datapath *ld, const char *name,
+                                   bool erase)
+{
+    struct shash_node *node = shash_find(&ld->external_ports, name);
+
+    if (!node && !erase) { /* add a new element */
+        local_datapath_usage += (sizeof *node + strlen(name));
+    } else if (node && erase) { /* remove an element */
+        local_datapath_usage -= (sizeof *node + strlen(name));
+    }
+}
+
 struct local_datapath *
 get_local_datapath(const struct hmap *local_datapaths, uint32_t tunnel_key)
 {
@@ -63,6 +87,9 @@ local_datapath_alloc(const struct sbrec_datapath_binding *dp)
     ld->datapath = dp;
     ld->is_switch = datapath_is_switch(dp);
     shash_init(&ld->external_ports);
+    /* memory accounting - common part. */
+    local_datapath_usage += sizeof *ld;
+
     return ld;
 }
 
@@ -80,6 +107,16 @@ local_datapaths_destroy(struct hmap *local_datapaths)
 void
 local_datapath_destroy(struct local_datapath *ld)
 {
+    /* memory accounting. */
+    struct shash_node *node;
+    SHASH_FOR_EACH (node, &ld->external_ports) {
+        local_datapath_usage -= strlen(node->name);
+    }
+    local_datapath_usage -= shash_count(&ld->external_ports) * sizeof *node;
+    local_datapath_usage -= sizeof *ld;
+    local_datapath_usage -=
+        ld->n_allocated_peer_ports * sizeof *ld->peer_ports;
+
     free(ld->peer_ports);
     shash_destroy(&ld->external_ports);
     free(ld);
@@ -175,10 +212,12 @@ add_local_datapath_peer_port(
     if (!present) {
         ld->n_peer_ports++;
         if (ld->n_peer_ports > ld->n_allocated_peer_ports) {
+            size_t n_peer_ports = ld->n_allocated_peer_ports;
             ld->peer_ports =
                 x2nrealloc(ld->peer_ports,
                            &ld->n_allocated_peer_ports,
                            sizeof *ld->peer_ports);
+            local_datapath_peer_ports_mem_add(ld, n_peer_ports);
         }
         ld->peer_ports[ld->n_peer_ports - 1].local = pb;
         ld->peer_ports[ld->n_peer_ports - 1].remote = peer;
@@ -204,10 +243,12 @@ add_local_datapath_peer_port(
 
     peer_ld->n_peer_ports++;
     if (peer_ld->n_peer_ports > peer_ld->n_allocated_peer_ports) {
+        size_t n_peer_ports = peer_ld->n_allocated_peer_ports;
         peer_ld->peer_ports =
             x2nrealloc(peer_ld->peer_ports,
                         &peer_ld->n_allocated_peer_ports,
                         sizeof *peer_ld->peer_ports);
+            local_datapath_peer_ports_mem_add(peer_ld, n_peer_ports);
     }
     peer_ld->peer_ports[peer_ld->n_peer_ports - 1].local = peer;
     peer_ld->peer_ports[peer_ld->n_peer_ports - 1].remote = pb;
@@ -248,6 +289,22 @@ remove_local_datapath_peer_port(const struct sbrec_port_binding *pb,
     }
 }
 
+void
+add_local_datapath_external_port(struct local_datapath *ld,
+                                 char *logical_port, const void *data)
+{
+    local_datapath_ext_port_mem_update(ld, logical_port, false);
+    shash_replace(&ld->external_ports, logical_port, data);
+}
+
+void
+remove_local_datapath_external_port(struct local_datapath *ld,
+                                    char *logical_port)
+{
+    local_datapath_ext_port_mem_update(ld, logical_port, true);
+    shash_find_and_delete(&ld->external_ports, logical_port);
+}
+
 /* track datapath functions. */
 struct tracked_datapath *
 tracked_datapath_add(const struct sbrec_datapath_binding *dp,
@@ -537,10 +594,12 @@ add_local_datapath__(struct ovsdb_idl_index *sbrec_datapath_binding_by_key,
                     }
                     ld->n_peer_ports++;
                     if (ld->n_peer_ports > ld->n_allocated_peer_ports) {
+                        size_t n_peer_ports = ld->n_allocated_peer_ports;
                         ld->peer_ports =
                             x2nrealloc(ld->peer_ports,
                                        &ld->n_allocated_peer_ports,
                                        sizeof *ld->peer_ports);
+                        local_datapath_peer_ports_mem_add(ld, n_peer_ports);
                     }
                     ld->peer_ports[ld->n_peer_ports - 1].local = pb;
                     ld->peer_ports[ld->n_peer_ports - 1].remote = peer;
@@ -563,3 +622,10 @@ tracked_datapath_create(const struct sbrec_datapath_binding *dp,
     hmap_insert(tracked_datapaths, &t_dp->node, uuid_hash(&dp->header_.uuid));
     return t_dp;
 }
+
+void
+local_datapath_memory_usage(struct simap *usage)
+{
+    simap_increase(usage, "local_datapath_usage-KB",
+                   ROUND_UP(local_datapath_usage, 1024) / 1024);
+}
diff --git a/controller/local_data.h b/controller/local_data.h
index f6317e9ca..3defa9925 100644
--- a/controller/local_data.h
+++ b/controller/local_data.h
@@ -154,5 +154,12 @@ bool get_chassis_tunnel_ofport(const struct hmap *chassis_tunnels,
                                ofp_port_t *ofport);
 
 void chassis_tunnels_destroy(struct hmap *chassis_tunnels);
+void local_datapath_memory_usage(struct simap *usage);
+void
+add_local_datapath_external_port(struct local_datapath *ld,
+                                 char *logical_port, const void *data);
+void
+remove_local_datapath_external_port(struct local_datapath *ld,
+                                    char *logical_port);
 
 #endif /* controller/local_data.h */
diff --git a/controller/ovn-controller.c b/controller/ovn-controller.c
index e0fb0988f..a8e252e9c 100644
--- a/controller/ovn-controller.c
+++ b/controller/ovn-controller.c
@@ -3464,6 +3464,7 @@ main(int argc, char *argv[])
             lflow_cache_get_memory_usage(ctrl_engine_ctx.lflow_cache, &usage);
             ofctrl_get_memory_usage(&usage);
             if_status_mgr_get_memory_usage(if_mgr, &usage);
+            local_datapath_memory_usage(&usage);
             memory_report(&usage);
             simap_destroy(&usage);
         }
-- 
2.31.1



More information about the dev mailing list