From: Qi Zhang <qi.z.zhang@intel.com>
To: qiming.yang@intel.com, wenjun1.wu@intel.com
Cc: dev@dpdk.org, Qi Zhang <qi.z.zhang@intel.com>
Subject: [PATCH v7 1/2] net/ice: add Tx scheduling tree dump support
Date: Tue, 2 Jan 2024 07:39:34 -0500 [thread overview]
Message-ID: <20240102123935.3524184-1-qi.z.zhang@intel.com> (raw)
In-Reply-To: <20231226185428.3158880-1-qi.z.zhang@intel.com>
Added Testpmd CLI support for dumping Tx scheduling tree.
Usage:
testpmd>txsched dump <port_id> <brief|detail> <filename>
The output file is in "dot" format, which can be converted
into an image file using Graphviz.
- In "brief" mode, all scheduling nodes in the tree are displayed.
- In "detail" mode, each node's configuration parameters are also
displayed.
Renamed `ice_ddp_package.c` to `ice_diagnose.c`, which now contains
all CLI support for diagnostic purposes.
Signed-off-by: Qi Zhang <qi.z.zhang@intel.com>
---
v7:
- fix ci warning.
v5:
- ignore the error when query node failed at queue level, as queue may
be stopped.
v4:
- show node type in brief mode
v3:
- fix incorrect parameter when query rl profile
v2:
- fix CI build issue
.../ice/{ice_ddp_package.c => ice_diagnose.c} | 372 ++++++++++++++++++
drivers/net/ice/ice_ethdev.h | 3 +
drivers/net/ice/ice_testpmd.c | 65 +++
drivers/net/ice/meson.build | 2 +-
drivers/net/ice/version.map | 1 +
5 files changed, 442 insertions(+), 1 deletion(-)
rename drivers/net/ice/{ice_ddp_package.c => ice_diagnose.c} (60%)
diff --git a/drivers/net/ice/ice_ddp_package.c b/drivers/net/ice/ice_diagnose.c
similarity index 60%
rename from drivers/net/ice/ice_ddp_package.c
rename to drivers/net/ice/ice_diagnose.c
index 0aa19eb282..3be819d7f8 100644
--- a/drivers/net/ice/ice_ddp_package.c
+++ b/drivers/net/ice/ice_diagnose.c
@@ -11,6 +11,7 @@
#include <rte_tailq.h>
#include "ice_ethdev.h"
+#include "ice_rxtx.h"
#define ICE_BLK_MAX_COUNT 512
#define ICE_BUFF_SEG_HEADER_FLAG 0x1
@@ -507,3 +508,374 @@ int rte_pmd_ice_dump_switch(uint16_t port, uint8_t **buff, uint32_t *size)
return ice_dump_switch(dev, buff, size);
}
+
+static void print_rl_profile(struct ice_aqc_rl_profile_elem *prof,
+ FILE *stream)
+{
+ fprintf(stream, "\t\t\t\t\t<td>\n");
+ fprintf(stream, "\t\t\t\t\t\t<table>\n");
+
+ fprintf(stream, "\t\t\t\t\t\t\t<tr>\n");
+ fprintf(stream, "\t\t\t\t\t\t\t\t<td>id</td>\n");
+ fprintf(stream, "\t\t\t\t\t\t\t\t<td>%d</td>\n", prof->profile_id);
+ fprintf(stream, "\t\t\t\t\t\t\t</tr>\n");
+
+ fprintf(stream, "\t\t\t\t\t\t\t<tr>\n");
+ fprintf(stream, "\t\t\t\t\t\t\t\t<td>max burst size</td>\n");
+ fprintf(stream, "\t\t\t\t\t\t\t\t<td>%d</td>\n", prof->max_burst_size);
+ fprintf(stream, "\t\t\t\t\t\t\t</tr>\n");
+
+ fprintf(stream, "\t\t\t\t\t\t\t<tr>\n");
+ fprintf(stream, "\t\t\t\t\t\t\t\t<td>rate limit multiply</td>\n");
+ fprintf(stream, "\t\t\t\t\t\t\t\t<td>%d</td>\n", prof->rl_multiply);
+ fprintf(stream, "\t\t\t\t\t\t\t</tr>\n");
+
+ fprintf(stream, "\t\t\t\t\t\t\t<tr>\n");
+ fprintf(stream, "\t\t\t\t\t\t\t\t<td>wake up calculation</td>\n");
+ fprintf(stream, "\t\t\t\t\t\t\t\t<td>%d</td>\n", prof->wake_up_calc);
+ fprintf(stream, "\t\t\t\t\t\t\t</tr>\n");
+
+ fprintf(stream, "\t\t\t\t\t\t\t<tr>\n");
+ fprintf(stream, "\t\t\t\t\t\t\t\t<td>rate limit encode</td>\n");
+ fprintf(stream, "\t\t\t\t\t\t\t\t<td>%d</td>\n", prof->rl_encode);
+ fprintf(stream, "\t\t\t\t\t\t\t</tr>\n");
+
+ fprintf(stream, "\t\t\t\t\t\t</table>\n");
+ fprintf(stream, "\t\t\t\t\t</td>\n");
+}
+
+static
+void print_elem_type(FILE *stream, u8 type)
+{
+ switch (type) {
+ case 1:
+ fprintf(stream, "root");
+ break;
+ case 2:
+ fprintf(stream, "tc");
+ break;
+ case 3:
+ fprintf(stream, "se_generic");
+ break;
+ case 4:
+ fprintf(stream, "entry_point");
+ break;
+ case 5:
+ fprintf(stream, "leaf");
+ break;
+ default:
+ fprintf(stream, "%d", type);
+ break;
+ }
+}
+
+static
+void print_valid_sections(FILE *stream, u8 vs)
+{
+ if ((vs & 0x1) != 0)
+ fprintf(stream, "generic ");
+ if ((vs & 0x2) != 0)
+ fprintf(stream, "cir ");
+ if ((vs & 0x4) != 0)
+ fprintf(stream, "eir ");
+ if ((vs & 0x8) != 0)
+ fprintf(stream, "shared ");
+}
+
+static
+void print_scheduling_mode(FILE *stream, bool flag)
+{
+ if (flag)
+ fprintf(stream, "pps");
+ else
+ fprintf(stream, "bps");
+}
+
+static
+void print_priority_mode(FILE *stream, bool flag)
+{
+ if (flag)
+ fprintf(stream, "single priority node");
+ else
+ fprintf(stream, "wfq");
+}
+
+static
+void print_node(struct ice_aqc_txsched_elem_data *data,
+ struct ice_aqc_rl_profile_elem *cir_prof,
+ struct ice_aqc_rl_profile_elem *eir_prof,
+ struct ice_aqc_rl_profile_elem *shared_prof,
+ bool detail, FILE *stream)
+{
+ fprintf(stream, "\tNODE_%d [\n", data->node_teid);
+ fprintf(stream, "\t\tlabel=<\n");
+
+ fprintf(stream, "\t\t\t<table>\n");
+
+ fprintf(stream, "\t\t\t\t<tr>\n");
+ fprintf(stream, "\t\t\t\t\t<td> teid </td>\n");
+ fprintf(stream, "\t\t\t\t\t<td> %d </td>\n", data->node_teid);
+ fprintf(stream, "\t\t\t\t</tr>\n");
+
+ fprintf(stream, "\t\t\t\t<tr>\n");
+ fprintf(stream, "\t\t\t\t\t<td> type </td>\n");
+ fprintf(stream, "\t\t\t\t\t<td>");
+ print_elem_type(stream, data->data.elem_type);
+ fprintf(stream, "</td>\n");
+ fprintf(stream, "\t\t\t\t</tr>\n");
+
+ if (!detail)
+ goto brief;
+
+ fprintf(stream, "\t\t\t\t<tr>\n");
+ fprintf(stream, "\t\t\t\t\t<td> valid sections </td>\n");
+ fprintf(stream, "\t\t\t\t\t<td>");
+ print_valid_sections(stream, data->data.valid_sections);
+ fprintf(stream, "</td>\n");
+ fprintf(stream, "\t\t\t\t</tr>\n");
+
+ fprintf(stream, "\t\t\t\t<tr>\n");
+ fprintf(stream, "\t\t\t\t\t<td> scheduling mode </td>\n");
+ fprintf(stream, "\t\t\t\t\t<td>");
+ print_scheduling_mode(stream, (data->data.generic & 0x1) != 0);
+ fprintf(stream, "</td>\n");
+ fprintf(stream, "\t\t\t\t</tr>\n");
+
+ fprintf(stream, "\t\t\t\t<tr>\n");
+ fprintf(stream, "\t\t\t\t\t<td> priority </td>\n");
+ fprintf(stream, "\t\t\t\t\t<td> %d </td>\n", (data->data.generic >> 1) & 0x7);
+ fprintf(stream, "\t\t\t\t</tr>\n");
+
+ fprintf(stream, "\t\t\t\t<tr>\n");
+ fprintf(stream, "\t\t\t\t\t<td> priority mode</td>\n");
+ fprintf(stream, "\t\t\t\t\t<td>");
+ print_priority_mode(stream, ((data->data.generic >> 4) & 0x1) != 0);
+ fprintf(stream, "</td>\n");
+ fprintf(stream, "\t\t\t\t</tr>\n");
+
+ fprintf(stream, "\t\t\t\t<tr>\n");
+ fprintf(stream, "\t\t\t\t\t<td> adjustment value </td>\n");
+ fprintf(stream, "\t\t\t\t\t<td> %d </td>\n", (data->data.generic >> 5) & 0x3);
+ fprintf(stream, "\t\t\t\t</tr>\n");
+
+ fprintf(stream, "\t\t\t\t<tr>\n");
+ fprintf(stream, "\t\t\t\t\t<td> suspended </td>\n");
+ fprintf(stream, "\t\t\t\t\t<td> %d </td>\n", data->data.flags & 0x1);
+ fprintf(stream, "\t\t\t\t</tr>\n");
+
+ fprintf(stream, "\t\t\t\t<tr>\n");
+ fprintf(stream, "\t\t\t\t\t<td> cir bw profile </td>\n");
+ if (cir_prof == NULL)
+ fprintf(stream, "\t\t\t\t\t<td> default </td>\n");
+ else
+ print_rl_profile(cir_prof, stream);
+ fprintf(stream, "\t\t\t\t</tr>\n");
+
+ fprintf(stream, "\t\t\t\t<tr>\n");
+ fprintf(stream, "\t\t\t\t\t<td> cir bw weight </td>\n");
+ fprintf(stream, "\t\t\t\t\t<td> %d </td>\n", data->data.cir_bw.bw_alloc);
+ fprintf(stream, "\t\t\t\t</tr>\n");
+
+ fprintf(stream, "\t\t\t\t<tr>\n");
+ fprintf(stream, "\t\t\t\t\t<td> eir bw profile </td>\n");
+ if (eir_prof == NULL)
+ fprintf(stream, "\t\t\t\t\t<td> default </td>\n");
+ else
+ print_rl_profile(eir_prof, stream);
+ fprintf(stream, "\t\t\t\t</tr>\n");
+
+ fprintf(stream, "\t\t\t\t<tr>\n");
+ fprintf(stream, "\t\t\t\t\t<td> eir bw weight </td>\n");
+ fprintf(stream, "\t\t\t\t\t<td> %d </td>\n", data->data.eir_bw.bw_alloc);
+ fprintf(stream, "\t\t\t\t</tr>\n");
+
+ fprintf(stream, "\t\t\t\t<tr>\n");
+ fprintf(stream, "\t\t\t\t\t<td> shared rl profile </td>\n");
+ if (shared_prof == NULL)
+ fprintf(stream, "\t\t\t\t\t<td> default </td>\n");
+ else
+ print_rl_profile(shared_prof, stream);
+ fprintf(stream, "\t\t\t\t</tr>\n");
+
+brief:
+ fprintf(stream, "\t\t\t</table>\n");
+
+ fprintf(stream, "\t\t>\n");
+ fprintf(stream, "\t\tshape=plain\n");
+ fprintf(stream, "\t]\n");
+
+ if (data->parent_teid != 0xFFFFFFFF)
+ fprintf(stream, "\tNODE_%d -> NODE_%d\n", data->parent_teid, data->node_teid);
+}
+
+static
+int query_rl_profile(struct ice_hw *hw,
+ uint8_t level, uint8_t flags, uint16_t profile_id,
+ struct ice_aqc_rl_profile_elem *data)
+{
+ enum ice_status ice_status;
+
+ data->level = level;
+ data->flags = flags;
+ data->profile_id = profile_id;
+
+ ice_status = ice_aq_query_rl_profile(hw, 1, data,
+ sizeof(struct ice_aqc_rl_profile_elem), NULL);
+
+ if (ice_status != ICE_SUCCESS) {
+ PMD_DRV_LOG(ERR, "Failed to query rl profile.");
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static
+int query_node(struct ice_hw *hw, uint32_t child, uint32_t *parent,
+ uint8_t level, bool detail, FILE *stream)
+{
+ struct ice_aqc_txsched_elem_data data;
+ enum ice_status status;
+ struct ice_aqc_rl_profile_elem cir_prof;
+ struct ice_aqc_rl_profile_elem eir_prof;
+ struct ice_aqc_rl_profile_elem shared_prof;
+ struct ice_aqc_rl_profile_elem *cp = NULL;
+ struct ice_aqc_rl_profile_elem *ep = NULL;
+ struct ice_aqc_rl_profile_elem *sp = NULL;
+ int ret;
+
+ status = ice_sched_query_elem(hw, child, &data);
+ if (status != ICE_SUCCESS) {
+ if (level == hw->num_tx_sched_layers) {
+ /* ignore the error when a queue has been stopped. */
+ PMD_DRV_LOG(WARNING, "Failed to query queue node %d.", child);
+ *parent = 0xffffffff;
+ return 0;
+ }
+ PMD_DRV_LOG(ERR, "Failed to query scheduling node %d.", child);
+ return -EINVAL;
+ }
+
+ *parent = data.parent_teid;
+
+ if (data.data.cir_bw.bw_profile_idx != 0) {
+ ret = query_rl_profile(hw, level, 0, data.data.cir_bw.bw_profile_idx, &cir_prof);
+
+ if (ret)
+ return ret;
+ cp = &cir_prof;
+ }
+
+ if (data.data.eir_bw.bw_profile_idx != 0) {
+ ret = query_rl_profile(hw, level, 1, data.data.eir_bw.bw_profile_idx, &eir_prof);
+
+ if (ret)
+ return ret;
+ ep = &eir_prof;
+ }
+
+ if (data.data.srl_id != 0) {
+ ret = query_rl_profile(hw, level, 2, data.data.srl_id, &shared_prof);
+
+ if (ret)
+ return ret;
+ sp = &shared_prof;
+ }
+
+ print_node(&data, cp, ep, sp, detail, stream);
+
+ return 0;
+}
+
+static
+int query_nodes(struct ice_hw *hw,
+ uint32_t *children, int child_num,
+ uint32_t *parents, int *parent_num,
+ uint8_t level, bool detail,
+ FILE *stream)
+{
+ uint32_t parent;
+ int i;
+ int j;
+
+ *parent_num = 0;
+ for (i = 0; i < child_num; i++) {
+ bool exist = false;
+ int ret;
+
+ ret = query_node(hw, children[i], &parent, level, detail, stream);
+ if (ret)
+ return -EINVAL;
+
+ for (j = 0; j < *parent_num; j++) {
+ if (parents[j] == parent) {
+ exist = true;
+ break;
+ }
+ }
+
+ if (!exist && parent != 0xFFFFFFFF)
+ parents[(*parent_num)++] = parent;
+ }
+
+ return 0;
+}
+
+int rte_pmd_ice_dump_txsched(uint16_t port, bool detail, FILE *stream)
+{
+ struct rte_eth_dev *dev;
+ struct ice_hw *hw;
+ struct ice_pf *pf;
+ struct ice_q_ctx *q_ctx;
+ uint16_t q_num;
+ uint16_t i;
+ struct ice_tx_queue *txq;
+ uint32_t buf1[256];
+ uint32_t buf2[256];
+ uint32_t *children = buf1;
+ uint32_t *parents = buf2;
+ int child_num = 0;
+ int parent_num = 0;
+ uint8_t level;
+
+ RTE_ETH_VALID_PORTID_OR_ERR_RET(port, -ENODEV);
+
+ dev = &rte_eth_devices[port];
+ if (!is_ice_supported(dev))
+ return -ENOTSUP;
+
+ dev = &rte_eth_devices[port];
+ hw = ICE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+ pf = ICE_DEV_PRIVATE_TO_PF(dev->data->dev_private);
+ level = hw->num_tx_sched_layers;
+
+ q_num = dev->data->nb_tx_queues;
+
+ /* main vsi */
+ for (i = 0; i < q_num; i++) {
+ txq = dev->data->tx_queues[i];
+ q_ctx = ice_get_lan_q_ctx(hw, txq->vsi->idx, 0, i);
+ children[child_num++] = q_ctx->q_teid;
+ }
+
+ /* fdir vsi */
+ q_ctx = ice_get_lan_q_ctx(hw, pf->fdir.fdir_vsi->idx, 0, 0);
+ children[child_num++] = q_ctx->q_teid;
+
+ fprintf(stream, "digraph tx_sched {\n");
+ while (child_num > 0) {
+ int ret;
+ ret = query_nodes(hw, children, child_num,
+ parents, &parent_num,
+ level, detail, stream);
+ if (ret)
+ return ret;
+
+ children = parents;
+ child_num = parent_num;
+ level--;
+ }
+ fprintf(stream, "}\n");
+
+ return 0;
+}
diff --git a/drivers/net/ice/ice_ethdev.h b/drivers/net/ice/ice_ethdev.h
index d607f028e0..1338c80d14 100644
--- a/drivers/net/ice/ice_ethdev.h
+++ b/drivers/net/ice/ice_ethdev.h
@@ -739,4 +739,7 @@ int rte_pmd_ice_dump_package(uint16_t port, uint8_t **buff, uint32_t *size);
__rte_experimental
int rte_pmd_ice_dump_switch(uint16_t port, uint8_t **buff, uint32_t *size);
+
+__rte_experimental
+int rte_pmd_ice_dump_txsched(uint16_t port, bool detail, FILE *stream);
#endif /* _ICE_ETHDEV_H_ */
diff --git a/drivers/net/ice/ice_testpmd.c b/drivers/net/ice/ice_testpmd.c
index a7a8d0c53c..98c02d68c6 100644
--- a/drivers/net/ice/ice_testpmd.c
+++ b/drivers/net/ice/ice_testpmd.c
@@ -3,6 +3,7 @@
*/
#include <stdlib.h>
+#include <stdio.h>
#include <cmdline_parse_num.h>
#include <cmdline_parse_string.h>
@@ -148,6 +149,63 @@ cmdline_parse_inst_t cmd_ddp_dump_switch = {
},
};
+/* Dump Tx Scheduling Tree configuration, only for ice PF */
+struct cmd_txsched_dump_result {
+ cmdline_fixed_string_t txsched;
+ cmdline_fixed_string_t dump;
+ portid_t port_id;
+ cmdline_fixed_string_t mode;
+ char filepath[];
+};
+
+cmdline_parse_token_string_t cmd_txsched_dump_txsched =
+ TOKEN_STRING_INITIALIZER(struct cmd_txsched_dump_result, txsched, "txsched");
+cmdline_parse_token_string_t cmd_txsched_dump_dump =
+ TOKEN_STRING_INITIALIZER(struct cmd_txsched_dump_result, dump, "dump");
+cmdline_parse_token_num_t cmd_txsched_dump_port_id =
+ TOKEN_NUM_INITIALIZER(struct cmd_txsched_dump_result, port_id, RTE_UINT16);
+cmdline_parse_token_string_t cmd_txsched_dump_mode =
+ TOKEN_STRING_INITIALIZER(struct cmd_txsched_dump_result, mode, "brief#detail");
+cmdline_parse_token_string_t cmd_txsched_dump_filepath =
+ TOKEN_STRING_INITIALIZER(struct cmd_txsched_dump_result, filepath, NULL);
+
+static void
+cmd_txsched_dump_parsed(void *parsed_result,
+ __rte_unused struct cmdline *cl,
+ __rte_unused void *data)
+{
+ struct cmd_txsched_dump_result *res = parsed_result;
+ bool detail = false;
+ FILE *fp;
+
+ if (!strcmp(res->mode, "detail"))
+ detail = true;
+
+ fp = fopen(res->filepath, "w");
+ if (fp == NULL) {
+ fprintf(stderr, "Failed to open file\n");
+ return;
+ }
+
+ if (rte_pmd_ice_dump_txsched(res->port_id, detail, fp))
+ fprintf(stderr, "Failed to dump Tx scheduring runtime configure.\n");
+ fclose(fp);
+}
+
+cmdline_parse_inst_t cmd_txsched_dump = {
+ .f = cmd_txsched_dump_parsed,
+ .data = NULL,
+ .help_str = "txsched dump <port_id> <brief|detail> <config_path>",
+ .tokens = {
+ (void *)&cmd_txsched_dump_txsched,
+ (void *)&cmd_txsched_dump_dump,
+ (void *)&cmd_txsched_dump_port_id,
+ (void *)&cmd_txsched_dump_mode,
+ (void *)&cmd_txsched_dump_filepath,
+ NULL,
+ },
+};
+
static struct testpmd_driver_commands ice_cmds = {
.commands = {
{
@@ -161,8 +219,15 @@ static struct testpmd_driver_commands ice_cmds = {
"ddp dump switch (port_id) (config_path)\n"
" Dump a runtime switch configure on a port\n\n",
+ },
+ {
+ &cmd_txsched_dump,
+ "txsched dump (port_id) <brief|detail> (config_path)\n"
+ " Dump tx scheduling runtime configure on a port\n\n",
+
},
{ NULL, NULL },
},
};
+
TESTPMD_ADD_DRIVER_COMMANDS(ice_cmds)
diff --git a/drivers/net/ice/meson.build b/drivers/net/ice/meson.build
index a957fc5d3a..b7f2188e62 100644
--- a/drivers/net/ice/meson.build
+++ b/drivers/net/ice/meson.build
@@ -6,7 +6,7 @@ objs = [base_objs]
sources = files(
'ice_acl_filter.c',
- 'ice_ddp_package.c',
+ 'ice_diagnose.c',
'ice_ethdev.c',
'ice_fdir_filter.c',
'ice_generic_flow.c',
diff --git a/drivers/net/ice/version.map b/drivers/net/ice/version.map
index 4e924c8f4d..24b425d6f7 100644
--- a/drivers/net/ice/version.map
+++ b/drivers/net/ice/version.map
@@ -8,4 +8,5 @@ EXPERIMENTAL {
# added in 19.11
rte_pmd_ice_dump_package;
rte_pmd_ice_dump_switch;
+ rte_pmd_ice_dump_txsched;
};
--
2.31.1
next prev parent reply other threads:[~2024-01-02 4:18 UTC|newest]
Thread overview: 22+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-12-26 18:54 [PATCH 1/2] net/ice: add Tx scheduling tree dump support Qi Zhang
2023-12-26 18:54 ` [PATCH 2/2] doc: add document for diagnostic utilities Qi Zhang
2023-12-27 12:31 ` [PATCH v2 1/2] net/ice: add Tx scheduling tree dump support Qi Zhang
2023-12-27 12:31 ` [PATCH v2 2/2] doc: add document for diagnostic utilities Qi Zhang
2023-12-28 10:10 ` [PATCH v3 1/2] net/ice: add Tx scheduling tree dump support Qi Zhang
2023-12-28 10:10 ` [PATCH v3 2/2] doc: add document for diagnostic utilities Qi Zhang
2024-01-02 10:28 ` [PATCH v4 1/2] net/ice: reset Tx sched node during commit Qi Zhang
2024-01-02 10:29 ` [PATCH v4 2/2] net/ice: support Tx sched commit before dev_start Qi Zhang
2024-01-02 10:32 ` [PATCH 1/2] net/ice: add Tx scheduling tree dump support Qi Zhang
2024-01-02 10:32 ` [PATCH 2/2] doc: add document for diagnostic utilities Qi Zhang
2024-01-02 10:33 ` [PATCH v4 1/2] net/ice: add Tx scheduling tree dump support Qi Zhang
2024-01-02 10:33 ` [PATCH v4 2/2] doc: add document for diagnostic utilities Qi Zhang
2024-01-02 12:24 ` [PATCH v5 1/2] net/ice: add Tx scheduling tree dump support Qi Zhang
2024-01-02 12:24 ` [PATCH v5 2/2] doc: add document for diagnostic utilities Qi Zhang
2024-01-02 23:30 ` [PATCH v5 1/2] net/ice: add Tx scheduling tree dump support Stephen Hemminger
2024-01-02 12:29 ` [PATCH v6 " Qi Zhang
2024-01-02 12:29 ` [PATCH v6 2/2] doc: add document for ice diagnostic utilities Qi Zhang
2024-01-02 17:05 ` Stephen Hemminger
2024-01-02 12:39 ` Qi Zhang [this message]
2024-01-02 6:22 ` [PATCH v7 1/2] net/ice: add Tx scheduling tree dump support Wu, Wenjun1
2024-01-02 12:39 ` [PATCH v7 2/2] doc: add document for ice diagnostic utilities Qi Zhang
2024-01-02 7:14 ` Yang, Qiming
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20240102123935.3524184-1-qi.z.zhang@intel.com \
--to=qi.z.zhang@intel.com \
--cc=dev@dpdk.org \
--cc=qiming.yang@intel.com \
--cc=wenjun1.wu@intel.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.