[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <20231226073103.116153-6-xuanzhuo@linux.alibaba.com>
Date: Tue, 26 Dec 2023 15:31:02 +0800
From: Xuan Zhuo <xuanzhuo@...ux.alibaba.com>
To: netdev@...r.kernel.org
Cc: "Michael S. Tsirkin" <mst@...hat.com>,
Jason Wang <jasowang@...hat.com>,
Xuan Zhuo <xuanzhuo@...ux.alibaba.com>,
"David S. Miller" <davem@...emloft.net>,
Eric Dumazet <edumazet@...gle.com>,
Jakub Kicinski <kuba@...nel.org>,
Paolo Abeni <pabeni@...hat.com>,
virtualization@...ts.linux.dev,
Zhu Yanjun <yanjun.zhu@...ux.dev>
Subject: [PATCH net-next v1 5/6] 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.
Signed-off-by: Xuan Zhuo <xuanzhuo@...ux.alibaba.com>
---
drivers/net/virtio_net.c | 72 ++++++++++++++++++++++++++++++++++------
1 file changed, 61 insertions(+), 11 deletions(-)
diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c
index 75d68795f2bc..e97a9474d91a 100644
--- a/drivers/net/virtio_net.c
+++ b/drivers/net/virtio_net.c
@@ -3290,6 +3290,7 @@ static int virtnet_set_channels(struct net_device *dev,
return err;
}
+/* qid == -1: for rx/tx queue total field */
static void virtnet_get_stats_string(struct virtnet_info *vi, int type, int qid, u8 **data)
{
struct virtnet_stats_map *m;
@@ -3312,14 +3313,23 @@ static void virtnet_get_stats_string(struct virtnet_info *vi, int type, int qid,
else
tp = "_hw";
- if (type == VIRTNET_STATS_Q_TYPE_RX)
- ethtool_sprintf(&p, "rx_queue%s_%u_%s", tp, qid, m->desc[j].desc);
-
- else if (type == VIRTNET_STATS_Q_TYPE_TX)
- ethtool_sprintf(&p, "tx_queue%s_%u_%s", tp, qid, m->desc[j].desc);
-
- else if (type == VIRTNET_STATS_Q_TYPE_CQ)
+ if (type == VIRTNET_STATS_Q_TYPE_RX) {
+ if (qid < 0)
+ ethtool_sprintf(&p, "rx%s_%s", tp, m->desc[j].desc);
+ else
+ ethtool_sprintf(&p, "rx_queue%s_%u_%s", tp, qid,
+ m->desc[j].desc);
+
+ } else if (type == VIRTNET_STATS_Q_TYPE_TX) {
+ if (qid < 0)
+ ethtool_sprintf(&p, "tx%s_%s", tp, m->desc[j].desc);
+ else
+ ethtool_sprintf(&p, "tx_queue%s_%u_%s", tp, qid,
+ m->desc[j].desc);
+
+ } else if (type == VIRTNET_STATS_Q_TYPE_CQ) {
ethtool_sprintf(&p, "cq%s_%s", tp, m->desc[j].desc);
+ }
}
}
@@ -3376,6 +3386,38 @@ static void virtnet_stats_ctx_init(struct virtnet_info *vi,
}
}
+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;
+
+ first_rx_q = ctx->data + ctx->num_rx + ctx->num_tx + ctx->num_cq;
+ first_tx_q = first_rx_q + vi->curr_queue_pairs * ctx->num_rx;
+
+ data = ctx->data;
+
+ stats_sum_queue(data, ctx->num_rx, first_rx_q, vi->curr_queue_pairs);
+
+ data = ctx->data + ctx->num_rx;
+
+ stats_sum_queue(data, ctx->num_tx, first_tx_q, vi->curr_queue_pairs);
+}
+
static void virtnet_fill_stats(struct virtnet_info *vi, u32 qid,
struct virtnet_stats_ctx *ctx,
const u8 *base, bool from_driver, u8 type)
@@ -3387,14 +3429,17 @@ static void virtnet_fill_stats(struct virtnet_info *vi, u32 qid,
u64 offset;
int i, j;
+ /* skip the total fields of pairs */
+ offset = ctx->num_rx + ctx->num_tx;
+
if (qid == vi->max_queue_pairs * 2) {
- offset = 0;
queue_type = VIRTNET_STATS_Q_TYPE_CQ;
} else if (qid % 2) {
- offset = ctx->num_cq + ctx->num_rx * vi->curr_queue_pairs + ctx->num_tx * (qid / 2);
+ offset += ctx->num_cq + ctx->num_rx * vi->curr_queue_pairs +
+ ctx->num_tx * (qid / 2);
queue_type = VIRTNET_STATS_Q_TYPE_TX;
} else {
- offset = ctx->num_cq + ctx->num_rx * (qid / 2);
+ offset += ctx->num_cq + ctx->num_rx * (qid / 2);
queue_type = VIRTNET_STATS_Q_TYPE_RX;
}
@@ -3513,6 +3558,9 @@ static void virtnet_get_strings(struct net_device *dev, u32 stringset, u8 *data)
switch (stringset) {
case ETH_SS_STATS:
+ virtnet_get_stats_string(vi, VIRTNET_STATS_Q_TYPE_RX, -1, &p);
+ virtnet_get_stats_string(vi, VIRTNET_STATS_Q_TYPE_TX, -1, &p);
+
virtnet_get_stats_string(vi, VIRTNET_STATS_Q_TYPE_CQ, 0, &p);
for (i = 0; i < vi->curr_queue_pairs; ++i)
@@ -3554,7 +3602,7 @@ static int virtnet_get_sset_count(struct net_device *dev, int sset)
pair_count = ctx.num_rx + ctx.num_tx;
- return ctx.num_cq + vi->curr_queue_pairs * pair_count;
+ return pair_count + ctx.num_cq + vi->curr_queue_pairs * pair_count;
default:
return -EOPNOTSUPP;
}
@@ -3587,6 +3635,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