The mac-learning implementation used a free list to keep track of
statically allocated table entries.  This made the code slightly
more difficult to understand than the more straightforward heap
based strategy implemented by this patch.
---
 lib/mac-learning.c |   23 +++++++++++++----------
 lib/mac-learning.h |    2 --
 2 files changed, 13 insertions(+), 12 deletions(-)

diff --git a/lib/mac-learning.c b/lib/mac-learning.c
index 067ef82..1f9a3b4 100644
--- a/lib/mac-learning.c
+++ b/lib/mac-learning.c
@@ -103,16 +103,10 @@ struct mac_learning *
 mac_learning_create(void)
 {
     struct mac_learning *ml;
-    int i;
 
     ml = xmalloc(sizeof *ml);
     list_init(&ml->lrus);
-    list_init(&ml->free);
     hmap_init(&ml->table);
-    for (i = 0; i < MAC_MAX; i++) {
-        struct mac_entry *s = &ml->entries[i];
-        list_push_front(&ml->free, &s->lru_node);
-    }
     ml->secret = random_uint32();
     ml->flood_vlans = NULL;
     return ml;
@@ -123,7 +117,14 @@ void
 mac_learning_destroy(struct mac_learning *ml)
 {
     if (ml) {
+        struct mac_entry *e, *next;
+
+        HMAP_FOR_EACH_SAFE (e, next, hmap_node, &ml->table) {
+            hmap_remove(&ml->table, &e->hmap_node);
+            free(e);
+        }
         hmap_destroy(&ml->table);
+
         bitmap_free(ml->flood_vlans);
         free(ml);
     }
@@ -181,11 +182,12 @@ mac_learning_insert(struct mac_learning *ml,
     if (!e) {
         uint32_t hash = mac_table_hash(ml, src_mac, vlan);
 
-        if (!list_is_empty(&ml->free)) {
-            e = mac_entry_from_lru_node(ml->free.next);
+        if (hmap_count(&ml->table) < MAC_MAX) {
+            e = xmalloc(sizeof *e);
         } else {
             e = mac_entry_from_lru_node(ml->lrus.next);
             hmap_remove(&ml->table, &e->hmap_node);
+            list_remove(&e->lru_node);
         }
 
         hmap_insert(&ml->table, &e->hmap_node, hash);
@@ -193,10 +195,11 @@ mac_learning_insert(struct mac_learning *ml,
         e->vlan = vlan;
         e->tag = 0;
         e->grat_arp_lock = TIME_MIN;
+    } else {
+        list_remove(&e->lru_node);
     }
 
     /* Mark 'e' as recently used. */
-    list_remove(&e->lru_node);
     list_push_back(&ml->lrus, &e->lru_node);
     e->expires = time_now() + MAC_ENTRY_IDLE_TIME;
 
@@ -257,7 +260,7 @@ mac_learning_expire(struct mac_learning *ml, struct 
mac_entry *e)
 {
     hmap_remove(&ml->table, &e->hmap_node);
     list_remove(&e->lru_node);
-    list_push_front(&ml->free, &e->lru_node);
+    free(e);
 }
 
 /* Expires all the mac-learning entries in 'ml'.  The tags in 'ml' are
diff --git a/lib/mac-learning.h b/lib/mac-learning.h
index d2f2874..d08cb2c 100644
--- a/lib/mac-learning.h
+++ b/lib/mac-learning.h
@@ -76,10 +76,8 @@ static inline bool mac_entry_is_grat_arp_locked(const struct 
mac_entry *mac)
 /* MAC learning table. */
 struct mac_learning {
     struct hmap table;          /* Learning table. */
-    struct list free;           /* Not-in-use entries. */
     struct list lrus;           /* In-use entries, least recently used at the
                                    front, most recently used at the back. */
-    struct mac_entry entries[MAC_MAX]; /* All entries. */
     uint32_t secret;            /* Secret for randomizing hash table. */
     unsigned long *flood_vlans; /* Bitmap of learning disabled VLANs. */
 };
-- 
1.7.6

_______________________________________________
dev mailing list
[email protected]
http://openvswitch.org/mailman/listinfo/dev

Reply via email to