ofproto internally modifies 'modify_cookie' field, and adding a
replica to ofproto_flow_mod allows the ofputil_flow_mod argument to be
changed to a const.

Signed-off-by: Jarno Rajahalme <ja...@ovn.org>
---
 ofproto/ofproto-dpif.c     | 27 +++++++++------------------
 ofproto/ofproto-provider.h |  3 ++-
 ofproto/ofproto.c          | 36 +++++++++++++++++++-----------------
 3 files changed, 30 insertions(+), 36 deletions(-)

diff --git a/ofproto/ofproto-dpif.c b/ofproto/ofproto-dpif.c
index aa933b1..fd2c2bd 100644
--- a/ofproto/ofproto-dpif.c
+++ b/ofproto/ofproto-dpif.c
@@ -362,16 +362,7 @@ void
 ofproto_dpif_flow_mod(struct ofproto_dpif *ofproto,
                       const struct ofputil_flow_mod *fm)
 {
-    struct ofproto_flow_mod ofm;
-
-    /* Multiple threads may do this for the same 'fm' at the same time.
-     * Allocate ofproto_flow_mod with execution context from stack.
-     *
-     * Note: This copy could be avoided by making ofproto_flow_mod more
-     * complex, but that may not be desireable, and a learn action is not that
-     * fast to begin with. */
-    ofm.fm = *fm;
-    ofproto_flow_mod(&ofproto->up, &ofm);
+    ofproto_flow_mod(&ofproto->up, fm);
 }
 
 /* Appends 'am' to the queue of asynchronous messages to be sent to the
@@ -5546,11 +5537,11 @@ ofproto_dpif_add_internal_flow(struct ofproto_dpif 
*ofproto,
                                const struct ofpbuf *ofpacts,
                                struct rule **rulep)
 {
-    struct ofproto_flow_mod ofm;
+    struct ofputil_flow_mod fm;
     struct rule_dpif *rule;
     int error;
 
-    ofm.fm = (struct ofputil_flow_mod) {
+    fm = (struct ofputil_flow_mod) {
         .match = *match,
         .priority = priority,
         .table_id = TBL_INTERNAL,
@@ -5561,7 +5552,7 @@ ofproto_dpif_add_internal_flow(struct ofproto_dpif 
*ofproto,
         .ofpacts_len = ofpacts->size,
     };
 
-    error = ofproto_flow_mod(&ofproto->up, &ofm);
+    error = ofproto_flow_mod(&ofproto->up, &fm);
     if (error) {
         VLOG_ERR_RL(&rl, "failed to add internal flow (%s)",
                     ofperr_to_string(error));
@@ -5571,8 +5562,8 @@ ofproto_dpif_add_internal_flow(struct ofproto_dpif 
*ofproto,
 
     rule = rule_dpif_lookup_in_table(ofproto,
                                      ofproto_dpif_get_tables_version(ofproto),
-                                     TBL_INTERNAL, &ofm.fm.match.flow,
-                                     &ofm.fm.match.wc);
+                                     TBL_INTERNAL, &fm.match.flow,
+                                     &fm.match.wc);
     if (rule) {
         *rulep = &rule->up;
     } else {
@@ -5585,10 +5576,10 @@ int
 ofproto_dpif_delete_internal_flow(struct ofproto_dpif *ofproto,
                                   struct match *match, int priority)
 {
-    struct ofproto_flow_mod ofm;
+    struct ofputil_flow_mod fm;
     int error;
 
-    ofm.fm = (struct ofputil_flow_mod) {
+    fm = (struct ofputil_flow_mod) {
         .match = *match,
         .priority = priority,
         .table_id = TBL_INTERNAL,
@@ -5596,7 +5587,7 @@ ofproto_dpif_delete_internal_flow(struct ofproto_dpif 
*ofproto,
         .command = OFPFC_DELETE_STRICT,
     };
 
-    error = ofproto_flow_mod(&ofproto->up, &ofm);
+    error = ofproto_flow_mod(&ofproto->up, &fm);
     if (error) {
         VLOG_ERR_RL(&rl, "failed to delete internal flow (%s)",
                     ofperr_to_string(error));
diff --git a/ofproto/ofproto-provider.h b/ofproto/ofproto-provider.h
index fb5fc95..f328b4a 100644
--- a/ofproto/ofproto-provider.h
+++ b/ofproto/ofproto-provider.h
@@ -1911,6 +1911,7 @@ struct ofproto_flow_mod {
     /* Replicate needed fields from ofputil_flow_mod to not need it after the
      * flow has been created. */
     uint32_t buffer_id;
+    bool modify_cookie;
 
     bool modify_may_add_flow;
     enum nx_flow_update_event event;
@@ -1937,7 +1938,7 @@ struct ofproto_group_mod {
     struct group_collection old_groups; /* Affected groups. */
 };
 
-enum ofperr ofproto_flow_mod(struct ofproto *, struct ofproto_flow_mod *)
+enum ofperr ofproto_flow_mod(struct ofproto *, const struct ofputil_flow_mod *)
     OVS_EXCLUDED(ofproto_mutex);
 void ofproto_add_flow(struct ofproto *, const struct match *, int priority,
                       const struct ofpact *ofpacts, size_t ofpacts_len)
diff --git a/ofproto/ofproto.c b/ofproto/ofproto.c
index 853b2a3..47020b8 100644
--- a/ofproto/ofproto.c
+++ b/ofproto/ofproto.c
@@ -305,7 +305,7 @@ static void ofproto_flow_mod_finish(struct ofproto *,
                                     const struct openflow_mod_requester *)
     OVS_REQUIRES(ofproto_mutex);
 static enum ofperr handle_flow_mod__(struct ofproto *,
-                                     struct ofproto_flow_mod *,
+                                     const struct ofputil_flow_mod *,
                                      const struct openflow_mod_requester *)
     OVS_EXCLUDED(ofproto_mutex);
 static void calc_duration(long long int start, long long int now,
@@ -2123,11 +2123,11 @@ simple_flow_mod(struct ofproto *ofproto,
                 const struct ofpact *ofpacts, size_t ofpacts_len,
                 enum ofp_flow_mod_command command)
 {
-    struct ofproto_flow_mod ofm;
+    struct ofputil_flow_mod fm;
 
-    flow_mod_init(&ofm.fm, match, priority, ofpacts, ofpacts_len, command);
+    flow_mod_init(&fm, match, priority, ofpacts, ofpacts_len, command);
 
-    return handle_flow_mod__(ofproto, &ofm, NULL);
+    return handle_flow_mod__(ofproto, &fm, NULL);
 }
 
 /* Adds a flow to OpenFlow flow table 0 in 'p' that matches 'cls_rule' and
@@ -2179,11 +2179,9 @@ ofproto_add_flow(struct ofproto *ofproto, const struct 
match *match,
  * This is a helper function for in-band control and fail-open and the "learn"
  * action. */
 enum ofperr
-ofproto_flow_mod(struct ofproto *ofproto, struct ofproto_flow_mod *ofm)
+ofproto_flow_mod(struct ofproto *ofproto, const struct ofputil_flow_mod *fm)
     OVS_EXCLUDED(ofproto_mutex)
 {
-    struct ofputil_flow_mod *fm = &ofm->fm;
-
     /* Optimize for the most common case of a repeated learn action.
      * If an identical flow already exists we only need to update its
      * 'modified' time. */
@@ -2224,7 +2222,7 @@ ofproto_flow_mod(struct ofproto *ofproto, struct 
ofproto_flow_mod *ofm)
         }
     }
 
-    return handle_flow_mod__(ofproto, ofm, NULL);
+    return handle_flow_mod__(ofproto, fm, NULL);
 }
 
 /* Searches for a rule with matching criteria exactly equal to 'target' in
@@ -4870,7 +4868,7 @@ add_flow_start(struct ofproto *ofproto, struct 
ofproto_flow_mod *ofm)
             *old_rule = rule;
         }
     } else {
-        fm->modify_cookie = true;
+        ofm->modify_cookie = true;
     }
 
     /* Allocate new rule. */
@@ -4979,7 +4977,7 @@ replace_rule_create(struct ofproto *ofproto, struct 
ofproto_flow_mod *ofm,
 
     /* Copy values from old rule for modify semantics. */
     if (old_rule && old_rule->removed_reason != OFPRR_EVICTION) {
-        bool change_cookie = (fm->modify_cookie
+        bool change_cookie = (ofm->modify_cookie
                               && fm->new_cookie != OVS_BE64_MAX
                               && fm->new_cookie != old_rule->flow_cookie);
 
@@ -5531,7 +5529,7 @@ handle_flow_mod(struct ofconn *ofconn, const struct 
ofp_header *oh)
     OVS_EXCLUDED(ofproto_mutex)
 {
     struct ofproto *ofproto = ofconn_get_ofproto(ofconn);
-    struct ofproto_flow_mod ofm;
+    struct ofputil_flow_mod fm;
     uint64_t ofpacts_stub[1024 / 8];
     struct ofpbuf ofpacts;
     enum ofperr error;
@@ -5542,13 +5540,13 @@ handle_flow_mod(struct ofconn *ofconn, const struct 
ofp_header *oh)
     }
 
     ofpbuf_use_stub(&ofpacts, ofpacts_stub, sizeof ofpacts_stub);
-    error = ofputil_decode_flow_mod(&ofm.fm, oh, ofconn_get_protocol(ofconn),
+    error = ofputil_decode_flow_mod(&fm, oh, ofconn_get_protocol(ofconn),
                                     &ofpacts,
                                     u16_to_ofp(ofproto->max_ports),
                                     ofproto->n_tables);
     if (!error) {
         struct openflow_mod_requester req = { ofconn, oh };
-        error = handle_flow_mod__(ofproto, &ofm, &req);
+        error = handle_flow_mod__(ofproto, &fm, &req);
     }
 
     ofpbuf_uninit(&ofpacts);
@@ -5556,18 +5554,21 @@ handle_flow_mod(struct ofconn *ofconn, const struct 
ofp_header *oh)
 }
 
 static enum ofperr
-handle_flow_mod__(struct ofproto *ofproto, struct ofproto_flow_mod *ofm,
+handle_flow_mod__(struct ofproto *ofproto, const struct ofputil_flow_mod *fm,
                   const struct openflow_mod_requester *req)
     OVS_EXCLUDED(ofproto_mutex)
 {
+    struct ofproto_flow_mod ofm;
     enum ofperr error;
 
+    ofm.fm = *fm;
+
     ovs_mutex_lock(&ofproto_mutex);
-    ofm->version = ofproto->tables_version + 1;
-    error = ofproto_flow_mod_start(ofproto, ofm);
+    ofm.version = ofproto->tables_version + 1;
+    error = ofproto_flow_mod_start(ofproto, &ofm);
     if (!error) {
         ofproto_bump_tables_version(ofproto);
-        ofproto_flow_mod_finish(ofproto, ofm, req);
+        ofproto_flow_mod_finish(ofproto, &ofm, req);
     }
     ofmonitor_flush(ofproto->connmgr);
     ovs_mutex_unlock(&ofproto_mutex);
@@ -7140,6 +7141,7 @@ ofproto_flow_mod_start(struct ofproto *ofproto, struct 
ofproto_flow_mod *ofm)
 
     /* Forward flow mod fields we need later. */
     ofm->buffer_id = ofm->fm.buffer_id;
+    ofm->modify_cookie = ofm->fm.modify_cookie;
 
     ofm->modify_may_add_flow = (ofm->fm.new_cookie != OVS_BE64_MAX
                                 && ofm->fm.cookie_mask == htonll(0));
-- 
2.1.4

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

Reply via email to