[ovs-dev] [PATCH v5 6/6] meta-flow: Avoid unnecessary large memset.

Jarno Rajahalme jrajahalme at nicira.com
Fri Aug 21 22:25:23 UTC 2015


mf_mask_field_and_prereqs() used to memset a static variable again and
again.  Now that mf_value is larger (due to tun_metadata field), this
is more expensive.  Avoid this by using static initialization.

mf_mask_field_and_prereqs() is used only for set field and reg move,
which never deal with the tun_metadata field as a whole.

Signed-off-by: Jarno Rajahalme <jrajahalme at nicira.com>
---
 lib/flow.h                   |  2 ++
 lib/meta-flow.c              | 20 ++++++++++----------
 lib/meta-flow.h              |  3 ++-
 lib/nx-match.c               |  4 ++--
 ofproto/ofproto-dpif-xlate.c | 10 +++++-----
 5 files changed, 21 insertions(+), 18 deletions(-)

diff --git a/lib/flow.h b/lib/flow.h
index f9da6b3..1751aed 100644
--- a/lib/flow.h
+++ b/lib/flow.h
@@ -318,6 +318,8 @@ struct flow_wildcards {
 
 #define WC_MASK_FIELD(WC, FIELD) \
     memset(&(WC)->masks.FIELD, 0xff, sizeof (WC)->masks.FIELD)
+#define WC_MASK_FIELD_MASK(WC, FIELD, MASK)     \
+    ((WC)->masks.FIELD |= (MASK))
 #define WC_UNMASK_FIELD(WC, FIELD) \
     memset(&(WC)->masks.FIELD, 0, sizeof (WC)->masks.FIELD)
 
diff --git a/lib/meta-flow.c b/lib/meta-flow.c
index 528c109..1b7f9ca 100644
--- a/lib/meta-flow.c
+++ b/lib/meta-flow.c
@@ -390,21 +390,21 @@ mf_are_prereqs_ok(const struct mf_field *mf, const struct flow *flow)
 
 /* Set field and it's prerequisities in the mask.
  * This is only ever called for writeable 'mf's, but we do not make the
- * distinction here. */
+ * distinction here.
+ * The widest field this is ever called for an IPv6 address (16 bytes). */
 void
-mf_mask_field_and_prereqs(const struct mf_field *mf, struct flow *mask)
+mf_mask_field_and_prereqs(const struct mf_field *mf, struct flow_wildcards *wc)
 {
-    static union mf_value exact_match_mask;
+    static union mf_value exact_match_mask = { .ipv6 = IN6ADDR_EXACT_INIT };
 
-    memset(&exact_match_mask, 0xff, sizeof exact_match_mask);
-    mf_set_flow_value(mf, &exact_match_mask, mask);
+    mf_set_flow_value(mf, &exact_match_mask, &wc->masks);
 
     switch (mf->prereqs) {
     case MFP_ND:
     case MFP_ND_SOLICIT:
     case MFP_ND_ADVERT:
-        mask->tp_src = OVS_BE16_MAX;
-        mask->tp_dst = OVS_BE16_MAX;
+        WC_MASK_FIELD(wc, tp_src);
+        WC_MASK_FIELD(wc, tp_dst);
         /* Fall through. */
     case MFP_TCP:
     case MFP_UDP:
@@ -412,17 +412,17 @@ mf_mask_field_and_prereqs(const struct mf_field *mf, struct flow *mask)
     case MFP_ICMPV4:
     case MFP_ICMPV6:
         /* nw_frag always unwildcarded. */
-        mask->nw_proto = 0xff;
+        WC_MASK_FIELD(wc, nw_proto);
         /* Fall through. */
     case MFP_ARP:
     case MFP_IPV4:
     case MFP_IPV6:
     case MFP_MPLS:
     case MFP_IP_ANY:
-        mask->dl_type = OVS_BE16_MAX;
+        /* dl_type always unwildcarded. */
         break;
     case MFP_VLAN_VID:
-        mask->vlan_tci |= htons(VLAN_CFI);
+        WC_MASK_FIELD_MASK(wc, vlan_tci, htons(VLAN_CFI));
         break;
     case MFP_NONE:
         break;
diff --git a/lib/meta-flow.h b/lib/meta-flow.h
index 8feefcc..3dc342d 100644
--- a/lib/meta-flow.h
+++ b/lib/meta-flow.h
@@ -1824,7 +1824,8 @@ void mf_get_mask(const struct mf_field *, const struct flow_wildcards *,
 
 /* Prerequisites. */
 bool mf_are_prereqs_ok(const struct mf_field *, const struct flow *);
-void mf_mask_field_and_prereqs(const struct mf_field *, struct flow *mask);
+void mf_mask_field_and_prereqs(const struct mf_field *,
+                               struct flow_wildcards *);
 void mf_bitmap_set_field_and_prereqs(const struct mf_field *mf, struct
                                      mf_bitmap *bm);
 
diff --git a/lib/nx-match.c b/lib/nx-match.c
index a8b1183..54645df 100644
--- a/lib/nx-match.c
+++ b/lib/nx-match.c
@@ -1577,8 +1577,8 @@ nxm_execute_reg_move(const struct ofpact_reg_move *move,
     union mf_value src_value;
     union mf_value dst_value;
 
-    mf_mask_field_and_prereqs(move->dst.field, &wc->masks);
-    mf_mask_field_and_prereqs(move->src.field, &wc->masks);
+    mf_mask_field_and_prereqs(move->dst.field, wc);
+    mf_mask_field_and_prereqs(move->src.field, wc);
 
     /* A flow may wildcard nw_frag.  Do nothing if setting a transport
      * header field on a packet that does not have them. */
diff --git a/ofproto/ofproto-dpif-xlate.c b/ofproto/ofproto-dpif-xlate.c
index a34b5f9..6b9713f 100644
--- a/ofproto/ofproto-dpif-xlate.c
+++ b/ofproto/ofproto-dpif-xlate.c
@@ -4327,7 +4327,7 @@ do_xlate_actions(const struct ofpact *ofpacts, size_t ofpacts_len,
             }
             /* A flow may wildcard nw_frag.  Do nothing if setting a trasport
              * header field on a packet that does not have them. */
-            mf_mask_field_and_prereqs(mf, &wc->masks);
+            mf_mask_field_and_prereqs(mf, wc);
             if (mf_are_prereqs_ok(mf, flow)) {
                 mf_set_flow_value_masked(mf, &set_field->value,
                                          &set_field->mask, flow);
@@ -4689,16 +4689,16 @@ xlate_wc_init(struct xlate_ctx *ctx)
     flow_wildcards_init_catchall(ctx->wc);
 
     /* Some fields we consider to always be examined. */
-    memset(&ctx->wc->masks.in_port, 0xff, sizeof ctx->wc->masks.in_port);
-    memset(&ctx->wc->masks.dl_type, 0xff, sizeof ctx->wc->masks.dl_type);
+    WC_MASK_FIELD(ctx->wc, in_port);
+    WC_MASK_FIELD(ctx->wc, dl_type);
     if (is_ip_any(&ctx->xin->flow)) {
-        ctx->wc->masks.nw_frag |= FLOW_NW_FRAG_MASK;
+        WC_MASK_FIELD_MASK(ctx->wc, nw_frag, FLOW_NW_FRAG_MASK);
     }
 
     if (ctx->xbridge->support.odp.recirc) {
         /* Always exactly match recirc_id when datapath supports
          * recirculation.  */
-        ctx->wc->masks.recirc_id = UINT32_MAX;
+        WC_MASK_FIELD(ctx->wc, recirc_id);
     }
 
     if (ctx->xbridge->netflow) {
-- 
2.1.4




More information about the dev mailing list