[ovs-dev] [PATCH] dpif-linux: Recycle leaked ports.

Ethan Jackson ethan at nicira.com
Fri Apr 29 22:50:08 UTC 2011


I was borderline on doing something like this.  In the case where the dump
doesn't complete successfully, the LRU list will essentially be re-initialized.
Without the following incremental, you could end up in a situation where the
LRU list is always completely repopulated by the dump code and thus useless.
With this patch, you could end up in a situation where the dumps are never
successful and all of the ports leak.  Both are extreme edge cases.  I suppose
the following incremental is more correct.

---
 lib/dpif-linux.c |   14 ++++++++++----
 1 files changed, 10 insertions(+), 4 deletions(-)

diff --git a/lib/dpif-linux.c b/lib/dpif-linux.c
index db917d9..90ed1fb 100644
--- a/lib/dpif-linux.c
+++ b/lib/dpif-linux.c
@@ -473,6 +473,7 @@ dpif_linux_flow_flush(struct dpif *dpif_)
 struct dpif_linux_port_state {
     struct nl_dump dump;
     unsigned long *port_bitmap; /* Ports in the datapath. */
+    bool success;               /* Dump completed without error. */
 };
 
 static int
@@ -485,6 +486,7 @@ dpif_linux_port_dump_start(const struct dpif *dpif_, void **statep)
 
     *statep = state = xmalloc(sizeof *state);
     state->port_bitmap = bitmap_allocate(LRU_MAX_PORTS);
+    state->success = false;
 
     dpif_linux_vport_init(&request);
     request.cmd = ODP_DP_CMD_GET;
@@ -508,6 +510,7 @@ dpif_linux_port_dump_next(const struct dpif *dpif OVS_UNUSED, void *state_,
     int error;
 
     if (!nl_dump_next(&state->dump, &buf)) {
+        state->success = true;
         return EOF;
     }
 
@@ -532,11 +535,14 @@ dpif_linux_port_dump_done(const struct dpif *dpif_, void *state_)
     struct dpif_linux *dpif = dpif_linux_cast(dpif_);
     struct dpif_linux_port_state *state = state_;
     int error = nl_dump_done(&state->dump);
-    uint16_t i;
 
-    for (i = 0; i < LRU_MAX_PORTS; i++) {
-        if (!bitmap_is_set(state->port_bitmap, i)) {
-            dpif_linux_push_port(dpif, i);
+    if (state->success) {
+        uint16_t i;
+
+        for (i = 0; i < LRU_MAX_PORTS; i++) {
+            if (!bitmap_is_set(state->port_bitmap, i)) {
+                dpif_linux_push_port(dpif, i);
+            }
         }
     }
 
-- 
1.7.4.4




More information about the dev mailing list