ofproto: Re-use port numbers of ports that were deleted an hour ago.
authorGurucharan Shetty <gshetty@nicira.com>
Mon, 14 Oct 2013 20:36:41 +0000 (13:36 -0700)
committerGurucharan Shetty <gshetty@nicira.com>
Wed, 16 Oct 2013 16:54:06 +0000 (09:54 -0700)
We have a least recently used algorithm for assigning ofport values
to newly created ports. i.e., when we don't have any unused ofport
numbers, we use ofport numbers from the oldest deleted port.
What this means is that after using ~65000 previously unused ofport
numbers, we will have to go through all of the possible ports
to see which one was least recently used. This will eventually
slow down ofport allocation.

With this commit, any port that was deleted more than an hour ago is
considered never to have been used. So it's ofport number becomes
free to be used.

Signed-off-by: Gurucharan Shetty <gshetty@nicira.com>
Acked-by: Ben Pfaff <blp@nicira.com>
ofproto/ofproto.c

index fe004b5..f44a7c4 100644 (file)
@@ -241,6 +241,7 @@ static long long int ofport_get_usage(const struct ofproto *,
                                       ofp_port_t ofp_port);
 static void ofport_set_usage(struct ofproto *, ofp_port_t ofp_port,
                              long long int last_used);
+static void ofport_remove_usage(struct ofproto *, ofp_port_t ofp_port);
 
 /* Ofport usage.
  *
@@ -1972,6 +1973,13 @@ alloc_ofp_port(struct ofproto *ofproto, const char *netdev_name)
             if (!last_used_at) {
                 port_idx = ofproto->alloc_port_no;
                 break;
+            } else if ( last_used_at < time_msec() - 60*60*1000) {
+                /* If the port with ofport 'ofproto->alloc_port_no' was deleted
+                 * more than an hour ago, consider it usable. */
+                ofport_remove_usage(ofproto,
+                    u16_to_ofp(ofproto->alloc_port_no));
+                port_idx = ofproto->alloc_port_no;
+                break;
             } else if (last_used_at < lru) {
                 lru = last_used_at;
                 lru_ofport = ofproto->alloc_port_no;
@@ -2254,6 +2262,20 @@ ofport_set_usage(struct ofproto *ofproto, ofp_port_t ofp_port,
                 hash_ofp_port(ofp_port));
 }
 
+static void
+ofport_remove_usage(struct ofproto *ofproto, ofp_port_t ofp_port)
+{
+    struct ofport_usage *usage;
+    HMAP_FOR_EACH_IN_BUCKET (usage, hmap_node, hash_ofp_port(ofp_port),
+                             &ofproto->ofport_usage) {
+        if (usage->ofp_port == ofp_port) {
+            hmap_remove(&ofproto->ofport_usage, &usage->hmap_node);
+            free(usage);
+            break;
+        }
+    }
+}
+
 int
 ofproto_port_get_stats(const struct ofport *port, struct netdev_stats *stats)
 {