Re: [PATCH net-next 4/5] virtio-net: support rx netdim

2023-11-01 Thread Jason Wang
On Wed, Nov 1, 2023 at 6:55 PM Heng Qi  wrote:
>
>
>
> 在 2023/10/25 上午11:34, Jason Wang 写道:
> > On Thu, Oct 12, 2023 at 3:44 PM Heng Qi  wrote:
> >> 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 
> >> ---
> >>   drivers/net/virtio_net.c | 147 +--
> >>   1 file changed, 126 insertions(+), 21 deletions(-)
> >>
> >> diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c
> >> index caef78bb3963..6ad2890a7909 100644
> >> --- a/drivers/net/virtio_net.c
> >> +++ b/drivers/net/virtio_net.c
> >> @@ -19,6 +19,7 @@
> >>   #include 
> >>   #include 
> >>   #include 
> >> +#include 
> >>   #include 
> >>   #include 
> >>   #include 
> >> @@ -172,6 +173,17 @@ struct receive_queue {
> >>
> >>  struct virtnet_rq_stats stats;
> >>
> >> +   /* The number of rx notifications */
> >> +   u16 calls;
> >> +
> >> +   /* Is dynamic interrupt moderation enabled? */
> >> +   bool dim_enabled;
> >> +
> >> +   /* Dynamic Interrupt Moderation */
> >> +   struct dim dim;
> >> +
> >> +   u32 packets_in_napi;
> >> +
> >>  struct virtnet_interrupt_coalesce intr_coal;
> >>
> >>  /* Chain pages by the private ptr. */
> >> @@ -305,6 +317,9 @@ struct virtnet_info {
> >>  u8 duplex;
> >>  u32 speed;
> >>
> >> +   /* Is rx 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;
> >> @@ -2001,6 +2016,7 @@ static void skb_recv_done(struct virtqueue *rvq)
> >>  struct virtnet_info *vi = rvq->vdev->priv;
> >>  struct receive_queue *rq = >rq[vq2rxq(rvq)];
> >>
> >> +   rq->calls++;
> >>  virtqueue_napi_schedule(>napi, rvq);
> >>   }
> >>
> >> @@ -2138,6 +2154,25 @@ 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 = >stats;
> >> +   struct dim_sample cur_sample = {};
> >> +
> >> +   if (!rq->packets_in_napi)
> >> +   return;
> >> +
> >> +   u64_stats_update_begin(>stats.syncp);
> >> +   dim_update_sample(rq->calls, stats->packets,
> >> + stats->bytes, _sample);
> >> +   u64_stats_update_end(>stats.syncp);
> >> +
> >> +   net_dim(>dim, cur_sample);
> >> +   rq->packets_in_napi = 0;
> >> +}
> >> +
> >>   static int virtnet_poll(struct napi_struct *napi, int budget)
> >>   {
> >>  struct receive_queue *rq =
> >> @@ -2146,17 +2181,22 @@ 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);
> >>
> >>  received = virtnet_receive(rq, budget, _xmit);
> >> +   rq->packets_in_napi += received;
> >>
> >>  if (xdp_xmit & VIRTIO_XDP_REDIR)
> >>  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 && rq->dim_enabled)
> >> +   virtnet_rx_dim_update(vi, rq);
> >> +   }
> >>
> >>  if (xdp_xmit & VIRTIO_XDP_TX) {
> >>  sq = virtnet_xdp_get_sq(vi);
> >> @@ -2176,6 +2216,7 @@ static void virtnet_disable_queue_pair(struct 
> >> virtnet_info *vi, int qp_index)
> >>  virtnet_napi_tx_disable(>sq[qp_index].napi);
> >>  napi_disable(>rq[qp_index].napi);
> >>  xdp_rxq_info_unreg(>rq[qp_index].xdp_rxq);
> >> +   cancel_work_sync(>rq[qp_index].dim.work);
> >>   }
> >>
> >>   static int virtnet_enable_queue_pair(struct virtnet_info *vi, int 
> >> qp_index)
> >> @@ -2193,6 +2234,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(>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, >rq[qp_index].napi);
> >>  virtnet_napi_tx_enable(vi, vi->sq[qp_index].vq, 
> >> >sq[qp_index].napi);
> >>
> >> @@ -3335,23 +3379,42 @@ static int virtnet_send_tx_notf_coal_cmds(struct 
> >> 

Re: [PATCH net-next 4/5] virtio-net: support rx netdim

2023-10-24 Thread Jason Wang
On Thu, Oct 12, 2023 at 3:44 PM Heng Qi  wrote:
>
> 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 
> ---
>  drivers/net/virtio_net.c | 147 +--
>  1 file changed, 126 insertions(+), 21 deletions(-)
>
> diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c
> index caef78bb3963..6ad2890a7909 100644
> --- a/drivers/net/virtio_net.c
> +++ b/drivers/net/virtio_net.c
> @@ -19,6 +19,7 @@
>  #include 
>  #include 
>  #include 
> +#include 
>  #include 
>  #include 
>  #include 
> @@ -172,6 +173,17 @@ struct receive_queue {
>
> struct virtnet_rq_stats stats;
>
> +   /* The number of rx notifications */
> +   u16 calls;
> +
> +   /* Is dynamic interrupt moderation enabled? */
> +   bool dim_enabled;
> +
> +   /* Dynamic Interrupt Moderation */
> +   struct dim dim;
> +
> +   u32 packets_in_napi;
> +
> struct virtnet_interrupt_coalesce intr_coal;
>
> /* Chain pages by the private ptr. */
> @@ -305,6 +317,9 @@ struct virtnet_info {
> u8 duplex;
> u32 speed;
>
> +   /* Is rx 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;
> @@ -2001,6 +2016,7 @@ static void skb_recv_done(struct virtqueue *rvq)
> struct virtnet_info *vi = rvq->vdev->priv;
> struct receive_queue *rq = >rq[vq2rxq(rvq)];
>
> +   rq->calls++;
> virtqueue_napi_schedule(>napi, rvq);
>  }
>
> @@ -2138,6 +2154,25 @@ 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 = >stats;
> +   struct dim_sample cur_sample = {};
> +
> +   if (!rq->packets_in_napi)
> +   return;
> +
> +   u64_stats_update_begin(>stats.syncp);
> +   dim_update_sample(rq->calls, stats->packets,
> + stats->bytes, _sample);
> +   u64_stats_update_end(>stats.syncp);
> +
> +   net_dim(>dim, cur_sample);
> +   rq->packets_in_napi = 0;
> +}
> +
>  static int virtnet_poll(struct napi_struct *napi, int budget)
>  {
> struct receive_queue *rq =
> @@ -2146,17 +2181,22 @@ 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);
>
> received = virtnet_receive(rq, budget, _xmit);
> +   rq->packets_in_napi += received;
>
> if (xdp_xmit & VIRTIO_XDP_REDIR)
> 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 && rq->dim_enabled)
> +   virtnet_rx_dim_update(vi, rq);
> +   }
>
> if (xdp_xmit & VIRTIO_XDP_TX) {
> sq = virtnet_xdp_get_sq(vi);
> @@ -2176,6 +2216,7 @@ static void virtnet_disable_queue_pair(struct 
> virtnet_info *vi, int qp_index)
> virtnet_napi_tx_disable(>sq[qp_index].napi);
> napi_disable(>rq[qp_index].napi);
> xdp_rxq_info_unreg(>rq[qp_index].xdp_rxq);
> +   cancel_work_sync(>rq[qp_index].dim.work);
>  }
>
>  static int virtnet_enable_queue_pair(struct virtnet_info *vi, int qp_index)
> @@ -2193,6 +2234,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(>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, >rq[qp_index].napi);
> virtnet_napi_tx_enable(vi, vi->sq[qp_index].vq, 
> >sq[qp_index].napi);
>
> @@ -3335,23 +3379,42 @@ 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;
> +   int i;
>
> -   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(_rx, >ctrl->coal_rx, sizeof(vi->ctrl->coal_rx));
> -
> -   if