From mboxrd@z Thu Jan  1 00:00:00 1970
Return-Path: <dev-bounces@dpdk.org>
Received: from mails.dpdk.org (mails.dpdk.org [217.70.189.124])
	by inbox.dpdk.org (Postfix) with ESMTP id 1218345720;
	Fri,  2 Aug 2024 21:59:06 +0200 (CEST)
Received: from mails.dpdk.org (localhost [127.0.0.1])
	by mails.dpdk.org (Postfix) with ESMTP id 86C30427E5;
	Fri,  2 Aug 2024 21:58:41 +0200 (CEST)
Received: from mail-pg1-f171.google.com (mail-pg1-f171.google.com
 [209.85.215.171])
 by mails.dpdk.org (Postfix) with ESMTP id B063C427AD
 for <dev@dpdk.org>; Fri,  2 Aug 2024 21:58:37 +0200 (CEST)
Received: by mail-pg1-f171.google.com with SMTP id
 41be03b00d2f7-7a264a24ea7so5646148a12.3
 for <dev@dpdk.org>; Fri, 02 Aug 2024 12:58:37 -0700 (PDT)
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
 d=networkplumber-org.20230601.gappssmtp.com; s=20230601; t=1722628717;
 x=1723233517; darn=dpdk.org; 
 h=content-transfer-encoding:mime-version:references:in-reply-to
 :message-id:date:subject:cc:to:from:from:to:cc:subject:date
 :message-id:reply-to;
 bh=J1R1odZ0oHOJF5vgnVEzIvFRm7WKvcbCRzqOKQsMEMY=;
 b=VrsxefGqasDh4Ku1rYOxTijtHWQOVnCdA5IcTb1I9JyAK6VrZOZSrBeDAZyWT65s5a
 LWTpHUi/7VDuJULJen7qD2deCTZclM8chE3mrdo3TIRBn7495Bnf8H/dXqXeMbudpDjN
 jNyjJcRXjX3yDVQX5EMr5ieg+Lp0CwufuPcS2ewVPJkduZXtMlncTu9O8hx+64r5I6JN
 c/rv5sbcJHGud2qwGDTfos5H+LHBrIG/nPW4pxiKG+PBvhw1wnVurNGvTiE65q4HCAV1
 Tve+hZHAsxFR0/B5mwvWVy1UpJ7azFTla6vdkzvPZZAl2v8iND8CU63wXWHNPvGypeFc
 7diQ==
X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
 d=1e100.net; s=20230601; t=1722628717; x=1723233517;
 h=content-transfer-encoding:mime-version:references:in-reply-to
 :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc
 :subject:date:message-id:reply-to;
 bh=J1R1odZ0oHOJF5vgnVEzIvFRm7WKvcbCRzqOKQsMEMY=;
 b=V9s+GVbko1NAR2LLaY7hUfj/OQT8rkPzG0GAuFLmfVWzquaYrwKAmLBThlOTUe2VJv
 g+Up4QGo03ZGE2V0rJto36bNNBWCLejfVa5tak+8mTTpS9h3W2jGWVTWKUsYEsqWupG7
 8dvIQdF43t1ksBsEj0OD1DFTptcrLDcp2ER2wHD9HPCPAYRfw4p7Fe6PBTzjkyDZtOt0
 w03RbnrGCrvHYtnBkN7ReqcwBeSso041yPcRCF6ULQaFfgfvvpQ2Htb3+/NF8ZYDEQDA
 y0N4GGHhAxFO+pcRHMj9CA9RDUH7t8Sx89/W7+4ljLuDiJ5UWKU6wTQx3Nri3ZNzgBBu
 Vydg==
X-Gm-Message-State: AOJu0YyFJTEToAgI7bskeXppDFAfqGmT3otF8RUQA9VuWjGpDPynlJuh
 4KJTJhD3zFcLavB+XL04NOX0I8iWYsjlOJsAJShRdGJ02RuwzLVDbR95qIHq+JsfjZW4NXAF3x/
 3
X-Google-Smtp-Source: AGHT+IGXqDNfLHPrKsnNUOE0Jvc1N79/mptofbCYIi1Vilia1kAgwYbbGF9W9W12rXhMIq+pwPZkeQ==
X-Received: by 2002:a05:6a21:4603:b0:1c3:ff33:2471 with SMTP id
 adf61e73a8af0-1c699579845mr5515093637.8.1722628716802; 
 Fri, 02 Aug 2024 12:58:36 -0700 (PDT)
Received: from hermes.local (204-195-96-226.wavecable.com. [204.195.96.226])
 by smtp.gmail.com with ESMTPSA id
 d2e1a72fcca58-7106ecfc344sm1697180b3a.151.2024.08.02.12.58.36
 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256);
 Fri, 02 Aug 2024 12:58:36 -0700 (PDT)
From: Stephen Hemminger <stephen@networkplumber.org>
To: dev@dpdk.org
Cc: Stephen Hemminger <stephen@networkplumber.org>, Ori Kam <orika@nvidia.com>,
 Aman Singh <aman.deep.singh@intel.com>
Subject: [PATCH v7 4/4] test-pmd: add more packet verbose decode options
Date: Fri,  2 Aug 2024 12:56:55 -0700
Message-ID: <20240802195824.1336603-5-stephen@networkplumber.org>
X-Mailer: git-send-email 2.43.0
In-Reply-To: <20240802195824.1336603-1-stephen@networkplumber.org>
References: <20240312220129.70667-1-stephen@networkplumber.org>
 <20240802195824.1336603-1-stephen@networkplumber.org>
MIME-Version: 1.0
Content-Transfer-Encoding: 8bit
X-BeenThere: dev@dpdk.org
X-Mailman-Version: 2.1.29
Precedence: list
List-Id: DPDK patches and discussions <dev.dpdk.org>
List-Unsubscribe: <https://mails.dpdk.org/options/dev>,
 <mailto:dev-request@dpdk.org?subject=unsubscribe>
List-Archive: <http://mails.dpdk.org/archives/dev/>
List-Post: <mailto:dev@dpdk.org>
List-Help: <mailto:dev-request@dpdk.org?subject=help>
List-Subscribe: <https://mails.dpdk.org/listinfo/dev>,
 <mailto:dev-request@dpdk.org?subject=subscribe>
Errors-To: dev-bounces@dpdk.org

The existing verbose levels 1..3 provide a messy multi-line
output per packet. I found this unhelpful when diagnosing many
types of problems like packet flow.

This patch keeps the previous levels and adds two new levels:
4: one line per packet is printed in a format resembling
   tshark output. With addresses and protocol info.

5: dump packet in hex.
   Useful if the driver is messing up the data.

Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
---
 app/test-pmd/cmdline_flow.c                 |  3 +-
 app/test-pmd/config.c                       | 33 ++++++---
 app/test-pmd/testpmd.h                      | 11 +++
 app/test-pmd/util.c                         | 77 +++++++++++++++++++--
 doc/guides/testpmd_app_ug/testpmd_funcs.rst |  5 +-
 5 files changed, 111 insertions(+), 18 deletions(-)

diff --git a/app/test-pmd/cmdline_flow.c b/app/test-pmd/cmdline_flow.c
index d04280eb3e..a010fcf61a 100644
--- a/app/test-pmd/cmdline_flow.c
+++ b/app/test-pmd/cmdline_flow.c
@@ -14143,7 +14143,8 @@ cmd_set_raw_parsed(const struct buffer *in)
 			upper_layer = proto;
 		}
 	}
-	if (verbose_level & 0x1)
+
+	if (verbose_level > 0)
 		printf("total data size is %zu\n", (*total_size));
 	RTE_ASSERT((*total_size) <= ACTION_RAW_ENCAP_MAX_DATA);
 	memmove(data, (data_tail - (*total_size)), *total_size);
diff --git a/app/test-pmd/config.c b/app/test-pmd/config.c
index 6f0beafa27..b5b5f3b464 100644
--- a/app/test-pmd/config.c
+++ b/app/test-pmd/config.c
@@ -6246,26 +6246,37 @@ configure_rxtx_dump_callbacks(uint16_t verbose)
 		return;
 #endif
 
-	RTE_ETH_FOREACH_DEV(portid)
-	{
-		if (verbose == 1 || verbose > 2)
+	RTE_ETH_FOREACH_DEV(portid) {
+		switch (verbose) {
+		case VERBOSE_OFF:
+			remove_rx_dump_callbacks(portid);
+			remove_tx_dump_callbacks(portid);
+			break;
+		case VERBOSE_RX:
 			add_rx_dump_callbacks(portid);
-		else
+			remove_tx_dump_callbacks(portid);
+			break;
+		case VERBOSE_TX:
+			add_tx_dump_callbacks(portid);
 			remove_rx_dump_callbacks(portid);
-		if (verbose >= 2)
+			break;
+		default:
+			add_rx_dump_callbacks(portid);
 			add_tx_dump_callbacks(portid);
-		else
-			remove_tx_dump_callbacks(portid);
+		}
 	}
 }
 
 void
 set_verbose_level(uint16_t vb_level)
 {
-	printf("Change verbose level from %u to %u\n",
-	       (unsigned int) verbose_level, (unsigned int) vb_level);
-	verbose_level = vb_level;
-	configure_rxtx_dump_callbacks(verbose_level);
+	if (vb_level < VERBOSE_MAX) {
+		printf("Change verbose level from %u to %u\n", verbose_level, vb_level);
+		verbose_level = vb_level;
+		configure_rxtx_dump_callbacks(verbose_level);
+	} else {
+		fprintf(stderr, "Verbose level %u is out of range\n", vb_level);
+	}
 }
 
 void
diff --git a/app/test-pmd/testpmd.h b/app/test-pmd/testpmd.h
index 9facd7f281..3d7a2b6dac 100644
--- a/app/test-pmd/testpmd.h
+++ b/app/test-pmd/testpmd.h
@@ -489,6 +489,17 @@ enum dcb_mode_enable
 
 extern uint8_t xstats_hide_zero; /**< Hide zero values for xstats display */
 
+enum verbose_mode {
+	VERBOSE_OFF = 0,
+	VERBOSE_RX,
+	VERBOSE_TX,
+	VERBOSE_BOTH,
+	VERBOSE_DISSECT,
+	VERBOSE_HEX,
+	VERBOSE_MAX
+};
+
+
 /* globals used for configuration */
 extern uint8_t record_core_cycles; /**< Enables measurement of CPU cycles */
 extern uint8_t record_burst_stats; /**< Enables display of RX and TX bursts */
diff --git a/app/test-pmd/util.c b/app/test-pmd/util.c
index bf9b639d95..f277e7f035 100644
--- a/app/test-pmd/util.c
+++ b/app/test-pmd/util.c
@@ -5,9 +5,11 @@
 
 #include <stdio.h>
 
+#include <rte_atomic.h>
 #include <rte_bitops.h>
 #include <rte_net.h>
 #include <rte_mbuf.h>
+#include <rte_dissect.h>
 #include <rte_ether.h>
 #include <rte_vxlan.h>
 #include <rte_ethdev.h>
@@ -16,6 +18,7 @@
 #include "testpmd.h"
 
 #define MAX_STRING_LEN 8192
+#define MAX_DUMP_LEN   1024
 
 #define MKDUMPSTR(buf, buf_size, cur_len, ...) \
 do { \
@@ -67,9 +70,10 @@ get_timestamp(const struct rte_mbuf *mbuf)
 			timestamp_dynfield_offset, rte_mbuf_timestamp_t *);
 }
 
-static inline void
-dump_pkt_burst(uint16_t port_id, uint16_t queue, struct rte_mbuf *pkts[],
-	      uint16_t nb_pkts, int is_rx)
+/* More verbose older style packet decode */
+static void
+dump_pkt_verbose(uint16_t port_id, uint16_t queue, struct rte_mbuf *pkts[],
+		 uint16_t nb_pkts, int is_rx)
 {
 	struct rte_mbuf  *mb;
 	const struct rte_ether_hdr *eth_hdr;
@@ -90,8 +94,6 @@ dump_pkt_burst(uint16_t port_id, uint16_t queue, struct rte_mbuf *pkts[],
 	size_t cur_len = 0;
 	uint64_t restore_info_dynflag;
 
-	if (!nb_pkts)
-		return;
 	restore_info_dynflag = rte_flow_restore_info_dynflag();
 	MKDUMPSTR(print_buf, buf_size, cur_len,
 		  "port %u/queue %u: %s %u packets\n", port_id, queue,
@@ -299,6 +301,71 @@ dump_pkt_burst(uint16_t port_id, uint16_t queue, struct rte_mbuf *pkts[],
 	}
 }
 
+/* Brief tshark style one line output which is
+ * number time_delta Source Destination Protocol len info
+ */
+static void
+dump_pkt_brief(uint16_t port, uint16_t queue, struct rte_mbuf *pkts[], uint16_t nb_pkts, int is_rx)
+{
+	static uint64_t start_cycles;
+	static RTE_ATOMIC(uint64_t) packet_count = 1;
+	uint64_t now;
+	uint64_t count;
+	double interval;
+	uint16_t i;
+
+	now = rte_rdtsc();
+	if (start_cycles == 0) {
+		start_cycles = now;
+		printf("Seq#   Time        Port:Que R Description\n");
+	}
+
+	interval = (double)(now - start_cycles) / (double)rte_get_tsc_hz();
+
+	count = rte_atomic_fetch_add_explicit(&packet_count, nb_pkts, rte_memory_order_relaxed);
+
+	for (i = 0; i < nb_pkts; i++) {
+		const struct rte_mbuf *mb = pkts[i];
+		char str[256];
+
+		rte_dissect_mbuf(str, sizeof(str), mb, 0);
+		printf("%6"PRIu64" %11.9f %4u:%-3u %c %s\n",
+		       count + i, interval, port, queue, is_rx ? 'R' : 'T', str);
+	}
+}
+
+/* Hex dump of packet data */
+static void
+dump_pkt_hex(struct rte_mbuf *pkts[], uint16_t nb_pkts)
+{
+	uint16_t i;
+
+	for (i = 0; i < nb_pkts; i++)
+		rte_pktmbuf_dump(stdout, pkts[i], MAX_DUMP_LEN);
+
+}
+
+static uint16_t
+dump_pkt_burst(uint16_t port_id, uint16_t queue, struct rte_mbuf *pkts[],
+	      uint16_t nb_pkts, int is_rx)
+{
+	if (unlikely(nb_pkts == 0))
+		return 0;
+
+	switch (verbose_level) {
+	case VERBOSE_RX ... VERBOSE_BOTH:
+		dump_pkt_verbose(port_id, queue, pkts, nb_pkts, is_rx);
+		break;
+	case VERBOSE_DISSECT:
+		dump_pkt_brief(port_id, queue, pkts, nb_pkts, is_rx);
+		break;
+	case VERBOSE_HEX:
+		dump_pkt_hex(pkts, nb_pkts);
+	}
+	fflush(stdout);
+	return nb_pkts;
+}
+
 uint16_t
 dump_rx_pkts(uint16_t port_id, uint16_t queue, struct rte_mbuf *pkts[],
 	     uint16_t nb_pkts, __rte_unused uint16_t max_pkts,
diff --git a/doc/guides/testpmd_app_ug/testpmd_funcs.rst b/doc/guides/testpmd_app_ug/testpmd_funcs.rst
index f00ab07605..b9ce7698db 100644
--- a/doc/guides/testpmd_app_ug/testpmd_funcs.rst
+++ b/doc/guides/testpmd_app_ug/testpmd_funcs.rst
@@ -677,7 +677,10 @@ Available levels are as following:
 * ``0`` silent except for error.
 * ``1`` fully verbose except for Tx packets.
 * ``2`` fully verbose except for Rx packets.
-* ``> 2`` fully verbose.
+* ``3`` fully verbose except for Tx and Rx packets.
+* ``4`` dissected protocol information for Tx and Rx packets.
+* ``5`` hex dump of packets
+
 
 set log
 ~~~~~~~
-- 
2.43.0