Minor comments below, otherwise:

Acked-by: Jarno Rajahalme <jrajaha...@nicira.com>

  Jarno

On Jun 30, 2014, at 1:11 PM, Ethan Jackson <et...@nicira.com> wrote:

> Signed-off-by: Ethan Jackson <et...@nicira.com>
> ---
> lib/dpif-netdev.c | 96 +++++++++++++++++++++++++++++++------------------------
> 1 file changed, 54 insertions(+), 42 deletions(-)
> 
> diff --git a/lib/dpif-netdev.c b/lib/dpif-netdev.c
> index 3a2b68f..58c629b 100644
> --- a/lib/dpif-netdev.c
> +++ b/lib/dpif-netdev.c
> @@ -2034,18 +2034,14 @@ packet_batch_update(struct packet_batch *batch,
> 
> static inline void
> packet_batch_init(struct packet_batch *batch, struct dp_netdev_flow *flow,
> -                  struct dpif_packet *packet, struct pkt_metadata *md,
> -                  const struct miniflow *mf)
> +                  struct pkt_metadata *md)
> {
>     batch->flow = flow;
>     batch->md = *md;
> -    batch->packets[0] = packet;
> 
>     batch->packet_count = 0;
>     batch->byte_count = 0;
>     batch->tcp_flags = 0;
> -
> -    packet_batch_update(batch, packet, mf);
> }
> 
> static inline void
> @@ -2070,61 +2066,77 @@ static void
> dp_netdev_input(struct dp_netdev *dp, struct dpif_packet **packets, int cnt,
>                 struct pkt_metadata *md)
> {
> -    struct packet_batch batch;
> -
> -    struct netdev_flow_key key;
> -
> -    int i;
> +    struct packet_batch batches[NETDEV_MAX_RX_BATCH];
> +    struct netdev_flow_key keys[NETDEV_MAX_RX_BATCH];
> +    const struct miniflow *mfs[NETDEV_MAX_RX_BATCH]; /* NULL at bad packets. 
> */
> +    struct cls_rule *rules[NETDEV_MAX_RX_BATCH];
> +    size_t n_batches, i;
> 
> -    batch.flow = NULL;
> +    for (i = 0; i < cnt; i++) {
> +        if (OVS_UNLIKELY(ofpbuf_size(&packets[i]->ofpbuf) < ETH_HEADER_LEN)) 
> {
> +            dpif_packet_delete(packets[i]);
> +            mfs[i] = NULL;
> +            continue;
> +        }
> 
> -    miniflow_initialize(&key.flow, key.buf);
> +        miniflow_initialize(&keys[i].flow, keys[i].buf);
> +        miniflow_extract(&packets[i]->ofpbuf, md, &keys[i].flow);
> +        mfs[i] = &keys[i].flow;
> +    }
> 
>     fat_rwlock_rdlock(&dp->cls.rwlock);
> +    classifier_lookup_miniflow_batch(&dp->cls, mfs, rules, cnt);
> +    fat_rwlock_unlock(&dp->cls.rwlock);
> +
> +    n_batches = 0;
>     for (i = 0; i < cnt; i++) {
> -        struct dp_netdev_flow *netdev_flow;
> -        struct ofpbuf *buf = &packets[i]->ofpbuf;
> +        struct dp_netdev_flow *flow;
> +        struct packet_batch *batch;
> +        size_t j;
> 
> -        if (ofpbuf_size(buf) < ETH_HEADER_LEN) {
> -            dpif_packet_delete(packets[i]);
> +        if (OVS_UNLIKELY(!mfs[i])) {
>             continue;
>         }
> 
> -        miniflow_extract(buf, md, &key.flow);
> -
> -        netdev_flow = dp_netdev_lookup_flow(dp, &key.flow);
> -
> -        if (netdev_flow) {
> -            if (!batch.flow) {
> -                packet_batch_init(&batch, netdev_flow, packets[i], md,
> -                                  &key.flow);
> -            } else if (batch.flow == netdev_flow) {
> -                packet_batch_update(&batch, packets[i], &key.flow);
> -            } else {
> -                packet_batch_execute(&batch, dp);
> -                packet_batch_init(&batch, netdev_flow, packets[i], md,
> -                                  &key.flow);
> -            }
> -        } else {
> -            /* Packet's flow not in datapath */
> +        if (OVS_UNLIKELY(!rules[i])) {
>             dp_netdev_count_packet(dp, DP_STAT_MISS, 1);
> +            if (OVS_LIKELY(dp->handler_queues)) {
> +                uint32_t hash = miniflow_hash_5tuple(mfs[i], 0);
> +                struct ofpbuf *buf = &packets[i]->ofpbuf;
> 
> -            if (dp->handler_queues) {
> -                /* Upcall */
> -                dp_netdev_output_userspace(dp, &buf, 1,
> -                                           miniflow_hash_5tuple(&key.flow, 0)
> -                                           % dp->n_handlers,
> -                                           DPIF_UC_MISS, &key.flow, NULL);
> +                dp_netdev_output_userspace(dp, &buf, 1, hash % 
> dp->n_handlers,
> +                                           DPIF_UC_MISS, mfs[i], NULL);

Would it make sense to batch the upcalls as well, i.e. collect them up and then 
issue them with a single dp_netdev_output_userspace()?

>             } else {
>                 /* No upcall queue.  Freeing the packet */
>                 dpif_packet_delete(packets[i]);
>             }
> +            continue;
> +        }
> +
> +        /* XXX: This O(n^2) algortihm makes sense if we're operating under 
> the
> +         * assumption that the number of distinct flows (and therefore the
> +         * number of distinct batches) is quite small.  If this turns out not
> +         * to be the case, it may make sense to pre sort based on the
> +         * netdev_flow pointer.  That done we can get the appropriate 
> batching
> +         * in O(n * log(n)) instead. */
> +        batch = NULL;
> +        flow = dp_netdev_flow_cast(rules[i]);
> +        for (j = 0; j < n_batches; j++) {

It would seem that starting from the newest batch and looping backwards might 
find the batch sooner, especially if the packets of a batch arrive back to back.

> +            if (batches[j].flow == flow) {
> +                batch = &batches[j];
> +                break;
> +            }
>         }
> +
> +        if (!batch) {
> +            batch = &batches[n_batches++];
> +            packet_batch_init(batch, flow, md);
> +        }
> +        packet_batch_update(batch, packets[i], mfs[i]);
>     }
> -    fat_rwlock_unlock(&dp->cls.rwlock);
> 
> -    if (batch.flow) {
> -        packet_batch_execute(&batch, dp);
> +    for (i = 0; i < n_batches; i++) {
> +        packet_batch_execute(&batches[i], dp);
>     }
> }
> 
> -- 
> 1.8.1.2
> 
> _______________________________________________
> dev mailing list
> dev@openvswitch.org
> http://openvswitch.org/mailman/listinfo/dev

_______________________________________________
dev mailing list
dev@openvswitch.org
http://openvswitch.org/mailman/listinfo/dev

Reply via email to