[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