<div dir="ltr"><br><br><div class="gmail_quote"><div dir="ltr">On Wed, Sep 26, 2018 at 3:29 AM Gurchetan Singh <<a href="mailto:gurchetansingh@chromium.org">gurchetansingh@chromium.org</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">On Tue, Sep 25, 2018 at 2:10 AM Gerd Hoffmann <<a href="mailto:kraxel@redhat.com" target="_blank">kraxel@redhat.com</a>> wrote:<br>
><br>
>   Hi,<br>
><br>
> > > Who will do the actual allocations?  I expect we need new virglrenderer<br>
> > > functions for that?<br>
> ><br>
> > The decision to back memory via iovecs or host memory is up to the<br>
> > VMM.<br>
><br>
> What exactly do you mean with "via iovecs"?  The current way to allocate<br>
> resources?  They are guest-allocated and the iovecs passed to<br>
> virglrenderer point into guest memory.  So that clearly is *not* in the<br>
> hands of the VMM.  Or do you mean something else?<br>
<br>
I guess I'm just brainstorming about one-copy with virgl and how we<br>
want to implement it.<br>
<br>
The simplest case that can be improved with host memory is:<br>
<br>
(1) Guest app maps the buffer (glMapBufferRange --> virgl_buffer_transfer_map).<br>
      (i)  If the buffer is not marked clean (texture buffers, SSBOs)<br>
this will trigger a TRANSFER_FROM_HOST_3D (copies++)<br>
(2) The guest app copies the buffer data (unavoidable - copies++)<br>
(3) Guest unmaps the buffer, triggering a TRANSFER_TO_HOST (copies++).<br>
<br>
For host GL buffers, the copies are done in<br>
{vrend_renderer_transfer_write_iov, vrend_renderer_transfer_send_iov}.<br>
If there are N iovecs backing the guest resource, we will have N<br>
copies (see vrend_write_to_iovec, vrend_read_from_iovec).<br>
<br>
udmabuf could be helpful, since it bundles up the iovecs and it will<br>
make the N small copies into one big copy.  udmabuf could also<br>
eliminate some copies for textures completely.  Right now, for most<br>
textures, virglrenderer copies iovecs into a temporary buffer (see<br>
read_transfer_data), and then calls glTexSubImage2D*.  Just mmaping<br>
the udmabuf and calling glTexSubImage2D* is definite win.<br>
<br>
But making host memory guest visible will bring the worst-case buffer<br>
copies from 3 to 1.  For textures, if we start counting when the GPU<br>
buffer gets detiled, there will be 5 copies currently, 3 with udmabuf,<br>
and 1 with host exposed memory.<br>
<br>
><br>
><br>
> To make sure we all are on the same page wrt. resource allocation, the<br>
> workflow we have now looks like this:<br>
><br>
>   (1) guest virtio-gpu driver allocates resource.  Uses normal (guest) ram.<br>
>       Resources can be scattered.<br>
>   (2) guest driver creates resources (RESOURCE_CREATE_*).<br>
>   (3) qemu (virgl=off) or virglrenderer (virgl=on) creates host resource.<br>
>       virglrenderer might use a different format (tiling, ...).<br>
>   (4) guest sets up backing storage (RESOURCE_ATTACH_BACKING).<br>
>   (5) qemu creates a iovec for the guest resource.<br>
>   (6) guest writes data to resource.<br>
>   (7) guest requests a transfer (TRANSFER_TO_HOST_*).<br>
>   (8) qemu or virglrenderer copy data from guest resource to<br>
>       host resource, possibly converting (again tiling, ...).<br>
>   (9) guest can use the resource now ...<br>
><br>
><br>
> One thing I'm prototyping right now is zerocopy resources, the workflow<br>
> changes to look like this:<br>
><br>
>   (2) guest additionally sets a flag to request a zerocopy buffer.<br>
>   (3) not needed (well, the bookkeeping part of it is still needed, but<br>
>       it would *not* allocate a host resource).<br>
>   (5) qemu additionally creates a host dma-buf for the guest resource<br>
>       using the udmabuf driver.<br>
>   (7+8) not needed.<br>
><br>
> Right now I have (not tested yet) code to handle dumb buffers.<br>
> Interfacing to guest userspace (virtio-gpu driver ioctls) is not<br>
> there yet.  Interfacing with virglrenderer isn't there yet either.<br>
><br>
> I expect that doesn't solve the coherent mapping issue.  The host gpu<br>
> could import the dma-buf of the resource, but as it has no control over<br>
> the allocation it might not be able to use it without copying.<br>
><br>
><br>
> I'm not sure how the API for coherent resources should look like.<br>
> One option I see is yet another resource flag, so the workflow would<br>
> change like this (with virgl=on only ...):<br>
><br>
>   (2) guest additionally sets a flag to request a coherent resource.<br>
>   (3) virglrenderer would create a coherent host resource.<br>
>   (4) guest finds some address space in the (new) pci bar and asks<br>
>       for the resource being mapped there (new command needed for<br>
>       this).<br>
>   (5) qemu maps the coherent resource into the pci bar.<br>
>   (7+8) not needed.<br>
><br>
> Probably works for GL_MAP_COHERENT_BIT use case.  Dunno about vulkan.<br>
><br>
> Interfaces to guest userspace and virglrenderer likewise need updates<br>
> to support this.<br>
><br>
><br>
> > A related question: are we going to also expose host memory to the<br>
> > guest for the non-{GL_MAP_COHERENT_BIT,<br>
> > VK_MEMORY_PROPERTY_HOST_COHERENT_BIT} cases?<br>
><br>
> The guest should be able to do that, yes.  In case both coherent and<br>
> zerocopy resources are supported by the host it can even pick.<br>
><br>
> coherent resources will be limited though (pci bar size, also because<br>
> we don't want allow guests allocate unlimited host memory for security<br>
> reasons), so using them for everything is probably not a good idea.<br>
<br>
The 64-bit BAR should be enough, especially if it's managed<br>
intelligently.  Vulkan may take some time and I don't think stacks<br>
with host GLES drivers support GL_MAP_COHERENT_BIT, so there will be<br>
cases when that space goes unused.<br>
<br>
Here's one possible flow:<br>
<br>
i) virtio_gpu_resource_create_coherent -- for strictly coherent needs<br>
(i.e, no unmap needed)<br>
ii) virtio_gpu_resource_create_3d  -- may or may not be host backed<br>
(depends on the PCI bar size, platform-specific information -- guest<br>
doesn't need to know)<br>
<br>
The guest would still issue the transfer ioctls for the<br>
virtio_gpu_resource_create_3d resource, but the work performed would<br>
be pared down when backed by host memory.<br>
<br>
This will require increased VMM <--> virglrenderer inter-op.  Maybe<br>
behind a flag that QEMU doesn't set, but cros_vm will.  WDTY?<br></blockquote><div>I think that's a pretty good middle ground. The amount of inter-op between vmm and virglrenderer is already fairly high, especially with the stuff crosvm does to ensure virtio_gpu resource are allocated in a way so that they can't be sent over wayland connections.</div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<br>
><br>
> cheers,<br>
>   Gerd<br>
><br>
_______________________________________________<br>
virglrenderer-devel mailing list<br>
<a href="mailto:virglrenderer-devel@lists.freedesktop.org" target="_blank">virglrenderer-devel@lists.freedesktop.org</a><br>
<a href="https://lists.freedesktop.org/mailman/listinfo/virglrenderer-devel" rel="noreferrer" target="_blank">https://lists.freedesktop.org/mailman/listinfo/virglrenderer-devel</a><br>
</blockquote></div></div>