[ovs-dev] [PATCH 7/7] ofproto-dpif-xlate: Improve tracing through groups.

Ben Pfaff blp at ovn.org
Thu May 10 23:24:39 UTC 2018


This makes it clear which buckets from a group are executed and why.

The update to nsh.at provides an example.

Signed-off-by: Ben Pfaff <blp at ovn.org>
---
 ofproto/ofproto-dpif-trace.c |  2 ++
 ofproto/ofproto-dpif-trace.h |  1 +
 ofproto/ofproto-dpif-xlate.c | 48 ++++++++++++++++++++++++++++++++++++++++++--
 tests/nsh.at                 | 41 +++++++++++++++++++------------------
 4 files changed, 71 insertions(+), 21 deletions(-)

diff --git a/ofproto/ofproto-dpif-trace.c b/ofproto/ofproto-dpif-trace.c
index 7211eac8e1a5..396a06ba0a6c 100644
--- a/ofproto/ofproto-dpif-trace.c
+++ b/ofproto/ofproto-dpif-trace.c
@@ -49,6 +49,7 @@ oftrace_node_type_is_terminal(enum oftrace_node_type type)
     case OFT_DETAIL:
     case OFT_WARN:
     case OFT_ERROR:
+    case OFT_BUCKET:
         return true;
 
     case OFT_BRIDGE:
@@ -167,6 +168,7 @@ oftrace_node_print_details(struct ds *output,
             ds_put_char(output, '\n');
             break;
         case OFT_TABLE:
+        case OFT_BUCKET:
         case OFT_THAW:
         case OFT_ACTION:
             ds_put_format(output, "%s\n", sub->text);
diff --git a/ofproto/ofproto-dpif-trace.h b/ofproto/ofproto-dpif-trace.h
index ea6cb3fc01ac..63dbb50bad57 100644
--- a/ofproto/ofproto-dpif-trace.h
+++ b/ofproto/ofproto-dpif-trace.h
@@ -39,6 +39,7 @@ enum oftrace_node_type {
     /* Nodes that may have children (nonterminal nodes). */
     OFT_BRIDGE,                 /* Packet travel through an OpenFlow switch. */
     OFT_TABLE,                  /* Packet travel through a flow table. */
+    OFT_BUCKET,                 /* Executing a bucket in an OpenFlow group. */
     OFT_THAW,                   /* Thawing a frozen state. */
 
     /* Nodes that never have children (terminal nodes). */
diff --git a/ofproto/ofproto-dpif-xlate.c b/ofproto/ofproto-dpif-xlate.c
index 5c436b8a3440..a6657b387c46 100644
--- a/ofproto/ofproto-dpif-xlate.c
+++ b/ofproto/ofproto-dpif-xlate.c
@@ -1829,6 +1829,30 @@ bucket_is_alive(const struct xlate_ctx *ctx,
                && group_is_alive(ctx, bucket->watch_group, depth + 1)));
 }
 
+static void
+xlate_report_bucket_not_live(const struct xlate_ctx *ctx,
+                             const struct ofputil_bucket *bucket)
+{
+    if (OVS_UNLIKELY(ctx->xin->trace)) {
+        struct ds s = DS_EMPTY_INITIALIZER;
+        if (bucket->watch_port != OFPP_ANY) {
+            ds_put_cstr(&s, "port ");
+            ofputil_format_port(bucket->watch_port, NULL, &s);
+        }
+        if (bucket->watch_group != OFPG_ANY) {
+            if (s.length) {
+                ds_put_cstr(&s, " and ");
+            }
+            ds_put_format(&s, "port %"PRIu32, bucket->watch_group);
+        }
+
+        xlate_report(ctx, OFT_DETAIL, "bucket %"PRIu32": not live due to %s",
+                     bucket->bucket_id, ds_cstr(&s));
+
+        ds_destroy(&s);
+    }
+}
+
 static struct ofputil_bucket *
 group_first_live_bucket(const struct xlate_ctx *ctx,
                         const struct group_dpif *group, int depth)
@@ -1838,6 +1862,7 @@ group_first_live_bucket(const struct xlate_ctx *ctx,
         if (bucket_is_alive(ctx, bucket, depth)) {
             return bucket;
         }
+        xlate_report_bucket_not_live(ctx, bucket);
     }
 
     return NULL;
@@ -1860,6 +1885,10 @@ group_best_live_bucket(const struct xlate_ctx *ctx,
                 best_bucket = bucket;
                 best_score = score;
             }
+            xlate_report(ctx, OFT_DETAIL, "bucket %"PRIu32": score %"PRIu32,
+                         bucket->bucket_id, score);
+        } else {
+            xlate_report_bucket_not_live(ctx, bucket);
         }
     }
 
@@ -4221,6 +4250,14 @@ static void
 xlate_group_bucket(struct xlate_ctx *ctx, struct ofputil_bucket *bucket,
                    bool is_last_action)
 {
+    struct ovs_list *old_trace = ctx->xin->trace;
+    if (OVS_UNLIKELY(ctx->xin->trace)) {
+        char *s = xasprintf("bucket %"PRIu32, bucket->bucket_id);
+        ctx->xin->trace = &oftrace_report(ctx->xin->trace, OFT_BUCKET,
+                                          s)->subs;
+        free(s);
+    }
+
     uint64_t action_list_stub[1024 / 8];
     struct ofpbuf action_list = OFPBUF_STUB_INITIALIZER(action_list_stub);
     struct ofpbuf action_set = ofpbuf_const_initializer(bucket->ofpacts,
@@ -4282,6 +4319,7 @@ xlate_group_bucket(struct xlate_ctx *ctx, struct ofputil_bucket *bucket,
         ctx->error = XLATE_OK;
     }
 
+    ctx->xin->trace = old_trace;
 }
 
 static struct ofputil_bucket *
@@ -4414,11 +4452,17 @@ xlate_group_action__(struct xlate_ctx *ctx, struct group_dpif *group,
         } else {
             OVS_NOT_REACHED();
         }
+
         if (bucket) {
+            xlate_report(ctx, OFT_DETAIL, "using bucket %"PRIu32,
+                         bucket->bucket_id);
             xlate_group_bucket(ctx, bucket, is_last_action);
             xlate_group_stats(ctx, group, bucket);
-        } else if (ctx->xin->xcache) {
-            ofproto_group_unref(&group->up);
+        } else {
+            xlate_report(ctx, OFT_DETAIL, "no live bucket");
+            if (ctx->xin->xcache) {
+                ofproto_group_unref(&group->up);
+            }
         }
     }
 
diff --git a/tests/nsh.at b/tests/nsh.at
index 7539e91e97bb..70d8b483620d 100644
--- a/tests/nsh.at
+++ b/tests/nsh.at
@@ -331,25 +331,28 @@ bridge("br0")
 -------------
  0. ip,in_port=1, priority 32768
     group:100
-    encap(nsh(md_type=1))
-    set_field:0x1234->nsh_spi
-    set_field:0x11223344->nsh_c1
-    group:200
-    encap(nsh(md_type=1))
-    set_field:0x5678->nsh_spi
-    set_field:0x55667788->nsh_c1
-    group:300
-    encap(ethernet)
-    set_field:11:22:33:44:55:66->eth_dst
-    output:3
-
-bridge("br0")
--------------
- 0. in_port=4,dl_type=0x894f,nsh_mdtype=1,nsh_spi=0x5678,nsh_c1=0x55667788, priority 32768
-    decap()
-    goto_table:1
- 1. packet_type=(1,0x894f),nsh_mdtype=1,nsh_spi=0x5678,nsh_c1=0x55667788, priority 32768
-    decap()
+    bucket 0
+            encap(nsh(md_type=1))
+            set_field:0x1234->nsh_spi
+            set_field:0x11223344->nsh_c1
+            group:200
+            bucket 0
+                    encap(nsh(md_type=1))
+                    set_field:0x5678->nsh_spi
+                    set_field:0x55667788->nsh_c1
+                    group:300
+                    bucket 0
+                            encap(ethernet)
+                            set_field:11:22:33:44:55:66->eth_dst
+                            output:3
+
+                        bridge("br0")
+                        -------------
+                         0. in_port=4,dl_type=0x894f,nsh_mdtype=1,nsh_spi=0x5678,nsh_c1=0x55667788, priority 32768
+                            decap()
+                            goto_table:1
+                         1. packet_type=(1,0x894f),nsh_mdtype=1,nsh_spi=0x5678,nsh_c1=0x55667788, priority 32768
+                            decap()
 
 Final flow: unchanged
 Megaflow: recirc_id=0,eth,ip,in_port=1,dl_dst=66:77:88:99:aa:bb,nw_frag=no
-- 
2.16.1



More information about the dev mailing list