Skip to content

Commit d86769b

Browse files
fengidriPaolo Abeni
authored andcommitted
virtio_net: device stats helpers support driver stats
In the last commit, we introduced some helpers for device stats. And the drivers stats are realized by the open code. This commit make the helpers to support driver stats. Then we can have the unify helper for device and driver stats. Signed-off-by: Xuan Zhuo <xuanzhuo@linux.alibaba.com> Acked-by: Jason Wang <jasowang@redhat.com> Signed-off-by: Paolo Abeni <pabeni@redhat.com>
1 parent 941168f commit d86769b

File tree

1 file changed

+82
-75
lines changed

1 file changed

+82
-75
lines changed

drivers/net/virtio_net.c

Lines changed: 82 additions & 75 deletions
Original file line numberDiff line numberDiff line change
@@ -107,32 +107,29 @@ struct virtnet_rq_stats {
107107
u64_stats_t kicks;
108108
};
109109

110-
#define VIRTNET_SQ_STAT(m) offsetof(struct virtnet_sq_stats, m)
111-
#define VIRTNET_RQ_STAT(m) offsetof(struct virtnet_rq_stats, m)
110+
#define VIRTNET_SQ_STAT(name, m) {name, offsetof(struct virtnet_sq_stats, m)}
111+
#define VIRTNET_RQ_STAT(name, m) {name, offsetof(struct virtnet_rq_stats, m)}
112112

113113
static const struct virtnet_stat_desc virtnet_sq_stats_desc[] = {
114-
{ "packets", VIRTNET_SQ_STAT(packets) },
115-
{ "bytes", VIRTNET_SQ_STAT(bytes) },
116-
{ "xdp_tx", VIRTNET_SQ_STAT(xdp_tx) },
117-
{ "xdp_tx_drops", VIRTNET_SQ_STAT(xdp_tx_drops) },
118-
{ "kicks", VIRTNET_SQ_STAT(kicks) },
119-
{ "tx_timeouts", VIRTNET_SQ_STAT(tx_timeouts) },
114+
VIRTNET_SQ_STAT("packets", packets),
115+
VIRTNET_SQ_STAT("bytes", bytes),
116+
VIRTNET_SQ_STAT("xdp_tx", xdp_tx),
117+
VIRTNET_SQ_STAT("xdp_tx_drops", xdp_tx_drops),
118+
VIRTNET_SQ_STAT("kicks", kicks),
119+
VIRTNET_SQ_STAT("tx_timeouts", tx_timeouts),
120120
};
121121

122122
static const struct virtnet_stat_desc virtnet_rq_stats_desc[] = {
123-
{ "packets", VIRTNET_RQ_STAT(packets) },
124-
{ "bytes", VIRTNET_RQ_STAT(bytes) },
125-
{ "drops", VIRTNET_RQ_STAT(drops) },
126-
{ "xdp_packets", VIRTNET_RQ_STAT(xdp_packets) },
127-
{ "xdp_tx", VIRTNET_RQ_STAT(xdp_tx) },
128-
{ "xdp_redirects", VIRTNET_RQ_STAT(xdp_redirects) },
129-
{ "xdp_drops", VIRTNET_RQ_STAT(xdp_drops) },
130-
{ "kicks", VIRTNET_RQ_STAT(kicks) },
123+
VIRTNET_RQ_STAT("packets", packets),
124+
VIRTNET_RQ_STAT("bytes", bytes),
125+
VIRTNET_RQ_STAT("drops", drops),
126+
VIRTNET_RQ_STAT("xdp_packets", xdp_packets),
127+
VIRTNET_RQ_STAT("xdp_tx", xdp_tx),
128+
VIRTNET_RQ_STAT("xdp_redirects", xdp_redirects),
129+
VIRTNET_RQ_STAT("xdp_drops", xdp_drops),
130+
VIRTNET_RQ_STAT("kicks", kicks),
131131
};
132132

133-
#define VIRTNET_SQ_STATS_LEN ARRAY_SIZE(virtnet_sq_stats_desc)
134-
#define VIRTNET_RQ_STATS_LEN ARRAY_SIZE(virtnet_rq_stats_desc)
135-
136133
#define VIRTNET_STATS_DESC_CQ(name) \
137134
{#name, offsetof(struct virtio_net_stats_cvq, name)}
138135

@@ -2210,7 +2207,7 @@ static int virtnet_receive(struct receive_queue *rq, int budget,
22102207

22112208
u64_stats_set(&stats.packets, packets);
22122209
u64_stats_update_begin(&rq->stats.syncp);
2213-
for (i = 0; i < VIRTNET_RQ_STATS_LEN; i++) {
2210+
for (i = 0; i < ARRAY_SIZE(virtnet_rq_stats_desc); i++) {
22142211
size_t offset = virtnet_rq_stats_desc[i].offset;
22152212
u64_stats_t *item, *src;
22162213

@@ -3386,16 +3383,13 @@ static void virtnet_stats_sprintf(u8 **p, const char *fmt, const char *noq_fmt,
33863383
}
33873384
}
33883385

3389-
static void virtnet_get_hw_stats_string(struct virtnet_info *vi, int type, int qid, u8 **data)
3386+
static void virtnet_get_stats_string(struct virtnet_info *vi, int type, int qid, u8 **data)
33903387
{
33913388
const struct virtnet_stat_desc *desc;
33923389
const char *fmt, *noq_fmt;
33933390
u8 *p = *data;
33943391
u32 num = 0;
33953392

3396-
if (!virtio_has_feature(vi->vdev, VIRTIO_NET_F_DEVICE_STATS))
3397-
return;
3398-
33993393
if (type == VIRTNET_Q_TYPE_CQ) {
34003394
noq_fmt = "cq_hw_%s";
34013395

@@ -3408,6 +3402,13 @@ static void virtnet_get_hw_stats_string(struct virtnet_info *vi, int type, int q
34083402
}
34093403

34103404
if (type == VIRTNET_Q_TYPE_RX) {
3405+
fmt = "rx%u_%s";
3406+
3407+
desc = &virtnet_rq_stats_desc[0];
3408+
num = ARRAY_SIZE(virtnet_rq_stats_desc);
3409+
3410+
virtnet_stats_sprintf(&p, fmt, NULL, num, qid, desc);
3411+
34113412
fmt = "rx%u_hw_%s";
34123413

34133414
if (vi->device_stats_cap & VIRTIO_NET_STATS_TYPE_RX_BASIC) {
@@ -3433,6 +3434,13 @@ static void virtnet_get_hw_stats_string(struct virtnet_info *vi, int type, int q
34333434
}
34343435

34353436
if (type == VIRTNET_Q_TYPE_TX) {
3437+
fmt = "tx%u_%s";
3438+
3439+
desc = &virtnet_sq_stats_desc[0];
3440+
num = ARRAY_SIZE(virtnet_sq_stats_desc);
3441+
3442+
virtnet_stats_sprintf(&p, fmt, NULL, num, qid, desc);
3443+
34363444
fmt = "tx%u_hw_%s";
34373445

34383446
if (vi->device_stats_cap & VIRTIO_NET_STATS_TYPE_TX_BASIC) {
@@ -3482,6 +3490,9 @@ static void virtnet_stats_ctx_init(struct virtnet_info *vi,
34823490

34833491
ctx->data = data;
34843492

3493+
ctx->desc_num[VIRTNET_Q_TYPE_RX] = ARRAY_SIZE(virtnet_rq_stats_desc);
3494+
ctx->desc_num[VIRTNET_Q_TYPE_TX] = ARRAY_SIZE(virtnet_sq_stats_desc);
3495+
34853496
if (vi->device_stats_cap & VIRTIO_NET_STATS_TYPE_CVQ) {
34863497
queue_type = VIRTNET_Q_TYPE_CQ;
34873498

@@ -3532,37 +3543,55 @@ static void virtnet_stats_ctx_init(struct virtnet_info *vi,
35323543
}
35333544

35343545
/* virtnet_fill_stats - copy the stats to ethtool -S
3535-
* The stats source is the device.
3546+
* The stats source is the device or the driver.
35363547
*
35373548
* @vi: virtio net info
35383549
* @qid: the vq id
35393550
* @ctx: stats ctx (initiated by virtnet_stats_ctx_init())
3540-
* @base: pointer to the device reply.
3541-
* @type: the type of the device reply
3551+
* @base: pointer to the device reply or the driver stats structure.
3552+
* @drv_stats: designate the base type (device reply, driver stats)
3553+
* @type: the type of the device reply (if drv_stats is true, this must be zero)
35423554
*/
35433555
static void virtnet_fill_stats(struct virtnet_info *vi, u32 qid,
35443556
struct virtnet_stats_ctx *ctx,
3545-
const u8 *base, u8 reply_type)
3557+
const u8 *base, bool drv_stats, u8 reply_type)
35463558
{
35473559
u32 queue_type, num_rx, num_tx, num_cq;
35483560
const struct virtnet_stat_desc *desc;
3561+
const u64_stats_t *v_stat;
35493562
u64 offset, bitmap;
35503563
const __le64 *v;
35513564
int i, num;
35523565

3553-
num_rx = VIRTNET_RQ_STATS_LEN + ctx->desc_num[VIRTNET_Q_TYPE_RX];
3554-
num_tx = VIRTNET_SQ_STATS_LEN + ctx->desc_num[VIRTNET_Q_TYPE_TX];
35553566
num_cq = ctx->desc_num[VIRTNET_Q_TYPE_CQ];
3567+
num_rx = ctx->desc_num[VIRTNET_Q_TYPE_RX];
3568+
num_tx = ctx->desc_num[VIRTNET_Q_TYPE_TX];
35563569

35573570
queue_type = vq_type(vi, qid);
35583571
bitmap = ctx->bitmap[queue_type];
35593572
offset = 0;
35603573

35613574
if (queue_type == VIRTNET_Q_TYPE_TX) {
3562-
offset = num_cq + num_rx * vi->curr_queue_pairs + num_tx * (qid / 2);
3563-
offset += VIRTNET_SQ_STATS_LEN;
3575+
offset += num_cq + num_rx * vi->curr_queue_pairs + num_tx * (qid / 2);
3576+
3577+
num = ARRAY_SIZE(virtnet_sq_stats_desc);
3578+
if (drv_stats) {
3579+
desc = &virtnet_sq_stats_desc[0];
3580+
goto drv_stats;
3581+
}
3582+
3583+
offset += num;
3584+
35643585
} else if (queue_type == VIRTNET_Q_TYPE_RX) {
3565-
offset = num_cq + num_rx * (qid / 2) + VIRTNET_RQ_STATS_LEN;
3586+
offset += num_cq + num_rx * (qid / 2);
3587+
3588+
num = ARRAY_SIZE(virtnet_rq_stats_desc);
3589+
if (drv_stats) {
3590+
desc = &virtnet_rq_stats_desc[0];
3591+
goto drv_stats;
3592+
}
3593+
3594+
offset += num;
35663595
}
35673596

35683597
if (bitmap & VIRTIO_NET_STATS_TYPE_CVQ) {
@@ -3635,6 +3664,14 @@ static void virtnet_fill_stats(struct virtnet_info *vi, u32 qid,
36353664
v = (const __le64 *)(base + desc[i].offset);
36363665
ctx->data[offset + i] = le64_to_cpu(*v);
36373666
}
3667+
3668+
return;
3669+
3670+
drv_stats:
3671+
for (i = 0; i < num; ++i) {
3672+
v_stat = (const u64_stats_t *)(base + desc[i].offset);
3673+
ctx->data[offset + i] = u64_stats_read(v_stat);
3674+
}
36383675
}
36393676

36403677
static int __virtnet_get_hw_stats(struct virtnet_info *vi,
@@ -3661,7 +3698,7 @@ static int __virtnet_get_hw_stats(struct virtnet_info *vi,
36613698
for (p = reply; p - reply < res_size; p += le16_to_cpu(hdr->size)) {
36623699
hdr = p;
36633700
qid = le16_to_cpu(hdr->vq_index);
3664-
virtnet_fill_stats(vi, qid, ctx, p, hdr->type);
3701+
virtnet_fill_stats(vi, qid, ctx, p, false, hdr->type);
36653702
}
36663703

36673704
return 0;
@@ -3738,28 +3775,18 @@ static int virtnet_get_hw_stats(struct virtnet_info *vi,
37383775
static void virtnet_get_strings(struct net_device *dev, u32 stringset, u8 *data)
37393776
{
37403777
struct virtnet_info *vi = netdev_priv(dev);
3741-
unsigned int i, j;
3778+
unsigned int i;
37423779
u8 *p = data;
37433780

37443781
switch (stringset) {
37453782
case ETH_SS_STATS:
3746-
virtnet_get_hw_stats_string(vi, VIRTNET_Q_TYPE_CQ, 0, &p);
3747-
3748-
for (i = 0; i < vi->curr_queue_pairs; i++) {
3749-
for (j = 0; j < VIRTNET_RQ_STATS_LEN; j++)
3750-
ethtool_sprintf(&p, "rx%u_%s", i,
3751-
virtnet_rq_stats_desc[j].desc);
3783+
virtnet_get_stats_string(vi, VIRTNET_Q_TYPE_CQ, 0, &p);
37523784

3753-
virtnet_get_hw_stats_string(vi, VIRTNET_Q_TYPE_RX, i, &p);
3754-
}
3785+
for (i = 0; i < vi->curr_queue_pairs; ++i)
3786+
virtnet_get_stats_string(vi, VIRTNET_Q_TYPE_RX, i, &p);
37553787

3756-
for (i = 0; i < vi->curr_queue_pairs; i++) {
3757-
for (j = 0; j < VIRTNET_SQ_STATS_LEN; j++)
3758-
ethtool_sprintf(&p, "tx%u_%s", i,
3759-
virtnet_sq_stats_desc[j].desc);
3760-
3761-
virtnet_get_hw_stats_string(vi, VIRTNET_Q_TYPE_TX, i, &p);
3762-
}
3788+
for (i = 0; i < vi->curr_queue_pairs; ++i)
3789+
virtnet_get_stats_string(vi, VIRTNET_Q_TYPE_TX, i, &p);
37633790
break;
37643791
}
37653792
}
@@ -3774,8 +3801,7 @@ static int virtnet_get_sset_count(struct net_device *dev, int sset)
37743801
case ETH_SS_STATS:
37753802
virtnet_stats_ctx_init(vi, &ctx, NULL);
37763803

3777-
pair_count = VIRTNET_RQ_STATS_LEN + VIRTNET_SQ_STATS_LEN;
3778-
pair_count += ctx.desc_num[VIRTNET_Q_TYPE_RX] + ctx.desc_num[VIRTNET_Q_TYPE_TX];
3804+
pair_count = ctx.desc_num[VIRTNET_Q_TYPE_RX] + ctx.desc_num[VIRTNET_Q_TYPE_TX];
37793805

37803806
return ctx.desc_num[VIRTNET_Q_TYPE_CQ] + vi->curr_queue_pairs * pair_count;
37813807
default:
@@ -3788,47 +3814,28 @@ static void virtnet_get_ethtool_stats(struct net_device *dev,
37883814
{
37893815
struct virtnet_info *vi = netdev_priv(dev);
37903816
struct virtnet_stats_ctx ctx = {0};
3791-
unsigned int idx, start, i, j;
3817+
unsigned int start, i;
37923818
const u8 *stats_base;
3793-
const u64_stats_t *p;
3794-
size_t offset;
37953819

37963820
virtnet_stats_ctx_init(vi, &ctx, data);
37973821
if (virtnet_get_hw_stats(vi, &ctx))
37983822
dev_warn(&vi->dev->dev, "Failed to get hw stats.\n");
37993823

3800-
idx = ctx.desc_num[VIRTNET_Q_TYPE_CQ];
3801-
38023824
for (i = 0; i < vi->curr_queue_pairs; i++) {
38033825
struct receive_queue *rq = &vi->rq[i];
3826+
struct send_queue *sq = &vi->sq[i];
38043827

38053828
stats_base = (const u8 *)&rq->stats;
38063829
do {
38073830
start = u64_stats_fetch_begin(&rq->stats.syncp);
3808-
for (j = 0; j < VIRTNET_RQ_STATS_LEN; j++) {
3809-
offset = virtnet_rq_stats_desc[j].offset;
3810-
p = (const u64_stats_t *)(stats_base + offset);
3811-
data[idx + j] = u64_stats_read(p);
3812-
}
3831+
virtnet_fill_stats(vi, i * 2, &ctx, stats_base, true, 0);
38133832
} while (u64_stats_fetch_retry(&rq->stats.syncp, start));
3814-
idx += VIRTNET_RQ_STATS_LEN;
3815-
idx += ctx.desc_num[VIRTNET_Q_TYPE_RX];
3816-
}
3817-
3818-
for (i = 0; i < vi->curr_queue_pairs; i++) {
3819-
struct send_queue *sq = &vi->sq[i];
38203833

38213834
stats_base = (const u8 *)&sq->stats;
38223835
do {
38233836
start = u64_stats_fetch_begin(&sq->stats.syncp);
3824-
for (j = 0; j < VIRTNET_SQ_STATS_LEN; j++) {
3825-
offset = virtnet_sq_stats_desc[j].offset;
3826-
p = (const u64_stats_t *)(stats_base + offset);
3827-
data[idx + j] = u64_stats_read(p);
3828-
}
3837+
virtnet_fill_stats(vi, i * 2 + 1, &ctx, stats_base, true, 0);
38293838
} while (u64_stats_fetch_retry(&sq->stats.syncp, start));
3830-
idx += VIRTNET_SQ_STATS_LEN;
3831-
idx += ctx.desc_num[VIRTNET_Q_TYPE_TX];
38323839
}
38333840
}
38343841

0 commit comments

Comments
 (0)