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 <jrajaha...@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 _______________________________________________ dev mailing list dev@openvswitch.org http://openvswitch.org/mailman/listinfo/dev