From: "Michael S. Tsirkin" <mst@redhat.com>
To: Jason Wang <jasowang@redhat.com>
Cc: Heng Qi <hengqi@linux.alibaba.com>,
virtio-comment@lists.oasis-open.org,
Yuri Benditovich <yuri.benditovich@daynix.com>,
Xuan Zhuo <xuanzhuo@linux.alibaba.com>,
Alvaro Karsz <alvaro.karsz@solid-run.com>,
Parav Pandit <parav@nvidia.com>
Subject: Re: [virtio-comment] Re: [PATCH RESEND] virtio-net: support setting coalescing params for multiple vqs
Date: Tue, 26 Dec 2023 04:18:17 -0500 [thread overview]
Message-ID: <20231226040940-mutt-send-email-mst@kernel.org> (raw)
In-Reply-To: <CACGkMEtCtFvY0rMO0nvpBRL6qQa94jZRJC66YTyRHDoDbSgJ_g@mail.gmail.com>
On Tue, Dec 26, 2023 at 11:32:12AM +0800, Jason Wang wrote:
> On Fri, Dec 22, 2023 at 2:45 PM Heng Qi <hengqi@linux.alibaba.com> wrote:
> >
> >
> >
> > 在 2023/12/22 上午10:40, Jason Wang 写道:
> > > On Thu, Dec 21, 2023 at 12:55 PM Heng Qi <hengqi@linux.alibaba.com> wrote:
> > >>
> > >>
> > >> 在 2023/12/21 上午11:37, Jason Wang 写道:
> > >>> On Wed, Dec 20, 2023 at 10:40 PM Heng Qi <hengqi@linux.alibaba.com> wrote:
> > >>>> Currently, when each time the driver attempts to update the coalescing parameters
> > >>>> for a vq, it needs to kick the device and wait for the ctrlq response to return.
> > >>>>
> > >>>> If a command can only update one vq parameters, when the parameters are updated
> > >>>> frequently (such as netdim), ctrlq on the device is kicked frequently, which will
> > >>>> increase the device CPU scheduling overhead, and the number and overhead of device
> > >>>> DMA will also increase.
> > >>>>
> > >>>> Merging multiple vq updated parameters into one command can effectively reduce
> > >>>> the number of kick devices and device DMA times.
> > >>>>
> > >>>> Test results show that this greatly improves the efficiency of the ctrlq in
> > >>>> responding to multiple vq coalescing parameter updates issued by the driver.
> > >>> So netdim is per virtqueue, to make use of this, you need to batch the
> > >>> netdim requests first.
> > >> Yes. I think the code looks more intuitive.
> > >> Please view the following PoC test code combined with the current code
> > >> of upstream virtio netdim
> > >>
> > >> +struct ctrl_coal_vq_entry {
> > >> + u16 vqn;
> > >> + u16 reserved;
> > >> + int usecs;
> > >> + int packets;
> > >> +};
> > >> +
> > >> +struct virtio_net_ctrl_mrg_coal_vq {
> > >> + int num_entries;
> > >> + struct ctrl_coal_vq_entry coal_vqs[];
> > >> +};
> > >> +
> > >>
> > >> @@ -313,12 +335,18 @@ struct virtnet_info {
> > >>
> > >> struct control_buf *ctrl;
> > >>
> > >> + struct virtio_net_ctrl_mrg_coal_vq *ctrl_coal_vqs;
> > >> +
> > >>
> > >>
> > >> @@ -4390,6 +4586,7 @@ static int virtnet_alloc_queues(struct
> > >> virtnet_info *vi)
> > >> if (!vi->rq)
> > >> goto err_rq;
> > >>
> > >> + vi->ctrl_coal_vqs = kzalloc(sizeof(struct
> > >> virtio_net_ctrl_mrg_coal_vq) + vi->max_queue_pairs * sizeof(struct
> > >> ctrl_coal_vq_entry), GFP_KERNEL);
> > >>
> > >>
> > >> + struct scatterlist sg;
> > >> + for (i = 0; i < vi->curr_queue_pairs; i++) {
> > >> + vi->ctrl_coal_vqs->coal_vqs[i].vqn = rxq2vq(i);
> > >> + vi->ctrl_coal_vqs->coal_vqs[i].usecs = 8;
> > >> + vi->ctrl_coal_vqs->coal_vqs[i].packets = 16;
> > >> + }
> > >> + vi->ctrl_coal_vqs->num_entries = i;
> > >> + sg_init_one(&sg, vi->ctrl_coal_vqs, sizeof(struct
> > >> virtio_net_ctrl_mrg_coal_vq) + vi->ctrl_coal_vqs->num_entries *
> > >> sizeof(struct ctrl_coal_vq_entry));
> > >> + vi->req_num++;
> > >> + if (!virtnet_send_command(vi, VIRTIO_NET_CTRL_NOTF_COAL,
> > >> + VIRTIO_NET_CTRL_NOTF_COAL_*VQS*_SET, &sg))
> > >>
> > >> #define VIRTIO_NET_CTRL_NOTF_COAL_VQ_GET 3
> > >> +#define VIRTIO_NET_CTRL_NOTF_COAL_VQS_SET 4
> > >>
> > >>> And if you do that, you can batch the commands
> > >>> as well.
> > >>
> > >> Batch commands we have tried:
> > >>
> > >> + for (i = 0; i < vi->curr_queue_pairs; i++) {
> > >> + err = virtnet_pre_send_cmd(vi, &vi->vq_ctrls[i],
> > >> 8, 16);
> > >> + }
> > >> +
> > >> + if (unlikely(!virtqueue_kick(vi->cvq)))
> > >> + return vi->ctrl->status == VIRTIO_NET_OK;
> > >> +
> > >> + for (i = 0; i < vi->curr_queue_pairs; i++) {
> > >> + while (!virtqueue_is_broken(vi->cvq) &&
> > >> !virtqueue_get_buf(vi->cvq, &tmp))
> > >> + cpu_relax();
> > >> + }
> > >> + }
> > >>
> > >>
> > >> +
> > >> +static bool virtnet_pre_send_cmd(struct virtnet_info *vi, struct
> > >> vq_coal *vq_ctrls,
> > >> + u32 max_usecs, u32 max_packets)
> > >> +{
> > >> + struct scatterlist hdr, out, stat;
> > >> + struct scatterlist *sgs[4];
> > >> + unsigned out_num = 0;
> > >> + int ret;
> > >> +
> > >> + BUG_ON(!virtio_has_feature(vi->vdev, VIRTIO_NET_F_CTRL_VQ));
> > >> +
> > >> + vq_ctrls->hdr.class = VIRTIO_NET_CTRL_NOTF_COAL;
> > >> + vq_ctrls->hdr.cmd = VIRTIO_NET_CTRL_NOTF_COAL_VQ_SET;
> > >> + sg_init_one(&hdr, &vq_ctrls->hdr, sizeof(vq_ctrls->hdr));
> > >> + sgs[out_num++] = &hdr;
> > >> +
> > >> + vq_ctrls->coal_vq.vqn = cpu_to_le16(0);
> > >> + vq_ctrls->coal_vq.coal.max_usecs = cpu_to_le32(max_usecs);
> > >> + vq_ctrls->coal_vq.coal.max_packets = cpu_to_le32(max_packets);
> > >> + sg_init_one(&out, &vq_ctrls->ho, sizeof(vq_ctrls->ho));
> > >> +
> > >> + if (&out)
> > >> + sgs[out_num++] = &out;
> > >> +
> > >> + vq_ctrls->status = ~0;
> > >> + sg_init_one(&stat, &vq_ctrls->status, sizeof(vq_ctrls->status));
> > >> + sgs[out_num] = &stat;
> > >> +
> > >> + BUG_ON(out_num + 1 > ARRAY_SIZE(sgs));
> > >> + ret = virtqueue_add_sgs(vi->cvq, sgs, out_num, 1, vi, GFP_ATOMIC);
> > >> + if (ret < 0) {
> > >> + dev_warn(&vi->vdev->dev,
> > >> + "Failed to add sgs for command vq: %d\n.", ret);
> > >> + return false;
> > >> + }
> > >>
> > >>
> > >> Overall, batch reqs are sufficient. Because the current major overhead
> > >> is the number of DMAs.
> > >> For example, for a device with 256 queues,
> > >>
> > >> For the current upstream code, the overhead is 256 kicks + 256*8 DMA times.
> > >> The overhead of batch cmds is 1 kick + 256*8 DMA times.
> > > This can furtherly optimized by using IN_ORDER. The DMA can be batched as well.
> >
> > DMA batch reduces the number of DMA requests, but not the actual number
> > of DMAs.
>
> Well, if we do IN_ORDER, then
>
> 1 for avail idx.
>
> At most 2 DMA is needed for all descriptors.
>
> Driver can allocate an array of cvq commands. So CVQ commands could be
> fetched at most 2 DMA.
>
> etc.
For most users, all this happens maybe once per VM start. It's not
reasonable to start micro-optimizing this until it is taking so much
time it slows VM start measureably. With each DMA taking at most
of an extra microsecond I just do not see the benefit, even with 1000s
of DMAs, this will take at most milliseconds.
> > For out DPU, how much to batch and when to end the batch also need to be
> > evaluated in detail.
> >
> > >
> > > Or even using packed virtqueue.
> > >
> > >> The overhead of batch reqs is 1 kick + 8 DMA times.
> > > If this is a real issue for your architecture, we should not make it
> > > only work for coalescing. Any per vq tweaking may suffer from that.
> >
> > YES.
> >
> > > E.g if you want to do ARFS in the future. So it should a e.g a
> > > container command for cvq instead of just for coalescing command
> > > itself.
> > >
> > > We need to make sure if the existing facility is sufficient or not.
> >
> > We considered to update the generic ctrlq batch command. But so far we
> > have only seen
> > this requirement for netdim and aRFS.
>
> Two use cases should be sufficient to justify.
>
> We do have others, for example the vlan/mac filters.
>
>
> > At the same time, aRFS has not yet
> > entered the community.
> > We will try to add a batch req interface for it and it may have a
> > dedicated flow vq to ensure that
> > the number of command issuances larger than netdim is responded to in time.
> > So we temporarily plan to advance the batch of coalescing parameter
> > requests first.
>
> Thanks
This publicly archived list offers a means to provide input to the
OASIS Virtual I/O Device (VIRTIO) TC.
In order to verify user consent to the Feedback License terms and
to minimize spam in the list archive, subscription is required
before posting.
Subscribe: virtio-comment-subscribe@lists.oasis-open.org
Unsubscribe: virtio-comment-unsubscribe@lists.oasis-open.org
List help: virtio-comment-help@lists.oasis-open.org
List archive: https://lists.oasis-open.org/archives/virtio-comment/
Feedback License: https://www.oasis-open.org/who/ipr/feedback_license.pdf
List Guidelines: https://www.oasis-open.org/policies-guidelines/mailing-lists
Committee: https://www.oasis-open.org/committees/virtio/
Join OASIS: https://www.oasis-open.org/join/
next prev parent reply other threads:[~2023-12-26 9:18 UTC|newest]
Thread overview: 18+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-12-20 14:40 [virtio-comment] [PATCH RESEND] virtio-net: support setting coalescing params for multiple vqs Heng Qi
2023-12-21 3:37 ` [virtio-comment] " Jason Wang
2023-12-21 4:55 ` Heng Qi
2023-12-22 2:40 ` Jason Wang
2023-12-22 6:45 ` Heng Qi
2023-12-22 8:20 ` Michael S. Tsirkin
2023-12-26 2:17 ` Heng Qi
2023-12-26 3:32 ` Jason Wang
2023-12-26 9:18 ` Michael S. Tsirkin [this message]
2023-12-27 2:32 ` Jason Wang
2023-12-22 8:26 ` Michael S. Tsirkin
2023-12-21 6:56 ` Michael S. Tsirkin
2023-12-21 7:01 ` Heng Qi
2023-12-21 7:08 ` Michael S. Tsirkin
2023-12-21 7:19 ` Heng Qi
2023-12-21 7:48 ` Heng Qi
2023-12-22 8:24 ` Michael S. Tsirkin
2023-12-26 2:04 ` Heng Qi
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20231226040940-mutt-send-email-mst@kernel.org \
--to=mst@redhat.com \
--cc=alvaro.karsz@solid-run.com \
--cc=hengqi@linux.alibaba.com \
--cc=jasowang@redhat.com \
--cc=parav@nvidia.com \
--cc=virtio-comment@lists.oasis-open.org \
--cc=xuanzhuo@linux.alibaba.com \
--cc=yuri.benditovich@daynix.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox