All of lore.kernel.org
 help / color / mirror / Atom feed
* [RFC PATCH 0/6] virtio-net: support dynamic coalescing moderation
@ 2023-08-01  8:22 Heng Qi
  2023-08-01  8:22 ` [RFC PATCH 1/6] virtio-net: returns whether napi is complete Heng Qi
                   ` (5 more replies)
  0 siblings, 6 replies; 7+ messages in thread
From: Heng Qi @ 2023-08-01  8:22 UTC (permalink / raw)
  To: Michael S. Tsirkin, Jason Wang, netdev, virtualization
  Cc: David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Alexei Starovoitov, Daniel Borkmann, Jesper Dangaard Brouer,
	John Fastabend, Xuan Zhuo

Now, virtio-net already supports per-queue moderation parameter
setting. Based on this, we use the netdim library[1] of linux to support
dynamic coalescing moderation for virtio-net.

[1] https://docs.kernel.org/networking/net_dim.html

---
On top of
https://lore.kernel.org/all/20230731070656.96411-1-gavinl@nvidia.com/

Heng Qi (6):
  virtio-net: returns whether napi is complete
  virtio-net: separate rx/tx coalescing moderation cmds
  virtio-net: extract virtqueue coalescig cmd for reuse
  virtio-net: support rx netdim
  virtio-net: support tx netdim
  virtio-net: a tiny comment update

 drivers/net/virtio_net.c | 284 +++++++++++++++++++++++++++++++++------
 1 file changed, 242 insertions(+), 42 deletions(-)

-- 
2.19.1.6.gb485710b


^ permalink raw reply	[flat|nested] 7+ messages in thread

* [RFC PATCH 1/6] virtio-net: returns whether napi is complete
  2023-08-01  8:22 [RFC PATCH 0/6] virtio-net: support dynamic coalescing moderation Heng Qi
@ 2023-08-01  8:22 ` Heng Qi
  2023-08-01  8:22 ` [RFC PATCH 2/6] virtio-net: separate rx/tx coalescing moderation cmds Heng Qi
                   ` (4 subsequent siblings)
  5 siblings, 0 replies; 7+ messages in thread
From: Heng Qi @ 2023-08-01  8:22 UTC (permalink / raw)
  To: Michael S. Tsirkin, Jason Wang, netdev, virtualization
  Cc: David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Alexei Starovoitov, Daniel Borkmann, Jesper Dangaard Brouer,
	John Fastabend, Xuan Zhuo

rx netdim needs to count the traffic during a complete napi process,
and start updating and comparing samples to make decisions after
the napi ends. Let virtqueue_napi_complete() return true if napi is done,
otherwise vice versa.

Signed-off-by: Heng Qi <hengqi@linux.alibaba.com>
---
 drivers/net/virtio_net.c | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c
index 10eba113b5fa..30dd12e7d28f 100644
--- a/drivers/net/virtio_net.c
+++ b/drivers/net/virtio_net.c
@@ -407,7 +407,7 @@ static void virtqueue_napi_schedule(struct napi_struct *napi,
 	}
 }
 
-static void virtqueue_napi_complete(struct napi_struct *napi,
+static bool virtqueue_napi_complete(struct napi_struct *napi,
 				    struct virtqueue *vq, int processed)
 {
 	int opaque;
@@ -416,9 +416,13 @@ static void virtqueue_napi_complete(struct napi_struct *napi,
 	if (napi_complete_done(napi, processed)) {
 		if (unlikely(virtqueue_poll(vq, opaque)))
 			virtqueue_napi_schedule(napi, vq);
+		else
+			return true;
 	} else {
 		virtqueue_disable_cb(vq);
 	}
+
+	return false;
 }
 
 static void skb_xmit_done(struct virtqueue *vq)
-- 
2.19.1.6.gb485710b


^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [RFC PATCH 2/6] virtio-net: separate rx/tx coalescing moderation cmds
  2023-08-01  8:22 [RFC PATCH 0/6] virtio-net: support dynamic coalescing moderation Heng Qi
  2023-08-01  8:22 ` [RFC PATCH 1/6] virtio-net: returns whether napi is complete Heng Qi
@ 2023-08-01  8:22 ` Heng Qi
  2023-08-01  8:22 ` [RFC PATCH 3/6] virtio-net: extract virtqueue coalescig cmd for reuse Heng Qi
                   ` (3 subsequent siblings)
  5 siblings, 0 replies; 7+ messages in thread
From: Heng Qi @ 2023-08-01  8:22 UTC (permalink / raw)
  To: Michael S. Tsirkin, Jason Wang, netdev, virtualization
  Cc: David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Alexei Starovoitov, Daniel Borkmann, Jesper Dangaard Brouer,
	John Fastabend, Xuan Zhuo

This patch separates the rx and tx global coalescing moderation
commands to support netdim switches in subsequent patches.

Signed-off-by: Heng Qi <hengqi@linux.alibaba.com>
---
 drivers/net/virtio_net.c | 30 +++++++++++++++++++++++++++---
 1 file changed, 27 insertions(+), 3 deletions(-)

diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c
index 30dd12e7d28f..9bf39024d53d 100644
--- a/drivers/net/virtio_net.c
+++ b/drivers/net/virtio_net.c
@@ -3053,10 +3053,10 @@ static int virtnet_get_link_ksettings(struct net_device *dev,
 	return 0;
 }
 
-static int virtnet_send_notf_coal_cmds(struct virtnet_info *vi,
-				       struct ethtool_coalesce *ec)
+static int virtnet_send_tx_notf_coal_cmds(struct virtnet_info *vi,
+					  struct ethtool_coalesce *ec)
 {
-	struct scatterlist sgs_tx, sgs_rx;
+	struct scatterlist sgs_tx;
 
 	vi->ctrl->coal_tx.tx_usecs = cpu_to_le32(ec->tx_coalesce_usecs);
 	vi->ctrl->coal_tx.tx_max_packets = cpu_to_le32(ec->tx_max_coalesced_frames);
@@ -3071,6 +3071,14 @@ static int virtnet_send_notf_coal_cmds(struct virtnet_info *vi,
 	vi->intr_coal_tx.max_usecs = ec->tx_coalesce_usecs;
 	vi->intr_coal_tx.max_packets = ec->tx_max_coalesced_frames;
 
+	return 0;
+}
+
+static int virtnet_send_rx_notf_coal_cmds(struct virtnet_info *vi,
+					  struct ethtool_coalesce *ec)
+{
+	struct scatterlist sgs_rx;
+
 	vi->ctrl->coal_rx.rx_usecs = cpu_to_le32(ec->rx_coalesce_usecs);
 	vi->ctrl->coal_rx.rx_max_packets = cpu_to_le32(ec->rx_max_coalesced_frames);
 	sg_init_one(&sgs_rx, &vi->ctrl->coal_rx, sizeof(vi->ctrl->coal_rx));
@@ -3087,6 +3095,22 @@ static int virtnet_send_notf_coal_cmds(struct virtnet_info *vi,
 	return 0;
 }
 
+static int virtnet_send_notf_coal_cmds(struct virtnet_info *vi,
+				       struct ethtool_coalesce *ec)
+{
+	int err;
+
+	err = virtnet_send_tx_notf_coal_cmds(vi, ec);
+	if (err)
+		return err;
+
+	err = virtnet_send_rx_notf_coal_cmds(vi, ec);
+	if (err)
+		return err;
+
+	return 0;
+}
+
 static int virtnet_send_ctrl_coal_vq_cmd(struct virtnet_info *vi,
 					 u16 vqn, u32 max_usecs, u32 max_packets)
 {
-- 
2.19.1.6.gb485710b


^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [RFC PATCH 3/6] virtio-net: extract virtqueue coalescig cmd for reuse
  2023-08-01  8:22 [RFC PATCH 0/6] virtio-net: support dynamic coalescing moderation Heng Qi
  2023-08-01  8:22 ` [RFC PATCH 1/6] virtio-net: returns whether napi is complete Heng Qi
  2023-08-01  8:22 ` [RFC PATCH 2/6] virtio-net: separate rx/tx coalescing moderation cmds Heng Qi
@ 2023-08-01  8:22 ` Heng Qi
  2023-08-01  8:22 ` [RFC PATCH 4/6] virtio-net: support rx netdim Heng Qi
                   ` (2 subsequent siblings)
  5 siblings, 0 replies; 7+ messages in thread
From: Heng Qi @ 2023-08-01  8:22 UTC (permalink / raw)
  To: Michael S. Tsirkin, Jason Wang, netdev, virtualization
  Cc: David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Alexei Starovoitov, Daniel Borkmann, Jesper Dangaard Brouer,
	John Fastabend, Xuan Zhuo

Extract commands to set virtqueue coalescing parameters for reuse
by ethtool -Q and netdim.

Signed-off-by: Heng Qi <hengqi@linux.alibaba.com>
---
 drivers/net/virtio_net.c | 54 +++++++++++++++++++++++++++++++---------
 1 file changed, 42 insertions(+), 12 deletions(-)

diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c
index 9bf39024d53d..91b284567c96 100644
--- a/drivers/net/virtio_net.c
+++ b/drivers/net/virtio_net.c
@@ -3129,6 +3129,42 @@ static int virtnet_send_ctrl_coal_vq_cmd(struct virtnet_info *vi,
 	return 0;
 }
 
+static int virtnet_send_tx_notf_coal_vq_cmd(struct virtnet_info *vi,
+					    u16 queue, u32 max_usecs,
+					    u32 max_packets)
+{
+	int err;
+
+	err = virtnet_send_ctrl_coal_vq_cmd(vi, txq2vq(queue),
+					    max_usecs, max_packets);
+	if (err)
+		return err;
+
+	/* Save parameters */
+	vi->sq[queue].intr_coal.max_usecs = max_usecs;
+	vi->sq[queue].intr_coal.max_packets = max_packets;
+
+	return 0;
+}
+
+static int virtnet_send_rx_notf_coal_vq_cmd(struct virtnet_info *vi,
+					    u16 queue, u32 max_usecs,
+					    u32 max_packets)
+{
+	int err;
+
+	err = virtnet_send_ctrl_coal_vq_cmd(vi, rxq2vq(queue),
+					    max_usecs, max_packets);
+	if (err)
+		return err;
+
+	/* Save parameters */
+	vi->rq[queue].intr_coal.max_usecs = max_usecs;
+	vi->rq[queue].intr_coal.max_packets = max_packets;
+
+	return 0;
+}
+
 static int virtnet_send_notf_coal_vq_cmds(struct virtnet_info *vi,
 					  struct ethtool_coalesce *ec,
 					  u16 queue)
@@ -3136,25 +3172,19 @@ static int virtnet_send_notf_coal_vq_cmds(struct virtnet_info *vi,
 	int err;
 
 	if (ec->rx_coalesce_usecs || ec->rx_max_coalesced_frames) {
-		err = virtnet_send_ctrl_coal_vq_cmd(vi, rxq2vq(queue),
-						    ec->rx_coalesce_usecs,
-						    ec->rx_max_coalesced_frames);
+		err = virtnet_send_rx_notf_coal_vq_cmd(vi, queue,
+						       ec->rx_coalesce_usecs,
+						       ec->rx_max_coalesced_frames);
 		if (err)
 			return err;
-		/* Save parameters */
-		vi->rq[queue].intr_coal.max_usecs = ec->rx_coalesce_usecs;
-		vi->rq[queue].intr_coal.max_packets = ec->rx_max_coalesced_frames;
 	}
 
 	if (ec->tx_coalesce_usecs || ec->tx_max_coalesced_frames) {
-		err = virtnet_send_ctrl_coal_vq_cmd(vi, txq2vq(queue),
-						    ec->tx_coalesce_usecs,
-						    ec->tx_max_coalesced_frames);
+		err = virtnet_send_tx_notf_coal_vq_cmd(vi, queue,
+						       ec->tx_coalesce_usecs,
+						       ec->tx_max_coalesced_frames);
 		if (err)
 			return err;
-		/* Save parameters */
-		vi->sq[queue].intr_coal.max_usecs = ec->tx_coalesce_usecs;
-		vi->sq[queue].intr_coal.max_packets = ec->tx_max_coalesced_frames;
 	}
 
 	return 0;
-- 
2.19.1.6.gb485710b


^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [RFC PATCH 4/6] virtio-net: support rx netdim
  2023-08-01  8:22 [RFC PATCH 0/6] virtio-net: support dynamic coalescing moderation Heng Qi
                   ` (2 preceding siblings ...)
  2023-08-01  8:22 ` [RFC PATCH 3/6] virtio-net: extract virtqueue coalescig cmd for reuse Heng Qi
@ 2023-08-01  8:22 ` Heng Qi
  2023-08-01  8:22 ` [RFC PATCH 5/6] virtio-net: support tx netdim Heng Qi
  2023-08-01  8:22 ` [RFC PATCH 6/6] virtio-net: a tiny comment update Heng Qi
  5 siblings, 0 replies; 7+ messages in thread
From: Heng Qi @ 2023-08-01  8:22 UTC (permalink / raw)
  To: Michael S. Tsirkin, Jason Wang, netdev, virtualization
  Cc: David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Alexei Starovoitov, Daniel Borkmann, Jesper Dangaard Brouer,
	John Fastabend, Xuan Zhuo

By comparing the traffic information in the complete napi processes,
let the virtio-net driver automatically adjust the coalescing
moderation parameters of each receive queue.

Signed-off-by: Heng Qi <hengqi@linux.alibaba.com>
---
 drivers/net/virtio_net.c | 97 ++++++++++++++++++++++++++++++++++------
 1 file changed, 84 insertions(+), 13 deletions(-)

diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c
index 91b284567c96..069e68a52598 100644
--- a/drivers/net/virtio_net.c
+++ b/drivers/net/virtio_net.c
@@ -19,6 +19,7 @@
 #include <linux/average.h>
 #include <linux/filter.h>
 #include <linux/kernel.h>
+#include <linux/dim.h>
 #include <net/route.h>
 #include <net/xdp.h>
 #include <net/net_failover.h>
@@ -163,8 +164,14 @@ struct receive_queue {
 
 	struct virtnet_rq_stats stats;
 
+	/* The number of rx notifications */
+	u16 calls;
+
 	struct virtnet_interrupt_coalesce intr_coal;
 
+	/* Dynamic Iterrupt Moderation */
+	struct dim dim;
+
 	/* Chain pages by the private ptr. */
 	struct page *pages;
 
@@ -290,6 +297,9 @@ struct virtnet_info {
 	u8 duplex;
 	u32 speed;
 
+	/* Is dynamic interrupt moderation enabled? */
+	bool rx_dim_enabled;
+
 	/* Interrupt coalescing settings */
 	struct virtnet_interrupt_coalesce intr_coal_tx;
 	struct virtnet_interrupt_coalesce intr_coal_rx;
@@ -1821,6 +1831,7 @@ static void skb_recv_done(struct virtqueue *rvq)
 	struct virtnet_info *vi = rvq->vdev->priv;
 	struct receive_queue *rq = &vi->rq[vq2rxq(rvq)];
 
+	rq->calls++;
 	virtqueue_napi_schedule(&rq->napi, rvq);
 }
 
@@ -1958,6 +1969,21 @@ static void virtnet_poll_cleantx(struct receive_queue *rq)
 	}
 }
 
+static void virtnet_rx_dim_work(struct work_struct *work);
+
+static void virtnet_rx_dim_update(struct virtnet_info *vi, struct receive_queue *rq)
+{
+	struct virtnet_rq_stats *stats = &rq->stats;
+	struct dim_sample cur_sample = {};
+
+	u64_stats_update_begin(&rq->stats.syncp);
+	dim_update_sample(rq->calls, stats->packets,
+			  stats->bytes, &cur_sample);
+	u64_stats_update_end(&rq->stats.syncp);
+
+	net_dim(&rq->dim, cur_sample);
+}
+
 static int virtnet_poll(struct napi_struct *napi, int budget)
 {
 	struct receive_queue *rq =
@@ -1966,6 +1992,7 @@ static int virtnet_poll(struct napi_struct *napi, int budget)
 	struct send_queue *sq;
 	unsigned int received;
 	unsigned int xdp_xmit = 0;
+	bool napi_complete;
 
 	virtnet_poll_cleantx(rq);
 
@@ -1975,8 +2002,11 @@ static int virtnet_poll(struct napi_struct *napi, int budget)
 		xdp_do_flush();
 
 	/* Out of packets? */
-	if (received < budget)
-		virtqueue_napi_complete(napi, rq->vq, received);
+	if (received < budget) {
+		napi_complete = virtqueue_napi_complete(napi, rq->vq, received);
+		if (napi_complete && vi->rx_dim_enabled)
+			virtnet_rx_dim_update(vi, rq);
+	}
 
 	if (xdp_xmit & VIRTIO_XDP_TX) {
 		sq = virtnet_xdp_get_sq(vi);
@@ -1996,6 +2026,7 @@ static void virtnet_disable_queue_pair(struct virtnet_info *vi, int qp_index)
 	virtnet_napi_tx_disable(&vi->sq[qp_index].napi);
 	napi_disable(&vi->rq[qp_index].napi);
 	xdp_rxq_info_unreg(&vi->rq[qp_index].xdp_rxq);
+	cancel_work_sync(&vi->rq[qp_index].dim.work);
 }
 
 static int virtnet_enable_queue_pair(struct virtnet_info *vi, int qp_index)
@@ -2013,6 +2044,9 @@ static int virtnet_enable_queue_pair(struct virtnet_info *vi, int qp_index)
 	if (err < 0)
 		goto err_xdp_reg_mem_model;
 
+	INIT_WORK(&vi->rq[qp_index].dim.work, virtnet_rx_dim_work);
+	vi->rq[qp_index].dim.mode = DIM_CQ_PERIOD_MODE_START_FROM_EQE;
+
 	virtnet_napi_enable(vi->rq[qp_index].vq, &vi->rq[qp_index].napi);
 	virtnet_napi_tx_enable(vi, vi->sq[qp_index].vq, &vi->sq[qp_index].napi);
 
@@ -3077,20 +3111,33 @@ static int virtnet_send_tx_notf_coal_cmds(struct virtnet_info *vi,
 static int virtnet_send_rx_notf_coal_cmds(struct virtnet_info *vi,
 					  struct ethtool_coalesce *ec)
 {
+	bool rx_ctrl_dim_on = !!ec->use_adaptive_rx_coalesce;
 	struct scatterlist sgs_rx;
 
-	vi->ctrl->coal_rx.rx_usecs = cpu_to_le32(ec->rx_coalesce_usecs);
-	vi->ctrl->coal_rx.rx_max_packets = cpu_to_le32(ec->rx_max_coalesced_frames);
-	sg_init_one(&sgs_rx, &vi->ctrl->coal_rx, sizeof(vi->ctrl->coal_rx));
-
-	if (!virtnet_send_command(vi, VIRTIO_NET_CTRL_NOTF_COAL,
-				  VIRTIO_NET_CTRL_NOTF_COAL_RX_SET,
-				  &sgs_rx))
+	if (rx_ctrl_dim_on && (ec->rx_coalesce_usecs != vi->intr_coal_rx.max_usecs ||
+			       ec->rx_max_coalesced_frames != vi->intr_coal_rx.max_packets))
 		return -EINVAL;
 
-	/* Save parameters */
-	vi->intr_coal_rx.max_usecs = ec->rx_coalesce_usecs;
-	vi->intr_coal_rx.max_packets = ec->rx_max_coalesced_frames;
+	if (rx_ctrl_dim_on) {
+		if (virtio_has_feature(vi->vdev, VIRTIO_NET_F_VQ_NOTF_COAL))
+			vi->rx_dim_enabled = true;
+		else
+			return -EOPNOTSUPP;
+	}  else if (!rx_ctrl_dim_on) {
+		vi->rx_dim_enabled = false;
+		vi->ctrl->coal_rx.rx_usecs = cpu_to_le32(ec->rx_coalesce_usecs);
+		vi->ctrl->coal_rx.rx_max_packets = cpu_to_le32(ec->rx_max_coalesced_frames);
+		sg_init_one(&sgs_rx, &vi->ctrl->coal_rx, sizeof(vi->ctrl->coal_rx));
+
+		if (!virtnet_send_command(vi, VIRTIO_NET_CTRL_NOTF_COAL,
+					  VIRTIO_NET_CTRL_NOTF_COAL_RX_SET,
+					  &sgs_rx))
+			return -EINVAL;
+
+		/* Save parameters */
+		vi->intr_coal_rx.max_usecs = ec->rx_coalesce_usecs;
+		vi->intr_coal_rx.max_packets = ec->rx_max_coalesced_frames;
+	}
 
 	return 0;
 }
@@ -3172,6 +3219,9 @@ static int virtnet_send_notf_coal_vq_cmds(struct virtnet_info *vi,
 	int err;
 
 	if (ec->rx_coalesce_usecs || ec->rx_max_coalesced_frames) {
+		if (vi->rx_dim_enabled)
+			return -EBUSY;
+
 		err = virtnet_send_rx_notf_coal_vq_cmd(vi, queue,
 						       ec->rx_coalesce_usecs,
 						       ec->rx_max_coalesced_frames);
@@ -3190,6 +3240,27 @@ static int virtnet_send_notf_coal_vq_cmds(struct virtnet_info *vi,
 	return 0;
 }
 
+static void virtnet_rx_dim_work(struct work_struct *work)
+{
+	struct dim *dim = container_of(work, struct dim, work);
+	struct receive_queue *rq = container_of(dim,
+			struct receive_queue, dim);
+	struct virtnet_info *vi = rq->vq->vdev->priv;
+	struct net_device *dev = vi->dev;
+	struct dim_cq_moder update_moder;
+	int qnum = rq - vi->rq, err;
+
+	update_moder = net_dim_get_rx_moderation(dim->mode, dim->profile_ix);
+	err = virtnet_send_rx_notf_coal_vq_cmd(vi, qnum,
+					       update_moder.usec,
+					       update_moder.pkts);
+	if (err)
+		pr_debug("%s: Failed to send dim parameters on rxq%d\n",
+				dev->name, (int)(rq - vi->rq));
+
+	dim->state = DIM_START_MEASURE;
+}
+
 static int virtnet_coal_params_supported(struct ethtool_coalesce *ec)
 {
 	/* usecs coalescing is supported only if VIRTIO_NET_F_NOTF_COAL
@@ -3453,7 +3524,7 @@ static int virtnet_set_rxnfc(struct net_device *dev, struct ethtool_rxnfc *info)
 
 static const struct ethtool_ops virtnet_ethtool_ops = {
 	.supported_coalesce_params = ETHTOOL_COALESCE_MAX_FRAMES |
-		ETHTOOL_COALESCE_USECS,
+		ETHTOOL_COALESCE_USECS | ETHTOOL_COALESCE_USE_ADAPTIVE_RX,
 	.get_drvinfo = virtnet_get_drvinfo,
 	.get_link = ethtool_op_get_link,
 	.get_ringparam = virtnet_get_ringparam,
-- 
2.19.1.6.gb485710b


^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [RFC PATCH 5/6] virtio-net: support tx netdim
  2023-08-01  8:22 [RFC PATCH 0/6] virtio-net: support dynamic coalescing moderation Heng Qi
                   ` (3 preceding siblings ...)
  2023-08-01  8:22 ` [RFC PATCH 4/6] virtio-net: support rx netdim Heng Qi
@ 2023-08-01  8:22 ` Heng Qi
  2023-08-01  8:22 ` [RFC PATCH 6/6] virtio-net: a tiny comment update Heng Qi
  5 siblings, 0 replies; 7+ messages in thread
From: Heng Qi @ 2023-08-01  8:22 UTC (permalink / raw)
  To: Michael S. Tsirkin, Jason Wang, netdev, virtualization
  Cc: David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Alexei Starovoitov, Daniel Borkmann, Jesper Dangaard Brouer,
	John Fastabend, Xuan Zhuo

Similar to rx netdim, this patch supports adaptive tx
coalescing moderation for the virtio-net driver.

Signed-off-by: Heng Qi <hengqi@linux.alibaba.com>
---
 drivers/net/virtio_net.c | 99 ++++++++++++++++++++++++++++++++++------
 1 file changed, 85 insertions(+), 14 deletions(-)

diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c
index 069e68a52598..d8e66460e37d 100644
--- a/drivers/net/virtio_net.c
+++ b/drivers/net/virtio_net.c
@@ -145,8 +145,14 @@ struct send_queue {
 
 	struct virtnet_sq_stats stats;
 
+	/* The number of tx notifications */
+	u16 calls;
+
 	struct virtnet_interrupt_coalesce intr_coal;
 
+	/* Dynamic Iterrupt Moderation */
+	struct dim dim;
+
 	struct napi_struct napi;
 
 	/* Record whether sq is in reset state. */
@@ -299,6 +305,7 @@ struct virtnet_info {
 
 	/* Is dynamic interrupt moderation enabled? */
 	bool rx_dim_enabled;
+	bool tx_dim_enabled;
 
 	/* Interrupt coalescing settings */
 	struct virtnet_interrupt_coalesce intr_coal_tx;
@@ -435,19 +442,40 @@ static bool virtqueue_napi_complete(struct napi_struct *napi,
 	return false;
 }
 
+static void virtnet_tx_dim_work(struct work_struct *work);
+
+static void virtnet_tx_dim_update(struct virtnet_info *vi, struct send_queue *sq)
+{
+	struct virtnet_sq_stats *stats = &sq->stats;
+	struct dim_sample cur_sample = {};
+
+	u64_stats_update_begin(&sq->stats.syncp);
+	dim_update_sample(sq->calls, stats->packets,
+			  stats->bytes, &cur_sample);
+	u64_stats_update_end(&sq->stats.syncp);
+
+	net_dim(&sq->dim, cur_sample);
+}
+
 static void skb_xmit_done(struct virtqueue *vq)
 {
 	struct virtnet_info *vi = vq->vdev->priv;
-	struct napi_struct *napi = &vi->sq[vq2txq(vq)].napi;
+	struct send_queue *sq = &vi->sq[vq2txq(vq)];
+	struct napi_struct *napi = &sq->napi;
+
+	sq->calls++;
 
 	/* Suppress further interrupts. */
 	virtqueue_disable_cb(vq);
 
-	if (napi->weight)
+	if (napi->weight) {
 		virtqueue_napi_schedule(napi, vq);
-	else
+	} else {
+		if (vi->tx_dim_enabled)
+			virtnet_tx_dim_update(vi, sq);
 		/* We were probably waiting for more output buffers. */
 		netif_wake_subqueue(vi->dev, vq2txq(vq));
+	}
 }
 
 #define MRG_CTX_HEADER_SHIFT 22
@@ -2027,6 +2055,7 @@ static void virtnet_disable_queue_pair(struct virtnet_info *vi, int qp_index)
 	napi_disable(&vi->rq[qp_index].napi);
 	xdp_rxq_info_unreg(&vi->rq[qp_index].xdp_rxq);
 	cancel_work_sync(&vi->rq[qp_index].dim.work);
+	cancel_work_sync(&vi->sq[qp_index].dim.work);
 }
 
 static int virtnet_enable_queue_pair(struct virtnet_info *vi, int qp_index)
@@ -2046,6 +2075,8 @@ static int virtnet_enable_queue_pair(struct virtnet_info *vi, int qp_index)
 
 	INIT_WORK(&vi->rq[qp_index].dim.work, virtnet_rx_dim_work);
 	vi->rq[qp_index].dim.mode = DIM_CQ_PERIOD_MODE_START_FROM_EQE;
+	INIT_WORK(&vi->sq[qp_index].dim.work, virtnet_tx_dim_work);
+	vi->sq[qp_index].dim.mode = DIM_CQ_PERIOD_MODE_START_FROM_EQE;
 
 	virtnet_napi_enable(vi->rq[qp_index].vq, &vi->rq[qp_index].napi);
 	virtnet_napi_tx_enable(vi, vi->sq[qp_index].vq, &vi->sq[qp_index].napi);
@@ -2126,6 +2157,9 @@ static int virtnet_poll_tx(struct napi_struct *napi, int budget)
 				__netif_tx_unlock(txq);
 				__napi_schedule(napi);
 			}
+		} else {
+			if (vi->tx_dim_enabled)
+				virtnet_tx_dim_update(vi, sq);
 		}
 	}
 
@@ -3090,20 +3124,33 @@ static int virtnet_get_link_ksettings(struct net_device *dev,
 static int virtnet_send_tx_notf_coal_cmds(struct virtnet_info *vi,
 					  struct ethtool_coalesce *ec)
 {
+	bool tx_ctrl_dim_on = !!ec->use_adaptive_tx_coalesce;
 	struct scatterlist sgs_tx;
 
-	vi->ctrl->coal_tx.tx_usecs = cpu_to_le32(ec->tx_coalesce_usecs);
-	vi->ctrl->coal_tx.tx_max_packets = cpu_to_le32(ec->tx_max_coalesced_frames);
-	sg_init_one(&sgs_tx, &vi->ctrl->coal_tx, sizeof(vi->ctrl->coal_tx));
-
-	if (!virtnet_send_command(vi, VIRTIO_NET_CTRL_NOTF_COAL,
-				  VIRTIO_NET_CTRL_NOTF_COAL_TX_SET,
-				  &sgs_tx))
+	if (tx_ctrl_dim_on && (ec->tx_coalesce_usecs != vi->intr_coal_tx.max_usecs ||
+			       ec->tx_max_coalesced_frames != vi->intr_coal_tx.max_packets))
 		return -EINVAL;
 
-	/* Save parameters */
-	vi->intr_coal_tx.max_usecs = ec->tx_coalesce_usecs;
-	vi->intr_coal_tx.max_packets = ec->tx_max_coalesced_frames;
+	if (tx_ctrl_dim_on) {
+		if (virtio_has_feature(vi->vdev, VIRTIO_NET_F_VQ_NOTF_COAL))
+			vi->tx_dim_enabled = true;
+		else
+			return -EOPNOTSUPP;
+	} else if (!tx_ctrl_dim_on) {
+		vi->tx_dim_enabled = false;
+		vi->ctrl->coal_tx.tx_usecs = cpu_to_le32(ec->tx_coalesce_usecs);
+		vi->ctrl->coal_tx.tx_max_packets = cpu_to_le32(ec->tx_max_coalesced_frames);
+		sg_init_one(&sgs_tx, &vi->ctrl->coal_tx, sizeof(vi->ctrl->coal_tx));
+
+		if (!virtnet_send_command(vi, VIRTIO_NET_CTRL_NOTF_COAL,
+					  VIRTIO_NET_CTRL_NOTF_COAL_TX_SET,
+					  &sgs_tx))
+			return -EINVAL;
+
+		/* Save parameters */
+		vi->intr_coal_tx.max_usecs = ec->tx_coalesce_usecs;
+		vi->intr_coal_tx.max_packets = ec->tx_max_coalesced_frames;
+	}
 
 	return 0;
 }
@@ -3194,6 +3241,27 @@ static int virtnet_send_tx_notf_coal_vq_cmd(struct virtnet_info *vi,
 	return 0;
 }
 
+static void virtnet_tx_dim_work(struct work_struct *work)
+{
+	struct dim *dim = container_of(work, struct dim, work);
+	struct send_queue *sq = container_of(dim,
+			struct send_queue, dim);
+	struct virtnet_info *vi = sq->vq->vdev->priv;
+	struct net_device *dev = vi->dev;
+	struct dim_cq_moder update_moder;
+	int qnum = sq - vi->sq, err;
+
+	update_moder = net_dim_get_tx_moderation(dim->mode, dim->profile_ix);
+	err = virtnet_send_tx_notf_coal_vq_cmd(vi, qnum,
+					       update_moder.usec,
+					       update_moder.pkts);
+	if (err)
+		pr_debug("%s: Failed to send dim parameters on txq%d\n",
+				dev->name, (int)(sq - vi->sq));
+
+	dim->state = DIM_START_MEASURE;
+}
+
 static int virtnet_send_rx_notf_coal_vq_cmd(struct virtnet_info *vi,
 					    u16 queue, u32 max_usecs,
 					    u32 max_packets)
@@ -3230,6 +3298,9 @@ static int virtnet_send_notf_coal_vq_cmds(struct virtnet_info *vi,
 	}
 
 	if (ec->tx_coalesce_usecs || ec->tx_max_coalesced_frames) {
+		if (vi->tx_dim_enabled)
+			return -EBUSY;
+
 		err = virtnet_send_tx_notf_coal_vq_cmd(vi, queue,
 						       ec->tx_coalesce_usecs,
 						       ec->tx_max_coalesced_frames);
@@ -3524,7 +3595,7 @@ static int virtnet_set_rxnfc(struct net_device *dev, struct ethtool_rxnfc *info)
 
 static const struct ethtool_ops virtnet_ethtool_ops = {
 	.supported_coalesce_params = ETHTOOL_COALESCE_MAX_FRAMES |
-		ETHTOOL_COALESCE_USECS | ETHTOOL_COALESCE_USE_ADAPTIVE_RX,
+		ETHTOOL_COALESCE_USECS | ETHTOOL_COALESCE_USE_ADAPTIVE,
 	.get_drvinfo = virtnet_get_drvinfo,
 	.get_link = ethtool_op_get_link,
 	.get_ringparam = virtnet_get_ringparam,
-- 
2.19.1.6.gb485710b


^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [RFC PATCH 6/6] virtio-net: a tiny comment update
  2023-08-01  8:22 [RFC PATCH 0/6] virtio-net: support dynamic coalescing moderation Heng Qi
                   ` (4 preceding siblings ...)
  2023-08-01  8:22 ` [RFC PATCH 5/6] virtio-net: support tx netdim Heng Qi
@ 2023-08-01  8:22 ` Heng Qi
  5 siblings, 0 replies; 7+ messages in thread
From: Heng Qi @ 2023-08-01  8:22 UTC (permalink / raw)
  To: Michael S. Tsirkin, Jason Wang, netdev, virtualization
  Cc: David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Alexei Starovoitov, Daniel Borkmann, Jesper Dangaard Brouer,
	John Fastabend, Xuan Zhuo

Update a comment because virtio-net now supports both
VIRTIO_NET_F_NOTF_COAL and VIRTIO_NET_F_VQ_NOTF_COAL.

Signed-off-by: Heng Qi <hengqi@linux.alibaba.com>
---
 drivers/net/virtio_net.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c
index d8e66460e37d..806a750ff515 100644
--- a/drivers/net/virtio_net.c
+++ b/drivers/net/virtio_net.c
@@ -3335,7 +3335,7 @@ static void virtnet_rx_dim_work(struct work_struct *work)
 static int virtnet_coal_params_supported(struct ethtool_coalesce *ec)
 {
 	/* usecs coalescing is supported only if VIRTIO_NET_F_NOTF_COAL
-	 * feature is negotiated.
+	 * or VIRTIO_NET_F_VQ_NOTF_COAL feature is negotiated.
 	 */
 	if (ec->rx_coalesce_usecs || ec->tx_coalesce_usecs)
 		return -EOPNOTSUPP;
-- 
2.19.1.6.gb485710b


^ permalink raw reply related	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2023-08-01  8:22 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-08-01  8:22 [RFC PATCH 0/6] virtio-net: support dynamic coalescing moderation Heng Qi
2023-08-01  8:22 ` [RFC PATCH 1/6] virtio-net: returns whether napi is complete Heng Qi
2023-08-01  8:22 ` [RFC PATCH 2/6] virtio-net: separate rx/tx coalescing moderation cmds Heng Qi
2023-08-01  8:22 ` [RFC PATCH 3/6] virtio-net: extract virtqueue coalescig cmd for reuse Heng Qi
2023-08-01  8:22 ` [RFC PATCH 4/6] virtio-net: support rx netdim Heng Qi
2023-08-01  8:22 ` [RFC PATCH 5/6] virtio-net: support tx netdim Heng Qi
2023-08-01  8:22 ` [RFC PATCH 6/6] virtio-net: a tiny comment update Heng Qi

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.