Looks Good.
On Fri, Mar 25, 2011 at 10:35 AM, Ben Pfaff <b...@nicira.com> wrote: > Scanning the dsts twice seems may be a little more efficient than > partitioning it, and it now seems more straightforward to me. > --- > vswitchd/bridge.c | 73 > ++++++++++++++--------------------------------------- > 1 files changed, 19 insertions(+), 54 deletions(-) > > diff --git a/vswitchd/bridge.c b/vswitchd/bridge.c > index 2a13822..efc61ea 100644 > --- a/vswitchd/bridge.c > +++ b/vswitchd/bridge.c > @@ -2080,51 +2080,6 @@ set_dst(struct dst *dst, const struct flow *flow, > return dst->iface != NULL; > } > > -static void > -swap_dst(struct dst *p, struct dst *q) > -{ > - struct dst tmp = *p; > - *p = *q; > - *q = tmp; > -} > - > -/* Moves all the dsts with vlan == 'vlan' to the front of the 'n_dsts' in > - * 'dsts'. (This may help performance by reducing the number of VLAN changes > - * that we push to the datapath. We could in fact fully sort the array by > - * vlan, but in most cases there are at most two different vlan tags so > that's > - * possibly overkill.) */ > -static void > -partition_dsts(struct dst_set *set, int vlan) > -{ > - struct dst *first = set->dsts; > - struct dst *last = set->dsts + set->n; > - > - while (first != last) { > - /* Invariants: > - * - All dsts < first have vlan == 'vlan'. > - * - All dsts >= last have vlan != 'vlan'. > - * - first < last. */ > - while (first->vlan == vlan) { > - if (++first == last) { > - return; > - } > - } > - > - /* Same invariants, plus one additional: > - * - first->vlan != vlan. > - */ > - while (last[-1].vlan != vlan) { > - if (--last == first) { > - return; > - } > - } > - > - /* Same invariants, plus one additional: > - * - last[-1].vlan == vlan.*/ > - swap_dst(first++, --last); > - } > -} > - > static int > mirror_mask_ffs(mirror_mask_t mask) > { > @@ -2312,24 +2267,33 @@ compose_actions(struct bridge *br, const struct flow > *flow, uint16_t vlan, > tag_type *tags, struct ofpbuf *actions, > uint16_t *nf_output_iface) > { > + uint16_t initial_vlan, cur_vlan; > + const struct dst *dst; > struct dst_set set; > - uint16_t cur_vlan; > - size_t i; > > dst_set_init(&set); > compose_dsts(br, flow, vlan, in_port, out_port, &set, tags, > nf_output_iface); > compose_mirror_dsts(br, flow, vlan, in_port, &set, tags); > > - cur_vlan = vlan_tci_to_vid(flow->vlan_tci); > - if (cur_vlan == 0) { > - cur_vlan = OFP_VLAN_NONE; > + /* Output all the packets we can without having to change the VLAN. */ > + initial_vlan = vlan_tci_to_vid(flow->vlan_tci); > + if (initial_vlan == 0) { > + initial_vlan = OFP_VLAN_NONE; > + } > + for (dst = set.dsts; dst < &set.dsts[set.n]; dst++) { > + if (dst->vlan != initial_vlan) { > + continue; > + } > + nl_msg_put_u32(actions, ODP_ACTION_ATTR_OUTPUT, > dst->iface->dp_ifidx); > } > > - partition_dsts(&set, cur_vlan); > - > - for (i = 0; i < set.n; i++) { > - const struct dst *dst = &set.dsts[i]; > + /* Then output the rest. */ > + cur_vlan = initial_vlan; > + for (dst = set.dsts; dst < &set.dsts[set.n]; dst++) { > + if (dst->vlan == initial_vlan) { > + continue; > + } > if (dst->vlan != cur_vlan) { > if (dst->vlan == OFP_VLAN_NONE) { > nl_msg_put_flag(actions, ODP_ACTION_ATTR_STRIP_VLAN); > @@ -2343,6 +2307,7 @@ compose_actions(struct bridge *br, const struct flow > *flow, uint16_t vlan, > } > nl_msg_put_u32(actions, ODP_ACTION_ATTR_OUTPUT, dst->iface->dp_ifidx); > } > + > dst_set_free(&set); > } > > -- > 1.7.1 > > _______________________________________________ > dev mailing list > dev@openvswitch.org > http://openvswitch.org/mailman/listinfo/dev > _______________________________________________ dev mailing list dev@openvswitch.org http://openvswitch.org/mailman/listinfo/dev