On Tue, Jan 16, 2024 at 09:11:33PM +0800, Heng Qi wrote: > Accumulate multiple request commands to kick the device once, > and obtain the processing results of the corresponding commands > asynchronously. The batch command method is used to optimize the > CPU overhead of the DIM worker caused by the guest being busy > waiting for the command response result. > > On an 8-queue device, without this patch, the guest cpu overhead > due to waiting for cvq could be 10+% and above. With this patch, > the corresponding overhead is basically invisible. > > Signed-off-by: Heng Qi <hengqi@xxxxxxxxxxxxxxxxx> ... > @@ -3520,22 +3568,99 @@ static int virtnet_send_notf_coal_vq_cmds(struct virtnet_info *vi, > return 0; > } > > +static bool virtnet_add_dim_command(struct virtnet_info *vi, > + struct virtnet_batch_coal *ctrl) > +{ > + struct scatterlist *sgs[4], hdr, stat, out; > + unsigned out_num = 0; > + int ret; > + > + /* Caller should know better */ > + BUG_ON(!virtio_has_feature(vi->vdev, VIRTIO_NET_F_CTRL_VQ)); > + > + ctrl->hdr.class = VIRTIO_NET_CTRL_NOTF_COAL; > + ctrl->hdr.cmd = VIRTIO_NET_CTRL_NOTF_COAL_VQS_SET; > + > + /* Add header */ > + sg_init_one(&hdr, &ctrl->hdr, sizeof(ctrl->hdr)); > + sgs[out_num++] = &hdr; > + > + /* Add body */ > + sg_init_one(&out, &ctrl->num_entries, sizeof(ctrl->num_entries) + > + ctrl->num_entries * sizeof(struct virtnet_coal_entry)); Hi Heng Qi, I am a bit confused. With this series applied on top of net-next struct virtnet_coal_entry doesn't seem to exist. > + sgs[out_num++] = &out; > + > + /* Add return status. */ > + ctrl->status = VIRTIO_NET_OK; > + sg_init_one(&stat, &ctrl->status, sizeof(ctrl->status)); > + sgs[out_num] = &stat; > + > + BUG_ON(out_num + 1 > ARRAY_SIZE(sgs)); > + ret = virtqueue_add_sgs(vi->cvq, sgs, out_num, 1, ctrl, GFP_ATOMIC); > + if (ret < 0) { > + dev_warn(&vi->vdev->dev, "Failed to add sgs for command vq: %d\n.", ret); > + return false; > + } > + > + virtqueue_kick(vi->cvq); > + > + ctrl->usable = false; > + vi->cvq_cmd_nums++; > + > + return true; > +} ...