Message ID | 20240423113141.1752-6-xuanzhuo@linux.alibaba.com (mailing list archive) |
---|---|
State | Superseded |
Delegated to: | Netdev Maintainers |
Headers | show |
Series | virtio-net: support device stats | expand |
Context | Check | Description |
---|---|---|
netdev/tree_selection | success | Clearly marked for net-next |
netdev/apply | fail | Patch does not apply to net-next-0 |
On Tue, Apr 23, 2024 at 7:32 PM Xuan Zhuo <xuanzhuo@linux.alibaba.com> wrote: > > 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@linux.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) Nit: -1 for all seems to be a wired API, could we have the caller to iterate the possible qid? Other parts look good. Thanks
On Wed, 24 Apr 2024 11:52:12 +0800, Jason Wang <jasowang@redhat.com> wrote: > On Tue, Apr 23, 2024 at 7:32 PM Xuan Zhuo <xuanzhuo@linux.alibaba.com> wrote: > > > > 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@linux.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) > > Nit: -1 for all seems to be a wired API, could we have the caller to > iterate the possible qid? Not for all, just the total fields: 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 The field names do not include "qid". Thanks. > > Other parts look good. > > Thanks >
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,
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@linux.alibaba.com> --- drivers/net/virtio_net.c | 81 ++++++++++++++++++++++++++++++++++------ 1 file changed, 69 insertions(+), 12 deletions(-)