From 0c6cf045fb0eea38cc7e53ee1984459ae90792bf Mon Sep 17 00:00:00 2001
From: hantwofish <hankangkang5@huawei.com>
Date: Sat, 29 Jun 2024 15:16:54 +0800
Subject: [PATCH] virtio: dfx data of virtio

---
 src/common/gazelle_dfx_msg.h        | 16 ++++++++++++++++
 src/lstack/core/lstack_stack_stat.c |  8 ++++++++
 src/lstack/include/lstack_virtio.h  |  2 +-
 src/ltran/ltran_dfx.c               | 23 +++++++++++++++++++++++
 4 files changed, 48 insertions(+), 1 deletion(-)

diff --git a/src/common/gazelle_dfx_msg.h b/src/common/gazelle_dfx_msg.h
index 696daf2..57bf631 100644
--- a/src/common/gazelle_dfx_msg.h
+++ b/src/common/gazelle_dfx_msg.h
@@ -53,6 +53,7 @@ enum GAZELLE_STAT_MODE {
     GAZELLE_STAT_LSTACK_LOG_LEVEL_SET,
     GAZELLE_STAT_LSTACK_SHOW_RATE,
     GAZELLE_STAT_LSTACK_SHOW_SNMP,
+    GAZELLE_STAT_LSTACK_SHOW_VIRTIO,
     GAZELLE_STAT_LSTACK_SHOW_CONN,
     GAZELLE_STAT_LSTACK_SHOW_LATENCY,
     GAZELLE_STAT_LSTACK_LOW_POWER_MDF,
@@ -137,6 +138,20 @@ struct gazelle_stat_pkts {
     struct gazelle_stack_aggregate_stats aggregate_stats;
 };
 
+// same with lstack_virtio.h struct virtio_instance
+struct gazelle_stat_lstack_virtio {
+#define VIRTIO_MAX_QUEUE_NUM 8
+    uint16_t lstack_port_id;
+    uint16_t virtio_port_id;
+    uint16_t rx_queue_num;
+    uint16_t tx_queue_num;
+
+    uint64_t rx_pkg[VIRTIO_MAX_QUEUE_NUM];
+    uint64_t rx_drop[VIRTIO_MAX_QUEUE_NUM];
+    uint64_t tx_pkg[VIRTIO_MAX_QUEUE_NUM];
+    uint64_t tx_drop[VIRTIO_MAX_QUEUE_NUM];
+};
+
 /* same as define in lwip/stats.h - struct stats_mib2 */
 struct gazelle_stat_lstack_snmp {
     /* IP */
@@ -328,6 +343,7 @@ struct gazelle_stack_dfx_data {
         struct gazelle_stack_latency latency;
         struct gazelle_stat_lstack_conn conn;
         struct gazelle_stat_lstack_snmp snmp;
+        struct gazelle_stat_lstack_virtio virtio;
         struct nic_eth_xstats nic_xstats;
         struct nic_eth_features nic_features;
         struct gazelle_stat_lstack_proto  proto_data;
diff --git a/src/lstack/core/lstack_stack_stat.c b/src/lstack/core/lstack_stack_stat.c
index 0f1f693..1e32c45 100644
--- a/src/lstack/core/lstack_stack_stat.c
+++ b/src/lstack/core/lstack_stack_stat.c
@@ -29,6 +29,7 @@
 #include "posix/lstack_epoll.h"
 #include "lstack_dpdk.h"
 #include "lstack_stack_stat.h"
+#include "lstack_virtio.h"
 
 #define US_PER_SEC  1000000
 
@@ -343,6 +344,13 @@ static void get_stack_dfx_data(struct gazelle_stack_dfx_data *dfx, struct protoc
                 LSTACK_LOG(ERR, LSTACK, "memcpy_s err ret=%d \n", ret);
             }
             break;
+        case GAZELLE_STAT_LSTACK_SHOW_VIRTIO:
+            ret = memcpy_s(&dfx->data.virtio, sizeof(dfx->data.virtio), virtio_instance_get(),
+                           sizeof(*(virtio_instance_get())));
+            if (ret != EOK) {
+                LSTACK_LOG(ERR, LSTACK, "memcpy_s err ret=%d \n", ret);
+            }
+            break;
         case GAZELLE_STAT_LSTACK_SHOW_CONN:
             rpc_call_result = rpc_call_conntable(&stack->dfx_rpc_queue, dfx->data.conn.conn_list,
                                                  GAZELLE_LSTACK_MAX_CONN);
diff --git a/src/lstack/include/lstack_virtio.h b/src/lstack/include/lstack_virtio.h
index 615d9c9..5298dbe 100644
--- a/src/lstack/include/lstack_virtio.h
+++ b/src/lstack/include/lstack_virtio.h
@@ -30,7 +30,7 @@
                                         ((mac_addrs)->addr_bytes[4]), \
                                         ((mac_addrs)->addr_bytes[5])
 #endif
-
+// When modifying virtio_instance, gazelle_stat_lstack_virtio also needs to be modified together.
 struct virtio_instance {
     uint16_t lstack_port_id;
     uint16_t virtio_port_id;
diff --git a/src/ltran/ltran_dfx.c b/src/ltran/ltran_dfx.c
index 4351891..cdcd7b3 100644
--- a/src/ltran/ltran_dfx.c
+++ b/src/ltran/ltran_dfx.c
@@ -128,6 +128,7 @@ static void gazelle_print_ltran_start_latency(void *buf, const struct gazelle_st
 static void gazelle_print_lstack_stat_total(void *buf, const struct gazelle_stat_msg_request *req_msg);
 static void gazelle_print_lstack_stat_rate(void *buf, const struct gazelle_stat_msg_request *req_msg);
 static void gazelle_print_lstack_stat_snmp(void *buf, const struct gazelle_stat_msg_request *req_msg);
+static void gazelle_print_lstack_stat_virtio(void *buf, const struct gazelle_stat_msg_request *req_msg);
 static void gazelle_print_lstack_stat_conn(void *buf, const struct gazelle_stat_msg_request *req_msg);
 static void gazelle_print_lstack_stat_latency(void *buf, const struct gazelle_stat_msg_request *req_msg);
 static void gazelle_print_lstack_stat_lpm(void *buf, const struct gazelle_stat_msg_request *req_msg);
@@ -163,6 +164,7 @@ static struct gazelle_dfx_list g_gazelle_dfx_tbl[] = {
     {GAZELLE_STAT_LSTACK_LOG_LEVEL_SET, 0,                                      gazelle_print_ltran_wait},
     {GAZELLE_STAT_LSTACK_SHOW_RATE,    sizeof(struct gazelle_stack_dfx_data), gazelle_print_lstack_stat_rate},
     {GAZELLE_STAT_LSTACK_SHOW_SNMP,    sizeof(struct gazelle_stack_dfx_data),  gazelle_print_lstack_stat_snmp},
+    {GAZELLE_STAT_LSTACK_SHOW_VIRTIO,  sizeof(struct gazelle_stack_dfx_data),  gazelle_print_lstack_stat_virtio},
     {GAZELLE_STAT_LSTACK_SHOW_CONN,    sizeof(struct gazelle_stack_dfx_data),  gazelle_print_lstack_stat_conn},
     {GAZELLE_STAT_LSTACK_SHOW_LATENCY, sizeof(struct gazelle_stack_dfx_data),  gazelle_print_lstack_stat_latency},
     {GAZELLE_STAT_LSTACK_LOW_POWER_MDF, sizeof(struct gazelle_stack_dfx_data),  gazelle_print_lstack_stat_lpm},
@@ -1169,6 +1171,24 @@ static void gazelle_print_lstack_stat_proto(void *buf, const struct gazelle_stat
     } while (true);
 }
 
+static void gazelle_print_lstack_stat_virtio(void *buf, const struct gazelle_stat_msg_request *req_msg)
+{
+    struct gazelle_stack_dfx_data *stat = (struct gazelle_stack_dfx_data *)buf;
+    struct gazelle_stat_lstack_virtio *virtio = &stat->data.virtio;
+    printf("\nStatistics of lstack virtio:\n");
+
+    printf("\nlstack_port_id =%u virtio_port_id =%u rx_queue_num =%u tx_queue_num =%u \n",
+           virtio->lstack_port_id, virtio->virtio_port_id, virtio->rx_queue_num,
+           virtio->tx_queue_num);
+
+    printf("\n%-8s %-8s  %-8s  %-8s  %-8s\n", "queue_id", "rx_pkg", "rx_drop", "tx_pkg", "tx_drop");
+    for (int i = 0; i < virtio->rx_queue_num; i++) {
+        printf("%-8d  %-8lu  %-8lu  %-8lu  %-8lu\n", i,
+               virtio->rx_pkg[i], virtio->rx_drop[i], virtio->tx_pkg[i], virtio->tx_drop[i]);
+    }
+    printf("\n");
+}
+
 static void gazelle_keepalive_string(char* str, int buff_len, struct gazelle_stat_lstack_conn_info *conn_info)
 {
     if (conn_info->keepalive == 0) {
@@ -1298,6 +1318,7 @@ static void show_usage(void)
            "                  show lstack all statistics \n"
            "  -r, rate        show lstack statistics per second \n"
            "  -s, snmp        show lstack snmp \n"
+           "  -v, virtio      show rx_pkg/rx_drop/tx_pkg/tx_drop num of virtio \n"
            "  -c, connect     show lstack connect \n"
            "  -l, latency     [time]   show lstack latency \n"
            "  -x, xstats      show lstack xstats \n"
@@ -1553,6 +1574,8 @@ static int32_t parse_dfx_lstack_show_args(int32_t argc, char *argv[], struct gaz
         req_msg[cmd_index++].stat_mode = GAZELLE_STAT_MODE_MAX;
     } else if (strcmp(param, "snmp") == 0 || strcmp(param, "-s") == 0) {
         req_msg[cmd_index++].stat_mode = GAZELLE_STAT_LSTACK_SHOW_SNMP;
+    } else if (strcmp(param, "virtio") == 0 || strcmp(param, "-v") == 0) {
+        req_msg[cmd_index++].stat_mode = GAZELLE_STAT_LSTACK_SHOW_VIRTIO;
     } else if (strcmp(param, "connect") == 0 || strcmp(param, "-c") == 0) {
         req_msg[cmd_index++].stat_mode = GAZELLE_STAT_LSTACK_SHOW_CONN;
     } else if (strcmp(param, "xstats") == 0 || strcmp(param, "-x") == 0) {
-- 
2.33.0

