<div dir="ltr"><div dir="ltr"><br></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Fri, Apr 9, 2021 at 12:48 AM Gerd Hoffmann <<a href="mailto:kraxel@redhat.com">kraxel@redhat.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">  Hi,<br>
<br>
> > IIRC the VIRTGPU_BLOB_FLAG_USE_SHAREABLE flag means that the host *can*<br>
> > create a shared mapping (i.e. the host seeing guest-side changes without<br>
> > explicit transfer doesn't cause problems for the guest).  It doesn not<br>
> > mean the host *must* create a shared mapping (note that there is no<br>
> > negotiation whenever the host supports shared mappings or not).<br>
> ><br>
> <br>
> VIRTGPU_BLOB_FLAG_USE_SHAREABLE means guest userspace intends to share the<br>
> blob resource with another virtgpu driver instance via drmPrimeHandleToFd.<br>
> It's a rough analogue to VkExportMemoryAllocateInfoKHR or<br>
> PIPE_BIND_USE_SHARED.<br>
<br>
Oh.  My memory was failing me then.  We should *really* clarify the spec<br>
for BLOB_MEM_GUEST. </blockquote><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
<br>
So shared mappings are allowed for all BLOB_MEM_GUEST resources, right?<br></blockquote><div><br></div><div><div>The guest iovecs are always shared with the host, so they may be copied to/from directly depending on the operation.  In the case of RESOURCE_FLUSH + BLOB_MEM_GUEST, it could be a copy from the guest iovecs to the host framebuffer [host framebuffer != host shadow memory].</div><div></div></div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
<br>
> > So the transfer calls are still needed, and the host can decide to<br>
> > shortcut them in case it can create a shared mapping.  In case there is<br>
> > no shared mapping (say due to missing udmabuf support) the host can<br>
> > fallback to copying.<br>
> <br>
> Transfers are a bit under-defined for BLOB_MEM_GUEST.  Even without udmabuf<br>
> on the host, there is no host side resource for guest-only blobs?  Before<br>
> blob resources, the dumb flow was:<br>
> <br>
> 1) update guest side resource<br>
> 2) TRANSFER_TO_HOST_2D to copy guest side contents to host side private<br>
> resource [Pixman??]<br>
> 3) RESOURCE_FLUSH to copy the host-side contents to the framebuffer and<br>
> page-flip<br>
<br>
Yes.<br>
<br>
> At least for crosvm, this is possible:<br>
> <br>
> 1) update guest side resource<br>
> 2) RESOURCE_FLUSH to copy the guest-side contents to the framebuffer and<br>
> pageflip<br>
> <br>
> With implicit udmabuf, it may be possible to do this:<br>
> <br>
> 1) update guest side resource<br>
> 2) RESOURCE_FLUSH to page-flip<br>
> <br>
> > So I think crosvm should be fixed to not consider transfer commands for<br>
> > VIRTGPU_BLOB_MEM_GUEST resources an error.<br>
> <br>
> It's a simple change to make and we can definitely do it, if TRANSFER_2D is<br>
> helpful for the QEMU case.  I haven't looked at the QEMU side patches.<br>
<br>
Well, we have two different cases:<br>
<br>
  (1) No udmabuf available.  qemu will have a host-side shadow then and<br>
      the workflow will be largely identical to the non-blob resource<br>
      workflow.<br></blockquote><div><br></div><div><div>I think this is the key difference.  With BLOB_MEM_GUEST, crosvm can only have a guest side iovecs and no host-side shadow memory.  With BLOB_MEM_GUEST_HOST3D, host-side shadow memory will exist.<br></div><div><br></div><div>I guess it boils down the Pixman dependency.  crosvm sits right on top of display APIs (X, wayland) rather than having intermediary layers.  Adding a new Pixman API takes time too.</div><div><br></div><div>There's a bunch of options:</div><div><br></div><div>1) Don't use BLOB_MEM_GUEST dumb buffers in 3D mode.</div><div>2) virglrenderer or crosvm modified to implicitly ignore TRANSFER_TO_HOST_2D for BLOB_MEM_GUEST when in 3D mode.</div><div>3) It's probably possible to create an implicit udmabuf for RESOURCE_CREATE_2D resources and ignore the transfer there too.  The benefit of this is TRANSFER_TO_HOST_2D makes a ton of sense for non-blob resources.  No kernel side change needed here, just QEMU.</div><div>4) modify QEMU display integration</div><div><br></div><div>I would choose (1) since it solves the log spam problem and it advances blob support in QEMU.  Though I leave the decision to QEMU devs.</div><div></div></div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
<br>
  (2) With udmabuf support.  qemu can create udmabufs for the resources,<br>
      mmap() the dmabuf to get a linear mapping, create a pixman buffer<br>
      backed by that dmabuf (no copying needed then).  Depending on<br>
      capabilities pass either the pixman image (gl=off) or the dmabuf<br>
      handle (gl=on) to the UI code to actually show the guest display.<br>
<br>
The guest doesn't need to know any of this, it'll just send transfer and<br>
flush commands.  In case (1) qemu must process the transfer commands and<br>
for case (2) qemu can simply ignore them.<br>
<br>
> For the PCI-passthrough + guest blob case, the end goal is to share it with<br>
> the host compositor.  If there is no guarantee the guest memory can be<br>
> converted to an OS-handle (to share with the host compositor), then I think<br>
> the guest user space should fallback to another technique involving<br>
> memcpy() to share the memory.<br>
<br>
This is what happens today (using non-blob resources).<br>
<br>
> So essentially, thinking for two new protocol additions:<br>
> <br>
> F_CREATE_GUEST_HANDLE (or F_HANDLE_FROM_GUEST) --> means an OS-specific<br>
> udmabuf-like mechanism exists on the host.<br>
> <br>
> BLOB_FLAG_CREATE_GUEST_HANDLE (or BLOB_FLAG_HANDLE_FROM_GUEST)--> tells<br>
> host userspace "you must create a udmabuf" [or OS-specific equivalent] upon<br>
> success<br>
<br>
Again:  Why do we actually need that?  Is there any benefit other than<br>
the guest knowing it doesn't need to send transfer commands?</blockquote><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
I see the whole udmabuf thing as a host-side performance optimization<br>
and I think this should be fully transparent to the guest as the host<br>
can easily just ignore the transfer commands.  </blockquote><div><br></div><div>So the use case I'm most interested in (and Vivek/Tina?) is tiled/compressed udmabufs, so they may be eventually shared with the host compositor via the DRM modifier API.<div><br></div><div>Transfers to linear udmabufs make sense.  Maybe transfers to tiled/compressed udmabufs shouldn't even be attempted.  </div><div><br></div><div>It's a complicated case with many ambiguities, especially with PCI passthrough involved.  Explicit tiled/compressed udmabufs are just an idea, will have to think more about it / have some proof of concept [with virgl and PCI passthrough], before making any concrete proposals.  Will keep your idea of just ignoring transfers on the host in mind.</div></div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">Given we batch commands<br>
the extra commands don't lead to extra context switches, so there<br>
shouldn't be much overhead.<br>
<br>
If we really want make the guest aware of the hosts udmabuf state I<br>
think this should be designed the other way around:  Add some way for<br>
the host to tell the guest transfer commands are not needed for a<br>
specific BLOB_MEM_GUEST resource.<br>
<br>
take care,<br>
  Gerd<br>
<br>
</blockquote></div></div>