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

Reply via email to