[ovs-dev] [PATCH 7/7] meta-flow: Add mf_mask_subfield_wc()

Jarno Rajahalme jrajahalme at nicira.com
Wed Feb 12 00:30:49 UTC 2014


The code setting wc masks shows up in 'perf' reports.  This patch streamlines
the code and avoids setting the mask bits for registers or metadata, as
those fields do not exist on datapaths.

Signed-off-by: Jarno Rajahalme <jrajahalme at nicira.com>
---
 lib/learn.c                  |    4 +-
 lib/meta-flow.c              |  158 ++++++++++++++++++++++++++++++++++++++++++
 lib/meta-flow.h              |    4 +-
 lib/nx-match.c               |   15 +---
 ofproto/ofproto-dpif-xlate.c |    8 +--
 5 files changed, 167 insertions(+), 22 deletions(-)

diff --git a/lib/learn.c b/lib/learn.c
index 61799c9..67cd63f 100644
--- a/lib/learn.c
+++ b/lib/learn.c
@@ -392,12 +392,10 @@ void
 learn_mask(const struct ofpact_learn *learn, struct flow_wildcards *wc)
 {
     const struct ofpact_learn_spec *spec;
-    union mf_subvalue value;
 
-    memset(&value, 0xff, sizeof value);
     for (spec = learn->specs; spec < &learn->specs[learn->n_specs]; spec++) {
         if (spec->src_type == NX_LEARN_SRC_FIELD) {
-            mf_write_subfield_flow(&spec->src, &value, &wc->masks);
+            mf_mask_subfield_wc(&spec->src, wc);
         }
     }
 }
diff --git a/lib/meta-flow.c b/lib/meta-flow.c
index 3afcd4c..3c1f159 100644
--- a/lib/meta-flow.c
+++ b/lib/meta-flow.c
@@ -1617,6 +1617,164 @@ mf_mask_field(const struct mf_field *mf, struct flow *mask)
     }
 }
 
+/* Unwildcard 'wc->masks' member field described by 'sf'.
+ * NOTE: Skips masking for fields known to not be used by the datapath! */
+void
+mf_mask_subfield_wc(const struct mf_subfield *sf, struct flow_wildcards *wc)
+{
+    const struct mf_field *field = sf->field;
+    union mf_value value;
+
+#define SUBMASK_BE64(sf) htonll((UINT64_C(~0) >> (64 - sf->n_bits)) << sf->ofs)
+#define SUBMASK_U32(sf) (((uint32_t)~0 >> (32 - sf->n_bits)) << sf->ofs)
+#define SUBMASK_BE32(sf) htonl(SUBMASK_U32(sf))
+#define SUBMASK_U16(sf) (((uint16_t)~0 >> (16 - sf->n_bits)) << sf->ofs)
+#define SUBMASK_BE16(sf) htons(SUBMASK_U16(sf))
+#define SUBMASK_U8(sf) (((uint8_t)~0 >> (8 - sf->n_bits)) << sf->ofs)
+
+    /* Handle trivial cases directly. */
+    switch (field->id) {
+
+    case MFF_METADATA:
+    CASE_MFF_REGS:
+        /* Datapaths don't care about these. */
+        break;
+
+    case MFF_TUN_ID:
+        wc->masks.tunnel.tun_id |= SUBMASK_BE64(sf);
+        break;
+    case MFF_TUN_SRC:
+        wc->masks.tunnel.ip_src |= SUBMASK_BE32(sf);
+        break;
+    case MFF_TUN_DST:
+        wc->masks.tunnel.ip_dst |= SUBMASK_BE32(sf);
+        break;
+    case MFF_TUN_FLAGS:
+        wc->masks.tunnel.flags |= SUBMASK_U16(sf);
+        break;
+    case MFF_TUN_TOS:
+        wc->masks.tunnel.ip_tos |= SUBMASK_U8(sf);
+        break;
+    case MFF_TUN_TTL:
+        wc->masks.tunnel.ip_ttl |= SUBMASK_U8(sf);
+        break;
+
+    case MFF_IN_PORT:
+        wc->masks.in_port.ofp_port |= u16_to_ofp(SUBMASK_U16(sf));
+        break;
+
+    case MFF_IN_PORT_OXM:
+        wc->masks.in_port.ofp_port |= u16_to_ofp(SUBMASK_U32(sf));
+        break;
+
+    case MFF_SKB_PRIORITY:
+        wc->masks.skb_priority |= SUBMASK_U32(sf);
+        break;
+
+    case MFF_PKT_MARK:
+        wc->masks.pkt_mark |= SUBMASK_U32(sf);
+        break;
+
+    case MFF_ETH_TYPE:
+        wc->masks.dl_type |= SUBMASK_BE16(sf);
+        break;
+
+    case MFF_VLAN_TCI:
+        wc->masks.vlan_tci |= SUBMASK_BE16(sf);
+        break;
+
+    case MFF_IPV4_SRC:
+        wc->masks.nw_src |= SUBMASK_BE32(sf);
+        break;
+
+    case MFF_IPV4_DST:
+        wc->masks.nw_dst |= SUBMASK_BE32(sf);
+        break;
+
+    case MFF_IPV6_LABEL:
+        wc->masks.ipv6_label |= SUBMASK_BE32(sf);
+        break;
+
+    case MFF_IP_PROTO:
+        wc->masks.nw_proto |= SUBMASK_U8(sf);
+        break;
+
+    case MFF_IP_TTL:
+        wc->masks.nw_ttl |= SUBMASK_U8(sf);
+        break;
+
+    case MFF_IP_FRAG:
+        wc->masks.nw_frag |= SUBMASK_U8(sf);
+        break;
+
+    case MFF_ARP_OP:
+        wc->masks.nw_proto |= SUBMASK_U16(sf);
+        break;
+
+    case MFF_ARP_SPA:
+        wc->masks.nw_src |= SUBMASK_BE32(sf);
+        break;
+
+    case MFF_ARP_TPA:
+        wc->masks.nw_dst |= SUBMASK_BE32(sf);
+        break;
+
+    case MFF_TCP_SRC:
+    case MFF_UDP_SRC:
+    case MFF_SCTP_SRC:
+        wc->masks.tp_src |= SUBMASK_BE16(sf);
+        break;
+
+    case MFF_TCP_DST:
+    case MFF_UDP_DST:
+    case MFF_SCTP_DST:
+        wc->masks.tp_dst |= SUBMASK_BE16(sf);
+        break;
+
+    case MFF_TCP_FLAGS:
+        wc->masks.tcp_flags |= SUBMASK_BE16(sf);
+        break;
+
+    case MFF_ICMPV4_TYPE:
+    case MFF_ICMPV6_TYPE:
+        wc->masks.tp_src |= SUBMASK_BE16(sf);
+        break;
+
+    case MFF_ICMPV4_CODE:
+    case MFF_ICMPV6_CODE:
+        wc->masks.tp_dst |= SUBMASK_BE16(sf);
+        break;
+
+    case MFF_IP_DSCP:
+    case MFF_IP_DSCP_SHIFTED:
+    case MFF_IP_ECN:
+    case MFF_MPLS_LABEL:
+    case MFF_MPLS_TC:
+    case MFF_MPLS_BOS:
+    case MFF_DL_VLAN:
+    case MFF_VLAN_VID:
+    case MFF_DL_VLAN_PCP:
+    case MFF_VLAN_PCP:
+    case MFF_ARP_THA:
+    case MFF_ND_TLL:
+    case MFF_ARP_SHA:
+    case MFF_ND_SLL:
+    case MFF_IPV6_SRC:
+    case MFF_IPV6_DST:
+    case MFF_ETH_SRC:
+    case MFF_ETH_DST:
+    case MFF_ND_TARGET:
+        mf_get_value(field, &wc->masks, &value);
+        bitwise_one (&value, field->n_bytes, sf->ofs, sf->n_bits);
+        mf_set_flow_value(field, &value, &wc->masks);
+        break;
+
+    case MFF_N_IDS:
+    default:
+        OVS_NOT_REACHED();
+    }
+}
+
 /* Sets 'flow' member field described by 'mf' to 'value'.  The caller is
  * responsible for ensuring that 'flow' meets 'mf''s prerequisites.*/
 void
diff --git a/lib/meta-flow.h b/lib/meta-flow.h
index cf92556..9f69084 100644
--- a/lib/meta-flow.h
+++ b/lib/meta-flow.h
@@ -370,7 +370,8 @@ void mf_set_flow_value(const struct mf_field *, const union mf_value *value,
                        struct flow *);
 bool mf_is_zero(const struct mf_field *, const struct flow *);
 void mf_mask_field(const struct mf_field *, struct flow *);
-
+void mf_mask_subfield_wc(const struct mf_subfield *,
+                         struct flow_wildcards *wc);
 void mf_get(const struct mf_field *, const struct match *,
             union mf_value *value, union mf_value *mask);
 
@@ -385,6 +386,7 @@ void mf_set_wild(const struct mf_field *, struct match *);
 /* Subfields. */
 void mf_write_subfield_flow(const struct mf_subfield *,
                             const union mf_subvalue *, struct flow *);
+
 void mf_write_subfield(const struct mf_subfield *, const union mf_subvalue *,
                        struct match *);
 
diff --git a/lib/nx-match.c b/lib/nx-match.c
index 437e85b..725b94e 100644
--- a/lib/nx-match.c
+++ b/lib/nx-match.c
@@ -1239,12 +1239,9 @@ nxm_reg_load(const struct mf_subfield *dst, uint64_t src_data,
              struct flow *flow, struct flow_wildcards *wc)
 {
     union mf_subvalue src_subvalue;
-    union mf_subvalue mask_value;
     ovs_be64 src_data_be = htonll(src_data);
 
-    memset(&mask_value, 0xff, sizeof mask_value);
-    mf_write_subfield_flow(dst, &mask_value, &wc->masks);
-
+    mf_mask_subfield_wc(dst, wc);
     bitwise_copy(&src_data_be, sizeof src_data_be, 0,
                  &src_subvalue, sizeof src_subvalue, 0,
                  sizeof src_data_be * 8);
@@ -1385,12 +1382,9 @@ nxm_execute_stack_push(const struct ofpact_stack *push,
                        const struct flow *flow, struct flow_wildcards *wc,
                        struct ofpbuf *stack)
 {
-    union mf_subvalue mask_value;
     union mf_subvalue dst_value;
 
-    memset(&mask_value, 0xff, sizeof mask_value);
-    mf_write_subfield_flow(&push->subfield, &mask_value, &wc->masks);
-
+    mf_mask_subfield_wc(&push->subfield, wc);
     mf_read_subfield(&push->subfield, flow, &dst_value);
     nx_stack_push(stack, &dst_value);
 }
@@ -1406,10 +1400,7 @@ nxm_execute_stack_pop(const struct ofpact_stack *pop,
 
     /* Only pop if stack is not empty. Otherwise, give warning. */
     if (src_value) {
-        union mf_subvalue mask_value;
-
-        memset(&mask_value, 0xff, sizeof mask_value);
-        mf_write_subfield_flow(&pop->subfield, &mask_value, &wc->masks);
+        mf_mask_subfield_wc(&pop->subfield, wc);
         mf_write_subfield_flow(&pop->subfield, src_value, flow);
     } else {
         if (!VLOG_DROP_WARN(&rl)) {
diff --git a/ofproto/ofproto-dpif-xlate.c b/ofproto/ofproto-dpif-xlate.c
index ccf0b75..f139371 100644
--- a/ofproto/ofproto-dpif-xlate.c
+++ b/ofproto/ofproto-dpif-xlate.c
@@ -2282,12 +2282,8 @@ xlate_output_reg_action(struct xlate_ctx *ctx,
 {
     uint64_t port = mf_get_subfield(&or->src, &ctx->xin->flow);
     if (port <= UINT16_MAX) {
-        union mf_subvalue value;
-
-        memset(&value, 0xff, sizeof value);
-        mf_write_subfield_flow(&or->src, &value, &ctx->xout->wc.masks);
-        xlate_output_action(ctx, u16_to_ofp(port),
-                            or->max_len, false);
+        mf_mask_subfield_wc(&or->src, &ctx->xout->wc);
+        xlate_output_action(ctx, u16_to_ofp(port), or->max_len, false);
     }
 }
 
-- 
1.7.10.4




More information about the dev mailing list