Before this patch, the "need_revalidate" flag and the
"revalidate_set" tag_set where maintained separately for each
ofproto.  This won't work in future patches when a flow table
change in one ofproto can require revalidation in another entirely
separate ofproto.  For this reason, this patch makes these flags
global for all ofprotos in ofproto-dpif.

Signed-off-by: Ethan Jackson <et...@nicira.com>
---
 ofproto/ofproto-dpif.c |  173 +++++++++++++++++++++++-------------------------
 1 file changed, 81 insertions(+), 92 deletions(-)

diff --git a/ofproto/ofproto-dpif.c b/ofproto/ofproto-dpif.c
index bc54122..f466f6a 100644
--- a/ofproto/ofproto-dpif.c
+++ b/ofproto/ofproto-dpif.c
@@ -612,6 +612,9 @@ COVERAGE_DEFINE(rev_port_toggled);
 COVERAGE_DEFINE(rev_flow_table);
 COVERAGE_DEFINE(rev_inconsistency);
 
+static enum revalidate_reason need_revalidate;
+static struct tag_set revalidate_set;
+
 /* All datapaths of a given type share a single dpif backer instance. */
 struct dpif_backer {
     char *type;
@@ -655,8 +658,6 @@ struct ofproto_dpif {
 
     /* Revalidation. */
     struct table_dpif tables[N_TABLES];
-    enum revalidate_reason need_revalidate;
-    struct tag_set revalidate_set;
 
     /* Support for debugging async flow mods. */
     struct list completions;
@@ -748,6 +749,8 @@ init(const struct shash *iface_hints)
 
         shash_add(&init_ofp_ports, node->name, new_hint);
     }
+    need_revalidate = 0;
+    tag_set_init(&revalidate_set);
 }
 
 static void
@@ -815,6 +818,32 @@ type_run(const char *type)
     char *devname;
     int error;
 
+    if (need_revalidate || !tag_set_is_empty(&revalidate_set)) {
+        struct ofproto_dpif *ofproto;
+
+        switch (need_revalidate) {
+        case REV_RECONFIGURE:   COVERAGE_INC(rev_reconfigure);   break;
+        case REV_STP:           COVERAGE_INC(rev_stp);           break;
+        case REV_PORT_TOGGLED:  COVERAGE_INC(rev_port_toggled);  break;
+        case REV_FLOW_TABLE:    COVERAGE_INC(rev_flow_table);    break;
+        case REV_INCONSISTENCY: COVERAGE_INC(rev_inconsistency); break;
+        }
+
+        HMAP_FOR_EACH (ofproto, all_ofproto_dpifs_node, &all_ofproto_dpifs) {
+            struct facet *facet;
+
+            HMAP_FOR_EACH (facet, hmap_node, &ofproto->facets) {
+                if (need_revalidate || tag_set_intersects(&revalidate_set,
+                                                          facet->tags)) {
+                    facet_revalidate(facet);
+                }
+            }
+        }
+
+        need_revalidate = 0;
+        tag_set_init(&revalidate_set);
+    }
+
     backer = shash_find_data(&all_dpif_backers, type);
     if (!backer) {
         /* This is not necessarily a problem, since backers are only
@@ -1106,8 +1135,6 @@ construct(struct ofproto *ofproto_)
         table->other_table = NULL;
         table->basis = random_uint32();
     }
-    ofproto->need_revalidate = 0;
-    tag_set_init(&ofproto->revalidate_set);
 
     list_init(&ofproto->completions);
 
@@ -1316,44 +1343,17 @@ run(struct ofproto *ofproto_)
     }
 
     stp_run(ofproto);
-    mac_learning_run(ofproto->ml, &ofproto->revalidate_set);
-
-    /* Now revalidate if there's anything to do. */
-    if (ofproto->need_revalidate
-        || !tag_set_is_empty(&ofproto->revalidate_set)) {
-        struct tag_set revalidate_set = ofproto->revalidate_set;
-        bool revalidate_all = ofproto->need_revalidate;
-        struct facet *facet;
-
-        switch (ofproto->need_revalidate) {
-        case REV_RECONFIGURE:   COVERAGE_INC(rev_reconfigure);   break;
-        case REV_STP:           COVERAGE_INC(rev_stp);           break;
-        case REV_PORT_TOGGLED:  COVERAGE_INC(rev_port_toggled);  break;
-        case REV_FLOW_TABLE:    COVERAGE_INC(rev_flow_table);    break;
-        case REV_INCONSISTENCY: COVERAGE_INC(rev_inconsistency); break;
-        }
-
-        /* Clear the revalidation flags. */
-        tag_set_init(&ofproto->revalidate_set);
-        ofproto->need_revalidate = 0;
-
-        HMAP_FOR_EACH (facet, hmap_node, &ofproto->facets) {
-            if (revalidate_all
-                || tag_set_intersects(&revalidate_set, facet->tags)) {
-                facet_revalidate(facet);
-            }
-        }
-    }
+    mac_learning_run(ofproto->ml, &revalidate_set);
 
     /* Check the consistency of a random facet, to aid debugging. */
-    if (!hmap_is_empty(&ofproto->facets) && !ofproto->need_revalidate) {
+    if (!hmap_is_empty(&ofproto->facets) && need_revalidate) {
         struct facet *facet;
 
         facet = CONTAINER_OF(hmap_random_node(&ofproto->facets),
                              struct facet, hmap_node);
-        if (!tag_set_intersects(&ofproto->revalidate_set, facet->tags)) {
+        if (!tag_set_intersects(&revalidate_set, facet->tags)) {
             if (!facet_check_consistency(facet)) {
-                ofproto->need_revalidate = REV_INCONSISTENCY;
+                need_revalidate = REV_INCONSISTENCY;
             }
         }
     }
@@ -1395,7 +1395,7 @@ wait(struct ofproto *ofproto_)
     if (ofproto->sflow) {
         dpif_sflow_wait(ofproto->sflow);
     }
-    if (!tag_set_is_empty(&ofproto->revalidate_set)) {
+    if (!tag_set_is_empty(&revalidate_set)) {
         poll_immediate_wake();
     }
     HMAP_FOR_EACH (ofport, up.hmap_node, &ofproto->up.ports) {
@@ -1409,7 +1409,7 @@ wait(struct ofproto *ofproto_)
     }
     mac_learning_wait(ofproto->ml);
     stp_wait(ofproto);
-    if (ofproto->need_revalidate) {
+    if (need_revalidate) {
         /* Shouldn't happen, but if it does just go around again. */
         VLOG_DBG_RL(&rl, "need revalidate in ofproto_wait_cb()");
         poll_immediate_wake();
@@ -1510,7 +1510,7 @@ port_construct(struct ofport *port_)
     struct dpif_port dpif_port;
     int error;
 
-    ofproto->need_revalidate = REV_RECONFIGURE;
+    need_revalidate = REV_RECONFIGURE;
     port->bundle = NULL;
     port->cfm = NULL;
     port->tag = tag_create_random();
@@ -1566,7 +1566,7 @@ port_destruct(struct ofport *port_)
 
     sset_find_and_delete(&ofproto->ports, devname);
     hmap_remove(&ofproto->backer->odp_to_ofport_map, &port->odp_port_node);
-    ofproto->need_revalidate = REV_RECONFIGURE;
+    need_revalidate = REV_RECONFIGURE;
     bundle_remove(port_);
     set_cfm(port_, NULL);
     if (ofproto->sflow) {
@@ -1591,13 +1591,12 @@ static void
 port_reconfigured(struct ofport *port_, enum ofputil_port_config old_config)
 {
     struct ofport_dpif *port = ofport_dpif_cast(port_);
-    struct ofproto_dpif *ofproto = ofproto_dpif_cast(port->up.ofproto);
     enum ofputil_port_config changed = old_config ^ port->up.pp.config;
 
     if (changed & (OFPUTIL_PC_NO_RECV | OFPUTIL_PC_NO_RECV_STP |
                    OFPUTIL_PC_NO_FWD | OFPUTIL_PC_NO_FLOOD |
                    OFPUTIL_PC_NO_PACKET_IN)) {
-        ofproto->need_revalidate = REV_RECONFIGURE;
+        need_revalidate = REV_RECONFIGURE;
 
         if (changed & OFPUTIL_PC_NO_FLOOD && port->bundle) {
             bundle_update(port->bundle);
@@ -1620,13 +1619,13 @@ set_sflow(struct ofproto *ofproto_,
             HMAP_FOR_EACH (ofport, up.hmap_node, &ofproto->up.ports) {
                 dpif_sflow_add_port(ds, &ofport->up, ofport->odp_port);
             }
-            ofproto->need_revalidate = REV_RECONFIGURE;
+            need_revalidate = REV_RECONFIGURE;
         }
         dpif_sflow_set_options(ds, sflow_options);
     } else {
         if (ds) {
             dpif_sflow_destroy(ds);
-            ofproto->need_revalidate = REV_RECONFIGURE;
+            need_revalidate = REV_RECONFIGURE;
             ofproto->sflow = NULL;
         }
     }
@@ -1643,10 +1642,7 @@ set_cfm(struct ofport *ofport_, const struct 
cfm_settings *s)
         error = 0;
     } else {
         if (!ofport->cfm) {
-            struct ofproto_dpif *ofproto;
-
-            ofproto = ofproto_dpif_cast(ofport->up.ofproto);
-            ofproto->need_revalidate = REV_RECONFIGURE;
+            need_revalidate = REV_RECONFIGURE;
             ofport->cfm = cfm_create(netdev_get_name(ofport->up.netdev));
         }
 
@@ -1734,7 +1730,7 @@ set_stp(struct ofproto *ofproto_, const struct 
ofproto_stp_settings *s)
 
     /* Only revalidate flows if the configuration changed. */
     if (!s != !ofproto->stp) {
-        ofproto->need_revalidate = REV_RECONFIGURE;
+        need_revalidate = REV_RECONFIGURE;
     }
 
     if (s) {
@@ -1802,12 +1798,12 @@ update_stp_port_state(struct ofport_dpif *ofport)
         if (stp_learn_in_state(ofport->stp_state)
                 != stp_learn_in_state(state)) {
             /* xxx Learning action flows should also be flushed. */
-            mac_learning_flush(ofproto->ml, &ofproto->revalidate_set);
+            mac_learning_flush(ofproto->ml, &revalidate_set);
         }
         fwd_change = stp_forward_in_state(ofport->stp_state)
                         != stp_forward_in_state(state);
 
-        ofproto->need_revalidate = REV_STP;
+        need_revalidate = REV_STP;
         ofport->stp_state = state;
         ofport->stp_state_entered = time_msec();
 
@@ -1907,7 +1903,7 @@ stp_run(struct ofproto_dpif *ofproto)
         }
 
         if (stp_check_and_reset_fdb_flush(ofproto->stp)) {
-            mac_learning_flush(ofproto->ml, &ofproto->revalidate_set);
+            mac_learning_flush(ofproto->ml, &revalidate_set);
         }
     }
 }
@@ -2005,12 +2001,12 @@ set_queues(struct ofport *ofport_,
             pdscp = xmalloc(sizeof *pdscp);
             pdscp->priority = priority;
             pdscp->dscp = dscp;
-            ofproto->need_revalidate = REV_RECONFIGURE;
+            need_revalidate = REV_RECONFIGURE;
         }
 
         if (pdscp->dscp != dscp) {
             pdscp->dscp = dscp;
-            ofproto->need_revalidate = REV_RECONFIGURE;
+            need_revalidate = REV_RECONFIGURE;
         }
 
         hmap_insert(&new, &pdscp->hmap_node, hash_int(pdscp->priority, 0));
@@ -2018,7 +2014,7 @@ set_queues(struct ofport *ofport_,
 
     if (!hmap_is_empty(&ofport->priorities)) {
         ofport_clear_priorities(ofport);
-        ofproto->need_revalidate = REV_RECONFIGURE;
+        need_revalidate = REV_RECONFIGURE;
     }
 
     hmap_swap(&new, &ofport->priorities);
@@ -2045,7 +2041,7 @@ bundle_flush_macs(struct ofbundle *bundle, bool 
all_ofprotos)
     struct mac_learning *ml = ofproto->ml;
     struct mac_entry *mac, *next_mac;
 
-    ofproto->need_revalidate = REV_RECONFIGURE;
+    need_revalidate = REV_RECONFIGURE;
     LIST_FOR_EACH_SAFE (mac, next_mac, lru_node, &ml->lrus) {
         if (mac->port.p == bundle) {
             if (all_ofprotos) {
@@ -2058,7 +2054,6 @@ bundle_flush_macs(struct ofbundle *bundle, bool 
all_ofprotos)
                         e = mac_learning_lookup(o->ml, mac->mac, mac->vlan,
                                                 NULL);
                         if (e) {
-                            tag_set_add(&o->revalidate_set, e->tag);
                             mac_learning_expire(o->ml, e);
                         }
                     }
@@ -2122,7 +2117,7 @@ bundle_del_port(struct ofport_dpif *port)
 {
     struct ofbundle *bundle = port->bundle;
 
-    bundle->ofproto->need_revalidate = REV_RECONFIGURE;
+    need_revalidate = REV_RECONFIGURE;
 
     list_remove(&port->bundle_node);
     port->bundle = NULL;
@@ -2150,7 +2145,7 @@ bundle_add_port(struct ofbundle *bundle, uint32_t 
ofp_port,
     }
 
     if (port->bundle != bundle) {
-        bundle->ofproto->need_revalidate = REV_RECONFIGURE;
+        need_revalidate = REV_RECONFIGURE;
         if (port->bundle) {
             bundle_del_port(port);
         }
@@ -2163,7 +2158,7 @@ bundle_add_port(struct ofbundle *bundle, uint32_t 
ofp_port,
         }
     }
     if (lacp) {
-        port->bundle->ofproto->need_revalidate = REV_RECONFIGURE;
+        need_revalidate = REV_RECONFIGURE;
         lacp_slave_register(bundle->lacp, port, lacp);
     }
 
@@ -2191,7 +2186,7 @@ bundle_destroy(struct ofbundle *bundle)
                 mirror_destroy(m);
             } else if (hmapx_find_and_delete(&m->srcs, bundle)
                        || hmapx_find_and_delete(&m->dsts, bundle)) {
-                ofproto->need_revalidate = REV_RECONFIGURE;
+                need_revalidate = REV_RECONFIGURE;
             }
         }
     }
@@ -2263,7 +2258,7 @@ bundle_set(struct ofproto *ofproto_, void *aux,
     /* LACP. */
     if (s->lacp) {
         if (!bundle->lacp) {
-            ofproto->need_revalidate = REV_RECONFIGURE;
+            need_revalidate = REV_RECONFIGURE;
             bundle->lacp = lacp_create();
         }
         lacp_configure(bundle->lacp, s->lacp);
@@ -2369,11 +2364,11 @@ bundle_set(struct ofproto *ofproto_, void *aux,
         bundle->ofproto->has_bonded_bundles = true;
         if (bundle->bond) {
             if (bond_reconfigure(bundle->bond, s->bond)) {
-                ofproto->need_revalidate = REV_RECONFIGURE;
+                need_revalidate = REV_RECONFIGURE;
             }
         } else {
             bundle->bond = bond_create(s->bond);
-            ofproto->need_revalidate = REV_RECONFIGURE;
+            need_revalidate = REV_RECONFIGURE;
         }
 
         LIST_FOR_EACH (port, bundle_node, &bundle->ports) {
@@ -2493,8 +2488,7 @@ bundle_run(struct ofbundle *bundle)
             bond_slave_set_may_enable(bundle->bond, port, port->may_enable);
         }
 
-        bond_run(bundle->bond, &bundle->ofproto->revalidate_set,
-                 lacp_status(bundle->lacp));
+        bond_run(bundle->bond, &revalidate_set, lacp_status(bundle->lacp));
         if (bond_should_send_learning_packets(bundle->bond)) {
             bundle_send_learning_packets(bundle);
         }
@@ -2678,9 +2672,9 @@ mirror_set(struct ofproto *ofproto_, void *aux,
         }
     }
 
-    ofproto->need_revalidate = REV_RECONFIGURE;
+    need_revalidate = REV_RECONFIGURE;
     ofproto->has_mirrors = true;
-    mac_learning_flush(ofproto->ml, &ofproto->revalidate_set);
+    mac_learning_flush(ofproto->ml, &revalidate_set);
     mirror_update_dups(ofproto);
 
     return 0;
@@ -2699,8 +2693,8 @@ mirror_destroy(struct ofmirror *mirror)
     }
 
     ofproto = mirror->ofproto;
-    ofproto->need_revalidate = REV_RECONFIGURE;
-    mac_learning_flush(ofproto->ml, &ofproto->revalidate_set);
+    need_revalidate = REV_RECONFIGURE;
+    mac_learning_flush(ofproto->ml, &revalidate_set);
 
     mirror_bit = MIRROR_MASK_C(1) << mirror->idx;
     HMAP_FOR_EACH (bundle, hmap_node, &ofproto->bundles) {
@@ -2751,7 +2745,7 @@ set_flood_vlans(struct ofproto *ofproto_, unsigned long 
*flood_vlans)
 {
     struct ofproto_dpif *ofproto = ofproto_dpif_cast(ofproto_);
     if (mac_learning_set_flood_vlans(ofproto->ml, flood_vlans)) {
-        mac_learning_flush(ofproto->ml, &ofproto->revalidate_set);
+        mac_learning_flush(ofproto->ml, &revalidate_set);
     }
     return 0;
 }
@@ -2765,10 +2759,9 @@ is_mirror_output_bundle(const struct ofproto *ofproto_, 
void *aux)
 }
 
 static void
-forward_bpdu_changed(struct ofproto *ofproto_)
+forward_bpdu_changed(struct ofproto *ofproto OVS_UNUSED)
 {
-    struct ofproto_dpif *ofproto = ofproto_dpif_cast(ofproto_);
-    ofproto->need_revalidate = REV_RECONFIGURE;
+    need_revalidate = REV_RECONFIGURE;
 }
 
 static void
@@ -2851,7 +2844,7 @@ port_run(struct ofport_dpif *ofport)
         struct ofproto_dpif *ofproto = ofproto_dpif_cast(ofport->up.ofproto);
 
         if (ofproto->has_bundle_action) {
-            ofproto->need_revalidate = REV_PORT_TOGGLED;
+            need_revalidate = REV_PORT_TOGGLED;
         }
     }
 
@@ -3757,7 +3750,7 @@ expire(struct dpif_backer *backer)
 
             HMAP_FOR_EACH (bundle, hmap_node, &ofproto->bundles) {
                 if (bundle->bond) {
-                    bond_rebalance(bundle->bond, &ofproto->revalidate_set);
+                    bond_rebalance(bundle->bond, &revalidate_set);
                 }
             }
         }
@@ -4321,8 +4314,8 @@ facet_lookup_valid(struct ofproto_dpif *ofproto, const 
struct flow *flow,
 
     facet = facet_find(ofproto, flow, hash);
     if (facet
-        && (ofproto->need_revalidate
-            || tag_set_intersects(&ofproto->revalidate_set, facet->tags))) {
+        && (need_revalidate || tag_set_intersects(&revalidate_set,
+                                                  facet->tags))) {
         facet_revalidate(facet);
     }
 
@@ -6590,8 +6583,7 @@ update_learning_table(struct ofproto_dpif *ofproto,
                     in_bundle->name, vlan);
 
         mac->port.p = in_bundle;
-        tag_set_add(&ofproto->revalidate_set,
-                    mac_learning_changed(ofproto->ml, mac));
+        tag_set_add(&revalidate_set, mac_learning_changed(ofproto->ml, mac));
     }
 }
 
@@ -6866,7 +6858,7 @@ table_update_taggable(struct ofproto_dpif *ofproto, 
uint8_t table_id)
     if (table->catchall_table != catchall || table->other_table != other) {
         table->catchall_table = catchall;
         table->other_table = other;
-        ofproto->need_revalidate = REV_FLOW_TABLE;
+        need_revalidate = REV_FLOW_TABLE;
     }
 }
 
@@ -6884,25 +6876,23 @@ rule_invalidate(const struct rule_dpif *rule)
 
     table_update_taggable(ofproto, rule->up.table_id);
 
-    if (!ofproto->need_revalidate) {
+    if (!need_revalidate) {
         struct table_dpif *table = &ofproto->tables[rule->up.table_id];
 
         if (table->other_table && rule->tag) {
-            tag_set_add(&ofproto->revalidate_set, rule->tag);
+            tag_set_add(&revalidate_set, rule->tag);
         } else {
-            ofproto->need_revalidate = REV_FLOW_TABLE;
+            need_revalidate = REV_FLOW_TABLE;
         }
     }
 }
 
 static bool
-set_frag_handling(struct ofproto *ofproto_,
+set_frag_handling(struct ofproto *ofproto OVS_UNUSED,
                   enum ofp_config_flags frag_handling)
 {
-    struct ofproto_dpif *ofproto = ofproto_dpif_cast(ofproto_);
-
     if (frag_handling != OFPC_FRAG_REASM) {
-        ofproto->need_revalidate = REV_RECONFIGURE;
+        need_revalidate = REV_RECONFIGURE;
         return true;
     } else {
         return false;
@@ -7034,10 +7024,10 @@ ofproto_unixctl_fdb_flush(struct unixctl_conn *conn, 
int argc,
             unixctl_command_reply_error(conn, "no such bridge");
             return;
         }
-        mac_learning_flush(ofproto->ml, &ofproto->revalidate_set);
+        mac_learning_flush(ofproto->ml, &revalidate_set);
     } else {
         HMAP_FOR_EACH (ofproto, all_ofproto_dpifs_node, &all_ofproto_dpifs) {
-            mac_learning_flush(ofproto->ml, &ofproto->revalidate_set);
+            mac_learning_flush(ofproto->ml, &revalidate_set);
         }
     }
 
@@ -7405,7 +7395,7 @@ ofproto_dpif_self_check__(struct ofproto_dpif *ofproto, 
struct ds *reply)
         }
     }
     if (errors) {
-        ofproto->need_revalidate = REV_INCONSISTENCY;
+        need_revalidate = REV_INCONSISTENCY;
     }
 
     if (errors) {
@@ -7690,7 +7680,6 @@ ofproto_dpif_unixctl_init(void)
 static int
 set_realdev(struct ofport *ofport_, uint16_t realdev_ofp_port, int vid)
 {
-    struct ofproto_dpif *ofproto = ofproto_dpif_cast(ofport_->ofproto);
     struct ofport_dpif *ofport = ofport_dpif_cast(ofport_);
 
     if (realdev_ofp_port == ofport->realdev_ofp_port
@@ -7698,7 +7687,7 @@ set_realdev(struct ofport *ofport_, uint16_t 
realdev_ofp_port, int vid)
         return 0;
     }
 
-    ofproto->need_revalidate = REV_RECONFIGURE;
+    need_revalidate = REV_RECONFIGURE;
 
     if (ofport->realdev_ofp_port) {
         vsp_remove(ofport);
-- 
1.7.9.5

_______________________________________________
dev mailing list
dev@openvswitch.org
http://openvswitch.org/mailman/listinfo/dev

Reply via email to