[ovs-dev] [PATCH v8 15/16] ofproto-dpif: Translation of select groups

Ben Pfaff blp at nicira.com
Sun Nov 3 02:19:41 UTC 2013


On Wed, Oct 30, 2013 at 06:17:19PM +0900, Simon Horman wrote:
> Select bucket from those that are alive based on a hash of the destination
> ethernet address of the packet.
> 
> Support for weights is proposed by a subsequent patch.
> 
> The selection is based on a hash of the destination ethernet
> address of the flow. It should be possible to extend
> this to cover a hash of user-specified elements of the flow.
> 
> Signed-off-by: Simon Horman <horms at verge.net.au>

The method used to select a group seemed really heavyweight to me.  I
replaced by a simpler "highest random weight" implementation:

diff --git a/ofproto/ofproto-dpif-xlate.c b/ofproto/ofproto-dpif-xlate.c
index 6537205..5c22db3 100644
--- a/ofproto/ofproto-dpif-xlate.c
+++ b/ofproto/ofproto-dpif-xlate.c
@@ -796,20 +796,31 @@ group_first_live_bucket(const struct xlate_ctx *ctx,
     return NULL;
 }
 
-static void
-group_all_live_buckets(const struct xlate_ctx *ctx,
+static const struct ofputil_bucket *
+group_best_live_bucket(const struct xlate_ctx *ctx,
                        const struct group_dpif *group,
-                       struct ofpbuf *live_buckets)
+                       uint32_t basis)
 {
-    struct ofputil_bucket *bucket;
+    const struct ofputil_bucket *best_bucket = NULL;
+    uint32_t best_score = 0;
+    int i = 0;
+
+    const struct ofputil_bucket *bucket;
     const struct list *buckets;
 
     group_dpif_get_buckets(group, &buckets);
     LIST_FOR_EACH (bucket, list_node, buckets) {
         if (bucket_is_alive(ctx, bucket, 0)) {
-            ofpbuf_push(live_buckets, &bucket, sizeof bucket);
+            uint32_t score = hash_int(i, basis);
+            if (score >= best_score) {
+                best_bucket = bucket;
+                best_score = score;
+            }
         }
+        i++;
     }
+
+    return best_bucket;
 }
 
 static bool
@@ -1932,27 +1943,15 @@ static void
 xlate_select_group(struct xlate_ctx *ctx, struct group_dpif *group)
 {
     struct flow_wildcards *wc = &ctx->xout->wc;
-    const struct ofputil_bucket **bucket;
-    struct ofputil_bucket *stub[1024 / sizeof *bucket];
-    struct ofpbuf live_buckets;
-    uint32_t hash;
+    const struct ofputil_bucket *bucket;
+    uint32_t basis;
 
-    ofpbuf_use_stub(&live_buckets, stub, sizeof stub);
-    group_all_live_buckets(ctx, group, &live_buckets);
-    if (live_buckets.size == 0) {
-        goto out;
+    basis = hash_bytes(ctx->xin->flow.dl_dst, sizeof ctx->xin->flow.dl_dst, 0);
+    bucket = group_best_live_bucket(ctx, group, basis);
+    if (bucket) {
+        memset(&wc->masks.dl_dst, 0xff, sizeof wc->masks.dl_dst);
+        xlate_group_bucket(ctx, bucket);
     }
-
-    memset(&wc->masks.dl_dst, 0xff, sizeof wc->masks.dl_dst);
-
-    hash = hash_bytes(ctx->xin->flow.dl_dst, sizeof ctx->xin->flow.dl_dst, 0);
-    bucket = ofpbuf_at_assert(&live_buckets,
-                              (hash % (live_buckets.size / sizeof *bucket)) *
-                               sizeof *bucket, sizeof *bucket);
-    xlate_group_bucket(ctx, *bucket);
-
-out:
-    ofpbuf_uninit(&live_buckets);
 }
 
 static void



More information about the dev mailing list