Re: [PATCH 03/11] dax: simplify the dax_device <-> gendisk association

2021-10-28 Thread Ira Weiny
On Mon, Oct 18, 2021 at 06:40:46AM +0200, Christoph Hellwig wrote:
> Replace the dax_host_hash with an xarray indexed by the pointer value
> of the gendisk, and require explicitl calls from the block drivers that
> want to associate their gendisk with a dax_device.
> 
> Signed-off-by: Christoph Hellwig 
> ---
>  drivers/dax/bus.c|   2 +-
>  drivers/dax/super.c  | 106 +--
>  drivers/md/dm.c  |   6 +-
>  drivers/nvdimm/pmem.c|   8 ++-
>  drivers/s390/block/dcssblk.c |  11 +++-
>  fs/fuse/virtio_fs.c  |   2 +-
>  include/linux/dax.h  |  19 +--
>  7 files changed, 60 insertions(+), 94 deletions(-)
> 
> diff --git a/drivers/dax/bus.c b/drivers/dax/bus.c
> index 6cc4da4c713d9..6d91b0186e3be 100644
> --- a/drivers/dax/bus.c
> +++ b/drivers/dax/bus.c
> @@ -1326,7 +1326,7 @@ struct dev_dax *devm_create_dev_dax(struct dev_dax_data 
> *data)
>* No 'host' or dax_operations since there is no access to this
>* device outside of mmap of the resulting character device.
>*/

NIT: this comment needs to be updated as well.

Ira

> - dax_dev = alloc_dax(dev_dax, NULL, NULL, DAXDEV_F_SYNC);
> + dax_dev = alloc_dax(dev_dax, NULL, DAXDEV_F_SYNC);
>   if (IS_ERR(dax_dev)) {
>   rc = PTR_ERR(dax_dev);
>   goto err_alloc_dax;

[snip]

___
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization


Re: vDPA bus driver selection

2021-10-28 Thread Jason Wang
On Thu, Oct 28, 2021 at 5:48 PM Parav Pandit  wrote:
>
>
>
> > From: Stefano Garzarella 
> > Sent: Thursday, October 28, 2021 3:08 PM
>
> > >> >$ vdpa/vdpa dev add mgmtdev vdpasim_net name vdpa0 mac
> > >> >00:11:22:33:44:55 $ echo 0 > /sys/bus/vdpa/drivers_autoprobe
> > >> >
> > >> >And after vdpa device creation, it manually binds to the desired
> > >> >driver such as,
> > >> >
> > >> >$ echo vdpa0 > /sys/bus/vdpa/drivers/virtio_vdpa/bind
> > >> >Or
> > >> >$ echo vdpa0 > /sys/bus/vdpa/drivers/vhost_vdpa/bind
> > >>
> > >> Cool, I didn't know that. This is very useful, but do you think it
> > >> might be better to integrate it with the netlink API and specify at
> > >> creation which bus driver to use?
> > >I think it is useful; for vduse case we need the ability to say "none"
> > >as well and when nothing specified it should be default driver.
> >
> > Yep, the default can be the actual behaviour.
> >
> > >
> > >More than netlink, I think we need the ability in the core kernel to
> > >make this choice.
> >
> > Okay, but I think we can include that in the vdpa tool.
> If functionality and interface exists in other part of the it is hard to wrap 
> that in vdpa tool that does the duplicate work.
>
> >
> > >I haven't explored what is already available to make that happen.
> >
> > Me too, I only saw the .match() callback of "struct bus_type" that could be 
> > used
> > for this purpose.
> >
> > >If/once its available, I am sure it has more users than just vdpa.
> >
> > Make sense. I'll spend some time next week.
>
> Ok. yeah, may be a desired driver can be stored in the vdpa_device that 
> match() routine can use.
> And if that driver is not available,  it returns EPROBE_DEFER; so whenever 
> such driver is loaded it can be bind.
>
> But I think before wrapping something in vdpa, need to find a reason why the 
> current interface doesn't solve the problem and also to figure out plumbing.

I agree. If it's something that can easily be addressed by the
management code (just a matter of the extra steps for manual setup).
It's probably not worth bothering.

Thanks

>

___
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization


Re: vDPA bus driver selection

2021-10-28 Thread Jason Wang
On Thu, Oct 28, 2021 at 5:47 PM Stefano Garzarella  wrote:
>
> On Thu, Oct 28, 2021 at 10:24:47AM +0800, Jason Wang wrote:
> >On Thu, Oct 28, 2021 at 4:16 AM Michael S. Tsirkin  wrote:
> >>
> >> On Wed, Oct 27, 2021 at 03:21:15PM +, Parav Pandit wrote:
> >> > Hi Stefano,
> >> >
> >> > > From: Stefano Garzarella 
> >> > > Sent: Wednesday, October 27, 2021 8:04 PM
> >> > >
> >> > > Hi folks,
> >> > > I was trying to understand if we have a way to specify which vDPA bus 
> >> > > driver
> >> > > (e.g. vhost-vdpa, virtio-vdpa) a device should use.
> >> > > IIUC we don't have it, and the first registered driver is used when a 
> >> > > new device
> >> > > is registered.
> >> > >
> >> > > I was thinking if it makes sense to extend the management API to 
> >> > > specify which
> >> > > bus driver to use for a device.
> >
> >Actually, we want to support this in the first version of vDPA bus.
> >But for some reason it was dropped. The idea is to specify the device
> >type 'virtio' or 'vhost'. But a concern is that, it may encourage
> >vendor to implement e.g virtio specific device (without DMA
> >isolation).
>
> Yep, I see the issue about device type, so I think make sense to require
> the support of both, how it is now basically.
>
> So instead of defining the type of the device, we could provide the
> possibility to choose which bus to connect it to,

I think you meant the "bus driver" here?

> in this way we
> continue to require that both are supported.
>
> As Michael suggested, instead of specify it at the creation time as was
> in my original idea, we can provide an API to attach/detach a device to
> a specific vDPA bus.

Does such an API exist in driver core?

>
> Of course, providing a default behaviour like now, which connects to the
> first registered.

If we want to change this, we can introduce "driver_override".

Thanks

>
> Thanks,
> Stefano
>

___
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization


Re: [PATCH v2 1/3] virtio: cache indirect desc for split

2021-10-28 Thread Xuan Zhuo
On Fri, 29 Oct 2021 10:20:04 +0800, Jason Wang  wrote:
> On Thu, Oct 28, 2021 at 6:49 PM Xuan Zhuo  wrote:
> >
> > In the case of using indirect, indirect desc must be allocated and
> > released each time, which increases a lot of cpu overhead.
> >
> > Here, a cache is added for indirect. If the number of indirect desc to be
> > applied for is less than VIRT_QUEUE_CACHE_DESC_NUM, the desc array with
> > the size of VIRT_QUEUE_CACHE_DESC_NUM is fixed and cached for reuse.
>
> The commit log looks out of date? It's actually desc_cache_thr now.

Yes, I will fix it in next version.

>
> >
> > Signed-off-by: Xuan Zhuo 
> > ---
> >  drivers/virtio/virtio.c  |  6 +++
> >  drivers/virtio/virtio_ring.c | 77 
> >  include/linux/virtio.h   | 14 +++
> >  3 files changed, 89 insertions(+), 8 deletions(-)
> >
> > diff --git a/drivers/virtio/virtio.c b/drivers/virtio/virtio.c
> > index 0a5b54034d4b..1047149ac2a4 100644
> > --- a/drivers/virtio/virtio.c
> > +++ b/drivers/virtio/virtio.c
> > @@ -431,6 +431,12 @@ bool is_virtio_device(struct device *dev)
> >  }
> >  EXPORT_SYMBOL_GPL(is_virtio_device);
> >
> > +void virtio_set_desc_cache(struct virtio_device *dev, u32 thr)
> > +{
> > +   dev->desc_cache_thr = thr;
> > +}
> > +EXPORT_SYMBOL_GPL(virtio_set_desc_cache);
> > +
> >  void unregister_virtio_device(struct virtio_device *dev)
> >  {
> > int index = dev->index; /* save for after device release */
> > diff --git a/drivers/virtio/virtio_ring.c b/drivers/virtio/virtio_ring.c
> > index dd95dfd85e98..0ebcd4f12d3b 100644
> > --- a/drivers/virtio/virtio_ring.c
> > +++ b/drivers/virtio/virtio_ring.c
> > @@ -117,6 +117,15 @@ struct vring_virtqueue {
> > /* Hint for event idx: already triggered no need to disable. */
> > bool event_triggered;
> >
> > +   /* desc cache threshold
> > +*0   - disable desc cache
> > +*> 0 - enable desc cache. As the threshold of the desc cache.
> > +*/
> > +   u32 desc_cache_thr;
> > +
> > +   /* desc cache chain */
> > +   struct list_head desc_cache;
> > +
> > union {
> > /* Available for split ring */
> > struct {
> > @@ -423,7 +432,53 @@ static unsigned int vring_unmap_one_split(const struct 
> > vring_virtqueue *vq,
> > return extra[i].next;
> >  }
> >
> > -static struct vring_desc *alloc_indirect_split(struct virtqueue *_vq,
> > +static void desc_cache_free(struct list_head *head)
> > +{
> > +   struct list_head *n, *pos;
> > +
> > +   BUILD_BUG_ON(sizeof(struct list_head) > sizeof(struct vring_desc));
> > +   BUILD_BUG_ON(sizeof(struct list_head) > sizeof(struct 
> > vring_packed_desc));
> > +
> > +   list_for_each_prev_safe(pos, n, head)
> > +   kfree(pos);
> > +}
> > +
> > +static void __desc_cache_put(struct vring_virtqueue *vq,
> > +struct list_head *node, int n)
> > +{
> > +   if (n <= vq->desc_cache_thr)
> > +   list_add(node, >desc_cache);
> > +   else
> > +   kfree(node);
> > +}
> > +
> > +#define desc_cache_put(vq, desc, n) \
> > +   __desc_cache_put(vq, (struct list_head *)desc, n)
> > +
> > +static void *desc_cache_get(struct vring_virtqueue *vq,
> > +   int size, int n, gfp_t gfp)
> > +{
> > +   struct list_head *node;
> > +
> > +   if (n > vq->desc_cache_thr)
> > +   return kmalloc_array(n, size, gfp);
> > +
> > +   if (!list_empty(>desc_cache)) {
> > +   node = vq->desc_cache.next;
> > +   list_del(node);
> > +   return node;
> > +   }
> > +
> > +   return kmalloc_array(vq->desc_cache_thr, size, gfp);
>
> Instead of doing the if .. kmalloc_array here. I wonder if we can
> simply pre-allocate per buffer indirect descriptors array.
>
> E.g if we use MAX_SKB_FRAGS + 1, it will be ~64KB for 256 queue size
> and ~272KB for 1024 queue size.
>
> Then we avoid list manipulation and kmalloc in datapath with much more
> simpler codes.

Yes, this is a good idea.

Thanks.

>
> Thanks
>
> > +}
> > +
> > +#define _desc_cache_get(vq, n, gfp, tp) \
> > +   ((tp *)desc_cache_get(vq, (sizeof(tp)), n, gfp))
> > +
> > +#define desc_cache_get_split(vq, n, gfp) \
> > +   _desc_cache_get(vq, n, gfp, struct vring_desc)
> > +
> > +static struct vring_desc *alloc_indirect_split(struct vring_virtqueue *vq,
> >unsigned int total_sg,
> >gfp_t gfp)
> >  {
> > @@ -437,12 +492,12 @@ static struct vring_desc *alloc_indirect_split(struct 
> > virtqueue *_vq,
> >  */
> > gfp &= ~__GFP_HIGHMEM;
> >
> > -   desc = kmalloc_array(total_sg, sizeof(struct vring_desc), gfp);
> > +   desc = desc_cache_get_split(vq, total_sg, gfp);
> > if (!desc)
> > return NULL;
> >
> > for (i = 0; i < total_sg; i++)
> > -   

Re: [PATCH v2 1/3] virtio: cache indirect desc for split

2021-10-28 Thread Jason Wang
On Thu, Oct 28, 2021 at 6:49 PM Xuan Zhuo  wrote:
>
> In the case of using indirect, indirect desc must be allocated and
> released each time, which increases a lot of cpu overhead.
>
> Here, a cache is added for indirect. If the number of indirect desc to be
> applied for is less than VIRT_QUEUE_CACHE_DESC_NUM, the desc array with
> the size of VIRT_QUEUE_CACHE_DESC_NUM is fixed and cached for reuse.

The commit log looks out of date? It's actually desc_cache_thr now.

>
> Signed-off-by: Xuan Zhuo 
> ---
>  drivers/virtio/virtio.c  |  6 +++
>  drivers/virtio/virtio_ring.c | 77 
>  include/linux/virtio.h   | 14 +++
>  3 files changed, 89 insertions(+), 8 deletions(-)
>
> diff --git a/drivers/virtio/virtio.c b/drivers/virtio/virtio.c
> index 0a5b54034d4b..1047149ac2a4 100644
> --- a/drivers/virtio/virtio.c
> +++ b/drivers/virtio/virtio.c
> @@ -431,6 +431,12 @@ bool is_virtio_device(struct device *dev)
>  }
>  EXPORT_SYMBOL_GPL(is_virtio_device);
>
> +void virtio_set_desc_cache(struct virtio_device *dev, u32 thr)
> +{
> +   dev->desc_cache_thr = thr;
> +}
> +EXPORT_SYMBOL_GPL(virtio_set_desc_cache);
> +
>  void unregister_virtio_device(struct virtio_device *dev)
>  {
> int index = dev->index; /* save for after device release */
> diff --git a/drivers/virtio/virtio_ring.c b/drivers/virtio/virtio_ring.c
> index dd95dfd85e98..0ebcd4f12d3b 100644
> --- a/drivers/virtio/virtio_ring.c
> +++ b/drivers/virtio/virtio_ring.c
> @@ -117,6 +117,15 @@ struct vring_virtqueue {
> /* Hint for event idx: already triggered no need to disable. */
> bool event_triggered;
>
> +   /* desc cache threshold
> +*0   - disable desc cache
> +*> 0 - enable desc cache. As the threshold of the desc cache.
> +*/
> +   u32 desc_cache_thr;
> +
> +   /* desc cache chain */
> +   struct list_head desc_cache;
> +
> union {
> /* Available for split ring */
> struct {
> @@ -423,7 +432,53 @@ static unsigned int vring_unmap_one_split(const struct 
> vring_virtqueue *vq,
> return extra[i].next;
>  }
>
> -static struct vring_desc *alloc_indirect_split(struct virtqueue *_vq,
> +static void desc_cache_free(struct list_head *head)
> +{
> +   struct list_head *n, *pos;
> +
> +   BUILD_BUG_ON(sizeof(struct list_head) > sizeof(struct vring_desc));
> +   BUILD_BUG_ON(sizeof(struct list_head) > sizeof(struct 
> vring_packed_desc));
> +
> +   list_for_each_prev_safe(pos, n, head)
> +   kfree(pos);
> +}
> +
> +static void __desc_cache_put(struct vring_virtqueue *vq,
> +struct list_head *node, int n)
> +{
> +   if (n <= vq->desc_cache_thr)
> +   list_add(node, >desc_cache);
> +   else
> +   kfree(node);
> +}
> +
> +#define desc_cache_put(vq, desc, n) \
> +   __desc_cache_put(vq, (struct list_head *)desc, n)
> +
> +static void *desc_cache_get(struct vring_virtqueue *vq,
> +   int size, int n, gfp_t gfp)
> +{
> +   struct list_head *node;
> +
> +   if (n > vq->desc_cache_thr)
> +   return kmalloc_array(n, size, gfp);
> +
> +   if (!list_empty(>desc_cache)) {
> +   node = vq->desc_cache.next;
> +   list_del(node);
> +   return node;
> +   }
> +
> +   return kmalloc_array(vq->desc_cache_thr, size, gfp);

Instead of doing the if .. kmalloc_array here. I wonder if we can
simply pre-allocate per buffer indirect descriptors array.

E.g if we use MAX_SKB_FRAGS + 1, it will be ~64KB for 256 queue size
and ~272KB for 1024 queue size.

Then we avoid list manipulation and kmalloc in datapath with much more
simpler codes.

Thanks

> +}
> +
> +#define _desc_cache_get(vq, n, gfp, tp) \
> +   ((tp *)desc_cache_get(vq, (sizeof(tp)), n, gfp))
> +
> +#define desc_cache_get_split(vq, n, gfp) \
> +   _desc_cache_get(vq, n, gfp, struct vring_desc)
> +
> +static struct vring_desc *alloc_indirect_split(struct vring_virtqueue *vq,
>unsigned int total_sg,
>gfp_t gfp)
>  {
> @@ -437,12 +492,12 @@ static struct vring_desc *alloc_indirect_split(struct 
> virtqueue *_vq,
>  */
> gfp &= ~__GFP_HIGHMEM;
>
> -   desc = kmalloc_array(total_sg, sizeof(struct vring_desc), gfp);
> +   desc = desc_cache_get_split(vq, total_sg, gfp);
> if (!desc)
> return NULL;
>
> for (i = 0; i < total_sg; i++)
> -   desc[i].next = cpu_to_virtio16(_vq->vdev, i + 1);
> +   desc[i].next = cpu_to_virtio16(vq->vq.vdev, i + 1);
> return desc;
>  }
>
> @@ -508,7 +563,7 @@ static inline int virtqueue_add_split(struct virtqueue 
> *_vq,
> head = vq->free_head;
>
> if (virtqueue_use_indirect(_vq, total_sg))
> -   desc = alloc_indirect_split(_vq, total_sg, 

Re: [PATCH v2 3/3] virtio-net: enable virtio indirect cache

2021-10-28 Thread kernel test robot
Hi Xuan,

Thank you for the patch! Perhaps something to improve:

[auto build test WARNING on horms-ipvs/master]
[also build test WARNING on linus/master v5.15-rc7]
[cannot apply to mst-vhost/linux-next next-20211028]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]

url:
https://github.com/0day-ci/linux/commits/Xuan-Zhuo/virtio-support-cache-indirect-desc/20211028-185145
base:   https://git.kernel.org/pub/scm/linux/kernel/git/horms/ipvs.git master
config: i386-randconfig-a004-20211028 (attached as .config)
compiler: gcc-9 (Debian 9.3.0-22) 9.3.0
reproduce (this is a W=1 build):
# 
https://github.com/0day-ci/linux/commit/e8418946355cc294b006c6692990dae15a22d85f
git remote add linux-review https://github.com/0day-ci/linux
git fetch --no-tags linux-review 
Xuan-Zhuo/virtio-support-cache-indirect-desc/20211028-185145
git checkout e8418946355cc294b006c6692990dae15a22d85f
# save the attached .config to linux build tree
make W=1 ARCH=i386 

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot 

All warnings (new ones prefixed by >>):

>> drivers/net/virtio_net.c:35: warning: This comment starts with '/**', but 
>> isn't a kernel-doc comment. Refer Documentation/doc-guide/kernel-doc.rst
* Because virtio desc cache will increase memory overhead, users can turn it


vim +35 drivers/net/virtio_net.c

33  
34  /**
  > 35   * Because virtio desc cache will increase memory overhead, users can 
turn it
36   * off or select an acceptable value. The maximum value is 2 + 
MAX_SKB_FRAGS.
37   */
38  static u32 virtio_desc_cache_thr = 4;
39  module_param(virtio_desc_cache_thr, uint, 0644);
40  

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-...@lists.01.org


.config.gz
Description: application/gzip
___
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization

Re: futher decouple DAX from block devices

2021-10-28 Thread Stephen Rothwell
Hi Dan,

On Wed, 27 Oct 2021 13:46:31 -0700 Dan Williams  
wrote:
>
> My merge resolution is here [1]. Christoph, please have a look. The
> rebase and the merge result are both passing my test and I'm now going
> to review the individual patches. However, while I do that and collect
> acks from DM and EROFS folks, I want to give Stephen a heads up that
> this is coming. Primarily I want to see if someone sees a better
> strategy to merge this, please let me know, but if not I plan to walk
> Stephen and Linus through the resolution.

It doesn't look to bad to me (however it is a bit late in the cycle :-(
).  Once you are happy, just put it in your tree (some of the conflicts
are against the current -rc3 based version of your tree anyway) and I
will cope with it on Monday.

You could do a test merge against next-^^ (that leaves out
Andrew's patch series) and if you think there is anything tricky please
send me a "git diff-tree --cc HEAD" after you have resolved the
conflicts to your satisfaction and committed the test merge or just
point me at the test merge in a tree somewhere (like this one).

-- 
Cheers,
Stephen Rothwell


pgp83NYjr6EaB.pgp
Description: OpenPGP digital signature
___
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization

Re: drm/virtio: not pin pages on demand

2021-10-28 Thread Chia-I Wu
On Wed, Oct 27, 2021 at 4:12 AM Gerd Hoffmann  wrote:
>
> [ Cc'ing Gurchetan Singh ]
>
> > Can we follow up on this issue?
> >
> > The main pain point with your suggestion is the fact,
> > that it will cause VirGL protocol breakage and we would
> > like to avoid this.
> >
> > Extending execbuffer ioctl and create_resource ioctl is
> > more convenient than having the protocol broken.
>
> Do you know at resource creation time whenever you need cpu access
> or not?  IOW can we make that a resource property, so we don't have
> pass around lists of objects on each and every execbuffer ioctl?
Yes.  The userspace driver should be able to internally mark the
resource as NO TRANSFER and omit it from execbuffer.  It can be tricky
though because resource wait will no longer work.


>
> > Blob resources is not a solution, too, because QEMU doesn't
> > support blob resources right now.
> >
> > In ideal solution when both QEMU and crosvm support blob resources
> > we can switch to blob resources for textures.
>
> That'll only happen if someone works on it.
> I will not be able to do that though.
>
> > I would like to introduce changes gradually and not make a protocol
> > breakage.
>
> Well, opengl switching to blob resources is a protocol change anyway.
> That doesn't imply things will break though.  We have capsets etc to
> extend the protocol while maintaining backward compatibility.
>
> > What do you think about that?
>
> I still think that switching to blob resources would be the better
> solution.  Yes, it's alot of work and not something which helps
> short-term.  But adding a new API as interim solution isn't great
> either.  So, not sure.  Chia-I Wu?  Gurchetan Singh?
I can agree with that, although it depends on how much work needs to
happen in the userspace for virgl.

We will look into a userspace-only solution, or at least something not
involving uAPI additions.

>
>
> While being at it:  Chia-I Wu & Gurchetan Singh, could you help
> reviewing virtio-gpu kernel patches?  I think you both have a better
> view on the big picture (with both mesa and virglrenderer) than I have.
> Also for the crosvm side of things.  The procedure for that would be to
> send a patch adding yourself to the virtio-gpu section of the
> MAINTAINERS file, so scripts/get_maintainer.pl will Cc you on patches
> submitted.
Sure.  Will do.
>
> thanks,
>   Gerd
>
> >
> > Maksym
> >
> >
> > On 10/22/21 10:44 AM, Maksym Wezdecki wrote:
> >
> > > Once again with all lists and receivers. I'm sorry for that.
> > >
> > > On 10/21/21 6:42 PM, Chia-I Wu wrote:
> > >> On Thu, Oct 21, 2021 at 4:52 AM Gerd Hoffmann  wrote:
> > >>> On Thu, Oct 21, 2021 at 11:55:47AM +0200, Maksym Wezdecki wrote:
> >  I get your point. However, we need to make resource_create ioctl,
> >  in order to create corresponding resource on the host.
> > >>> That used to be the case but isn't true any more with the new
> > >>> blob resources.  virglrenderer allows to create gpu objects
> > >>> via execbuffer.  Those gpu objects can be linked to a
> > >>> virtio-gpu resources, but it's optional.  In your case you
> > >>> would do that only for your staging buffer.  The other textures
> > >>> (which you fill with a host-side copy from the staging buffer)
> > >>> do not need a virtio-gpu resource in the first place.
> > >> That's however a breaking change to the virgl protocol.  All virgl
> > >> commands expect res ids rather than blob ids.
> > >>
> > >> Using VIRTGPU_BLOB_MEM_HOST3D could in theory work.  But there are a
> > >> few occasions where virglrenderer expects there to be guest storage.
> > >> There are also readbacks that we need to support.  We might end up
> > >> using VIRTGPU_BLOB_MEM_HOST3D_GUEST, where pin-on-demand is still
> > >> desirable.
> > >>
> > >> For this patch, I think the uapi change can be simplified.  It can be
> > >> a new param plus a new field in drm_virtgpu_execbuffer
> > >>
> > >>   __u64 bo_flags; /* pointer to an array of size num_bo_handles, or NULL 
> > >> */
> > >>
> > >> The other changes do not seem needed.
> > > My first approach was the same, as you mentioned. However, having "__u64 
> > > bo_flags"
> > > needs a for loop, where only few of the bo-s needs to be pinned - this has
> > > performance implications. I would rather pass bo handles that should be 
> > > pinned than
> > > having a lot of flags, where only 1-2 bos needs to be pinned.
> > >
> > >>> take care,
> > >>>   Gerd
> > >>>
>
> --
>
___
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization


Re: [GIT PULL] virtio: last minute fixes

2021-10-28 Thread pr-tracker-bot
The pull request you sent on Wed, 27 Oct 2021 16:08:29 -0400:

> https://git.kernel.org/pub/scm/linux/kernel/git/mst/vhost.git tags/for_linus

has been merged into torvalds/linux.git:
https://git.kernel.org/torvalds/c/9c5456773d79b64cc6cebb06f668e29249636ba9

Thank you!

-- 
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/prtracker.html
___
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization


WorldCist'22 - 10th World Conference on Information Systems and Technologies | Montenegro

2021-10-28 Thread WorldCIST
* Conference listed in CORE Ranking

** Google Scholar H5-Index = 23

*** Best papers selected for SCI/SSCI journals



--

WorldCIST'22 - 10th World Conference on Information Systems and Technologies

12-14 April 2022, Budva, Montenegro

http://worldcist.org 

---


The WorldCist'22 - 10th World Conference on Information Systems and 
Technologies, to be held in Budva, Montenegro, 12-14 April 2022, is a global 
forum for researchers and practitioners to present and discuss the most recent 
innovations, trends, results, experiences and concerns in the several 
perspectives of Information Systems and Technologies.

We are pleased to invite you to submit your papers to WorldCist'22. All 
submissions will be reviewed on the basis of relevance, originality, importance 
and clarity.



TOPICS

Submitted papers should be related with one or more of the main themes proposed 
for the Conference:

A) Information and Knowledge Management (IKM);

B) Organizational Models and Information Systems (OMIS);

C) Software and Systems Modeling (SSM);

D) Software Systems, Architectures, Applications and Tools (SSAAT);

E) Multimedia Systems and Applications (MSA);

F) Computer Networks, Mobility and Pervasive Systems (CNMPS);

G) Intelligent and Decision Support Systems (IDSS);

H) Big Data Analytics and Applications (BDAA);

I) Human-Computer Interaction (HCI);

J) Ethics, Computers and Security (ECS)

K) Health Informatics (HIS);

L) Information Technologies in Education (ITE);

M) Technologies for Biomedical Applications (TBA)

N) Information Technologies in Radiocommunications (ITR);



TYPES of SUBMISSIONS and DECISIONS

Four types of papers can be submitted:

Full paper: Finished or consolidated R works, to be included in one of the 
Conference themes. These papers are assigned a 10-page limit.

Short paper: Ongoing works with relevant preliminary results, open to 
discussion. These papers are assigned a 7-page limit.

Poster paper: Initial work with relevant ideas, open to discussion. These 
papers are assigned to a 4-page limit.

Company paper: Companies' papers that show practical experience, R & D, tools, 
etc., focused on some topics of the conference. These papers are assigned to a 
4-page limit.

Submitted papers must comply with the format of Advances in Intelligent Systems 
and Computing Series (see Instructions for Authors at Springer Website), be 
written in English, must not have been published before, not be under review 
for any other conference or publication and not include any information leading 
to the authors’ identification. Therefore, the authors’ names, affiliations and 
bibliographic references should not be included in the version for evaluation 
by the Program Committee. This information should only be included in the 
camera-ready version, saved in Word or Latex format and also in PDF format. 
These files must be accompanied by the Consent to Publish form filled out, in a 
ZIP file, and uploaded at the conference management system.

All papers will be subjected to a “double-blind review” by at least two members 
of the Program Committee.

Based on Program Committee evaluation, a paper can be rejected or accepted by 
the Conference Chairs. In the later case, it can be accepted as the type 
originally submitted or as another type. Thus, full papers can be accepted as 
short papers or poster papers only. Similarly, short papers can be accepted as 
poster papers only.

Poster papers and Company papers are not published in the Conference 
Proceedings, being only presented and discussed. The authors of accepted poster 
papers should build and print a poster to be exhibited during the Conference. 
This poster must follow an A1 or A2 vertical format. The Conference includes 
Work Sessions where these posters are presented and orally discussed, with a 7 
minute limit per poster.

The authors of accepted Full papers will have 15 minutes to present their work 
in a Conference Work Session; approximately 5 minutes of discussion will follow 
each presentation. The authors of accepted Short papers and Company papers will 
have 11 minutes to present their work in a Conference Work Session; 
approximately 4 minutes of discussion will follow each presentation.



PUBLICATION & INDEXING

To ensure that a full paper or short paper is published, poster paper or 
company paper is presented, at least one of the authors must be fully 
registered by the 8nd of January 2022, and the paper must comply with the 
suggested layout and page-limit. Additionally, all recommended changes must be 
addressed by the authors before they submit the camera-ready version.

No more than one paper per registration will be published. An extra fee must be 
paid for publication of additional papers, with a 

[PATCH v2 3/3] virtio-net: enable virtio indirect cache

2021-10-28 Thread Xuan Zhuo
If the VIRTIO_RING_F_INDIRECT_DESC negotiation succeeds, and the number
of sgs used for sending packets is greater than 1. We must constantly
call __kmalloc/kfree to allocate/release desc.

In the case of extremely fast package delivery, the overhead cannot be
ignored:

  27.46%  [kernel]  [k] virtqueue_add
  16.66%  [kernel]  [k] detach_buf_split
  16.51%  [kernel]  [k] virtnet_xsk_xmit
  14.04%  [kernel]  [k] virtqueue_add_outbuf
   5.18%  [kernel]  [k] __kmalloc
   4.08%  [kernel]  [k] kfree
   2.80%  [kernel]  [k] virtqueue_get_buf_ctx
   2.22%  [kernel]  [k] xsk_tx_peek_desc
   2.08%  [kernel]  [k] memset_erms
   0.83%  [kernel]  [k] virtqueue_kick_prepare
   0.76%  [kernel]  [k] virtnet_xsk_run
   0.62%  [kernel]  [k] __free_old_xmit_ptr
   0.60%  [kernel]  [k] vring_map_one_sg
   0.53%  [kernel]  [k] native_apic_mem_write
   0.46%  [kernel]  [k] sg_next
   0.43%  [kernel]  [k] sg_init_table
   0.41%  [kernel]  [k] kmalloc_slab

Compared to not using virtio indirect cache, virtio-net can get a 16%
performance improvement when using indirect desc cache.

In the test case, the CPU where the package is sent has reached 100%.
The following are the PPS in two cases:

indirect desc cache  | no cache
3074658  | 2685132
3111866  | 2666118
3152527  | 2653632
3125867  | 2669820
3027147  | 2644464
3069211  | 2669777
3038522  | 2675645
3034507  | 2671302
3102257  | 2685504
3083712  | 2692800
3051771  | 2676928
3080684  | 2695040
3147816  | 2720876
3123887  | 2705492
3180963  | 2699520
3191579  | 2676480
3161670  | 2686272
3189768  | 2692588
3174272  | 2686692
3143434  | 2682416

Signed-off-by: Xuan Zhuo 
---
 drivers/net/virtio_net.c | 12 
 1 file changed, 12 insertions(+)

diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c
index 4ad25a8b0870..e1ade176ab46 100644
--- a/drivers/net/virtio_net.c
+++ b/drivers/net/virtio_net.c
@@ -31,6 +31,13 @@ module_param(csum, bool, 0444);
 module_param(gso, bool, 0444);
 module_param(napi_tx, bool, 0644);
 
+/**
+ * Because virtio desc cache will increase memory overhead, users can turn it
+ * off or select an acceptable value. The maximum value is 2 + MAX_SKB_FRAGS.
+ */
+static u32 virtio_desc_cache_thr = 4;
+module_param(virtio_desc_cache_thr, uint, 0644);
+
 /* FIXME: MTU in config. */
 #define GOOD_PACKET_LEN (ETH_HLEN + VLAN_HLEN + ETH_DATA_LEN)
 #define GOOD_COPY_LEN  128
@@ -3214,6 +3221,11 @@ static int virtnet_probe(struct virtio_device *vdev)
vi->curr_queue_pairs = num_online_cpus();
vi->max_queue_pairs = max_queue_pairs;
 
+   if (virtio_desc_cache_thr > 2 + MAX_SKB_FRAGS)
+   virtio_set_desc_cache(vdev, 2 + MAX_SKB_FRAGS);
+   else
+   virtio_set_desc_cache(vdev, virtio_desc_cache_thr);
+
/* Allocate/initialize the rx/tx queues, and invoke find_vqs */
err = init_vqs(vi);
if (err)
-- 
2.31.0

___
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization


[PATCH v2 1/3] virtio: cache indirect desc for split

2021-10-28 Thread Xuan Zhuo
In the case of using indirect, indirect desc must be allocated and
released each time, which increases a lot of cpu overhead.

Here, a cache is added for indirect. If the number of indirect desc to be
applied for is less than VIRT_QUEUE_CACHE_DESC_NUM, the desc array with
the size of VIRT_QUEUE_CACHE_DESC_NUM is fixed and cached for reuse.

Signed-off-by: Xuan Zhuo 
---
 drivers/virtio/virtio.c  |  6 +++
 drivers/virtio/virtio_ring.c | 77 
 include/linux/virtio.h   | 14 +++
 3 files changed, 89 insertions(+), 8 deletions(-)

diff --git a/drivers/virtio/virtio.c b/drivers/virtio/virtio.c
index 0a5b54034d4b..1047149ac2a4 100644
--- a/drivers/virtio/virtio.c
+++ b/drivers/virtio/virtio.c
@@ -431,6 +431,12 @@ bool is_virtio_device(struct device *dev)
 }
 EXPORT_SYMBOL_GPL(is_virtio_device);
 
+void virtio_set_desc_cache(struct virtio_device *dev, u32 thr)
+{
+   dev->desc_cache_thr = thr;
+}
+EXPORT_SYMBOL_GPL(virtio_set_desc_cache);
+
 void unregister_virtio_device(struct virtio_device *dev)
 {
int index = dev->index; /* save for after device release */
diff --git a/drivers/virtio/virtio_ring.c b/drivers/virtio/virtio_ring.c
index dd95dfd85e98..0ebcd4f12d3b 100644
--- a/drivers/virtio/virtio_ring.c
+++ b/drivers/virtio/virtio_ring.c
@@ -117,6 +117,15 @@ struct vring_virtqueue {
/* Hint for event idx: already triggered no need to disable. */
bool event_triggered;
 
+   /* desc cache threshold
+*0   - disable desc cache
+*> 0 - enable desc cache. As the threshold of the desc cache.
+*/
+   u32 desc_cache_thr;
+
+   /* desc cache chain */
+   struct list_head desc_cache;
+
union {
/* Available for split ring */
struct {
@@ -423,7 +432,53 @@ static unsigned int vring_unmap_one_split(const struct 
vring_virtqueue *vq,
return extra[i].next;
 }
 
-static struct vring_desc *alloc_indirect_split(struct virtqueue *_vq,
+static void desc_cache_free(struct list_head *head)
+{
+   struct list_head *n, *pos;
+
+   BUILD_BUG_ON(sizeof(struct list_head) > sizeof(struct vring_desc));
+   BUILD_BUG_ON(sizeof(struct list_head) > sizeof(struct 
vring_packed_desc));
+
+   list_for_each_prev_safe(pos, n, head)
+   kfree(pos);
+}
+
+static void __desc_cache_put(struct vring_virtqueue *vq,
+struct list_head *node, int n)
+{
+   if (n <= vq->desc_cache_thr)
+   list_add(node, >desc_cache);
+   else
+   kfree(node);
+}
+
+#define desc_cache_put(vq, desc, n) \
+   __desc_cache_put(vq, (struct list_head *)desc, n)
+
+static void *desc_cache_get(struct vring_virtqueue *vq,
+   int size, int n, gfp_t gfp)
+{
+   struct list_head *node;
+
+   if (n > vq->desc_cache_thr)
+   return kmalloc_array(n, size, gfp);
+
+   if (!list_empty(>desc_cache)) {
+   node = vq->desc_cache.next;
+   list_del(node);
+   return node;
+   }
+
+   return kmalloc_array(vq->desc_cache_thr, size, gfp);
+}
+
+#define _desc_cache_get(vq, n, gfp, tp) \
+   ((tp *)desc_cache_get(vq, (sizeof(tp)), n, gfp))
+
+#define desc_cache_get_split(vq, n, gfp) \
+   _desc_cache_get(vq, n, gfp, struct vring_desc)
+
+static struct vring_desc *alloc_indirect_split(struct vring_virtqueue *vq,
   unsigned int total_sg,
   gfp_t gfp)
 {
@@ -437,12 +492,12 @@ static struct vring_desc *alloc_indirect_split(struct 
virtqueue *_vq,
 */
gfp &= ~__GFP_HIGHMEM;
 
-   desc = kmalloc_array(total_sg, sizeof(struct vring_desc), gfp);
+   desc = desc_cache_get_split(vq, total_sg, gfp);
if (!desc)
return NULL;
 
for (i = 0; i < total_sg; i++)
-   desc[i].next = cpu_to_virtio16(_vq->vdev, i + 1);
+   desc[i].next = cpu_to_virtio16(vq->vq.vdev, i + 1);
return desc;
 }
 
@@ -508,7 +563,7 @@ static inline int virtqueue_add_split(struct virtqueue *_vq,
head = vq->free_head;
 
if (virtqueue_use_indirect(_vq, total_sg))
-   desc = alloc_indirect_split(_vq, total_sg, gfp);
+   desc = alloc_indirect_split(vq, total_sg, gfp);
else {
desc = NULL;
WARN_ON_ONCE(total_sg > vq->split.vring.num && !vq->indirect);
@@ -652,7 +707,7 @@ static inline int virtqueue_add_split(struct virtqueue *_vq,
}
 
if (indirect)
-   kfree(desc);
+   desc_cache_put(vq, desc, total_sg);
 
END_USE(vq);
return -ENOMEM;
@@ -717,7 +772,7 @@ static void detach_buf_split(struct vring_virtqueue *vq, 
unsigned int head,
if (vq->indirect) {
struct vring_desc *indir_desc =
vq->split.desc_state[head].indir_desc;
-  

[PATCH v2 0/3] virtio support cache indirect desc

2021-10-28 Thread Xuan Zhuo
If the VIRTIO_RING_F_INDIRECT_DESC negotiation succeeds, and the number
of sgs used for sending packets is greater than 1. We must constantly
call __kmalloc/kfree to allocate/release desc.

In the case of extremely fast package delivery, the overhead cannot be
ignored:

  27.46%  [kernel]  [k] virtqueue_add
  16.66%  [kernel]  [k] detach_buf_split
  16.51%  [kernel]  [k] virtnet_xsk_xmit
  14.04%  [kernel]  [k] virtqueue_add_outbuf
   5.18%  [kernel]  [k] __kmalloc
   4.08%  [kernel]  [k] kfree
   2.80%  [kernel]  [k] virtqueue_get_buf_ctx
   2.22%  [kernel]  [k] xsk_tx_peek_desc
   2.08%  [kernel]  [k] memset_erms
   0.83%  [kernel]  [k] virtqueue_kick_prepare
   0.76%  [kernel]  [k] virtnet_xsk_run
   0.62%  [kernel]  [k] __free_old_xmit_ptr
   0.60%  [kernel]  [k] vring_map_one_sg
   0.53%  [kernel]  [k] native_apic_mem_write
   0.46%  [kernel]  [k] sg_next
   0.43%  [kernel]  [k] sg_init_table
   0.41%  [kernel]  [k] kmalloc_slab

This patch adds a cache function to virtio to cache these allocated indirect
desc instead of constantly allocating and releasing desc.

v2:
  use struct list_head to cache the desc

Xuan Zhuo (3):
  virtio: cache indirect desc for split
  virtio: cache indirect desc for packed
  virtio-net: enable virtio indirect cache

 drivers/net/virtio_net.c |  12 
 drivers/virtio/virtio.c  |   6 ++
 drivers/virtio/virtio_ring.c | 104 +--
 include/linux/virtio.h   |  14 +
 4 files changed, 119 insertions(+), 17 deletions(-)

--
2.31.0

___
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization


[PATCH v2 2/3] virtio: cache indirect desc for packed

2021-10-28 Thread Xuan Zhuo
In the case of using indirect, indirect desc must be allocated and
released each time, which increases a lot of cpu overhead.

Here, a cache is added for indirect. If the number of indirect desc to be
applied for is less than VIRT_QUEUE_CACHE_DESC_NUM, the desc array with
the size of VIRT_QUEUE_CACHE_DESC_NUM is fixed and cached for reuse.

Signed-off-by: Xuan Zhuo 
---
 drivers/virtio/virtio_ring.c | 29 +++--
 1 file changed, 19 insertions(+), 10 deletions(-)

diff --git a/drivers/virtio/virtio_ring.c b/drivers/virtio/virtio_ring.c
index 0ebcd4f12d3b..e6d1985a87a8 100644
--- a/drivers/virtio/virtio_ring.c
+++ b/drivers/virtio/virtio_ring.c
@@ -1089,7 +1089,11 @@ static void vring_unmap_desc_packed(const struct 
vring_virtqueue *vq,
}
 }
 
-static struct vring_packed_desc *alloc_indirect_packed(unsigned int total_sg,
+#define desc_cache_get_packed(vq, n, gfp) \
+   _desc_cache_get(vq, n, gfp, struct vring_packed_desc)
+
+static struct vring_packed_desc *alloc_indirect_packed(struct vring_virtqueue 
*vq,
+  unsigned int total_sg,
   gfp_t gfp)
 {
struct vring_packed_desc *desc;
@@ -1101,7 +1105,7 @@ static struct vring_packed_desc 
*alloc_indirect_packed(unsigned int total_sg,
 */
gfp &= ~__GFP_HIGHMEM;
 
-   desc = kmalloc_array(total_sg, sizeof(struct vring_packed_desc), gfp);
+   desc = desc_cache_get_packed(vq, total_sg, gfp);
 
return desc;
 }
@@ -1121,7 +1125,7 @@ static int virtqueue_add_indirect_packed(struct 
vring_virtqueue *vq,
dma_addr_t addr;
 
head = vq->packed.next_avail_idx;
-   desc = alloc_indirect_packed(total_sg, gfp);
+   desc = alloc_indirect_packed(vq, total_sg, gfp);
 
if (unlikely(vq->vq.num_free < 1)) {
pr_debug("Can't add buf len 1 - avail = 0\n");
@@ -1212,7 +1216,7 @@ static int virtqueue_add_indirect_packed(struct 
vring_virtqueue *vq,
for (i = 0; i < err_idx; i++)
vring_unmap_desc_packed(vq, [i]);
 
-   kfree(desc);
+   desc_cache_put(vq, desc, total_sg);
 
END_USE(vq);
return -ENOMEM;
@@ -1437,20 +1441,22 @@ static void detach_buf_packed(struct vring_virtqueue 
*vq,
}
 
if (vq->indirect) {
-   u32 len;
+   u32 len, n;
 
/* Free the indirect table, if any, now that it's unmapped. */
desc = state->indir_desc;
if (!desc)
return;
 
+   len = vq->packed.desc_extra[id].len;
+   n = len / sizeof(struct vring_packed_desc);
+
if (vq->use_dma_api) {
-   len = vq->packed.desc_extra[id].len;
-   for (i = 0; i < len / sizeof(struct vring_packed_desc);
-   i++)
+   for (i = 0; i < n; i++)
vring_unmap_desc_packed(vq, [i]);
}
-   kfree(desc);
+
+   desc_cache_put(vq, desc, n);
state->indir_desc = NULL;
} else if (ctx) {
*ctx = state->indir_desc;
@@ -1768,6 +1774,9 @@ static struct virtqueue *vring_create_virtqueue_packed(
vq->indirect = virtio_has_feature(vdev, VIRTIO_RING_F_INDIRECT_DESC) &&
!context;
vq->event = virtio_has_feature(vdev, VIRTIO_RING_F_EVENT_IDX);
+   vq->desc_cache_thr = vdev->desc_cache_thr;
+
+   INIT_LIST_HEAD(>desc_cache);
 
if (virtio_has_feature(vdev, VIRTIO_F_ORDER_PLATFORM))
vq->weak_barriers = false;
@@ -2389,8 +2398,8 @@ void vring_del_virtqueue(struct virtqueue *_vq)
if (!vq->packed_ring) {
kfree(vq->split.desc_state);
kfree(vq->split.desc_extra);
-   desc_cache_free(>desc_cache);
}
+   desc_cache_free(>desc_cache);
kfree(vq);
 }
 EXPORT_SYMBOL_GPL(vring_del_virtqueue);
-- 
2.31.0

___
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization


[PATCH v2 4/4] hwrng: virtio - always add a pending request

2021-10-28 Thread Laurent Vivier
If we ensure we have already some data available by enqueuing
again the buffer once data are exhausted, we can return what we
have without waiting for the device answer.

Signed-off-by: Laurent Vivier 
---
 drivers/char/hw_random/virtio-rng.c | 26 --
 1 file changed, 12 insertions(+), 14 deletions(-)

diff --git a/drivers/char/hw_random/virtio-rng.c 
b/drivers/char/hw_random/virtio-rng.c
index 8ba97cf4ca8f..0a7dde135db1 100644
--- a/drivers/char/hw_random/virtio-rng.c
+++ b/drivers/char/hw_random/virtio-rng.c
@@ -20,7 +20,6 @@ struct virtrng_info {
struct virtqueue *vq;
char name[25];
int index;
-   bool busy;
bool hwrng_register_done;
bool hwrng_removed;
/* data transfer */
@@ -44,16 +43,18 @@ static void random_recv_done(struct virtqueue *vq)
return;
 
vi->data_idx = 0;
-   vi->busy = false;
 
complete(>have_data);
 }
 
-/* The host will fill any buffer we give it with sweet, sweet randomness. */
-static void register_buffer(struct virtrng_info *vi)
+static void request_entropy(struct virtrng_info *vi)
 {
struct scatterlist sg;
 
+   reinit_completion(>have_data);
+   vi->data_avail = 0;
+   vi->data_idx = 0;
+
sg_init_one(, vi->data, sizeof(vi->data));
 
/* There should always be room for one buffer. */
@@ -69,6 +70,8 @@ static unsigned int copy_data(struct virtrng_info *vi, void 
*buf,
memcpy(buf, vi->data + vi->data_idx, size);
vi->data_idx += size;
vi->data_avail -= size;
+   if (vi->data_avail == 0)
+   request_entropy(vi);
return size;
 }
 
@@ -98,13 +101,7 @@ static int virtio_read(struct hwrng *rng, void *buf, size_t 
size, bool wait)
 * so either size is 0 or data_avail is 0
 */
while (size != 0) {
-   /* data_avail is 0 */
-   if (!vi->busy) {
-   /* no pending request, ask for more */
-   vi->busy = true;
-   reinit_completion(>have_data);
-   register_buffer(vi);
-   }
+   /* data_avail is 0 but a request is pending */
ret = wait_for_completion_killable(>have_data);
if (ret < 0)
return ret;
@@ -126,8 +123,7 @@ static void virtio_cleanup(struct hwrng *rng)
 {
struct virtrng_info *vi = (struct virtrng_info *)rng->priv;
 
-   if (vi->busy)
-   complete(>have_data);
+   complete(>have_data);
 }
 
 static int probe_common(struct virtio_device *vdev)
@@ -163,6 +159,9 @@ static int probe_common(struct virtio_device *vdev)
goto err_find;
}
 
+   /* we always have a pending entropy request */
+   request_entropy(vi);
+
return 0;
 
 err_find:
@@ -181,7 +180,6 @@ static void remove_common(struct virtio_device *vdev)
vi->data_idx = 0;
complete(>have_data);
vdev->config->reset(vdev);
-   vi->busy = false;
if (vi->hwrng_register_done)
hwrng_unregister(>hwrng);
vdev->config->del_vqs(vdev);
-- 
2.31.1

___
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization


[PATCH v2 3/4] hwrng: virtio - don't waste entropy

2021-10-28 Thread Laurent Vivier
if we don't use all the entropy available in the buffer, keep it
and use it later.

Signed-off-by: Laurent Vivier 
---
 drivers/char/hw_random/virtio-rng.c | 52 +++--
 1 file changed, 35 insertions(+), 17 deletions(-)

diff --git a/drivers/char/hw_random/virtio-rng.c 
b/drivers/char/hw_random/virtio-rng.c
index 173aeea835bb..8ba97cf4ca8f 100644
--- a/drivers/char/hw_random/virtio-rng.c
+++ b/drivers/char/hw_random/virtio-rng.c
@@ -26,6 +26,7 @@ struct virtrng_info {
/* data transfer */
struct completion have_data;
unsigned int data_avail;
+   unsigned int data_idx;
/* minimal size returned by rng_buffer_size() */
 #if SMP_CACHE_BYTES < 32
u8 data[32];
@@ -42,6 +43,9 @@ static void random_recv_done(struct virtqueue *vq)
if (!virtqueue_get_buf(vi->vq, >data_avail))
return;
 
+   vi->data_idx = 0;
+   vi->busy = false;
+
complete(>have_data);
 }
 
@@ -58,6 +62,16 @@ static void register_buffer(struct virtrng_info *vi)
virtqueue_kick(vi->vq);
 }
 
+static unsigned int copy_data(struct virtrng_info *vi, void *buf,
+ unsigned int size)
+{
+   size = min_t(unsigned int, size, vi->data_avail);
+   memcpy(buf, vi->data + vi->data_idx, size);
+   vi->data_idx += size;
+   vi->data_avail -= size;
+   return size;
+}
+
 static int virtio_read(struct hwrng *rng, void *buf, size_t size, bool wait)
 {
int ret;
@@ -68,17 +82,29 @@ static int virtio_read(struct hwrng *rng, void *buf, size_t 
size, bool wait)
if (vi->hwrng_removed)
return -ENODEV;
 
-   if (!vi->busy) {
-   vi->busy = true;
-   reinit_completion(>have_data);
-   register_buffer(vi);
+   read = 0;
+
+   /* copy available data */
+   if (vi->data_avail) {
+   chunk = copy_data(vi, buf, size);
+   size -= chunk;
+   read += chunk;
}
 
if (!wait)
-   return 0;
+   return read;
 
-   read = 0;
+   /* We have already copied available entropy,
+* so either size is 0 or data_avail is 0
+*/
while (size != 0) {
+   /* data_avail is 0 */
+   if (!vi->busy) {
+   /* no pending request, ask for more */
+   vi->busy = true;
+   reinit_completion(>have_data);
+   register_buffer(vi);
+   }
ret = wait_for_completion_killable(>have_data);
if (ret < 0)
return ret;
@@ -88,20 +114,11 @@ static int virtio_read(struct hwrng *rng, void *buf, 
size_t size, bool wait)
if (vi->data_avail == 0)
return read;
 
-   chunk = min_t(unsigned int, size, vi->data_avail);
-   memcpy(buf + read, vi->data, chunk);
-   read += chunk;
+   chunk = copy_data(vi, buf + read, size);
size -= chunk;
-   vi->data_avail = 0;
-
-   if (size != 0) {
-   reinit_completion(>have_data);
-   register_buffer(vi);
-   }
+   read += chunk;
}
 
-   vi->busy = false;
-
return read;
 }
 
@@ -161,6 +178,7 @@ static void remove_common(struct virtio_device *vdev)
 
vi->hwrng_removed = true;
vi->data_avail = 0;
+   vi->data_idx = 0;
complete(>have_data);
vdev->config->reset(vdev);
vi->busy = false;
-- 
2.31.1

___
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization


[PATCH v2 2/4] hwrng: virtio - don't wait on cleanup

2021-10-28 Thread Laurent Vivier
When virtio-rng device was dropped by the hwrng core we were forced
to wait the buffer to come back from the device to not have
remaining ongoing operation that could spoil the buffer.

But now, as the buffer is internal to the virtio-rng we can release
the waiting loop immediately, the buffer will be retrieve and use
when the virtio-rng driver will be selected again.

This avoids to hang on an rng_current write command if the virtio-rng
device is blocked by a lack of entropy. This allows to select
another entropy source if the current one is empty.

Signed-off-by: Laurent Vivier 
---
 drivers/char/hw_random/virtio-rng.c | 7 ++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/drivers/char/hw_random/virtio-rng.c 
b/drivers/char/hw_random/virtio-rng.c
index 208c547dcac1..173aeea835bb 100644
--- a/drivers/char/hw_random/virtio-rng.c
+++ b/drivers/char/hw_random/virtio-rng.c
@@ -82,6 +82,11 @@ static int virtio_read(struct hwrng *rng, void *buf, size_t 
size, bool wait)
ret = wait_for_completion_killable(>have_data);
if (ret < 0)
return ret;
+   /* if vi->data_avail is 0, we have been interrupted
+* by a cleanup, but buffer stays in the queue
+*/
+   if (vi->data_avail == 0)
+   return read;
 
chunk = min_t(unsigned int, size, vi->data_avail);
memcpy(buf + read, vi->data, chunk);
@@ -105,7 +110,7 @@ static void virtio_cleanup(struct hwrng *rng)
struct virtrng_info *vi = (struct virtrng_info *)rng->priv;
 
if (vi->busy)
-   wait_for_completion(>have_data);
+   complete(>have_data);
 }
 
 static int probe_common(struct virtio_device *vdev)
-- 
2.31.1

___
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization


[PATCH v2 1/4] hwrng: virtio - add an internal buffer

2021-10-28 Thread Laurent Vivier
hwrng core uses two buffers that can be mixed in the
virtio-rng queue.

If the buffer is provided with wait=0 it is enqueued in the
virtio-rng queue but unused by the caller.
On the next call, core provides another buffer but the
first one is filled instead and the new one queued.
And the caller reads the data from the new one that is not
updated, and the data in the first one are lost.

To avoid this mix, virtio-rng needs to use its own unique
internal buffer at a cost of a data copy to the caller buffer.

Signed-off-by: Laurent Vivier 
---
 drivers/char/hw_random/virtio-rng.c | 43 ++---
 1 file changed, 33 insertions(+), 10 deletions(-)

diff --git a/drivers/char/hw_random/virtio-rng.c 
b/drivers/char/hw_random/virtio-rng.c
index a90001e02bf7..208c547dcac1 100644
--- a/drivers/char/hw_random/virtio-rng.c
+++ b/drivers/char/hw_random/virtio-rng.c
@@ -18,13 +18,20 @@ static DEFINE_IDA(rng_index_ida);
 struct virtrng_info {
struct hwrng hwrng;
struct virtqueue *vq;
-   struct completion have_data;
char name[25];
-   unsigned int data_avail;
int index;
bool busy;
bool hwrng_register_done;
bool hwrng_removed;
+   /* data transfer */
+   struct completion have_data;
+   unsigned int data_avail;
+   /* minimal size returned by rng_buffer_size() */
+#if SMP_CACHE_BYTES < 32
+   u8 data[32];
+#else
+   u8 data[SMP_CACHE_BYTES];
+#endif
 };
 
 static void random_recv_done(struct virtqueue *vq)
@@ -39,14 +46,14 @@ static void random_recv_done(struct virtqueue *vq)
 }
 
 /* The host will fill any buffer we give it with sweet, sweet randomness. */
-static void register_buffer(struct virtrng_info *vi, u8 *buf, size_t size)
+static void register_buffer(struct virtrng_info *vi)
 {
struct scatterlist sg;
 
-   sg_init_one(, buf, size);
+   sg_init_one(, vi->data, sizeof(vi->data));
 
/* There should always be room for one buffer. */
-   virtqueue_add_inbuf(vi->vq, , 1, buf, GFP_KERNEL);
+   virtqueue_add_inbuf(vi->vq, , 1, vi->data, GFP_KERNEL);
 
virtqueue_kick(vi->vq);
 }
@@ -55,6 +62,8 @@ static int virtio_read(struct hwrng *rng, void *buf, size_t 
size, bool wait)
 {
int ret;
struct virtrng_info *vi = (struct virtrng_info *)rng->priv;
+   unsigned int chunk;
+   size_t read;
 
if (vi->hwrng_removed)
return -ENODEV;
@@ -62,19 +71,33 @@ static int virtio_read(struct hwrng *rng, void *buf, size_t 
size, bool wait)
if (!vi->busy) {
vi->busy = true;
reinit_completion(>have_data);
-   register_buffer(vi, buf, size);
+   register_buffer(vi);
}
 
if (!wait)
return 0;
 
-   ret = wait_for_completion_killable(>have_data);
-   if (ret < 0)
-   return ret;
+   read = 0;
+   while (size != 0) {
+   ret = wait_for_completion_killable(>have_data);
+   if (ret < 0)
+   return ret;
+
+   chunk = min_t(unsigned int, size, vi->data_avail);
+   memcpy(buf + read, vi->data, chunk);
+   read += chunk;
+   size -= chunk;
+   vi->data_avail = 0;
+
+   if (size != 0) {
+   reinit_completion(>have_data);
+   register_buffer(vi);
+   }
+   }
 
vi->busy = false;
 
-   return vi->data_avail;
+   return read;
 }
 
 static void virtio_cleanup(struct hwrng *rng)
-- 
2.31.1

___
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization


[PATCH v2 0/4] hwrng: virtio - add an internal buffer

2021-10-28 Thread Laurent Vivier
hwrng core uses two buffers that can be mixed in the virtio-rng queue.

This series fixes the problem by adding an internal buffer in virtio-rng.

Once the internal buffer is added, we can fix two other problems:

- to be able to release the driver without waiting the device releases the
  buffer

- actually returns some data when wait=0 as we can have some already
  available data

It also tries to improve the performance by always having a buffer in
the queue of the device.

v2:
fixes issue reported by syzbot+b86736b5935e0d25b...@syzkaller.appspotmail.com
by reseting data_idx to 0 when the buffer is submitted not when it is
received as the consumer checks for data_avail, not only for the completion.

Laurent Vivier (4):
  hwrng: virtio - add an internal buffer
  hwrng: virtio - don't wait on cleanup
  hwrng: virtio - don't waste entropy
  hwrng: virtio - always add a pending request

 drivers/char/hw_random/virtio-rng.c | 86 ++---
 1 file changed, 65 insertions(+), 21 deletions(-)

-- 
2.31.1


___
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization


RE: vDPA bus driver selection

2021-10-28 Thread Parav Pandit via Virtualization



> From: Stefano Garzarella 
> Sent: Thursday, October 28, 2021 3:08 PM

> >> >$ vdpa/vdpa dev add mgmtdev vdpasim_net name vdpa0 mac
> >> >00:11:22:33:44:55 $ echo 0 > /sys/bus/vdpa/drivers_autoprobe
> >> >
> >> >And after vdpa device creation, it manually binds to the desired
> >> >driver such as,
> >> >
> >> >$ echo vdpa0 > /sys/bus/vdpa/drivers/virtio_vdpa/bind
> >> >Or
> >> >$ echo vdpa0 > /sys/bus/vdpa/drivers/vhost_vdpa/bind
> >>
> >> Cool, I didn't know that. This is very useful, but do you think it
> >> might be better to integrate it with the netlink API and specify at
> >> creation which bus driver to use?
> >I think it is useful; for vduse case we need the ability to say "none"
> >as well and when nothing specified it should be default driver.
> 
> Yep, the default can be the actual behaviour.
> 
> >
> >More than netlink, I think we need the ability in the core kernel to
> >make this choice.
> 
> Okay, but I think we can include that in the vdpa tool.
If functionality and interface exists in other part of the it is hard to wrap 
that in vdpa tool that does the duplicate work.

> 
> >I haven't explored what is already available to make that happen.
> 
> Me too, I only saw the .match() callback of "struct bus_type" that could be 
> used
> for this purpose.
> 
> >If/once its available, I am sure it has more users than just vdpa.
> 
> Make sense. I'll spend some time next week.

Ok. yeah, may be a desired driver can be stored in the vdpa_device that match() 
routine can use.
And if that driver is not available,  it returns EPROBE_DEFER; so whenever such 
driver is loaded it can be bind.

But I think before wrapping something in vdpa, need to find a reason why the 
current interface doesn't solve the problem and also to figure out plumbing.

___
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization


Re: vDPA bus driver selection

2021-10-28 Thread Stefano Garzarella

On Thu, Oct 28, 2021 at 10:24:47AM +0800, Jason Wang wrote:

On Thu, Oct 28, 2021 at 4:16 AM Michael S. Tsirkin  wrote:


On Wed, Oct 27, 2021 at 03:21:15PM +, Parav Pandit wrote:
> Hi Stefano,
>
> > From: Stefano Garzarella 
> > Sent: Wednesday, October 27, 2021 8:04 PM
> >
> > Hi folks,
> > I was trying to understand if we have a way to specify which vDPA bus driver
> > (e.g. vhost-vdpa, virtio-vdpa) a device should use.
> > IIUC we don't have it, and the first registered driver is used when a new 
device
> > is registered.
> >
> > I was thinking if it makes sense to extend the management API to specify 
which
> > bus driver to use for a device.


Actually, we want to support this in the first version of vDPA bus.
But for some reason it was dropped. The idea is to specify the device
type 'virtio' or 'vhost'. But a concern is that, it may encourage
vendor to implement e.g virtio specific device (without DMA
isolation).


Yep, I see the issue about device type, so I think make sense to require 
the support of both, how it is now basically.


So instead of defining the type of the device, we could provide the 
possibility to choose which bus to connect it to, in this way we 
continue to require that both are supported.


As Michael suggested, instead of specify it at the creation time as was 
in my original idea, we can provide an API to attach/detach a device to 
a specific vDPA bus.


Of course, providing a default behaviour like now, which connects to the 
first registered.


Thanks,
Stefano

___
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization


Re: vDPA bus driver selection

2021-10-28 Thread Stefano Garzarella

On Wed, Oct 27, 2021 at 03:56:16PM +, Parav Pandit wrote:

Hi Stefano,


From: Stefano Garzarella 
Sent: Wednesday, October 27, 2021 9:17 PM
To: Parav Pandit 
Cc: Jason Wang ; Michael Tsirkin ;
Linux Virtualization ; Eli Cohen

Subject: Re: vDPA bus driver selection

Hi Parav,

On Wed, Oct 27, 2021 at 03:21:15PM +, Parav Pandit wrote:
>Hi Stefano,
>
>> From: Stefano Garzarella 
>> Sent: Wednesday, October 27, 2021 8:04 PM
>>
>> Hi folks,
>> I was trying to understand if we have a way to specify which vDPA bus
>> driver (e.g. vhost-vdpa, virtio-vdpa) a device should use.
>> IIUC we don't have it, and the first registered driver is used when a
>> new device is registered.
>>
>> I was thinking if it makes sense to extend the management API to
>> specify which bus driver to use for a device. A use case could be for
>> example a single host handling VMs and bare-metal containers, so we
>> would have both virtio-vdpa and vhost-vdpa loaded and we want to
>> attach some devices to VMs through vhost-vdpa and others to containers
through virtio-vdpa.
>>
>> What do you think?
>>
>One option is, user keeps the drivers_autoprobe disabled for the vdpa
>bus using,
>
>$ vdpa/vdpa dev add mgmtdev vdpasim_net name vdpa0 mac
>00:11:22:33:44:55 $ echo 0 > /sys/bus/vdpa/drivers_autoprobe
>
>And after vdpa device creation, it manually binds to the desired driver
>such as,
>
>$ echo vdpa0 > /sys/bus/vdpa/drivers/virtio_vdpa/bind
>Or
>$ echo vdpa0 > /sys/bus/vdpa/drivers/vhost_vdpa/bind

Cool, I didn't know that. This is very useful, but do you think it might be 
better
to integrate it with the netlink API and specify at creation which bus driver to
use?
I think it is useful; for vduse case we need the ability to say "none" 
as well and when nothing specified it should be default driver.


Yep, the default can be the actual behaviour.



More than netlink, I think we need the ability in the core kernel to 
make this choice.


Okay, but I think we can include that in the vdpa tool.


I haven't explored what is already available to make that happen.


Me too, I only saw the .match() callback of "struct bus_type" that could 
be used for this purpose.



If/once its available, I am sure it has more users than just vdpa.


Make sense. I'll spend some time next week.

Thanks,
Stefano

___
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization


Re: vDPA bus driver selection

2021-10-28 Thread Stefano Garzarella

On Wed, Oct 27, 2021 at 02:45:15PM -0400, Michael S. Tsirkin wrote:

On Wed, Oct 27, 2021 at 04:33:50PM +0200, Stefano Garzarella wrote:

Hi folks,
I was trying to understand if we have a way to specify which vDPA bus
driver (e.g. vhost-vdpa, virtio-vdpa) a device should use.
IIUC we don't have it, and the first registered driver is used when a
new device is registered.

I was thinking if it makes sense to extend the management API to
specify which bus driver to use for a device. A use case could be for
example a single host handling VMs and bare-metal containers, so we
would have both virtio-vdpa and vhost-vdpa loaded and we want to
attach some devices to VMs through vhost-vdpa and others to containers
through virtio-vdpa.

What do you think?

I can prepare an RFC with some code, the idea is to use the .match
callback of "struct bus_type" to use a driver instead of the other,
and extend netlink API to specify the vDPA bus driver name to use.

Thanks,
Stefano


So I think that doing this at create time is somewhat limited.
For example a great way to do migration could be to unbind
device from VM then bind virtio on the host to it, then
bind macvtap to that.


Yep, make sense!



Ideas on how to allow that?


Maybe we can split the device creation and the attach (probe) in two 
APIs, then we can add a detach API to allow changing bus.


Anyway I need to check the code better, but I think it's doable.

Stefano

___
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization


[PATCH 4/4] drm/qxl: use iterator instead of dma_resv_shared_list

2021-10-28 Thread Christian König
I'm not sure why it is useful to know the number of fences
in the reservation object, but we try to avoid exposing the
dma_resv_shared_list() function.

So use the iterator instead. If more information is desired
we could use dma_resv_describe() as well.

Signed-off-by: Christian König 
---
 drivers/gpu/drm/qxl/qxl_debugfs.c | 17 ++---
 1 file changed, 10 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/qxl/qxl_debugfs.c 
b/drivers/gpu/drm/qxl/qxl_debugfs.c
index 1f9a59601bb1..6a36b0fd845c 100644
--- a/drivers/gpu/drm/qxl/qxl_debugfs.c
+++ b/drivers/gpu/drm/qxl/qxl_debugfs.c
@@ -57,13 +57,16 @@ qxl_debugfs_buffers_info(struct seq_file *m, void *data)
struct qxl_bo *bo;
 
list_for_each_entry(bo, >gem.objects, list) {
-   struct dma_resv_list *fobj;
-   int rel;
-
-   rcu_read_lock();
-   fobj = dma_resv_shared_list(bo->tbo.base.resv);
-   rel = fobj ? fobj->shared_count : 0;
-   rcu_read_unlock();
+   struct dma_resv_iter cursor;
+   struct dma_fence *fence;
+   int rel = 0;
+
+   dma_resv_iter_begin(, bo->tbo.base.resv, true);
+   dma_resv_for_each_fence_unlocked(, fence) {
+   if (dma_resv_iter_is_restarted())
+   rel = 0;
+   ++rel;
+   }
 
seq_printf(m, "size %ld, pc %d, num releases %d\n",
   (unsigned long)bo->tbo.base.size,
-- 
2.25.1

___
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization

[PATCH 3/4] drm/etnaviv: use dma_resv_describe

2021-10-28 Thread Christian König
Instead of dumping the fence info manually.

Signed-off-by: Christian König 
Reviewed-by: Rob Clark 
---
 drivers/gpu/drm/etnaviv/etnaviv_gem.c | 26 +++---
 1 file changed, 7 insertions(+), 19 deletions(-)

diff --git a/drivers/gpu/drm/etnaviv/etnaviv_gem.c 
b/drivers/gpu/drm/etnaviv/etnaviv_gem.c
index b018693e3877..d5314aa28ff7 100644
--- a/drivers/gpu/drm/etnaviv/etnaviv_gem.c
+++ b/drivers/gpu/drm/etnaviv/etnaviv_gem.c
@@ -424,36 +424,24 @@ int etnaviv_gem_wait_bo(struct etnaviv_gpu *gpu, struct 
drm_gem_object *obj,
 }
 
 #ifdef CONFIG_DEBUG_FS
-static void etnaviv_gem_describe_fence(struct dma_fence *fence,
-   const char *type, struct seq_file *m)
-{
-   seq_printf(m, "\t%9s: %s %s seq %llu\n", type,
-  fence->ops->get_driver_name(fence),
-  fence->ops->get_timeline_name(fence),
-  fence->seqno);
-}
-
 static void etnaviv_gem_describe(struct drm_gem_object *obj, struct seq_file 
*m)
 {
struct etnaviv_gem_object *etnaviv_obj = to_etnaviv_bo(obj);
struct dma_resv *robj = obj->resv;
-   struct dma_resv_iter cursor;
-   struct dma_fence *fence;
unsigned long off = drm_vma_node_start(>vma_node);
+   int r;
 
seq_printf(m, "%08x: %c %2d (%2d) %08lx %p %zd\n",
etnaviv_obj->flags, is_active(etnaviv_obj) ? 'A' : 'I',
obj->name, kref_read(>refcount),
off, etnaviv_obj->vaddr, obj->size);
 
-   dma_resv_iter_begin(, robj, true);
-   dma_resv_for_each_fence_unlocked(, fence) {
-   if (dma_resv_iter_is_exclusive())
-   etnaviv_gem_describe_fence(fence, "Exclusive", m);
-   else
-   etnaviv_gem_describe_fence(fence, "Shared", m);
-   }
-   dma_resv_iter_end();
+   r = dma_resv_lock(robj, NULL);
+   if (r)
+   return;
+
+   dma_resv_describe(robj, m);
+   dma_resv_unlock(robj);
 }
 
 void etnaviv_gem_describe_objects(struct etnaviv_drm_private *priv,
-- 
2.25.1

___
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization

[PATCH 2/4] drm/msm: use the new dma_resv_describe

2021-10-28 Thread Christian König
Instead of hand rolling pretty much the same code.

Signed-off-by: Christian König 
Reviewed-by: Rob Clark 
---
 drivers/gpu/drm/msm/msm_gem.c | 20 +---
 1 file changed, 1 insertion(+), 19 deletions(-)

diff --git a/drivers/gpu/drm/msm/msm_gem.c b/drivers/gpu/drm/msm/msm_gem.c
index 5bd511f07c07..3878b8dc2d59 100644
--- a/drivers/gpu/drm/msm/msm_gem.c
+++ b/drivers/gpu/drm/msm/msm_gem.c
@@ -865,23 +865,11 @@ int msm_gem_cpu_fini(struct drm_gem_object *obj)
 }
 
 #ifdef CONFIG_DEBUG_FS
-static void describe_fence(struct dma_fence *fence, const char *type,
-   struct seq_file *m)
-{
-   if (!dma_fence_is_signaled(fence))
-   seq_printf(m, "\t%9s: %s %s seq %llu\n", type,
-   fence->ops->get_driver_name(fence),
-   fence->ops->get_timeline_name(fence),
-   fence->seqno);
-}
-
 void msm_gem_describe(struct drm_gem_object *obj, struct seq_file *m,
struct msm_gem_stats *stats)
 {
struct msm_gem_object *msm_obj = to_msm_bo(obj);
struct dma_resv *robj = obj->resv;
-   struct dma_resv_iter cursor;
-   struct dma_fence *fence;
struct msm_gem_vma *vma;
uint64_t off = drm_vma_node_start(>vma_node);
const char *madv;
@@ -955,13 +943,7 @@ void msm_gem_describe(struct drm_gem_object *obj, struct 
seq_file *m,
seq_puts(m, "\n");
}
 
-   dma_resv_for_each_fence(, robj, true, fence) {
-   if (dma_resv_iter_is_exclusive())
-   describe_fence(fence, "Exclusive", m);
-   else
-   describe_fence(fence, "Shared", m);
-   }
-
+   dma_resv_describe(robj, m);
msm_gem_unlock(obj);
 }
 
-- 
2.25.1

___
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization

[PATCH 1/4] dma-buf: add dma_fence_describe and dma_resv_describe

2021-10-28 Thread Christian König
Add functions to dump dma_fence and dma_resv objects into a seq_file and
use them for printing the debugfs informations.

Signed-off-by: Christian König 
Reviewed-by: Rob Clark 
---
 drivers/dma-buf/dma-buf.c   | 11 +--
 drivers/dma-buf/dma-fence.c | 16 
 drivers/dma-buf/dma-resv.c  | 23 +++
 include/linux/dma-fence.h   |  1 +
 include/linux/dma-resv.h|  1 +
 5 files changed, 42 insertions(+), 10 deletions(-)

diff --git a/drivers/dma-buf/dma-buf.c b/drivers/dma-buf/dma-buf.c
index 7b619998f03a..1d6f6c6a0b09 100644
--- a/drivers/dma-buf/dma-buf.c
+++ b/drivers/dma-buf/dma-buf.c
@@ -1332,8 +1332,6 @@ static int dma_buf_debug_show(struct seq_file *s, void 
*unused)
 {
struct dma_buf *buf_obj;
struct dma_buf_attachment *attach_obj;
-   struct dma_resv_iter cursor;
-   struct dma_fence *fence;
int count = 0, attach_count;
size_t size = 0;
int ret;
@@ -1361,14 +1359,7 @@ static int dma_buf_debug_show(struct seq_file *s, void 
*unused)
file_inode(buf_obj->file)->i_ino,
buf_obj->name ?: "");
 
-   dma_resv_for_each_fence(, buf_obj->resv, true, fence) {
-   seq_printf(s, "\t%s fence: %s %s %ssignalled\n",
-  dma_resv_iter_is_exclusive() ?
-   "Exclusive" : "Shared",
-  fence->ops->get_driver_name(fence),
-  fence->ops->get_timeline_name(fence),
-  dma_fence_is_signaled(fence) ? "" : "un");
-   }
+   dma_resv_describe(buf_obj->resv, s);
 
seq_puts(s, "\tAttached Devices:\n");
attach_count = 0;
diff --git a/drivers/dma-buf/dma-fence.c b/drivers/dma-buf/dma-fence.c
index 1e82ecd443fa..5175adf58644 100644
--- a/drivers/dma-buf/dma-fence.c
+++ b/drivers/dma-buf/dma-fence.c
@@ -907,6 +907,22 @@ dma_fence_wait_any_timeout(struct dma_fence **fences, 
uint32_t count,
 }
 EXPORT_SYMBOL(dma_fence_wait_any_timeout);
 
+/**
+ * dma_fence_describe - Dump fence describtion into seq_file
+ * @fence: the 6fence to describe
+ * @seq: the seq_file to put the textual description into
+ *
+ * Dump a textual description of the fence and it's state into the seq_file.
+ */
+void dma_fence_describe(struct dma_fence *fence, struct seq_file *seq)
+{
+   seq_printf(seq, "%s %s seq %llu %ssignalled\n",
+  fence->ops->get_driver_name(fence),
+  fence->ops->get_timeline_name(fence), fence->seqno,
+  dma_fence_is_signaled(fence) ? "" : "un");
+}
+EXPORT_SYMBOL(dma_fence_describe);
+
 /**
  * dma_fence_init - Initialize a custom fence.
  * @fence: the fence to initialize
diff --git a/drivers/dma-buf/dma-resv.c b/drivers/dma-buf/dma-resv.c
index 9eb2baa387d4..ff3c0558b3b8 100644
--- a/drivers/dma-buf/dma-resv.c
+++ b/drivers/dma-buf/dma-resv.c
@@ -38,6 +38,7 @@
 #include 
 #include 
 #include 
+#include 
 
 /**
  * DOC: Reservation Object Overview
@@ -666,6 +667,28 @@ bool dma_resv_test_signaled(struct dma_resv *obj, bool 
test_all)
 }
 EXPORT_SYMBOL_GPL(dma_resv_test_signaled);
 
+/**
+ * dma_resv_describe - Dump description of the resv object into seq_file
+ * @obj: the reservation object
+ * @seq: the seq_file to dump the description into
+ *
+ * Dump a textual description of the fences inside an dma_resv object into the
+ * seq_file.
+ */
+void dma_resv_describe(struct dma_resv *obj, struct seq_file *seq)
+{
+   struct dma_resv_iter cursor;
+   struct dma_fence *fence;
+
+   dma_resv_for_each_fence(, obj, true, fence) {
+   seq_printf(seq, "\t%s fence:",
+  dma_resv_iter_is_exclusive() ?
+   "Exclusive" : "Shared");
+   dma_fence_describe(fence, seq);
+   }
+}
+EXPORT_SYMBOL_GPL(dma_resv_describe);
+
 #if IS_ENABLED(CONFIG_LOCKDEP)
 static int __init dma_resv_lockdep(void)
 {
diff --git a/include/linux/dma-fence.h b/include/linux/dma-fence.h
index a706b7bf51d7..1ea691753bd3 100644
--- a/include/linux/dma-fence.h
+++ b/include/linux/dma-fence.h
@@ -264,6 +264,7 @@ void dma_fence_init(struct dma_fence *fence, const struct 
dma_fence_ops *ops,
 
 void dma_fence_release(struct kref *kref);
 void dma_fence_free(struct dma_fence *fence);
+void dma_fence_describe(struct dma_fence *fence, struct seq_file *seq);
 
 /**
  * dma_fence_put - decreases refcount of the fence
diff --git a/include/linux/dma-resv.h b/include/linux/dma-resv.h
index dbd235ab447f..09c6063b199a 100644
--- a/include/linux/dma-resv.h
+++ b/include/linux/dma-resv.h
@@ -490,5 +490,6 @@ int dma_resv_copy_fences(struct dma_resv *dst, struct 
dma_resv *src);
 long dma_resv_wait_timeout(struct dma_resv *obj, bool wait_all, bool intr,
   unsigned long timeout);
 bool dma_resv_test_signaled(struct dma_resv *obj, bool 

Re: [PATCH][next] virtio_blk: Fix spelling mistake: "advertisted" -> "advertised"

2021-10-28 Thread Stefan Hajnoczi
On Mon, Oct 25, 2021 at 11:22:40AM +0100, Colin Ian King wrote:
> There is a spelling mistake in a dev_err error message. Fix it.
> 
> Signed-off-by: Colin Ian King 
> ---
>  drivers/block/virtio_blk.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)

Reviewed-by: Stefan Hajnoczi 


signature.asc
Description: PGP signature
___
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization

Re: [PATCH 2/3] virtio: cache indirect desc for packed

2021-10-28 Thread kernel test robot
Hi Xuan,

Thank you for the patch! Yet something to improve:

[auto build test ERROR on horms-ipvs/master]
[also build test ERROR on linus/master v5.15-rc7]
[cannot apply to mst-vhost/linux-next next-20211027]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]

url:
https://github.com/0day-ci/linux/commits/Xuan-Zhuo/virtio-support-cache-indirect-desc/20211027-142025
base:   https://git.kernel.org/pub/scm/linux/kernel/git/horms/ipvs.git master
config: i386-buildonly-randconfig-r005-20211027 (attached as .config)
compiler: clang version 14.0.0 (https://github.com/llvm/llvm-project 
5db7568a6a1fcb408eb8988abdaff2a225a8eb72)
reproduce (this is a W=1 build):
wget 
https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O 
~/bin/make.cross
chmod +x ~/bin/make.cross
# 
https://github.com/0day-ci/linux/commit/bb65ceda850ed4592d8a940e01926d5e3d33ae92
git remote add linux-review https://github.com/0day-ci/linux
git fetch --no-tags linux-review 
Xuan-Zhuo/virtio-support-cache-indirect-desc/20211027-142025
git checkout bb65ceda850ed4592d8a940e01926d5e3d33ae92
# save the attached .config to linux build tree
COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross W=1 
ARCH=i386 

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot 

All errors (new ones prefixed by >>):

>> drivers/virtio/virtio_ring.c:1467:7: error: variable 'len' is uninitialized 
>> when used here [-Werror,-Wuninitialized]
   n = len / sizeof(struct vring_packed_desc);
   ^~~
   drivers/virtio/virtio_ring.c:1460:10: note: initialize the variable 'len' to 
silence this warning
   u32 len, n;
  ^
   = 0
   1 error generated.


vim +/len +1467 drivers/virtio/virtio_ring.c

  1433  
  1434  static void detach_buf_packed(struct vring_virtqueue *vq,
  1435unsigned int id, void **ctx)
  1436  {
  1437  struct vring_desc_state_packed *state = NULL;
  1438  struct vring_packed_desc *desc;
  1439  unsigned int i, curr;
  1440  
  1441  state = >packed.desc_state[id];
  1442  
  1443  /* Clear data ptr. */
  1444  state->data = NULL;
  1445  
  1446  vq->packed.desc_extra[state->last].next = vq->free_head;
  1447  vq->free_head = id;
  1448  vq->vq.num_free += state->num;
  1449  
  1450  if (unlikely(vq->use_dma_api)) {
  1451  curr = id;
  1452  for (i = 0; i < state->num; i++) {
  1453  vring_unmap_state_packed(vq,
  1454  >packed.desc_extra[curr]);
  1455  curr = vq->packed.desc_extra[curr].next;
  1456  }
  1457  }
  1458  
  1459  if (vq->indirect) {
  1460  u32 len, n;
  1461  
  1462  /* Free the indirect table, if any, now that it's 
unmapped. */
  1463  desc = state->indir_desc;
  1464  if (!desc)
  1465  return;
  1466  
> 1467  n = len / sizeof(struct vring_packed_desc);
  1468  
  1469  if (vq->use_dma_api) {
  1470  len = vq->packed.desc_extra[id].len;
  1471  for (i = 0; i < n; i++)
  1472  vring_unmap_desc_packed(vq, [i]);
  1473  }
  1474  
  1475  desc_cache_put_packed(vq, desc, n);
  1476  state->indir_desc = NULL;
  1477  } else if (ctx) {
  1478  *ctx = state->indir_desc;
  1479  }
  1480  }
  1481  

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-...@lists.01.org


.config.gz
Description: application/gzip
___
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization

[PATCH v3 2/2] x86/xen: switch initial pvops IRQ functions to dummy ones

2021-10-28 Thread Juergen Gross via Virtualization
The initial pvops functions handling irq flags will only ever be called
before interrupts are being enabled.

So switch them to be dummy functions:
- xen_save_fl() can always return 0
- xen_irq_disable() is a nop
- xen_irq_enable() can BUG()

Add some generic paravirt functions for that purpose.

Signed-off-by: Juergen Gross 
Acked-by: Peter Zijlstra (Intel) 
Reviewed-by: Boris Ostrovsky 
---
V3:
- make paravirt_BUG() noinstr
---
 arch/x86/include/asm/paravirt_types.h |  2 +
 arch/x86/kernel/paravirt.c| 13 +-
 arch/x86/xen/enlighten.c  | 19 +
 arch/x86/xen/irq.c| 61 ++-
 4 files changed, 20 insertions(+), 75 deletions(-)

diff --git a/arch/x86/include/asm/paravirt_types.h 
b/arch/x86/include/asm/paravirt_types.h
index d9d6b0203ec4..fc1151e77569 100644
--- a/arch/x86/include/asm/paravirt_types.h
+++ b/arch/x86/include/asm/paravirt_types.h
@@ -577,7 +577,9 @@ void paravirt_leave_lazy_mmu(void);
 void paravirt_flush_lazy_mmu(void);
 
 void _paravirt_nop(void);
+void paravirt_BUG(void);
 u64 _paravirt_ident_64(u64);
+unsigned long paravirt_ret0(void);
 
 #define paravirt_nop   ((void *)_paravirt_nop)
 
diff --git a/arch/x86/kernel/paravirt.c b/arch/x86/kernel/paravirt.c
index 04cafc057bed..b44814dfe83f 100644
--- a/arch/x86/kernel/paravirt.c
+++ b/arch/x86/kernel/paravirt.c
@@ -46,6 +46,17 @@ asm (".pushsection .entry.text, \"ax\"\n"
  ".type _paravirt_nop, @function\n\t"
  ".popsection");
 
+/* stub always returning 0. */
+asm (".pushsection .entry.text, \"ax\"\n"
+ ".global paravirt_ret0\n"
+ "paravirt_ret0:\n\t"
+ "xor %" _ASM_AX ", %" _ASM_AX ";\n\t"
+ "ret\n\t"
+ ".size paravirt_ret0, . - paravirt_ret0\n\t"
+ ".type paravirt_ret0, @function\n\t"
+ ".popsection");
+
+
 void __init default_banner(void)
 {
printk(KERN_INFO "Booting paravirtualized kernel on %s\n",
@@ -53,7 +64,7 @@ void __init default_banner(void)
 }
 
 /* Undefined instruction for dealing with missing ops pointers. */
-static void paravirt_BUG(void)
+noinstr void paravirt_BUG(void)
 {
BUG();
 }
diff --git a/arch/x86/xen/enlighten.c b/arch/x86/xen/enlighten.c
index 006b4a814fac..30c6e986a6cd 100644
--- a/arch/x86/xen/enlighten.c
+++ b/arch/x86/xen/enlighten.c
@@ -31,25 +31,10 @@ EXPORT_SYMBOL_GPL(hypercall_page);
  * Pointer to the xen_vcpu_info structure or
  * _shared_info->vcpu_info[cpu]. See xen_hvm_init_shared_info
  * and xen_vcpu_setup for details. By default it points to 
share_info->vcpu_info
- * but if the hypervisor supports VCPUOP_register_vcpu_info then it can point
- * to xen_vcpu_info. The pointer is used in __xen_evtchn_do_upcall to
- * acknowledge pending events.
- * Also more subtly it is used by the patched version of irq enable/disable
- * e.g. xen_irq_enable_direct and xen_iret in PV mode.
- *
- * The desire to be able to do those mask/unmask operations as a single
- * instruction by using the per-cpu offset held in %gs is the real reason
- * vcpu info is in a per-cpu pointer and the original reason for this
- * hypercall.
- *
+ * but during boot it is switched to point to xen_vcpu_info.
+ * The pointer is used in __xen_evtchn_do_upcall to acknowledge pending events.
  */
 DEFINE_PER_CPU(struct vcpu_info *, xen_vcpu);
-
-/*
- * Per CPU pages used if hypervisor supports VCPUOP_register_vcpu_info
- * hypercall. This can be used both in PV and PVHVM mode. The structure
- * overrides the default per_cpu(xen_vcpu, cpu) value.
- */
 DEFINE_PER_CPU(struct vcpu_info, xen_vcpu_info);
 
 /* Linux <-> Xen vCPU id mapping */
diff --git a/arch/x86/xen/irq.c b/arch/x86/xen/irq.c
index dfa091d79c2e..ae8537583102 100644
--- a/arch/x86/xen/irq.c
+++ b/arch/x86/xen/irq.c
@@ -24,60 +24,6 @@ void xen_force_evtchn_callback(void)
(void)HYPERVISOR_xen_version(0, NULL);
 }
 
-asmlinkage __visible unsigned long xen_save_fl(void)
-{
-   struct vcpu_info *vcpu;
-   unsigned long flags;
-
-   vcpu = this_cpu_read(xen_vcpu);
-
-   /* flag has opposite sense of mask */
-   flags = !vcpu->evtchn_upcall_mask;
-
-   /* convert to IF type flag
-  -0 -> 0x
-  -1 -> 0x
-   */
-   return (-flags) & X86_EFLAGS_IF;
-}
-PV_CALLEE_SAVE_REGS_THUNK(xen_save_fl);
-
-asmlinkage __visible void xen_irq_disable(void)
-{
-   /* There's a one instruction preempt window here.  We need to
-  make sure we're don't switch CPUs between getting the vcpu
-  pointer and updating the mask. */
-   preempt_disable();
-   this_cpu_read(xen_vcpu)->evtchn_upcall_mask = 1;
-   preempt_enable_no_resched();
-}
-PV_CALLEE_SAVE_REGS_THUNK(xen_irq_disable);
-
-asmlinkage __visible void xen_irq_enable(void)
-{
-   struct vcpu_info *vcpu;
-
-   /*
-* We may be preempted as soon as vcpu->evtchn_upcall_mask is
-* cleared, so disable preemption to ensure we check for
-* events on the VCPU we are still running on.
-*/
- 

[PATCH v3 0/2] x86/xen: simplify irq pvops

2021-10-28 Thread Juergen Gross via Virtualization
The pvops function for Xen PV guests handling the interrupt flag are
much more complex than needed.

With the supported Xen hypervisor versions they can be simplified a
lot, especially by removing the need for disabling preemption.

Juergen Gross (2):
  x86/xen: remove xen_have_vcpu_info_placement flag
  x86/xen: switch initial pvops IRQ functions to dummy ones

 arch/x86/include/asm/paravirt_types.h |   2 +
 arch/x86/kernel/paravirt.c|  13 ++-
 arch/x86/xen/enlighten.c  | 116 ++
 arch/x86/xen/enlighten_hvm.c  |   6 +-
 arch/x86/xen/enlighten_pv.c   |  28 ++-
 arch/x86/xen/irq.c|  61 +-
 arch/x86/xen/smp.c|  24 --
 arch/x86/xen/xen-ops.h|   4 +-
 8 files changed, 53 insertions(+), 201 deletions(-)

-- 
2.26.2

___
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization


Re: [PATCH 1/3] virtio: cache indirect desc for split

2021-10-28 Thread Xuan Zhuo
On Thu, 28 Oct 2021 10:16:10 +0800, Jason Wang  wrote:
> On Thu, Oct 28, 2021 at 1:07 AM Michael S. Tsirkin  wrote:
> >
> > On Wed, Oct 27, 2021 at 02:19:11PM +0800, Xuan Zhuo wrote:
> > > In the case of using indirect, indirect desc must be allocated and
> > > released each time, which increases a lot of cpu overhead.
> > >
> > > Here, a cache is added for indirect. If the number of indirect desc to be
> > > applied for is less than VIRT_QUEUE_CACHE_DESC_NUM, the desc array with
> > > the size of VIRT_QUEUE_CACHE_DESC_NUM is fixed and cached for reuse.
> > >
> > > Signed-off-by: Xuan Zhuo 
> > > ---
> > >  drivers/virtio/virtio.c  |  6 
> > >  drivers/virtio/virtio_ring.c | 63 ++--
> > >  include/linux/virtio.h   | 10 ++
> > >  3 files changed, 70 insertions(+), 9 deletions(-)
> > >
> > > diff --git a/drivers/virtio/virtio.c b/drivers/virtio/virtio.c
> > > index 0a5b54034d4b..04bcb74e5b9a 100644
> > > --- a/drivers/virtio/virtio.c
> > > +++ b/drivers/virtio/virtio.c
> > > @@ -431,6 +431,12 @@ bool is_virtio_device(struct device *dev)
> > >  }
> > >  EXPORT_SYMBOL_GPL(is_virtio_device);
> > >
> > > +void virtio_use_desc_cache(struct virtio_device *dev, bool val)
> > > +{
> > > + dev->desc_cache = val;
> > > +}
> > > +EXPORT_SYMBOL_GPL(virtio_use_desc_cache);
> > > +
> > >  void unregister_virtio_device(struct virtio_device *dev)
> > >  {
> > >   int index = dev->index; /* save for after device release */
> > > diff --git a/drivers/virtio/virtio_ring.c b/drivers/virtio/virtio_ring.c
> > > index dd95dfd85e98..0b9a8544b0e8 100644
> > > --- a/drivers/virtio/virtio_ring.c
> > > +++ b/drivers/virtio/virtio_ring.c
> > > @@ -117,6 +117,10 @@ struct vring_virtqueue {
> > >   /* Hint for event idx: already triggered no need to disable. */
> > >   bool event_triggered;
> > >
> > > + /* Is indirect cache used? */
> > > + bool use_desc_cache;
> > > + void *desc_cache_chain;
> > > +
> > >   union {
> > >   /* Available for split ring */
> > >   struct {
> > > @@ -423,12 +427,47 @@ static unsigned int vring_unmap_one_split(const 
> > > struct vring_virtqueue *vq,
> > >   return extra[i].next;
> > >  }
> > >
> > > -static struct vring_desc *alloc_indirect_split(struct virtqueue *_vq,
> > > +#define VIRT_QUEUE_CACHE_DESC_NUM 4
> > > +
> > > +static void desc_cache_chain_free_split(void *chain)
> > > +{
> > > + struct vring_desc *desc;
> > > +
> > > + while (chain) {
> > > + desc = chain;
> > > + chain = (void *)desc->addr;
> > > + kfree(desc);
> > > + }
> > > +}
> > > +
> > > +static void desc_cache_put_split(struct vring_virtqueue *vq,
> > > +  struct vring_desc *desc, int n)
> > > +{
> > > + if (vq->use_desc_cache && n <= VIRT_QUEUE_CACHE_DESC_NUM) {
> > > + desc->addr = (u64)vq->desc_cache_chain;
> > > + vq->desc_cache_chain = desc;
> > > + } else {
> > > + kfree(desc);
> > > + }
> > > +}
> > > +
> >
> >
> > So I have a question here. What happens if we just do:
> >
> > if (n <= VIRT_QUEUE_CACHE_DESC_NUM) {
> > return kmem_cache_alloc(VIRT_QUEUE_CACHE_DESC_NUM * sizeof desc, 
> > gfp)
> > } else {
> > return kmalloc_arrat(n, sizeof desc, gfp)
> > }
> >
> > A small change and won't we reap most performance benefits?
>
> Yes, I think we need a benchmark to use private cache to see how much
> it can help.

I did a test, the code is as follows:

+static void desc_cache_put_packed(struct vring_virtqueue *vq,
+  struct vring_packed_desc *desc, int n)
+ {
+   if (n <= VIRT_QUEUE_CACHE_DESC_NUM) {
+   kmem_cache_free(vq->desc_cache, desc);
+   } else {
+   kfree(desc);
+   }


@@ -476,11 +452,14 @@ static struct vring_desc *alloc_indirect_split(struct 
vring_virtqueue *vq,
 */
gfp &= ~__GFP_HIGHMEM;

-   desc = kmalloc_array(n, sizeof(struct vring_desc), gfp);
+   if (total_sg <= VIRT_QUEUE_CACHE_DESC_NUM)
+   desc = kmem_cache_alloc(vq->desc_cache, gfp);
+   else
+   desc = kmalloc_array(total_sg, sizeof(struct vring_desc), gfp);
+

...

+   vq->desc_cache = kmem_cache_create("virio_desc",
+  4 * sizeof(struct vring_desc),
+  0, 0, NULL);

The effect is not good, basically there is no improvement, using perf top can
see that the overhead of kmem_cache_alloc/kmem_cache_free is also relatively
large:

 26.91%  [kernel]  [k] virtqueue_add
 15.35%  [kernel]  [k] detach_buf_split
 14.15%  [kernel]  [k] virtnet_xsk_xmit
 13.24%  [kernel]  [k] virtqueue_add_outbuf
   >  9.30%  [kernel]  [k] __slab_free
   >  3.91%  [kernel]  [k] kmem_cache_alloc
  2.85%  [kernel]  [k] virtqueue_get_buf_ctx
   >  2.82%  [kernel]  [k]