From patchwork Tue Feb 27 08:02:58 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Xuan Zhuo X-Patchwork-Id: 13573330 X-Patchwork-Delegate: kuba@kernel.org Received: from out30-119.freemail.mail.aliyun.com (out30-119.freemail.mail.aliyun.com [115.124.30.119]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id AD7FC56442 for ; Tue, 27 Feb 2024 08:03:13 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=115.124.30.119 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1709020996; cv=none; b=RwoJUFR1dgbIXepLqxAZmRg40WBpeozkYHEk67kFk9VuJXsOt9frAIqJiNPLtlWmVUAGmJB/5cvmrkm0pzFCI7psXI0gAAd31ekCxEuZ17va+V8UFPovwgfqYcZ+pUXAcThWJ/A7B+dTLM6y3q9o0j8XOVDohrQEoKUfbeTv2rU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1709020996; c=relaxed/simple; bh=0UKZClT7YsyI88Zs/PnvgjEeZ+uHSCbya4LzeEKCVwU=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=LRhgod6q3AK/BjsJeI5XLak4tPoTPSpN4ZVnQCXi5IKzGoVXIkA+n277yDT2kVzxLShd5sJnxxp9pKS+d/eF1ESLl28gnRbPqLKF6Ut2jHxKZ8W5aT7OUL/wCI+T4JduI8xR29PpmffEgG1BwASxTKajKDVUS5b4oLW+V4gFJrE= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.alibaba.com; spf=pass smtp.mailfrom=linux.alibaba.com; dkim=pass (1024-bit key) header.d=linux.alibaba.com header.i=@linux.alibaba.com header.b=d4Gy+OX/; arc=none smtp.client-ip=115.124.30.119 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.alibaba.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linux.alibaba.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linux.alibaba.com header.i=@linux.alibaba.com header.b="d4Gy+OX/" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.alibaba.com; s=default; t=1709020986; h=From:To:Subject:Date:Message-Id:MIME-Version; bh=PaIsXQVxdHuV5jdj1pf9rN/0VKs9oh04cFCjiOYzzow=; b=d4Gy+OX/DwWKdS3elLGerCNkrQjQWn8FnSt3r8xbxQhfByLpzoZgL6w/ZieBfknCmci/8HXs5HQEFTN4Q9dfHqyikqL4ysofZtERJ2iq3MTZ+hX+L/vKk58J7jN/tv7JtBlbDTm90z67SXlVcvLRt5JE8m2xqQcEvGNwBv/BxUY= X-Alimail-AntiSpam: AC=PASS;BC=-1|-1;BR=01201311R181e4;CH=green;DM=||false|;DS=||;FP=0|-1|-1|-1|0|-1|-1|-1;HT=ay29a033018045168;MF=xuanzhuo@linux.alibaba.com;NM=1;PH=DS;RN=9;SR=0;TI=SMTPD_---0W1M4RLM_1709020984; Received: from localhost(mailfrom:xuanzhuo@linux.alibaba.com fp:SMTPD_---0W1M4RLM_1709020984) by smtp.aliyun-inc.com; Tue, 27 Feb 2024 16:03:05 +0800 From: Xuan Zhuo To: netdev@vger.kernel.org Cc: "Michael S. Tsirkin" , Jason Wang , Xuan Zhuo , "David S. Miller" , Eric Dumazet , Jakub Kicinski , Paolo Abeni , virtualization@lists.linux.dev Subject: [PATCH net-next v3 1/6] virtio_net: introduce device stats feature and structures Date: Tue, 27 Feb 2024 16:02:58 +0800 Message-Id: <20240227080303.63894-2-xuanzhuo@linux.alibaba.com> X-Mailer: git-send-email 2.32.0.3.g01195cf9f In-Reply-To: <20240227080303.63894-1-xuanzhuo@linux.alibaba.com> References: <20240227080303.63894-1-xuanzhuo@linux.alibaba.com> Precedence: bulk X-Mailing-List: netdev@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-Git-Hash: cacd048f99e7 X-Patchwork-Delegate: kuba@kernel.org The virtio-net device stats spec: https://github.com/oasis-tcs/virtio-spec/commit/42f389989823039724f95bbbd243291ab0064f82 This commit introduces the relative feature and structures. Signed-off-by: Xuan Zhuo --- include/uapi/linux/virtio_net.h | 137 ++++++++++++++++++++++++++++++++ 1 file changed, 137 insertions(+) diff --git a/include/uapi/linux/virtio_net.h b/include/uapi/linux/virtio_net.h index cc65ef0f3c3e..8fca4d1b7635 100644 --- a/include/uapi/linux/virtio_net.h +++ b/include/uapi/linux/virtio_net.h @@ -56,6 +56,7 @@ #define VIRTIO_NET_F_MQ 22 /* Device supports Receive Flow * Steering */ #define VIRTIO_NET_F_CTRL_MAC_ADDR 23 /* Set MAC address */ +#define VIRTIO_NET_F_DEVICE_STATS 50 /* Device can provide device-level statistics. */ #define VIRTIO_NET_F_VQ_NOTF_COAL 52 /* Device supports virtqueue notification coalescing */ #define VIRTIO_NET_F_NOTF_COAL 53 /* Device supports notifications coalescing */ #define VIRTIO_NET_F_GUEST_USO4 54 /* Guest can handle USOv4 in. */ @@ -406,4 +407,140 @@ struct virtio_net_ctrl_coal_vq { struct virtio_net_ctrl_coal coal; }; +/* + * Device Statistics + */ +#define VIRTIO_NET_CTRL_STATS 8 +#define VIRTIO_NET_CTRL_STATS_QUERY 0 +#define VIRTIO_NET_CTRL_STATS_GET 1 + +struct virtio_net_stats_capabilities { + +#define VIRTIO_NET_STATS_TYPE_CVQ (1ULL << 32) + +#define VIRTIO_NET_STATS_TYPE_RX_BASIC (1ULL << 0) +#define VIRTIO_NET_STATS_TYPE_RX_CSUM (1ULL << 1) +#define VIRTIO_NET_STATS_TYPE_RX_GSO (1ULL << 2) +#define VIRTIO_NET_STATS_TYPE_RX_SPEED (1ULL << 3) + +#define VIRTIO_NET_STATS_TYPE_TX_BASIC (1ULL << 16) +#define VIRTIO_NET_STATS_TYPE_TX_CSUM (1ULL << 17) +#define VIRTIO_NET_STATS_TYPE_TX_GSO (1ULL << 18) +#define VIRTIO_NET_STATS_TYPE_TX_SPEED (1ULL << 19) + + __le64 supported_stats_types[1]; +}; + +struct virtio_net_ctrl_queue_stats { + struct { + __le16 vq_index; + __le16 reserved[3]; + __le64 types_bitmap[1]; + } stats[1]; +}; + +struct virtio_net_stats_reply_hdr { +#define VIRTIO_NET_STATS_TYPE_REPLY_CVQ 32 + +#define VIRTIO_NET_STATS_TYPE_REPLY_RX_BASIC 0 +#define VIRTIO_NET_STATS_TYPE_REPLY_RX_CSUM 1 +#define VIRTIO_NET_STATS_TYPE_REPLY_RX_GSO 2 +#define VIRTIO_NET_STATS_TYPE_REPLY_RX_SPEED 3 + +#define VIRTIO_NET_STATS_TYPE_REPLY_TX_BASIC 16 +#define VIRTIO_NET_STATS_TYPE_REPLY_TX_CSUM 17 +#define VIRTIO_NET_STATS_TYPE_REPLY_TX_GSO 18 +#define VIRTIO_NET_STATS_TYPE_REPLY_TX_SPEED 19 + __u8 type; + __u8 reserved; + __le16 vq_index; + __le16 reserved1; + __le16 size; +}; + +struct virtio_net_stats_cvq { + struct virtio_net_stats_reply_hdr hdr; + + __le64 command_num; + __le64 ok_num; +}; + +struct virtio_net_stats_rx_basic { + struct virtio_net_stats_reply_hdr hdr; + + __le64 rx_notifications; + + __le64 rx_packets; + __le64 rx_bytes; + + __le64 rx_interrupts; + + __le64 rx_drops; + __le64 rx_drop_overruns; +}; + +struct virtio_net_stats_tx_basic { + struct virtio_net_stats_reply_hdr hdr; + + __le64 tx_notifications; + + __le64 tx_packets; + __le64 tx_bytes; + + __le64 tx_interrupts; + + __le64 tx_drops; + __le64 tx_drop_malformed; +}; + +struct virtio_net_stats_rx_csum { + struct virtio_net_stats_reply_hdr hdr; + + __le64 rx_csum_valid; + __le64 rx_needs_csum; + __le64 rx_csum_none; + __le64 rx_csum_bad; +}; + +struct virtio_net_stats_tx_csum { + struct virtio_net_stats_reply_hdr hdr; + + __le64 tx_csum_none; + __le64 tx_needs_csum; +}; + +struct virtio_net_stats_rx_gso { + struct virtio_net_stats_reply_hdr hdr; + + __le64 rx_gso_packets; + __le64 rx_gso_bytes; + __le64 rx_gso_packets_coalesced; + __le64 rx_gso_bytes_coalesced; +}; + +struct virtio_net_stats_tx_gso { + struct virtio_net_stats_reply_hdr hdr; + + __le64 tx_gso_packets; + __le64 tx_gso_bytes; + __le64 tx_gso_segments; + __le64 tx_gso_segments_bytes; + __le64 tx_gso_packets_noseg; + __le64 tx_gso_bytes_noseg; +}; + +struct virtio_net_stats_rx_speed { + struct virtio_net_stats_reply_hdr hdr; + + __le64 rx_packets_allowance_exceeded; + __le64 rx_bytes_allowance_exceeded; +}; + +struct virtio_net_stats_tx_speed { + struct virtio_net_stats_reply_hdr hdr; + + __le64 tx_packets_allowance_exceeded; + __le64 tx_bytes_allowance_exceeded; +}; + #endif /* _UAPI_LINUX_VIRTIO_NET_H */ From patchwork Tue Feb 27 08:02:59 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Xuan Zhuo X-Patchwork-Id: 13573331 X-Patchwork-Delegate: kuba@kernel.org Received: from out30-110.freemail.mail.aliyun.com (out30-110.freemail.mail.aliyun.com [115.124.30.110]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 5A28E54BC8 for ; Tue, 27 Feb 2024 08:03:14 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=115.124.30.110 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1709020997; cv=none; b=Km5B7o++4bt8yAs3Q2OYFi4M0FEpV/t8eS+1KAcoLMuxZZj0AY/5PQCMf3RqiKPefCK8IPu80lZIkUC/gXchtj1WvpBRI7bFX8rVI0Ul4ZrSdlS/xC7LdkdSDYAvhsAWNuij0wQsIVlnfp95zaAa0U4XzNcJNwSz788pkosUXHc= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1709020997; c=relaxed/simple; bh=mJoFWB5X20twTskzSrHyeHEl1Cn3DD+ViHdG+uYIB9A=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=YCNYrUkzEG86ACUGPjZwKftEPZJ1ND0M2yqznTNL94B1PVeXngE31mFS4I6refEBvZEQl+t9VSIv39xby6n/8hN9HAKNo9H9Kj9H4t2XyazYWGHx8s+9EcRg9QwN8j1uQ7/e5vTS9NpMId2ZzpUC/ZNnH3lsy5J2jYpNaDbQCvc= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.alibaba.com; spf=pass smtp.mailfrom=linux.alibaba.com; dkim=pass (1024-bit key) header.d=linux.alibaba.com header.i=@linux.alibaba.com header.b=Md+ddJQp; arc=none smtp.client-ip=115.124.30.110 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.alibaba.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linux.alibaba.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linux.alibaba.com header.i=@linux.alibaba.com header.b="Md+ddJQp" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.alibaba.com; s=default; t=1709020987; h=From:To:Subject:Date:Message-Id:MIME-Version; bh=pWG7mgMQPFtUZ7xPtHcrekIITF288nVb4a5i4xABx20=; b=Md+ddJQpNvvCR3cPLtWJxe1+Dzm7B105s8v12FRpvZMA7q+aYP+n9nNN0L+JQ1Y1tFW3vRxE0IPE0s1FfTXMrnaB0eNJeP6fP1efgo6SedazhWCAM89Orz7hq3RroAL3c94XWgUBN7etbW/A9j6BHRGSlacub68LUOkSePiRwPY= X-Alimail-AntiSpam: AC=PASS;BC=-1|-1;BR=01201311R211e4;CH=green;DM=||false|;DS=||;FP=0|-1|-1|-1|0|-1|-1|-1;HT=ay29a033018046051;MF=xuanzhuo@linux.alibaba.com;NM=1;PH=DS;RN=9;SR=0;TI=SMTPD_---0W1LyZ92_1709020985; Received: from localhost(mailfrom:xuanzhuo@linux.alibaba.com fp:SMTPD_---0W1LyZ92_1709020985) by smtp.aliyun-inc.com; Tue, 27 Feb 2024 16:03:06 +0800 From: Xuan Zhuo To: netdev@vger.kernel.org Cc: "Michael S. Tsirkin" , Jason Wang , Xuan Zhuo , "David S. Miller" , Eric Dumazet , Jakub Kicinski , Paolo Abeni , virtualization@lists.linux.dev Subject: [PATCH net-next v3 2/6] virtio_net: virtnet_send_command supports command-specific-result Date: Tue, 27 Feb 2024 16:02:59 +0800 Message-Id: <20240227080303.63894-3-xuanzhuo@linux.alibaba.com> X-Mailer: git-send-email 2.32.0.3.g01195cf9f In-Reply-To: <20240227080303.63894-1-xuanzhuo@linux.alibaba.com> References: <20240227080303.63894-1-xuanzhuo@linux.alibaba.com> Precedence: bulk X-Mailing-List: netdev@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-Git-Hash: cacd048f99e7 X-Patchwork-Delegate: kuba@kernel.org As the spec https://github.com/oasis-tcs/virtio-spec/commit/42f389989823039724f95bbbd243291ab0064f82 The virtnet cvq supports to get result from the device. This commit implement this. Signed-off-by: Xuan Zhuo --- drivers/net/virtio_net.c | 47 +++++++++++++++++++++++----------------- 1 file changed, 27 insertions(+), 20 deletions(-) diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c index d7ce4a1011ea..af512d85cd5b 100644 --- a/drivers/net/virtio_net.c +++ b/drivers/net/virtio_net.c @@ -2512,10 +2512,11 @@ static int virtnet_tx_resize(struct virtnet_info *vi, * never fail unless improperly formatted. */ static bool virtnet_send_command(struct virtnet_info *vi, u8 class, u8 cmd, - struct scatterlist *out) + struct scatterlist *out, + struct scatterlist *in) { - struct scatterlist *sgs[4], hdr, stat; - unsigned out_num = 0, tmp; + struct scatterlist *sgs[5], hdr, stat; + u32 out_num = 0, tmp, in_num = 0; int ret; /* Caller should know better */ @@ -2533,10 +2534,13 @@ static bool virtnet_send_command(struct virtnet_info *vi, u8 class, u8 cmd, /* Add return status. */ sg_init_one(&stat, &vi->ctrl->status, sizeof(vi->ctrl->status)); - sgs[out_num] = &stat; + sgs[out_num + in_num++] = &stat; - BUG_ON(out_num + 1 > ARRAY_SIZE(sgs)); - ret = virtqueue_add_sgs(vi->cvq, sgs, out_num, 1, vi, GFP_ATOMIC); + if (in) + sgs[out_num + in_num++] = in; + + BUG_ON(out_num + in_num > ARRAY_SIZE(sgs)); + ret = virtqueue_add_sgs(vi->cvq, sgs, out_num, in_num, vi, GFP_ATOMIC); if (ret < 0) { dev_warn(&vi->vdev->dev, "Failed to add sgs for command vq: %d\n.", ret); @@ -2578,7 +2582,8 @@ static int virtnet_set_mac_address(struct net_device *dev, void *p) if (virtio_has_feature(vdev, VIRTIO_NET_F_CTRL_MAC_ADDR)) { sg_init_one(&sg, addr->sa_data, dev->addr_len); if (!virtnet_send_command(vi, VIRTIO_NET_CTRL_MAC, - VIRTIO_NET_CTRL_MAC_ADDR_SET, &sg)) { + VIRTIO_NET_CTRL_MAC_ADDR_SET, + &sg, NULL)) { dev_warn(&vdev->dev, "Failed to set mac address by vq command.\n"); ret = -EINVAL; @@ -2647,7 +2652,7 @@ static void virtnet_ack_link_announce(struct virtnet_info *vi) { rtnl_lock(); if (!virtnet_send_command(vi, VIRTIO_NET_CTRL_ANNOUNCE, - VIRTIO_NET_CTRL_ANNOUNCE_ACK, NULL)) + VIRTIO_NET_CTRL_ANNOUNCE_ACK, NULL, NULL)) dev_warn(&vi->dev->dev, "Failed to ack link announce.\n"); rtnl_unlock(); } @@ -2664,7 +2669,7 @@ static int _virtnet_set_queues(struct virtnet_info *vi, u16 queue_pairs) sg_init_one(&sg, &vi->ctrl->mq, sizeof(vi->ctrl->mq)); if (!virtnet_send_command(vi, VIRTIO_NET_CTRL_MQ, - VIRTIO_NET_CTRL_MQ_VQ_PAIRS_SET, &sg)) { + VIRTIO_NET_CTRL_MQ_VQ_PAIRS_SET, &sg, NULL)) { dev_warn(&dev->dev, "Fail to set num of queue pairs to %d\n", queue_pairs); return -EINVAL; @@ -2727,14 +2732,14 @@ static void virtnet_set_rx_mode(struct net_device *dev) sg_init_one(sg, &vi->ctrl->promisc, sizeof(vi->ctrl->promisc)); if (!virtnet_send_command(vi, VIRTIO_NET_CTRL_RX, - VIRTIO_NET_CTRL_RX_PROMISC, sg)) + VIRTIO_NET_CTRL_RX_PROMISC, sg, NULL)) dev_warn(&dev->dev, "Failed to %sable promisc mode.\n", vi->ctrl->promisc ? "en" : "dis"); sg_init_one(sg, &vi->ctrl->allmulti, sizeof(vi->ctrl->allmulti)); if (!virtnet_send_command(vi, VIRTIO_NET_CTRL_RX, - VIRTIO_NET_CTRL_RX_ALLMULTI, sg)) + VIRTIO_NET_CTRL_RX_ALLMULTI, sg, NULL)) dev_warn(&dev->dev, "Failed to %sable allmulti mode.\n", vi->ctrl->allmulti ? "en" : "dis"); @@ -2770,7 +2775,7 @@ static void virtnet_set_rx_mode(struct net_device *dev) sizeof(mac_data->entries) + (mc_count * ETH_ALEN)); if (!virtnet_send_command(vi, VIRTIO_NET_CTRL_MAC, - VIRTIO_NET_CTRL_MAC_TABLE_SET, sg)) + VIRTIO_NET_CTRL_MAC_TABLE_SET, sg, NULL)) dev_warn(&dev->dev, "Failed to set MAC filter table.\n"); kfree(buf); @@ -2786,7 +2791,7 @@ static int virtnet_vlan_rx_add_vid(struct net_device *dev, sg_init_one(&sg, &vi->ctrl->vid, sizeof(vi->ctrl->vid)); if (!virtnet_send_command(vi, VIRTIO_NET_CTRL_VLAN, - VIRTIO_NET_CTRL_VLAN_ADD, &sg)) + VIRTIO_NET_CTRL_VLAN_ADD, &sg, NULL)) dev_warn(&dev->dev, "Failed to add VLAN ID %d.\n", vid); return 0; } @@ -2801,7 +2806,7 @@ static int virtnet_vlan_rx_kill_vid(struct net_device *dev, sg_init_one(&sg, &vi->ctrl->vid, sizeof(vi->ctrl->vid)); if (!virtnet_send_command(vi, VIRTIO_NET_CTRL_VLAN, - VIRTIO_NET_CTRL_VLAN_DEL, &sg)) + VIRTIO_NET_CTRL_VLAN_DEL, &sg, NULL)) dev_warn(&dev->dev, "Failed to kill VLAN ID %d.\n", vid); return 0; } @@ -2920,7 +2925,7 @@ static int virtnet_send_ctrl_coal_vq_cmd(struct virtnet_info *vi, if (!virtnet_send_command(vi, VIRTIO_NET_CTRL_NOTF_COAL, VIRTIO_NET_CTRL_NOTF_COAL_VQ_SET, - &sgs)) + &sgs, NULL)) return -EINVAL; return 0; @@ -3062,7 +3067,7 @@ static bool virtnet_commit_rss_command(struct virtnet_info *vi) if (!virtnet_send_command(vi, VIRTIO_NET_CTRL_MQ, vi->has_rss ? VIRTIO_NET_CTRL_MQ_RSS_CONFIG - : VIRTIO_NET_CTRL_MQ_HASH_CONFIG, sgs)) { + : VIRTIO_NET_CTRL_MQ_HASH_CONFIG, sgs, NULL)) { dev_warn(&dev->dev, "VIRTIONET issue with committing RSS sgs\n"); return false; } @@ -3380,7 +3385,7 @@ static int virtnet_send_tx_notf_coal_cmds(struct virtnet_info *vi, if (!virtnet_send_command(vi, VIRTIO_NET_CTRL_NOTF_COAL, VIRTIO_NET_CTRL_NOTF_COAL_TX_SET, - &sgs_tx)) + &sgs_tx, NULL)) return -EINVAL; vi->intr_coal_tx.max_usecs = ec->tx_coalesce_usecs; @@ -3430,7 +3435,7 @@ static int virtnet_send_rx_notf_coal_cmds(struct virtnet_info *vi, if (!virtnet_send_command(vi, VIRTIO_NET_CTRL_NOTF_COAL, VIRTIO_NET_CTRL_NOTF_COAL_RX_SET, - &sgs_rx)) + &sgs_rx, NULL)) return -EINVAL; vi->intr_coal_rx.max_usecs = ec->rx_coalesce_usecs; @@ -3899,7 +3904,8 @@ static int virtnet_set_guest_offloads(struct virtnet_info *vi, u64 offloads) sg_init_one(&sg, &vi->ctrl->offloads, sizeof(vi->ctrl->offloads)); if (!virtnet_send_command(vi, VIRTIO_NET_CTRL_GUEST_OFFLOADS, - VIRTIO_NET_CTRL_GUEST_OFFLOADS_SET, &sg)) { + VIRTIO_NET_CTRL_GUEST_OFFLOADS_SET, + &sg, NULL)) { dev_warn(&vi->dev->dev, "Fail to set guest offload.\n"); return -EINVAL; } @@ -4822,7 +4828,8 @@ static int virtnet_probe(struct virtio_device *vdev) sg_init_one(&sg, dev->dev_addr, dev->addr_len); if (!virtnet_send_command(vi, VIRTIO_NET_CTRL_MAC, - VIRTIO_NET_CTRL_MAC_ADDR_SET, &sg)) { + VIRTIO_NET_CTRL_MAC_ADDR_SET, + &sg, NULL)) { pr_debug("virtio_net: setting MAC address failed\n"); rtnl_unlock(); err = -EINVAL; From patchwork Tue Feb 27 08:03:00 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Xuan Zhuo X-Patchwork-Id: 13573332 X-Patchwork-Delegate: kuba@kernel.org Received: from out30-118.freemail.mail.aliyun.com (out30-118.freemail.mail.aliyun.com [115.124.30.118]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id AC66A55E6B for ; Tue, 27 Feb 2024 08:03:15 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=115.124.30.118 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1709020998; cv=none; b=PIGI3+Enke7FUZLP6JfMUurF9+SBtMrpr1gwTxUOBq37FxILE1ftcL1iz0SxBDH7GL8NRjXKTtVlBzFic2ep3uV4Fq+ybA/l6nF8BEAoZZUqMgCAxwOZbGN/7anbGAEGnUCZbGhNKcfDZPUT5DxVCqqMiHjqiYw6YF2ruSB7SbU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1709020998; c=relaxed/simple; bh=q720S0gwKbxBDOneZo+a5qKiCcMtjWYMmapnKySlWws=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=G2Zg0LofG2wSbGl/owJqCjXU8cY8s4V9bsz4nSB36CVFAlf/bY7gsSYnbd/Whvh2YMHyJtS67CwZP993nDgsxKJUFBwLBjhoTxdhPlOQN7F7l+o3dZ5gA4Zz9GFawAm7UlXW/VtyCNX3by2RmUcCCoNBGTNXtw9nZEgXYmebASw= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.alibaba.com; spf=pass smtp.mailfrom=linux.alibaba.com; dkim=pass (1024-bit key) header.d=linux.alibaba.com header.i=@linux.alibaba.com header.b=ooeeiaOP; arc=none smtp.client-ip=115.124.30.118 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.alibaba.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linux.alibaba.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linux.alibaba.com header.i=@linux.alibaba.com header.b="ooeeiaOP" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.alibaba.com; s=default; t=1709020988; h=From:To:Subject:Date:Message-Id:MIME-Version; bh=A9nh9gbtRNQDiY5CRmp00APsTxxr5/LAII+ZyPtk9oQ=; b=ooeeiaOP9C6TERS122ucVvIr+NUsJkPBwblxpTMtYmmxSOC9CnZVKxhZCVFyA0QegpKnsSO28otlL52s51gou7y2q4aufEkbaskOq42pvBNtMW+hMi6yjYmaJab/pf+bcHl3MiAISpGPQgdGcfbTqI4NPkykZ61q2VIMfW8ZeBA= X-Alimail-AntiSpam: AC=PASS;BC=-1|-1;BR=01201311R281e4;CH=green;DM=||false|;DS=||;FP=0|-1|-1|-1|0|-1|-1|-1;HT=ay29a033018045176;MF=xuanzhuo@linux.alibaba.com;NM=1;PH=DS;RN=9;SR=0;TI=SMTPD_---0W1M4RMv_1709020986; Received: from localhost(mailfrom:xuanzhuo@linux.alibaba.com fp:SMTPD_---0W1M4RMv_1709020986) by smtp.aliyun-inc.com; Tue, 27 Feb 2024 16:03:07 +0800 From: Xuan Zhuo To: netdev@vger.kernel.org Cc: "Michael S. Tsirkin" , Jason Wang , Xuan Zhuo , "David S. Miller" , Eric Dumazet , Jakub Kicinski , Paolo Abeni , virtualization@lists.linux.dev Subject: [PATCH net-next v3 3/6] virtio_net: support device stats Date: Tue, 27 Feb 2024 16:03:00 +0800 Message-Id: <20240227080303.63894-4-xuanzhuo@linux.alibaba.com> X-Mailer: git-send-email 2.32.0.3.g01195cf9f In-Reply-To: <20240227080303.63894-1-xuanzhuo@linux.alibaba.com> References: <20240227080303.63894-1-xuanzhuo@linux.alibaba.com> Precedence: bulk X-Mailing-List: netdev@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-Git-Hash: cacd048f99e7 X-Patchwork-Delegate: kuba@kernel.org As the spec https://github.com/oasis-tcs/virtio-spec/commit/42f389989823039724f95bbbd243291ab0064f82 make virtio-net support getting the stats from the device by ethtool -S . Signed-off-by: Xuan Zhuo --- drivers/net/virtio_net.c | 362 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 358 insertions(+), 4 deletions(-) diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c index af512d85cd5b..5549fc8508bd 100644 --- a/drivers/net/virtio_net.c +++ b/drivers/net/virtio_net.c @@ -128,6 +128,121 @@ static const struct virtnet_stat_desc virtnet_rq_stats_desc[] = { #define VIRTNET_SQ_STATS_LEN ARRAY_SIZE(virtnet_sq_stats_desc) #define VIRTNET_RQ_STATS_LEN ARRAY_SIZE(virtnet_rq_stats_desc) +#define VIRTNET_STATS_DESC(qtype, class, name) \ + {#name, offsetof(struct virtio_net_stats_ ## qtype ## _ ## class, qtype ## _ ## name)} + +static const struct virtnet_stat_desc virtnet_stats_cvq_desc[] = { + {"command_num", offsetof(struct virtio_net_stats_cvq, command_num)}, + {"ok_num", offsetof(struct virtio_net_stats_cvq, ok_num)} +}; + +static const struct virtnet_stat_desc virtnet_stats_rx_basic_desc[] = { + VIRTNET_STATS_DESC(rx, basic, packets), + VIRTNET_STATS_DESC(rx, basic, bytes), + + VIRTNET_STATS_DESC(rx, basic, notifications), + VIRTNET_STATS_DESC(rx, basic, interrupts), + + VIRTNET_STATS_DESC(rx, basic, drops), + VIRTNET_STATS_DESC(rx, basic, drop_overruns), +}; + +static const struct virtnet_stat_desc virtnet_stats_tx_basic_desc[] = { + VIRTNET_STATS_DESC(tx, basic, packets), + VIRTNET_STATS_DESC(tx, basic, bytes), + + VIRTNET_STATS_DESC(tx, basic, notifications), + VIRTNET_STATS_DESC(tx, basic, interrupts), + + VIRTNET_STATS_DESC(tx, basic, drops), + VIRTNET_STATS_DESC(tx, basic, drop_malformed), +}; + +static const struct virtnet_stat_desc virtnet_stats_rx_csum_desc[] = { + VIRTNET_STATS_DESC(rx, csum, csum_valid), + VIRTNET_STATS_DESC(rx, csum, needs_csum), + + VIRTNET_STATS_DESC(rx, csum, csum_none), + VIRTNET_STATS_DESC(rx, csum, csum_bad), +}; + +static const struct virtnet_stat_desc virtnet_stats_tx_csum_desc[] = { + VIRTNET_STATS_DESC(tx, csum, needs_csum), + VIRTNET_STATS_DESC(tx, csum, csum_none), +}; + +static const struct virtnet_stat_desc virtnet_stats_rx_gso_desc[] = { + VIRTNET_STATS_DESC(rx, gso, gso_packets), + VIRTNET_STATS_DESC(rx, gso, gso_bytes), + VIRTNET_STATS_DESC(rx, gso, gso_packets_coalesced), + VIRTNET_STATS_DESC(rx, gso, gso_bytes_coalesced), +}; + +static const struct virtnet_stat_desc virtnet_stats_tx_gso_desc[] = { + VIRTNET_STATS_DESC(tx, gso, gso_packets), + VIRTNET_STATS_DESC(tx, gso, gso_bytes), + VIRTNET_STATS_DESC(tx, gso, gso_segments), + VIRTNET_STATS_DESC(tx, gso, gso_segments_bytes), + VIRTNET_STATS_DESC(tx, gso, gso_packets_noseg), + VIRTNET_STATS_DESC(tx, gso, gso_bytes_noseg), +}; + +static const struct virtnet_stat_desc virtnet_stats_rx_speed_desc[] = { + VIRTNET_STATS_DESC(rx, speed, packets_allowance_exceeded), + VIRTNET_STATS_DESC(rx, speed, bytes_allowance_exceeded), +}; + +static const struct virtnet_stat_desc virtnet_stats_tx_speed_desc[] = { + VIRTNET_STATS_DESC(tx, speed, packets_allowance_exceeded), + VIRTNET_STATS_DESC(tx, speed, packets_allowance_exceeded), +}; + +struct virtnet_stats_map { + /* the stat type in bitmap */ + u64 stat_type; + + /* the bytes of the response for the stat */ + u32 len; + + /* the num of the response fields for the stat */ + u32 num; + +#define VIRTNET_STATS_Q_TYPE_RX 0 +#define VIRTNET_STATS_Q_TYPE_TX 1 +#define VIRTNET_STATS_Q_TYPE_CQ 2 + u32 queue_type; + + /* the reply type of the stat */ + u8 reply_type; + + /* describe the name and the offset in the response */ + const struct virtnet_stat_desc *desc; +}; + +#define VIRTNET_DEVICE_STATS_MAP_ITEM(TYPE, type, queue_type) \ + { \ + VIRTIO_NET_STATS_TYPE_##TYPE, \ + sizeof(struct virtio_net_stats_ ## type), \ + ARRAY_SIZE(virtnet_stats_ ## type ##_desc), \ + VIRTNET_STATS_Q_TYPE_##queue_type, \ + VIRTIO_NET_STATS_TYPE_REPLY_##TYPE, \ + &virtnet_stats_##type##_desc[0] \ + } + +static struct virtnet_stats_map virtio_net_stats_map[] = { + VIRTNET_DEVICE_STATS_MAP_ITEM(CVQ, cvq, CQ), + + VIRTNET_DEVICE_STATS_MAP_ITEM(RX_BASIC, rx_basic, RX), + VIRTNET_DEVICE_STATS_MAP_ITEM(RX_CSUM, rx_csum, RX), + VIRTNET_DEVICE_STATS_MAP_ITEM(RX_GSO, rx_gso, RX), + VIRTNET_DEVICE_STATS_MAP_ITEM(RX_SPEED, rx_speed, RX), + + VIRTNET_DEVICE_STATS_MAP_ITEM(TX_BASIC, tx_basic, TX), + VIRTNET_DEVICE_STATS_MAP_ITEM(TX_CSUM, tx_csum, TX), + VIRTNET_DEVICE_STATS_MAP_ITEM(TX_GSO, tx_gso, TX), + VIRTNET_DEVICE_STATS_MAP_ITEM(TX_SPEED, tx_speed, TX), +}; + struct virtnet_interrupt_coalesce { u32 max_packets; u32 max_usecs; @@ -244,6 +359,7 @@ struct control_buf { struct virtio_net_ctrl_coal_tx coal_tx; struct virtio_net_ctrl_coal_rx coal_rx; struct virtio_net_ctrl_coal_vq coal_vq; + struct virtio_net_stats_capabilities stats_cap; }; struct virtnet_info { @@ -329,6 +445,8 @@ struct virtnet_info { /* failover when STANDBY feature enabled */ struct failover *failover; + + u64 device_stats_cap; }; struct padded_vnet_hdr { @@ -3263,6 +3381,204 @@ static int virtnet_set_channels(struct net_device *dev, return err; } +static void virtnet_get_hw_stats_string(struct virtnet_info *vi, int type, int qid, u8 **data) +{ + struct virtnet_stats_map *m; + int i, j; + u8 *p = *data; + + if (!virtio_has_feature(vi->vdev, VIRTIO_NET_F_DEVICE_STATS)) + return; + + for (i = 0; i < ARRAY_SIZE(virtio_net_stats_map); ++i) { + m = &virtio_net_stats_map[i]; + + if (m->queue_type != type) + continue; + + if (!(vi->device_stats_cap & m->stat_type)) + continue; + + for (j = 0; j < m->num; ++j) { + if (type == VIRTNET_STATS_Q_TYPE_RX) + ethtool_sprintf(&p, "rx_queue_hw_%u_%s", qid, m->desc[j].desc); + + else if (type == VIRTNET_STATS_Q_TYPE_TX) + ethtool_sprintf(&p, "tx_queue_hw_%u_%s", qid, m->desc[j].desc); + + else if (type == VIRTNET_STATS_Q_TYPE_CQ) + ethtool_sprintf(&p, "cq_hw_%s", m->desc[j].desc); + } + } + + *data = p; +} + +struct virtnet_stats_ctx { + u32 num_cq; + u32 num_rx; + u32 num_tx; + + u64 bitmap_cq; + u64 bitmap_rx; + u64 bitmap_tx; + + u32 size_cq; + u32 size_rx; + u32 size_tx; + + u64 *data; +}; + +static void virtnet_stats_ctx_init(struct virtnet_info *vi, + struct virtnet_stats_ctx *ctx, + u64 *data) +{ + struct virtnet_stats_map *m; + int i; + + ctx->data = data; + + for (i = 0; i < ARRAY_SIZE(virtio_net_stats_map); ++i) { + m = &virtio_net_stats_map[i]; + + if (vi->device_stats_cap & m->stat_type) { + if (m->queue_type == VIRTNET_STATS_Q_TYPE_CQ) { + ctx->bitmap_cq |= m->stat_type; + ctx->num_cq += m->num; + ctx->size_cq += m->len; + } + + if (m->queue_type == VIRTNET_STATS_Q_TYPE_RX) { + ctx->bitmap_rx |= m->stat_type; + ctx->num_rx += m->num; + ctx->size_rx += m->len; + } + + if (m->queue_type == VIRTNET_STATS_Q_TYPE_TX) { + ctx->bitmap_tx |= m->stat_type; + ctx->num_tx += m->num; + ctx->size_tx += m->len; + } + } + } +} + +static int virtnet_get_hw_stats(struct virtnet_info *vi, + struct virtnet_stats_ctx *ctx) +{ + struct virtio_net_ctrl_queue_stats *req; + struct virtio_net_stats_reply_hdr *hdr; + struct scatterlist sgs_in, sgs_out; + u32 num_rx, num_tx, num_cq, offset; + int qnum, i, j, qid, res_size; + struct virtnet_stats_map *m; + void *reply, *p; + u64 bitmap; + int ok; + u64 *v; + + if (!virtio_has_feature(vi->vdev, VIRTIO_NET_F_DEVICE_STATS)) + return 0; + + qnum = 0; + if (ctx->bitmap_cq) + qnum += 1; + + if (ctx->bitmap_rx) + qnum += vi->curr_queue_pairs; + + if (ctx->bitmap_tx) + qnum += vi->curr_queue_pairs; + + req = kcalloc(qnum, sizeof(*req), GFP_KERNEL); + if (!req) + return -ENOMEM; + + res_size = (ctx->size_rx + ctx->size_tx) * vi->curr_queue_pairs + ctx->size_cq; + reply = kmalloc(res_size, GFP_KERNEL); + if (!reply) { + kfree(req); + return -ENOMEM; + } + + j = 0; + for (i = 0; i < vi->curr_queue_pairs; ++i) { + if (ctx->bitmap_rx) { + req->stats[j].vq_index = cpu_to_le16(i * 2); + req->stats[j].types_bitmap[0] = cpu_to_le64(ctx->bitmap_rx); + ++j; + } + + if (ctx->bitmap_tx) { + req->stats[j].vq_index = cpu_to_le16(i * 2 + 1); + req->stats[j].types_bitmap[0] = cpu_to_le64(ctx->bitmap_tx); + ++j; + } + } + + if (ctx->size_cq) { + req->stats[j].vq_index = cpu_to_le16(vi->max_queue_pairs * 2); + req->stats[j].types_bitmap[0] = cpu_to_le64(ctx->bitmap_cq); + ++j; + } + + sg_init_one(&sgs_out, req, sizeof(*req) * j); + sg_init_one(&sgs_in, reply, res_size); + + ok = virtnet_send_command(vi, VIRTIO_NET_CTRL_STATS, + VIRTIO_NET_CTRL_STATS_GET, + &sgs_out, &sgs_in); + kfree(req); + + if (!ok) { + kfree(reply); + return ok; + } + + num_rx = VIRTNET_RQ_STATS_LEN + ctx->num_rx; + num_tx = VIRTNET_SQ_STATS_LEN + ctx->num_tx; + num_cq = ctx->num_tx; + + for (p = reply; p - reply < res_size; p += le16_to_cpu(hdr->size)) { + hdr = p; + + qid = le16_to_cpu(hdr->vq_index); + + if (qid == vi->max_queue_pairs * 2) { + offset = 0; + bitmap = ctx->bitmap_cq; + } else if (qid % 2) { + offset = num_cq + num_rx * vi->curr_queue_pairs + num_tx * (qid / 2); + offset += VIRTNET_SQ_STATS_LEN; + bitmap = ctx->bitmap_tx; + } else { + offset = num_cq + num_rx * (qid / 2) + VIRTNET_RQ_STATS_LEN; + bitmap = ctx->bitmap_rx; + } + + for (i = 0; i < ARRAY_SIZE(virtio_net_stats_map); ++i) { + m = &virtio_net_stats_map[i]; + + if (m->stat_type & bitmap) + offset += m->num; + + if (hdr->type != m->reply_type) + continue; + + for (j = 0; j < m->num; ++j) { + v = p + m->desc[j].offset; + ctx->data[offset + j] = le64_to_cpu(*v); + } + + break; + } + } + + kfree(reply); + return 0; +} + static void virtnet_get_strings(struct net_device *dev, u32 stringset, u8 *data) { struct virtnet_info *vi = netdev_priv(dev); @@ -3271,16 +3587,22 @@ static void virtnet_get_strings(struct net_device *dev, u32 stringset, u8 *data) switch (stringset) { case ETH_SS_STATS: + virtnet_get_hw_stats_string(vi, VIRTNET_STATS_Q_TYPE_CQ, 0, &p); + for (i = 0; i < vi->curr_queue_pairs; i++) { for (j = 0; j < VIRTNET_RQ_STATS_LEN; j++) ethtool_sprintf(&p, "rx_queue_%u_%s", i, virtnet_rq_stats_desc[j].desc); + + virtnet_get_hw_stats_string(vi, VIRTNET_STATS_Q_TYPE_RX, i, &p); } for (i = 0; i < vi->curr_queue_pairs; i++) { for (j = 0; j < VIRTNET_SQ_STATS_LEN; j++) ethtool_sprintf(&p, "tx_queue_%u_%s", i, virtnet_sq_stats_desc[j].desc); + + virtnet_get_hw_stats_string(vi, VIRTNET_STATS_Q_TYPE_TX, i, &p); } break; } @@ -3289,11 +3611,35 @@ static void virtnet_get_strings(struct net_device *dev, u32 stringset, u8 *data) static int virtnet_get_sset_count(struct net_device *dev, int sset) { struct virtnet_info *vi = netdev_priv(dev); + struct virtnet_stats_ctx ctx = {0}; + u32 pair_count; switch (sset) { case ETH_SS_STATS: - return vi->curr_queue_pairs * (VIRTNET_RQ_STATS_LEN + - VIRTNET_SQ_STATS_LEN); + if (virtio_has_feature(vi->vdev, VIRTIO_NET_F_DEVICE_STATS) && + !vi->device_stats_cap) { + struct scatterlist sg; + + sg_init_one(&sg, &vi->ctrl->stats_cap, sizeof(vi->ctrl->stats_cap)); + + if (!virtnet_send_command(vi, VIRTIO_NET_CTRL_STATS, + VIRTIO_NET_CTRL_STATS_QUERY, + NULL, &sg)) { + dev_warn(&dev->dev, "Fail to get stats capability\n"); + } else { + __le64 v; + + v = vi->ctrl->stats_cap.supported_stats_types[0]; + vi->device_stats_cap = le64_to_cpu(v); + } + } + + virtnet_stats_ctx_init(vi, &ctx, NULL); + + pair_count = VIRTNET_RQ_STATS_LEN + VIRTNET_SQ_STATS_LEN; + pair_count += ctx.num_rx + ctx.num_tx; + + return ctx.num_cq + vi->curr_queue_pairs * pair_count; default: return -EOPNOTSUPP; } @@ -3303,11 +3649,17 @@ static void virtnet_get_ethtool_stats(struct net_device *dev, struct ethtool_stats *stats, u64 *data) { struct virtnet_info *vi = netdev_priv(dev); - unsigned int idx = 0, start, i, j; + struct virtnet_stats_ctx ctx = {0}; + unsigned int idx, start, i, j; const u8 *stats_base; const u64_stats_t *p; size_t offset; + virtnet_stats_ctx_init(vi, &ctx, data); + virtnet_get_hw_stats(vi, &ctx); + + idx = ctx.num_cq; + for (i = 0; i < vi->curr_queue_pairs; i++) { struct receive_queue *rq = &vi->rq[i]; @@ -3321,6 +3673,7 @@ static void virtnet_get_ethtool_stats(struct net_device *dev, } } while (u64_stats_fetch_retry(&rq->stats.syncp, start)); idx += VIRTNET_RQ_STATS_LEN; + idx += ctx.num_rx; } for (i = 0; i < vi->curr_queue_pairs; i++) { @@ -3336,6 +3689,7 @@ static void virtnet_get_ethtool_stats(struct net_device *dev, } } while (u64_stats_fetch_retry(&sq->stats.syncp, start)); idx += VIRTNET_SQ_STATS_LEN; + idx += ctx.num_tx; } } @@ -4963,7 +5317,7 @@ static struct virtio_device_id id_table[] = { VIRTIO_NET_F_SPEED_DUPLEX, VIRTIO_NET_F_STANDBY, \ VIRTIO_NET_F_RSS, VIRTIO_NET_F_HASH_REPORT, VIRTIO_NET_F_NOTF_COAL, \ VIRTIO_NET_F_VQ_NOTF_COAL, \ - VIRTIO_NET_F_GUEST_HDRLEN + VIRTIO_NET_F_GUEST_HDRLEN, VIRTIO_NET_F_DEVICE_STATS static unsigned int features[] = { VIRTNET_FEATURES, From patchwork Tue Feb 27 08:03:01 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Xuan Zhuo X-Patchwork-Id: 13573328 X-Patchwork-Delegate: kuba@kernel.org Received: from out30-98.freemail.mail.aliyun.com (out30-98.freemail.mail.aliyun.com [115.124.30.98]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 1583754BC8 for ; Tue, 27 Feb 2024 08:03:10 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=115.124.30.98 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1709020993; cv=none; b=qUOjPjr6oFFpjn+yYJblmX2cLAYewWF5lEeH+VI7upij5HxNlYCYttvMT+2bE6SBnWto/EYdgtZCEEe7lprdnuTRea5RKazhq6uJHSbH2jUffWo2jL8z11S0CMSK/xPVYYFL67XIb1vSQJ0bKCpn3gpy21Jt5gEK+weKkZeAQNU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1709020993; c=relaxed/simple; bh=ZtHHlM2tlid+u5KOR1PN5stKbfqq5XB54d92kHNBR/w=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=RgmdPyc59QtI5FZhopkDHgSwh7MvLv+ebOJMUxWfdUqSbnWyMohJJ48DfTp97b2slWgbeNtCcLiBkyqraZIwgVuSUkubSRrK41iOgKVigCRrOT9l5txR0l78AXNTJIHV43NmsCCNpKlgukZccXLF7FvaCu6Y8Bxdtz4JI/tcP2g= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.alibaba.com; spf=pass smtp.mailfrom=linux.alibaba.com; dkim=pass (1024-bit key) header.d=linux.alibaba.com header.i=@linux.alibaba.com header.b=TXUDSZpQ; arc=none smtp.client-ip=115.124.30.98 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.alibaba.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linux.alibaba.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linux.alibaba.com header.i=@linux.alibaba.com header.b="TXUDSZpQ" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.alibaba.com; s=default; t=1709020989; h=From:To:Subject:Date:Message-Id:MIME-Version; bh=c86DK5PmyOIfGATevZBcS4ksi0VLC5oh1qktT046tAU=; b=TXUDSZpQ1fWh+MaMT1+bFA3qwl8g+awPzOiGNA5625CCo/7HRjtVUp0bszdoCKnBu3LOyRVIAyB9LltveuBrMqXScLiidrUTZEeMqCg3obWPkKuwni212n2EX4PnjAVP0jyZGBl02BDhdV5gkKHYGNlC5aAyZb3eUWBojzz5Ffk= X-Alimail-AntiSpam: AC=PASS;BC=-1|-1;BR=01201311R191e4;CH=green;DM=||false|;DS=||;FP=0|-1|-1|-1|0|-1|-1|-1;HT=ay29a033018046050;MF=xuanzhuo@linux.alibaba.com;NM=1;PH=DS;RN=9;SR=0;TI=SMTPD_---0W1Lw1dq_1709020987; Received: from localhost(mailfrom:xuanzhuo@linux.alibaba.com fp:SMTPD_---0W1Lw1dq_1709020987) by smtp.aliyun-inc.com; Tue, 27 Feb 2024 16:03:08 +0800 From: Xuan Zhuo To: netdev@vger.kernel.org Cc: "Michael S. Tsirkin" , Jason Wang , Xuan Zhuo , "David S. Miller" , Eric Dumazet , Jakub Kicinski , Paolo Abeni , virtualization@lists.linux.dev Subject: [PATCH net-next v3 4/6] virtio_net: stats map include driver stats Date: Tue, 27 Feb 2024 16:03:01 +0800 Message-Id: <20240227080303.63894-5-xuanzhuo@linux.alibaba.com> X-Mailer: git-send-email 2.32.0.3.g01195cf9f In-Reply-To: <20240227080303.63894-1-xuanzhuo@linux.alibaba.com> References: <20240227080303.63894-1-xuanzhuo@linux.alibaba.com> Precedence: bulk X-Mailing-List: netdev@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-Git-Hash: cacd048f99e7 X-Patchwork-Delegate: kuba@kernel.org In the last commit, we use the stats map to manage the device stats. For the consistency, we let the stats map includes the driver stats. Signed-off-by: Xuan Zhuo --- drivers/net/virtio_net.c | 195 ++++++++++++++++++++------------------- 1 file changed, 100 insertions(+), 95 deletions(-) diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c index 5549fc8508bd..95cbfb159a03 100644 --- a/drivers/net/virtio_net.c +++ b/drivers/net/virtio_net.c @@ -125,9 +125,6 @@ static const struct virtnet_stat_desc virtnet_rq_stats_desc[] = { { "kicks", VIRTNET_RQ_STAT(kicks) }, }; -#define VIRTNET_SQ_STATS_LEN ARRAY_SIZE(virtnet_sq_stats_desc) -#define VIRTNET_RQ_STATS_LEN ARRAY_SIZE(virtnet_rq_stats_desc) - #define VIRTNET_STATS_DESC(qtype, class, name) \ {#name, offsetof(struct virtio_net_stats_ ## qtype ## _ ## class, qtype ## _ ## name)} @@ -198,10 +195,10 @@ static const struct virtnet_stat_desc virtnet_stats_tx_speed_desc[] = { }; struct virtnet_stats_map { - /* the stat type in bitmap */ + /* the stat type in bitmap. just for device stats */ u64 stat_type; - /* the bytes of the response for the stat */ + /* the bytes of the response for the stat. just for device stats */ u32 len; /* the num of the response fields for the stat */ @@ -212,9 +209,11 @@ struct virtnet_stats_map { #define VIRTNET_STATS_Q_TYPE_CQ 2 u32 queue_type; - /* the reply type of the stat */ + /* the reply type of the stat. just for device stats */ u8 reply_type; + u8 from_driver; + /* describe the name and the offset in the response */ const struct virtnet_stat_desc *desc; }; @@ -226,10 +225,24 @@ struct virtnet_stats_map { ARRAY_SIZE(virtnet_stats_ ## type ##_desc), \ VIRTNET_STATS_Q_TYPE_##queue_type, \ VIRTIO_NET_STATS_TYPE_REPLY_##TYPE, \ + false, \ &virtnet_stats_##type##_desc[0] \ } +#define VIRTNET_DRIVER_STATS_MAP_ITEM(type, queue_type) \ + { \ + 0, 0, \ + ARRAY_SIZE(virtnet_ ## type ## _stats_desc), \ + VIRTNET_STATS_Q_TYPE_##queue_type, \ + 0, true, \ + &virtnet_##type##_stats_desc[0] \ + } + static struct virtnet_stats_map virtio_net_stats_map[] = { + /* driver stats should on the start. */ + VIRTNET_DRIVER_STATS_MAP_ITEM(rq, RX), + VIRTNET_DRIVER_STATS_MAP_ITEM(sq, TX), + VIRTNET_DEVICE_STATS_MAP_ITEM(CVQ, cvq, CQ), VIRTNET_DEVICE_STATS_MAP_ITEM(RX_BASIC, rx_basic, RX), @@ -243,6 +256,11 @@ static struct virtnet_stats_map virtio_net_stats_map[] = { VIRTNET_DEVICE_STATS_MAP_ITEM(TX_SPEED, tx_speed, TX), }; +#define virtnet_stats_supported(vi, m) ({ \ + typeof(m) _m = (m); \ + (((vi)->device_stats_cap & _m->stat_type) || _m->from_driver); \ +}) + struct virtnet_interrupt_coalesce { u32 max_packets; u32 max_usecs; @@ -2247,7 +2265,7 @@ static int virtnet_receive(struct receive_queue *rq, int budget, u64_stats_set(&stats.packets, packets); u64_stats_update_begin(&rq->stats.syncp); - for (i = 0; i < VIRTNET_RQ_STATS_LEN; i++) { + for (i = 0; i < ARRAY_SIZE(virtnet_rq_stats_desc); i++) { size_t offset = virtnet_rq_stats_desc[i].offset; u64_stats_t *item, *src; @@ -3381,33 +3399,36 @@ static int virtnet_set_channels(struct net_device *dev, return err; } -static void virtnet_get_hw_stats_string(struct virtnet_info *vi, int type, int qid, u8 **data) +static void virtnet_get_stats_string(struct virtnet_info *vi, int type, int qid, u8 **data) { struct virtnet_stats_map *m; + const char *tp; int i, j; u8 *p = *data; - if (!virtio_has_feature(vi->vdev, VIRTIO_NET_F_DEVICE_STATS)) - return; - for (i = 0; i < ARRAY_SIZE(virtio_net_stats_map); ++i) { m = &virtio_net_stats_map[i]; if (m->queue_type != type) continue; - if (!(vi->device_stats_cap & m->stat_type)) + if (!virtnet_stats_supported(vi, m)) continue; for (j = 0; j < m->num; ++j) { + if (m->from_driver) + tp = ""; + else + tp = "_hw"; + if (type == VIRTNET_STATS_Q_TYPE_RX) - ethtool_sprintf(&p, "rx_queue_hw_%u_%s", qid, m->desc[j].desc); + 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_hw_%u_%s", qid, m->desc[j].desc); + 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_hw_%s", m->desc[j].desc); + ethtool_sprintf(&p, "cq%s_%s", tp, m->desc[j].desc); } } @@ -3442,7 +3463,7 @@ static void virtnet_stats_ctx_init(struct virtnet_info *vi, for (i = 0; i < ARRAY_SIZE(virtio_net_stats_map); ++i) { m = &virtio_net_stats_map[i]; - if (vi->device_stats_cap & m->stat_type) { + if (virtnet_stats_supported(vi, m)) { if (m->queue_type == VIRTNET_STATS_Q_TYPE_CQ) { ctx->bitmap_cq |= m->stat_type; ctx->num_cq += m->num; @@ -3464,19 +3485,66 @@ static void virtnet_stats_ctx_init(struct virtnet_info *vi, } } +static void virtnet_fill_stats(struct virtnet_info *vi, u32 qid, + struct virtnet_stats_ctx *ctx, + const u8 *base, bool from_driver, u8 type) +{ + struct virtnet_stats_map *m; + const u64_stats_t *v_stat; + u32 queue_type; + const u64 *v; + u64 offset; + int i, j; + + 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); + queue_type = VIRTNET_STATS_Q_TYPE_TX; + } else { + offset = ctx->num_cq + ctx->num_rx * (qid / 2); + queue_type = VIRTNET_STATS_Q_TYPE_RX; + } + + for (i = 0; i < ARRAY_SIZE(virtio_net_stats_map); ++i) { + m = &virtio_net_stats_map[i]; + + if (m->queue_type != queue_type) + continue; + + if (from_driver != m->from_driver) + goto skip; + + if (type != m->reply_type) + goto skip; + + for (j = 0; j < m->num; ++j) { + if (!from_driver) { + v = (const u64 *)(base + m->desc[j].offset); + ctx->data[offset + j] = le64_to_cpu(*v); + } else { + v_stat = (const u64_stats_t *)(base + m->desc[j].offset); + ctx->data[offset + j] = u64_stats_read(v_stat); + } + } + + break; +skip: + if (virtnet_stats_supported(vi, m)) + offset += m->num; + } +} + static int virtnet_get_hw_stats(struct virtnet_info *vi, struct virtnet_stats_ctx *ctx) { struct virtio_net_ctrl_queue_stats *req; struct virtio_net_stats_reply_hdr *hdr; struct scatterlist sgs_in, sgs_out; - u32 num_rx, num_tx, num_cq, offset; int qnum, i, j, qid, res_size; - struct virtnet_stats_map *m; void *reply, *p; - u64 bitmap; int ok; - u64 *v; if (!virtio_has_feature(vi->vdev, VIRTIO_NET_F_DEVICE_STATS)) return 0; @@ -3536,43 +3604,10 @@ static int virtnet_get_hw_stats(struct virtnet_info *vi, return ok; } - num_rx = VIRTNET_RQ_STATS_LEN + ctx->num_rx; - num_tx = VIRTNET_SQ_STATS_LEN + ctx->num_tx; - num_cq = ctx->num_tx; - for (p = reply; p - reply < res_size; p += le16_to_cpu(hdr->size)) { hdr = p; - qid = le16_to_cpu(hdr->vq_index); - - if (qid == vi->max_queue_pairs * 2) { - offset = 0; - bitmap = ctx->bitmap_cq; - } else if (qid % 2) { - offset = num_cq + num_rx * vi->curr_queue_pairs + num_tx * (qid / 2); - offset += VIRTNET_SQ_STATS_LEN; - bitmap = ctx->bitmap_tx; - } else { - offset = num_cq + num_rx * (qid / 2) + VIRTNET_RQ_STATS_LEN; - bitmap = ctx->bitmap_rx; - } - - for (i = 0; i < ARRAY_SIZE(virtio_net_stats_map); ++i) { - m = &virtio_net_stats_map[i]; - - if (m->stat_type & bitmap) - offset += m->num; - - if (hdr->type != m->reply_type) - continue; - - for (j = 0; j < m->num; ++j) { - v = p + m->desc[j].offset; - ctx->data[offset + j] = le64_to_cpu(*v); - } - - break; - } + virtnet_fill_stats(vi, qid, ctx, p, false, hdr->type); } kfree(reply); @@ -3582,28 +3617,18 @@ static int virtnet_get_hw_stats(struct virtnet_info *vi, static void virtnet_get_strings(struct net_device *dev, u32 stringset, u8 *data) { struct virtnet_info *vi = netdev_priv(dev); - unsigned int i, j; + unsigned int i; u8 *p = data; switch (stringset) { case ETH_SS_STATS: - virtnet_get_hw_stats_string(vi, VIRTNET_STATS_Q_TYPE_CQ, 0, &p); + virtnet_get_stats_string(vi, VIRTNET_STATS_Q_TYPE_CQ, 0, &p); - for (i = 0; i < vi->curr_queue_pairs; i++) { - for (j = 0; j < VIRTNET_RQ_STATS_LEN; j++) - ethtool_sprintf(&p, "rx_queue_%u_%s", i, - virtnet_rq_stats_desc[j].desc); + for (i = 0; i < vi->curr_queue_pairs; ++i) + virtnet_get_stats_string(vi, VIRTNET_STATS_Q_TYPE_RX, i, &p); - virtnet_get_hw_stats_string(vi, VIRTNET_STATS_Q_TYPE_RX, i, &p); - } - - for (i = 0; i < vi->curr_queue_pairs; i++) { - for (j = 0; j < VIRTNET_SQ_STATS_LEN; j++) - ethtool_sprintf(&p, "tx_queue_%u_%s", i, - virtnet_sq_stats_desc[j].desc); - - virtnet_get_hw_stats_string(vi, VIRTNET_STATS_Q_TYPE_TX, i, &p); - } + for (i = 0; i < vi->curr_queue_pairs; ++i) + virtnet_get_stats_string(vi, VIRTNET_STATS_Q_TYPE_TX, i, &p); break; } } @@ -3636,8 +3661,7 @@ static int virtnet_get_sset_count(struct net_device *dev, int sset) virtnet_stats_ctx_init(vi, &ctx, NULL); - pair_count = VIRTNET_RQ_STATS_LEN + VIRTNET_SQ_STATS_LEN; - pair_count += ctx.num_rx + ctx.num_tx; + pair_count = ctx.num_rx + ctx.num_tx; return ctx.num_cq + vi->curr_queue_pairs * pair_count; default: @@ -3650,46 +3674,27 @@ static void virtnet_get_ethtool_stats(struct net_device *dev, { struct virtnet_info *vi = netdev_priv(dev); struct virtnet_stats_ctx ctx = {0}; - unsigned int idx, start, i, j; + unsigned int start, i; const u8 *stats_base; - const u64_stats_t *p; - size_t offset; virtnet_stats_ctx_init(vi, &ctx, data); virtnet_get_hw_stats(vi, &ctx); - idx = ctx.num_cq; - for (i = 0; i < vi->curr_queue_pairs; i++) { struct receive_queue *rq = &vi->rq[i]; + struct send_queue *sq = &vi->sq[i]; stats_base = (const u8 *)&rq->stats; do { start = u64_stats_fetch_begin(&rq->stats.syncp); - for (j = 0; j < VIRTNET_RQ_STATS_LEN; j++) { - offset = virtnet_rq_stats_desc[j].offset; - p = (const u64_stats_t *)(stats_base + offset); - data[idx + j] = u64_stats_read(p); - } + virtnet_fill_stats(vi, i * 2, &ctx, stats_base, true, 0); } while (u64_stats_fetch_retry(&rq->stats.syncp, start)); - idx += VIRTNET_RQ_STATS_LEN; - idx += ctx.num_rx; - } - - for (i = 0; i < vi->curr_queue_pairs; i++) { - struct send_queue *sq = &vi->sq[i]; stats_base = (const u8 *)&sq->stats; do { start = u64_stats_fetch_begin(&sq->stats.syncp); - for (j = 0; j < VIRTNET_SQ_STATS_LEN; j++) { - offset = virtnet_sq_stats_desc[j].offset; - p = (const u64_stats_t *)(stats_base + offset); - data[idx + j] = u64_stats_read(p); - } + virtnet_fill_stats(vi, i * 2 + 1, &ctx, stats_base, true, 0); } while (u64_stats_fetch_retry(&sq->stats.syncp, start)); - idx += VIRTNET_SQ_STATS_LEN; - idx += ctx.num_tx; } } From patchwork Tue Feb 27 08:03:02 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Xuan Zhuo X-Patchwork-Id: 13573329 X-Patchwork-Delegate: kuba@kernel.org Received: from out30-133.freemail.mail.aliyun.com (out30-133.freemail.mail.aliyun.com [115.124.30.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 9EEB455E7E for ; Tue, 27 Feb 2024 08:03:12 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=115.124.30.133 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1709020995; cv=none; b=TzDtBGiH38oembMN3KfYQg3LPik/S+pNtr1Cx5ERx0nuNHhbkuF9EG6eOx0sBR/9M87pSs8m5IhfWg2Uf6uYnBayFZ2sydU2fMU5+U/vLSpRsD/7xuJQWGQThXOaTzz84GyWfwYHHw9gnQ5rai1Cy+OUiULqa8z2Yf5mVT8Avgo= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1709020995; c=relaxed/simple; bh=NujPk1XinbhSzvLrFov2imWLGZSpcuAFikTms7mq81I=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=bENse64DuI6ZcQte0+7Cr0FdbfhKIj27M1pGNs3etA5WaTu/zB0sPE/NGQAiULFqyuudyfhlc9rqxSbaA2vj7JANgF279RBMHKNo3521dNrJMkcwtd7crXnCTNGKg/s/pta2Lc1sT8aTwBjy8/RzqxcKtXzexbdi1bsx7IXd4Xo= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.alibaba.com; spf=pass smtp.mailfrom=linux.alibaba.com; dkim=pass (1024-bit key) header.d=linux.alibaba.com header.i=@linux.alibaba.com header.b=xDesCsho; arc=none smtp.client-ip=115.124.30.133 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.alibaba.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linux.alibaba.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linux.alibaba.com header.i=@linux.alibaba.com header.b="xDesCsho" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.alibaba.com; s=default; t=1709020991; h=From:To:Subject:Date:Message-Id:MIME-Version; bh=bevBx4KouHEw4KQD9nQgZP8470FlLDbzXo8XlhAEMhY=; b=xDesCshok1N6xj1BqpBYtDRRXbYVzb7GpQnEP5OOzIj6nRBoCcjoQEoB+hC/rHzQE9CHwV/yeTgZggM0MK4DfZMEAMr1yETCP1dL9V3Zlp8qs6g+1xVWA61tLBUwLq+zBb5BHKGeoV6mk1Gp3zBbXDrNv/UWb93qTEKJJg73A+c= X-Alimail-AntiSpam: AC=PASS;BC=-1|-1;BR=01201311R781e4;CH=green;DM=||false|;DS=||;FP=0|-1|-1|-1|0|-1|-1|-1;HT=ay29a033018045170;MF=xuanzhuo@linux.alibaba.com;NM=1;PH=DS;RN=9;SR=0;TI=SMTPD_---0W1Lw1ef_1709020988; Received: from localhost(mailfrom:xuanzhuo@linux.alibaba.com fp:SMTPD_---0W1Lw1ef_1709020988) by smtp.aliyun-inc.com; Tue, 27 Feb 2024 16:03:09 +0800 From: Xuan Zhuo To: netdev@vger.kernel.org Cc: "Michael S. Tsirkin" , Jason Wang , Xuan Zhuo , "David S. Miller" , Eric Dumazet , Jakub Kicinski , Paolo Abeni , virtualization@lists.linux.dev Subject: [PATCH net-next v3 5/6] virtio_net: add the total stats field Date: Tue, 27 Feb 2024 16:03:02 +0800 Message-Id: <20240227080303.63894-6-xuanzhuo@linux.alibaba.com> X-Mailer: git-send-email 2.32.0.3.g01195cf9f In-Reply-To: <20240227080303.63894-1-xuanzhuo@linux.alibaba.com> References: <20240227080303.63894-1-xuanzhuo@linux.alibaba.com> Precedence: bulk X-Mailing-List: netdev@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-Git-Hash: cacd048f99e7 X-Patchwork-Delegate: kuba@kernel.org 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 --- 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 95cbfb159a03..91838d75cff2 100644 --- a/drivers/net/virtio_net.c +++ b/drivers/net/virtio_net.c @@ -3399,6 +3399,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; @@ -3421,14 +3422,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); + } } } @@ -3485,6 +3495,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) @@ -3496,14 +3538,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; } @@ -3622,6 +3667,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) @@ -3663,7 +3711,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; } @@ -3696,6 +3744,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, From patchwork Tue Feb 27 08:03:03 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Xuan Zhuo X-Patchwork-Id: 13573333 X-Patchwork-Delegate: kuba@kernel.org Received: from out30-101.freemail.mail.aliyun.com (out30-101.freemail.mail.aliyun.com [115.124.30.101]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id B995F56762 for ; Tue, 27 Feb 2024 08:03:18 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=115.124.30.101 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1709021001; cv=none; b=GGtTewcNliezlY2I4Q42dVb6ivKI//BXXuE/GHND/3g7U1CR+L/kRcX8/dG9AQE7p3Z/wzBxKhmG3sUTmEY/ct/zD7JF2KqZKUuYvjfauXLUDwM7+Qt5xisru+8QljcLuAlCnRI/ECLFl1C0yypu3aGpKodNDpLjjeJFzI3gm8s= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1709021001; c=relaxed/simple; bh=I05ORVcpyq4EqsF2TIo6Eqrl9ra0z83u5K8YrZ0H74s=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=tl0Z+oBdhBl6zeQ4Z8lpVG6GjVLoYbZXsmVSvj52skHVGsYwL751Ds40CeGnhzb9occNUAhO5fUngHg9VcGwNUNKbAnDp9EoICimfybEJnUV7AysRDmkVTaB6IxVGGxjSuLv57iyvLVfD/uSlX3gk04DJht12oxtonRr37VZJBI= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.alibaba.com; spf=pass smtp.mailfrom=linux.alibaba.com; dkim=pass (1024-bit key) header.d=linux.alibaba.com header.i=@linux.alibaba.com header.b=EkE6F3Mu; arc=none smtp.client-ip=115.124.30.101 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.alibaba.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linux.alibaba.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linux.alibaba.com header.i=@linux.alibaba.com header.b="EkE6F3Mu" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.alibaba.com; s=default; t=1709020991; h=From:To:Subject:Date:Message-Id:MIME-Version; bh=VmtlNttH2hCP8SSaBmAxTigLi+f8Htbao7d6R3uMQLs=; b=EkE6F3MuYde/3Rygcc6p2AXxO0b9sKY1eepkfCme6cN3T+7HYmqX6sJ+C4JS3EOBLZ86zRNdtXI5Csb4l2szazj09lKqD472R23Ebu7IG935ZH4Ty/i4fa+9fURTcXurJw2lIl48SH4wKDASPpwFTu/4gBK0nAtquqButcECsk0= X-Alimail-AntiSpam: AC=PASS;BC=-1|-1;BR=01201311R141e4;CH=green;DM=||false|;DS=||;FP=0|-1|-1|-1|0|-1|-1|-1;HT=ay29a033018045176;MF=xuanzhuo@linux.alibaba.com;NM=1;PH=DS;RN=9;SR=0;TI=SMTPD_---0W1LxoIA_1709020989; Received: from localhost(mailfrom:xuanzhuo@linux.alibaba.com fp:SMTPD_---0W1LxoIA_1709020989) by smtp.aliyun-inc.com; Tue, 27 Feb 2024 16:03:10 +0800 From: Xuan Zhuo To: netdev@vger.kernel.org Cc: "Michael S. Tsirkin" , Jason Wang , Xuan Zhuo , "David S. Miller" , Eric Dumazet , Jakub Kicinski , Paolo Abeni , virtualization@lists.linux.dev Subject: [PATCH net-next v3 6/6] virtio_net: rename stat tx_timeout to timeout Date: Tue, 27 Feb 2024 16:03:03 +0800 Message-Id: <20240227080303.63894-7-xuanzhuo@linux.alibaba.com> X-Mailer: git-send-email 2.32.0.3.g01195cf9f In-Reply-To: <20240227080303.63894-1-xuanzhuo@linux.alibaba.com> References: <20240227080303.63894-1-xuanzhuo@linux.alibaba.com> Precedence: bulk X-Mailing-List: netdev@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-Git-Hash: cacd048f99e7 X-Patchwork-Delegate: kuba@kernel.org Now, we have this: tx_queue_0_tx_timeouts This is used to record the tx schedule timeout. But this has two "tx". I think the below is enough. tx_queue_0_timeouts So I rename this field. Signed-off-by: Xuan Zhuo Reviewed-by: Jiri Pirko --- drivers/net/virtio_net.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c index 91838d75cff2..4312850fd770 100644 --- a/drivers/net/virtio_net.c +++ b/drivers/net/virtio_net.c @@ -87,7 +87,7 @@ struct virtnet_sq_stats { u64_stats_t xdp_tx; u64_stats_t xdp_tx_drops; u64_stats_t kicks; - u64_stats_t tx_timeouts; + u64_stats_t timeouts; }; struct virtnet_rq_stats { @@ -111,7 +111,7 @@ static const struct virtnet_stat_desc virtnet_sq_stats_desc[] = { { "xdp_tx", VIRTNET_SQ_STAT(xdp_tx) }, { "xdp_tx_drops", VIRTNET_SQ_STAT(xdp_tx_drops) }, { "kicks", VIRTNET_SQ_STAT(kicks) }, - { "tx_timeouts", VIRTNET_SQ_STAT(tx_timeouts) }, + { "timeouts", VIRTNET_SQ_STAT(timeouts) }, }; static const struct virtnet_stat_desc virtnet_rq_stats_desc[] = { @@ -2760,7 +2760,7 @@ static void virtnet_stats(struct net_device *dev, start = u64_stats_fetch_begin(&sq->stats.syncp); tpackets = u64_stats_read(&sq->stats.packets); tbytes = u64_stats_read(&sq->stats.bytes); - terrors = u64_stats_read(&sq->stats.tx_timeouts); + terrors = u64_stats_read(&sq->stats.timeouts); } while (u64_stats_fetch_retry(&sq->stats.syncp, start)); do { @@ -4531,7 +4531,7 @@ static void virtnet_tx_timeout(struct net_device *dev, unsigned int txqueue) struct netdev_queue *txq = netdev_get_tx_queue(dev, txqueue); u64_stats_update_begin(&sq->stats.syncp); - u64_stats_inc(&sq->stats.tx_timeouts); + u64_stats_inc(&sq->stats.timeouts); u64_stats_update_end(&sq->stats.syncp); netdev_err(dev, "TX timeout on queue: %u, sq: %s, vq: 0x%x, name: %s, %u usecs ago\n",