When hitting max translation depth of 64, printing the full ofproto trace is huge and consumes too much log. The patch adds a short trace log, which collects, out of 64, the count of each table id the translation backward resubmit to. Finally, it printsi the top 3 table ids that have the highest counts.
VMWare-BZ: #2054659 Signed-off-by: William Tu <[email protected]> --- ofproto/ofproto-dpif-xlate.c | 45 ++++++++++++++++++++++++++++++++++++++++++-- tests/ofproto-dpif.at | 2 ++ 2 files changed, 45 insertions(+), 2 deletions(-) diff --git a/ofproto/ofproto-dpif-xlate.c b/ofproto/ofproto-dpif-xlate.c index cc450a896948..f82fe6bf711f 100644 --- a/ofproto/ofproto-dpif-xlate.c +++ b/ofproto/ofproto-dpif-xlate.c @@ -237,6 +237,7 @@ struct xlate_ctx { */ int depth; /* Current resubmit nesting depth. */ int resubmits; /* Total number of resubmits. */ + uint8_t bw_resubmit[MAX_DEPTH]; /* Track backward resubmit table IDs. */ bool in_group; /* Currently translating ofgroup, if true. */ bool in_action_set; /* Currently translating action_set, if true. */ bool in_packet_out; /* Currently translating a packet_out msg, if @@ -3912,8 +3913,11 @@ xlate_recursively(struct xlate_ctx *ctx, struct rule_dpif *rule, rule_dpif_credit_stats(rule, ctx->xin->resubmit_stats); } - ctx->resubmits++; + if (deepens) { + ctx->bw_resubmit[ctx->depth] = ctx->table_id; + } + ctx->resubmits++; ctx->depth += deepens; ctx->rule = rule; ctx->rule_cookie = rule->up.flow_cookie; @@ -3925,11 +3929,48 @@ xlate_recursively(struct xlate_ctx *ctx, struct rule_dpif *rule, ctx->depth -= deepens; } +static int +compare_uint8(const void *a_, const void *b_) +{ + const uint8_t *a = a_; + const uint8_t *b = b_; + return *a > *b ? -1 : *a < *b; +} + +static struct ds +format_bw_resubmit(uint8_t *bw_resubmit) +{ + int i; + uint8_t oftable[256]; + struct ds output; + + ds_init(&output); + memset(oftable, 0x0, sizeof oftable); + + for (i = 0; i < MAX_DEPTH; i++) { + uint8_t tab_id = bw_resubmit[i]; + oftable[tab_id]++; + } + qsort(oftable, 256, sizeof(uint8_t), compare_uint8); + + /* find the largest */ + ds_put_format(&output, "(%d,%d),", 0, oftable[0]); + ds_put_format(&output, "(%d,%d),", 1, oftable[1]); + ds_put_format(&output, "(%d,%d)", 2, oftable[2]); + return output; +} + static bool xlate_resubmit_resource_check(struct xlate_ctx *ctx) { if (ctx->depth >= MAX_DEPTH) { - xlate_report_error(ctx, "over max translation depth %d", MAX_DEPTH); + struct ds output; + + output = format_bw_resubmit(ctx->bw_resubmit); + xlate_report_error(ctx, "over max translation depth %d, " + "top 3 (table_id,count): [%s]", + MAX_DEPTH, ds_cstr(&output)); + ds_destroy(&output); ctx->error = XLATE_RECURSION_TOO_DEEP; } else if (ctx->resubmits >= MAX_RESUBMITS) { xlate_report_error(ctx, "over %d resubmit actions", MAX_RESUBMITS); diff --git a/tests/ofproto-dpif.at b/tests/ofproto-dpif.at index 600afdda8528..2c1c3685af6f 100644 --- a/tests/ofproto-dpif.at +++ b/tests/ofproto-dpif.at @@ -8453,6 +8453,8 @@ AT_CHECK([ovs-appctl -vpoll_loop:off ofproto/trace br0 'eth_dst=ff:ff:ff:ff:ff:f AT_CHECK([tail -1 stdout], [0], [Translation failed (Recursion too deep), packet is dropped. ]) +dnl make sure the short backward table trace is present +AT_CHECK([egrep "\(table_id,count\): \[[\(0,1\),\(1,1\),\(2,1\)\]]" ovs-vswitchd.log], [0], [stdout]) AT_CHECK([grep -c 'over max translation depth 64' stdout], [0], [1 ]) -- 2.7.4 _______________________________________________ dev mailing list [email protected] https://mail.openvswitch.org/mailman/listinfo/ovs-dev
