[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