From: Ben Pfaff Date: Fri, 16 Jan 2009 18:37:13 +0000 (-0800) Subject: vswitchd: Reduce flow idle time when flow table grows large. X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=60bad97df2736509f0782d6bb30b2d99ce85742c;p=openvswitch vswitchd: Reduce flow idle time when flow table grows large. This change halves the number of steady-state flows in the flow table for hping3 --faster --quiet, from over 5000 to less than 2500. It does cause some oscillation in flow table size, because there is a harsh step function in idle time when the flow table goes from 1000 to 1001 flows, from 2001 to 2002 flows, and from 4003 to 4004 flows, but I doubt that is a problem. (If it is, we can introduce some randomness.) --- diff --git a/vswitchd/bridge.c b/vswitchd/bridge.c index fd7deb27..9b88fcd4 100644 --- a/vswitchd/bridge.c +++ b/vswitchd/bridge.c @@ -1084,6 +1084,27 @@ sanitize_opp(struct ofp_phy_port *opp) } opp->name[sizeof opp->name - 1] = '\0'; } + +/* Returns the idle time that the bridge is currently using. We reduce the + * idle time as the flow table grows, so as to act as a brake on further flow + * table growth. */ +static int +bridge_idle_time(const struct bridge *br) +{ + int idle_time = br->flow_idle_time; + if (idle_time) { + size_t n_flows = hmap_count(&br->ft->flows); + int step = MAX(1, br->flow_idle_time / 5); + while (n_flows > 1000 && idle_time > 0) { + idle_time -= step; + n_flows /= 2; + } + if (idle_time < 1) { + idle_time = 1; + } + } + return idle_time; +} /* Bridge packet processing functions. */ @@ -1580,7 +1601,7 @@ send_packets(struct bridge *br, const struct flow *flow, struct ofp_flow_mod *ofm; struct ofpbuf *fbuf; - fbuf = make_add_flow(flow, pkt->buffer_id, br->flow_idle_time, + fbuf = make_add_flow(flow, pkt->buffer_id, bridge_idle_time(br), actions_len); ofm = fbuf->data; ofm->command = htons(command); @@ -1658,7 +1679,7 @@ process_flow(struct bridge *br, const struct flow *flow, "interface %"PRIu16, br->name, in_ifidx); queue_tx(br, make_add_flow(flow, pkt->buffer_id, - br->flow_idle_time, 0)); + bridge_idle_time(br), 0)); if (f) { ftf_set_dsts(f, NULL, 0); f->tags = tags;