[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <20240423113141.1752-6-xuanzhuo@linux.alibaba.com>
Date: Tue, 23 Apr 2024 19:31:38 +0800
From: Xuan Zhuo <xuanzhuo@...ux.alibaba.com>
To: netdev@...r.kernel.org
Cc: "David S. Miller" <davem@...emloft.net>,
Eric Dumazet <edumazet@...gle.com>,
Jakub Kicinski <kuba@...nel.org>,
Paolo Abeni <pabeni@...hat.com>,
"Michael S. Tsirkin" <mst@...hat.com>,
Jason Wang <jasowang@...hat.com>,
Xuan Zhuo <xuanzhuo@...ux.alibaba.com>,
Alexei Starovoitov <ast@...nel.org>,
Daniel Borkmann <daniel@...earbox.net>,
Jesper Dangaard Brouer <hawk@...nel.org>,
John Fastabend <john.fastabend@...il.com>,
Stanislav Fomichev <sdf@...gle.com>,
Amritha Nambiar <amritha.nambiar@...el.com>,
Larysa Zaremba <larysa.zaremba@...el.com>,
Sridhar Samudrala <sridhar.samudrala@...el.com>,
Maciej Fijalkowski <maciej.fijalkowski@...el.com>,
virtualization@...ts.linux.dev,
bpf@...r.kernel.org
Subject: [PATCH net-next v6 5/8] virtio_net: add the total stats field
Now, we just show the stats of every queue.
But for the user, the total values of every stat may are valuable.
NIC statistics:
rx_packets: 373522
rx_bytes: 85919736
rx_drops: 0
rx_xdp_packets: 0
rx_xdp_tx: 0
rx_xdp_redirects: 0
rx_xdp_drops: 0
rx_kicks: 11125
rx_hw_notifications: 0
rx_hw_packets: 1325870
rx_hw_bytes: 263348963
rx_hw_interrupts: 0
rx_hw_drops: 1451
rx_hw_drop_overruns: 0
rx_hw_csum_valid: 1325870
rx_hw_needs_csum: 1325870
rx_hw_csum_none: 0
rx_hw_csum_bad: 0
rx_hw_ratelimit_packets: 0
rx_hw_ratelimit_bytes: 0
tx_packets: 10050
tx_bytes: 1230176
tx_xdp_tx: 0
tx_xdp_tx_drops: 0
tx_kicks: 10050
tx_timeouts: 0
tx_hw_notifications: 0
tx_hw_packets: 32281
tx_hw_bytes: 4315590
tx_hw_interrupts: 0
tx_hw_drops: 0
tx_hw_drop_malformed: 0
tx_hw_csum_none: 0
tx_hw_needs_csum: 32281
tx_hw_ratelimit_packets: 0
tx_hw_ratelimit_bytes: 0
rx0_packets: 373522
rx0_bytes: 85919736
rx0_drops: 0
rx0_xdp_packets: 0
rx0_xdp_tx: 0
rx0_xdp_redirects: 0
rx0_xdp_drops: 0
rx0_kicks: 11125
rx0_hw_notifications: 0
rx0_hw_packets: 1325870
rx0_hw_bytes: 263348963
rx0_hw_interrupts: 0
rx0_hw_drops: 1451
rx0_hw_drop_overruns: 0
rx0_hw_csum_valid: 1325870
rx0_hw_needs_csum: 1325870
rx0_hw_csum_none: 0
rx0_hw_csum_bad: 0
rx0_hw_ratelimit_packets: 0
rx0_hw_ratelimit_bytes: 0
tx0_packets: 10050
tx0_bytes: 1230176
tx0_xdp_tx: 0
tx0_xdp_tx_drops: 0
tx0_kicks: 10050
tx0_timeouts: 0
tx0_hw_notifications: 0
tx0_hw_packets: 32281
tx0_hw_bytes: 4315590
tx0_hw_interrupts: 0
tx0_hw_drops: 0
tx0_hw_drop_malformed: 0
tx0_hw_csum_none: 0
tx0_hw_needs_csum: 32281
tx0_hw_ratelimit_packets: 0
tx0_hw_ratelimit_bytes: 0
Signed-off-by: Xuan Zhuo <xuanzhuo@...ux.alibaba.com>
---
drivers/net/virtio_net.c | 81 ++++++++++++++++++++++++++++++++++------
1 file changed, 69 insertions(+), 12 deletions(-)
diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c
index 6d24cd8fb15f..8a4d22f5f5b1 100644
--- a/drivers/net/virtio_net.c
+++ b/drivers/net/virtio_net.c
@@ -3344,14 +3344,15 @@ static void virtnet_stats_sprintf(u8 **p, const char *fmt, const char *noq_fmt,
}
}
+/* qid == -1: for rx/tx queue total field */
static void virtnet_get_stats_string(struct virtnet_info *vi, int type, int qid, u8 **data)
{
const struct virtnet_stat_desc *desc;
const char *fmt, *noq_fmt;
u8 *p = *data;
- u32 num = 0;
+ u32 num;
- if (type == VIRTNET_Q_TYPE_CQ) {
+ if (type == VIRTNET_Q_TYPE_CQ && qid >= 0) {
noq_fmt = "cq_hw_%s";
if (VIRTIO_NET_STATS_TYPE_CVQ & vi->device_stats_cap) {
@@ -3364,65 +3365,69 @@ static void virtnet_get_stats_string(struct virtnet_info *vi, int type, int qid,
if (type == VIRTNET_Q_TYPE_RX) {
fmt = "rx%u_%s";
+ noq_fmt = "rx_%s";
desc = &virtnet_rq_stats_desc[0];
num = ARRAY_SIZE(virtnet_rq_stats_desc);
- virtnet_stats_sprintf(&p, fmt, NULL, num, qid, desc);
+ virtnet_stats_sprintf(&p, fmt, noq_fmt, num, qid, desc);
fmt = "rx%u_hw_%s";
+ noq_fmt = "rx_hw_%s";
if (VIRTIO_NET_STATS_TYPE_RX_BASIC & vi->device_stats_cap) {
desc = &virtnet_stats_rx_basic_desc[0];
num = ARRAY_SIZE(virtnet_stats_rx_basic_desc);
- virtnet_stats_sprintf(&p, fmt, NULL, num, qid, desc);
+ virtnet_stats_sprintf(&p, fmt, noq_fmt, num, qid, desc);
}
if (VIRTIO_NET_STATS_TYPE_RX_CSUM & vi->device_stats_cap) {
desc = &virtnet_stats_rx_csum_desc[0];
num = ARRAY_SIZE(virtnet_stats_rx_csum_desc);
- virtnet_stats_sprintf(&p, fmt, NULL, num, qid, desc);
+ virtnet_stats_sprintf(&p, fmt, noq_fmt, num, qid, desc);
}
if (VIRTIO_NET_STATS_TYPE_RX_SPEED & vi->device_stats_cap) {
desc = &virtnet_stats_rx_speed_desc[0];
num = ARRAY_SIZE(virtnet_stats_rx_speed_desc);
- virtnet_stats_sprintf(&p, fmt, NULL, num, qid, desc);
+ virtnet_stats_sprintf(&p, fmt, noq_fmt, num, qid, desc);
}
}
if (type == VIRTNET_Q_TYPE_TX) {
fmt = "tx%u_%s";
+ noq_fmt = "tx_%s";
desc = &virtnet_sq_stats_desc[0];
num = ARRAY_SIZE(virtnet_sq_stats_desc);
- virtnet_stats_sprintf(&p, fmt, NULL, num, qid, desc);
+ virtnet_stats_sprintf(&p, fmt, noq_fmt, num, qid, desc);
fmt = "tx%u_hw_%s";
+ noq_fmt = "tx_hw_%s";
if (VIRTIO_NET_STATS_TYPE_TX_BASIC & vi->device_stats_cap) {
desc = &virtnet_stats_tx_basic_desc[0];
num = ARRAY_SIZE(virtnet_stats_tx_basic_desc);
- virtnet_stats_sprintf(&p, fmt, NULL, num, qid, desc);
+ virtnet_stats_sprintf(&p, fmt, noq_fmt, num, qid, desc);
}
if (VIRTIO_NET_STATS_TYPE_TX_GSO & vi->device_stats_cap) {
desc = &virtnet_stats_tx_gso_desc[0];
num = ARRAY_SIZE(virtnet_stats_tx_gso_desc);
- virtnet_stats_sprintf(&p, fmt, NULL, num, qid, desc);
+ virtnet_stats_sprintf(&p, fmt, noq_fmt, num, qid, desc);
}
if (VIRTIO_NET_STATS_TYPE_TX_SPEED & vi->device_stats_cap) {
desc = &virtnet_stats_tx_speed_desc[0];
num = ARRAY_SIZE(virtnet_stats_tx_speed_desc);
- virtnet_stats_sprintf(&p, fmt, NULL, num, qid, desc);
+ virtnet_stats_sprintf(&p, fmt, noq_fmt, num, qid, desc);
}
}
@@ -3503,6 +3508,49 @@ static void virtnet_stats_ctx_init(struct virtnet_info *vi,
}
}
+/* stats_sum_queue - Calculate the sum of the same fields in sq or rq.
+ * @sum: the position to store the sum values
+ * @num: field num
+ * @q_value: the first queue fields
+ * @q_num: number of the queues
+ */
+static void stats_sum_queue(u64 *sum, u32 num, u64 *q_value, u32 q_num)
+{
+ u32 step = num;
+ int i, j;
+ u64 *p;
+
+ for (i = 0; i < num; ++i) {
+ p = sum + i;
+ *p = 0;
+
+ for (j = 0; j < q_num; ++j)
+ *p += *(q_value + i + j * step);
+ }
+}
+
+static void virtnet_fill_total_fields(struct virtnet_info *vi,
+ struct virtnet_stats_ctx *ctx)
+{
+ u64 *data, *first_rx_q, *first_tx_q;
+ u32 num_cq, num_rx, num_tx;
+
+ num_cq = ctx->desc_num[VIRTNET_Q_TYPE_CQ];
+ num_rx = ctx->desc_num[VIRTNET_Q_TYPE_RX];
+ num_tx = ctx->desc_num[VIRTNET_Q_TYPE_TX];
+
+ first_rx_q = ctx->data + num_rx + num_tx + num_cq;
+ first_tx_q = first_rx_q + vi->curr_queue_pairs * num_rx;
+
+ data = ctx->data;
+
+ stats_sum_queue(data, num_rx, first_rx_q, vi->curr_queue_pairs);
+
+ data = ctx->data + num_rx;
+
+ stats_sum_queue(data, num_tx, first_tx_q, vi->curr_queue_pairs);
+}
+
/* virtnet_fill_stats - copy the stats to ethtool -S
* The stats source is the device or the driver.
*
@@ -3530,7 +3578,9 @@ static void virtnet_fill_stats(struct virtnet_info *vi, u32 qid,
queue_type = vq_type(vi, qid);
bitmap = ctx->bitmap[queue_type];
- offset = 0;
+
+ /* skip the total fields of pairs */
+ offset = num_rx + num_tx;
if (queue_type == VIRTNET_Q_TYPE_TX) {
offset += num_cq + num_rx * vi->curr_queue_pairs + num_tx * (qid / 2);
@@ -3741,6 +3791,10 @@ static void virtnet_get_strings(struct net_device *dev, u32 stringset, u8 *data)
switch (stringset) {
case ETH_SS_STATS:
+ /* Generate the total field names. */
+ virtnet_get_stats_string(vi, VIRTNET_Q_TYPE_RX, -1, &p);
+ virtnet_get_stats_string(vi, VIRTNET_Q_TYPE_TX, -1, &p);
+
virtnet_get_stats_string(vi, VIRTNET_Q_TYPE_CQ, 0, &p);
for (i = 0; i < vi->curr_queue_pairs; ++i)
@@ -3764,7 +3818,8 @@ static int virtnet_get_sset_count(struct net_device *dev, int sset)
pair_count = ctx.desc_num[VIRTNET_Q_TYPE_RX] + ctx.desc_num[VIRTNET_Q_TYPE_TX];
- return ctx.desc_num[VIRTNET_Q_TYPE_CQ] + vi->curr_queue_pairs * pair_count;
+ return pair_count + ctx.desc_num[VIRTNET_Q_TYPE_CQ] +
+ vi->curr_queue_pairs * pair_count;
default:
return -EOPNOTSUPP;
}
@@ -3798,6 +3853,8 @@ static void virtnet_get_ethtool_stats(struct net_device *dev,
virtnet_fill_stats(vi, i * 2 + 1, &ctx, stats_base, true, 0);
} while (u64_stats_fetch_retry(&sq->stats.syncp, start));
}
+
+ virtnet_fill_total_fields(vi, &ctx);
}
static void virtnet_get_channels(struct net_device *dev,
--
2.32.0.3.g01195cf9f
Powered by blists - more mailing lists