From patchwork Wed Jan 31 02:45:54 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Xuan Zhuo X-Patchwork-Id: 13538554 X-Patchwork-Delegate: kuba@kernel.org Received: from out30-99.freemail.mail.aliyun.com (out30-99.freemail.mail.aliyun.com [115.124.30.99]) (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 44B6DE544 for ; Wed, 31 Jan 2024 02:46:03 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=115.124.30.99 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1706669167; cv=none; b=SGCW2uMutBnOFMhwGw3IRB5vPsdPCm0wFsp+i5HiGI8MoGNMnCm7UhAdVYzI40cOP864HoZmVEVhKMywl0Vb0L+VBU1MKg5zHCGyRgUCtc4ZlqTpZ1qz02pH18HBWc8MuNSDvK9x7VcEPyO3lUnLdSjWXnk9O5rFAfCfe5wwhSU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1706669167; c=relaxed/simple; bh=0UKZClT7YsyI88Zs/PnvgjEeZ+uHSCbya4LzeEKCVwU=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=adNkZ4Oph5POy8lECHyoCd0/zEfxn5s02xtm1ySwEdpinDtaPVGfaKLnwgBOcJCpfS5xDPxbH19c25CgGtjWLTBkQ29/al8IDnUNPJ5HhV/xMmbQ4HVRgeXijogH0AGMqHtfrUOUHWpWYesyGTN7pJ3UioD8q6iodLs/2UgZvuM= 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=Sw0el2Ge; arc=none smtp.client-ip=115.124.30.99 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="Sw0el2Ge" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.alibaba.com; s=default; t=1706669161; h=From:To:Subject:Date:Message-Id:MIME-Version; bh=PaIsXQVxdHuV5jdj1pf9rN/0VKs9oh04cFCjiOYzzow=; b=Sw0el2Gevs+LWQqVCHXO/A4usLbjs41upv4G6SgCgW50ewmsmdy1E4/1r3BECjSRf3eRXBSdOuKBadxt1R2J1FCk6QZrwQNMlPoP7CXt609axMqYJVbjlJQlrPpSnUAQOnQSsz0BQZqXrFxjZrOveWvDUkuL9JvOBjMQ9kq+B38= X-Alimail-AntiSpam: AC=PASS;BC=-1|-1;BR=01201311R121e4;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=11;SR=0;TI=SMTPD_---0W.hnzD1_1706669160; Received: from localhost(mailfrom:xuanzhuo@linux.alibaba.com fp:SMTPD_---0W.hnzD1_1706669160) by smtp.aliyun-inc.com; Wed, 31 Jan 2024 10:46:01 +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, Zhu Yanjun , Simon Horman Subject: [PATCH net-next v2 1/6] virtio_net: introduce device stats feature and structures Date: Wed, 31 Jan 2024 10:45:54 +0800 Message-Id: <20240131024559.63572-2-xuanzhuo@linux.alibaba.com> X-Mailer: git-send-email 2.32.0.3.g01195cf9f In-Reply-To: <20240131024559.63572-1-xuanzhuo@linux.alibaba.com> References: <20240131024559.63572-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: 80d9c8e6c6fe 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 Wed Jan 31 02:45:55 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Xuan Zhuo X-Patchwork-Id: 13538555 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 310C7E572 for ; Wed, 31 Jan 2024 02:46:04 +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=1706669167; cv=none; b=J6YseqJoR+BqNY0b/Zq/NgcRx/QMCA7BlAXGgW6/L9QVYooUnLk73xGxwkzgubiouR0QY/wTTjyDyygsdIHGuZT8CYKMWQA60Yim1Ydk/gfl/X+0IvEUK6LFjdUy+sO8Qbo9qCHg8/cQRmTFfNweI+wtplwkwUDnYleji8KtG/8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1706669167; c=relaxed/simple; bh=gq1Stsbh8zjhsBrhGKod6jgA9j7lwXL6J6jlSUOBBv8=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=n/rhHloBT+hSy7iVjZOETtnmAdmChvIC0IXIU3JcpQcRah86aJdDqkBPwwi7pcWsg7PJRRSQc9hkw+HdH9RpBpnIGaYlZ9QjhpY8kGnYuJZ64Cg7jQHRPDzbgFll4JkGvV1bUY7OibfEkh8Bm5OxDlieFceQaTpmTy7mAnSQOdo= 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=G9BvgiFT; 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="G9BvgiFT" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.alibaba.com; s=default; t=1706669163; h=From:To:Subject:Date:Message-Id:MIME-Version; bh=9h91d8sar7EVVnmqdB0wQHOsQxqNZQWcUi7Hx2YCTzc=; b=G9BvgiFTMCqQe7PpVCQ8pJPyvVq8gyU4MIerrKNgsIfRaqeubwErcjcD4JQELN8r5pkTpgDQ+7ynhz//nlh59u4videIOnryYMsn9ENnOl1ciBLKaKglFzAhZw1Vgz30xfuyoMJzJbqLKKIuIijh7VNPTQ1br/pHsK/EO00Dz+o= X-Alimail-AntiSpam: AC=PASS;BC=-1|-1;BR=01201311R681e4;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=11;SR=0;TI=SMTPD_---0W.hp48D_1706669161; Received: from localhost(mailfrom:xuanzhuo@linux.alibaba.com fp:SMTPD_---0W.hp48D_1706669161) by smtp.aliyun-inc.com; Wed, 31 Jan 2024 10:46:02 +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, Zhu Yanjun , Simon Horman Subject: [PATCH net-next v2 2/6] virtio_net: virtnet_send_command supports command-specific-result Date: Wed, 31 Jan 2024 10:45:55 +0800 Message-Id: <20240131024559.63572-3-xuanzhuo@linux.alibaba.com> X-Mailer: git-send-email 2.32.0.3.g01195cf9f In-Reply-To: <20240131024559.63572-1-xuanzhuo@linux.alibaba.com> References: <20240131024559.63572-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: 80d9c8e6c6fe 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 d16f592c2061..31b9ead6260d 100644 --- a/drivers/net/virtio_net.c +++ b/drivers/net/virtio_net.c @@ -2451,10 +2451,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 */ @@ -2472,10 +2473,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); @@ -2517,7 +2521,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; @@ -2586,7 +2591,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(); } @@ -2603,7 +2608,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; @@ -2664,14 +2669,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"); @@ -2707,7 +2712,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); @@ -2723,7 +2728,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; } @@ -2738,7 +2743,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; } @@ -2956,7 +2961,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; } @@ -3274,7 +3279,7 @@ static int virtnet_send_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; /* Save parameters */ @@ -3291,7 +3296,7 @@ static int virtnet_send_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; /* Save parameters */ @@ -3317,7 +3322,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; @@ -3687,7 +3692,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; } @@ -4619,7 +4625,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 Wed Jan 31 02:45:56 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Xuan Zhuo X-Patchwork-Id: 13538556 X-Patchwork-Delegate: kuba@kernel.org Received: from out30-113.freemail.mail.aliyun.com (out30-113.freemail.mail.aliyun.com [115.124.30.113]) (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 362BDEAD3 for ; Wed, 31 Jan 2024 02:46:05 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=115.124.30.113 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1706669168; cv=none; b=u4pBxG415nra42C137e+kSdRPKCddrluqnOf2nWBilztTmeCcW0b0Q3imPQGKVezXejON6QoMqG4CEmFw0lkCwo9vCof1tH8oXG+ogWtHWKf9F8XuGZpajVHgK2qxfDPUG55liI2W9o32ncbXwYGJRLFs1I4XitKgGo+exsxwuA= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1706669168; c=relaxed/simple; bh=X8XQlf9658faWInwG0yECQKW492mEnB97ptQyvuoTYk=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=Zuv/uCtXYfHXSGhp6zJwdWCcHU/2tSn/7kqeNr3r35S36XUvJL+MJfjXI48KiQB88xIq2tOv0+t/wK9eIr+WoJSDRSKqTlmlhQ+dmW4d8FtjSYljrnpwU/6zrBKB+YkAsgSPG1WdHz1yzw6uJS8Tpcn5H5Tf6L4d8VCIrGm19+g= 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=g46iVPGA; arc=none smtp.client-ip=115.124.30.113 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="g46iVPGA" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.alibaba.com; s=default; t=1706669164; h=From:To:Subject:Date:Message-Id:MIME-Version; bh=dKdwOnV6W3ffLFWXSKPAY4DOkZBHHUwuzZWZ76ZtDxU=; b=g46iVPGAMckmsQdjClIr0npKpGULX3p30DG7s2g35M+f1YNKNRRGqphTjaW0unuTM6Enb96SaXDt/JZy2aEM3aaFBM9DvpHsO+TxDcDCJbYDcX8PMzgIgAQ6orOQEX1eqfNZEZ0WzQNu8pnA9Tfgf2+U8dBdX+Nzh2q/wtrkDc0= X-Alimail-AntiSpam: AC=PASS;BC=-1|-1;BR=01201311R151e4;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=11;SR=0;TI=SMTPD_---0W.hp48j_1706669162; Received: from localhost(mailfrom:xuanzhuo@linux.alibaba.com fp:SMTPD_---0W.hp48j_1706669162) by smtp.aliyun-inc.com; Wed, 31 Jan 2024 10:46:03 +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, Zhu Yanjun , Simon Horman Subject: [PATCH net-next v2 3/6] virtio_net: support device stats Date: Wed, 31 Jan 2024 10:45:56 +0800 Message-Id: <20240131024559.63572-4-xuanzhuo@linux.alibaba.com> X-Mailer: git-send-email 2.32.0.3.g01195cf9f In-Reply-To: <20240131024559.63572-1-xuanzhuo@linux.alibaba.com> References: <20240131024559.63572-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: 80d9c8e6c6fe 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 31b9ead6260d..b3364e169c76 100644 --- a/drivers/net/virtio_net.c +++ b/drivers/net/virtio_net.c @@ -127,6 +127,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; @@ -232,6 +347,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 { @@ -314,6 +430,8 @@ struct virtnet_info { /* failover when STANDBY feature enabled */ struct failover *failover; + + u64 device_stats_cap; }; struct padded_vnet_hdr { @@ -3157,6 +3275,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); @@ -3165,16 +3481,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; } @@ -3183,11 +3505,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; } @@ -3197,11 +3543,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]; @@ -3215,6 +3567,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++) { @@ -3230,6 +3583,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; } } @@ -4760,7 +5114,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 Wed Jan 31 02:45:57 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Xuan Zhuo X-Patchwork-Id: 13538557 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 569F8EAEB for ; Wed, 31 Jan 2024 02:46:06 +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=1706669169; cv=none; b=kX1SuKzgc/1TiFg/BxqpXzQeiSnur9lasvXUGgOImSWcnlCKhBHlbBYPfZM+sVruLp2Sw/WtoeAug3ovvCfBjqw5YDG4Y0Gzx3qfM9Fd4SvEDsSQNiCMHsSml7KORoBCEZFBjtFUnSg9xoRLNG+YPIywnYCPNDcWuYDUICddBZU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1706669169; c=relaxed/simple; bh=UXyHehTIvaxxWMN+irsBnTSA5PPC6A3k7cYm8B6O1sw=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=D4zoAdG+m+1s/jFDtR/1cnp9Ee3DFdcLCqaVPyusW3SW4YdUuF0G1qigjuAPoXjv4DBN2cUnJHbOidKOkFFCWWwsXWbG4mMjmQ9B0/Ks1U3Kke8LQ29QqtZgnQO8cJXTIqVXystBJVmXOpXeKc5Yfzjryk7jlSt1uaPE7LrHr9A= 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=TuavNBlU; 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="TuavNBlU" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.alibaba.com; s=default; t=1706669165; h=From:To:Subject:Date:Message-Id:MIME-Version; bh=3R9RPJKgQhb09UWNeQFIWprKi+ONoy7mN8dEfYhxImM=; b=TuavNBlUygXgRA4eXcAAmj5/55XueBR/pzZqJsnY59fHxJLf2FHUm4JFPbB0kkmH08fqBG5vxLJcUh7tzRZYDI+86Sv63eB1F17NyROIFiDnYMc8ORW3Id2SZ30Rd0mzDZ6+p91eva0KrfYc4gPfoSpEdEuoXhazWU29OSCDw0A= X-Alimail-AntiSpam: AC=PASS;BC=-1|-1;BR=01201311R481e4;CH=green;DM=||false|;DS=||;FP=0|-1|-1|-1|0|-1|-1|-1;HT=ay29a033018046059;MF=xuanzhuo@linux.alibaba.com;NM=1;PH=DS;RN=11;SR=0;TI=SMTPD_---0W.hoKJ7_1706669164; Received: from localhost(mailfrom:xuanzhuo@linux.alibaba.com fp:SMTPD_---0W.hoKJ7_1706669164) by smtp.aliyun-inc.com; Wed, 31 Jan 2024 10:46:04 +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, Zhu Yanjun , Simon Horman Subject: [PATCH net-next v2 4/6] virtio_net: stats map include driver stats Date: Wed, 31 Jan 2024 10:45:57 +0800 Message-Id: <20240131024559.63572-5-xuanzhuo@linux.alibaba.com> X-Mailer: git-send-email 2.32.0.3.g01195cf9f In-Reply-To: <20240131024559.63572-1-xuanzhuo@linux.alibaba.com> References: <20240131024559.63572-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: 80d9c8e6c6fe 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 b3364e169c76..595ed549eb61 100644 --- a/drivers/net/virtio_net.c +++ b/drivers/net/virtio_net.c @@ -124,9 +124,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)} @@ -197,10 +194,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 */ @@ -211,9 +208,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; }; @@ -225,10 +224,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), @@ -242,6 +255,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; @@ -2214,7 +2232,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; @@ -3275,33 +3293,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); } } @@ -3336,7 +3357,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; @@ -3358,19 +3379,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; @@ -3430,43 +3498,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); @@ -3476,28 +3511,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; } } @@ -3530,8 +3555,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: @@ -3544,46 +3568,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 Wed Jan 31 02:45: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: 13538558 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 69BC711196 for ; Wed, 31 Jan 2024 02:46:08 +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=1706669170; cv=none; b=hPm097zLgNTYNYmkrPbHhVQCg7J3SJBDagIG9MEhwkfpmv5CY3KxBEWmdOdeaa2rdGAupys5cTfLn5QNNpLsEDMDJ8l1SjdR4QvEy2QBKm89D2y8Oe0h71imXAnKJPtc7UKoOuXJBZ9FYGdBtgTegnOEJNYqqmZ85i6u2VR+m20= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1706669170; c=relaxed/simple; bh=31ucLxedTncSKURQU5yTXv4USdImcqo5z+WjoE30vJo=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=GFEkEK/c2bJ/xX7/rOWc1S1gO0epdRiMRrW79+kP9CJIT6dhHDxmzoPA2wG0Ni6wbeCslaBPJfkoVuxilrXpCtRoOop9TZ9TpR9Jg8PbcxoX6Hxv51/UsynsGVIgL13OksOrfeQh3NitYd6519fw39RQjQLjSQMImGG6qSkMVtM= 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=RrF/Vhls; 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="RrF/Vhls" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.alibaba.com; s=default; t=1706669166; h=From:To:Subject:Date:Message-Id:MIME-Version; bh=jDdO8oZFCE5PWwkmwk4zd2Z+17t2B6hmxDKLhvo8YGQ=; b=RrF/VhlswGS9Us65BDnKbY9NxuUrL1Q6O+wswiPSFEOHeFRvtc2exrY/3/jd2eCCEWYPBdvOw1nyjZIqurKGzUXx8Irh8X41Wqu4rCvqC17JRA3LIr4P9U7J/CMsZbtSvzEKA2TWFEcfkO4lJGlXmgdXASZZ6FvhSq6MSt/rG2c= X-Alimail-AntiSpam: AC=PASS;BC=-1|-1;BR=01201311R421e4;CH=green;DM=||false|;DS=||;FP=0|-1|-1|-1|0|-1|-1|-1;HT=ay29a033018046056;MF=xuanzhuo@linux.alibaba.com;NM=1;PH=DS;RN=11;SR=0;TI=SMTPD_---0W.hp49c_1706669165; Received: from localhost(mailfrom:xuanzhuo@linux.alibaba.com fp:SMTPD_---0W.hp49c_1706669165) by smtp.aliyun-inc.com; Wed, 31 Jan 2024 10:46: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, Zhu Yanjun , Simon Horman Subject: [PATCH net-next v2 5/6] virtio_net: add the total stats field Date: Wed, 31 Jan 2024 10:45:58 +0800 Message-Id: <20240131024559.63572-6-xuanzhuo@linux.alibaba.com> X-Mailer: git-send-email 2.32.0.3.g01195cf9f In-Reply-To: <20240131024559.63572-1-xuanzhuo@linux.alibaba.com> References: <20240131024559.63572-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: 80d9c8e6c6fe 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 595ed549eb61..ec141723f210 100644 --- a/drivers/net/virtio_net.c +++ b/drivers/net/virtio_net.c @@ -3293,6 +3293,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; @@ -3315,14 +3316,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); + } } } @@ -3379,6 +3389,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) @@ -3390,14 +3432,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; } @@ -3516,6 +3561,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) @@ -3557,7 +3605,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; } @@ -3590,6 +3638,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 Wed Jan 31 02:45: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: 13538559 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 6938B16416 for ; Wed, 31 Jan 2024 02:46:08 +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=1706669171; cv=none; b=qreeOUP5YDDdf15SjUHeNMfPjcJ4CVwFC56yoSXJ7ennXSQL8G7HtJIiTAKZMqoIGg2icf+WONnej/UZ6ric/lYzKHGKajWhbInH79TfzSwNnTPs6B4dekaiCyWP3HDQ/RcsEf1TGgZgM/ehq33/zOQq3f2K1s8nZNRNrw9vZu8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1706669171; c=relaxed/simple; bh=UNnK5rgFNfmEM7xUt00KXacyTD3XvrUIcFBpL7JzKXM=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=j9e8PvRCfm3zBw4fTcdapYA6XeuD1yOWUfhWSamqYH0r7UvWevyfK1WOtPIIKREpTFoIeu22S2T6WA9md77ZAbiGDR3nmMcjqCZbT1sUGpzO77jmpXEy1OO63Qr4XKk61+rGPbfRO8rG8bpIKuBFPIqk6XJieYOxmcESfGxOfK8= 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=CXpTeGLV; 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="CXpTeGLV" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.alibaba.com; s=default; t=1706669167; h=From:To:Subject:Date:Message-Id:MIME-Version; bh=8X80Bewe/lSupqvIvqUpTDdThF9X+KNNlM6GKT3BwAY=; b=CXpTeGLVnaRtCdOJgnrttKydHWuLDv5lUbgOhYhQp57aIUbniEUCWfFmU3HTQPVloobFjhER3LPgYvAugu8fddALwPAGdDJkx+evLqlX1lW0TEAxDRJbk0PZa0h6JTU5ULCoo8D5QpjvnqoPhk15QGiI8JnuYnLIRRSs7p5NWGg= X-Alimail-AntiSpam: AC=PASS;BC=-1|-1;BR=01201311R421e4;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=11;SR=0;TI=SMTPD_---0W.hp4A3_1706669166; Received: from localhost(mailfrom:xuanzhuo@linux.alibaba.com fp:SMTPD_---0W.hp4A3_1706669166) by smtp.aliyun-inc.com; Wed, 31 Jan 2024 10:46: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, Zhu Yanjun , Simon Horman Subject: [PATCH net-next v2 6/6] virtio_net: rename stat tx_timeout to timeout Date: Wed, 31 Jan 2024 10:45:59 +0800 Message-Id: <20240131024559.63572-7-xuanzhuo@linux.alibaba.com> X-Mailer: git-send-email 2.32.0.3.g01195cf9f In-Reply-To: <20240131024559.63572-1-xuanzhuo@linux.alibaba.com> References: <20240131024559.63572-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: 80d9c8e6c6fe 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 --- 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 ec141723f210..c6cce66c642a 100644 --- a/drivers/net/virtio_net.c +++ b/drivers/net/virtio_net.c @@ -86,7 +86,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 { @@ -110,7 +110,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[] = { @@ -2699,7 +2699,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 { @@ -4319,7 +4319,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",