[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [PATCH RFC v2 04/16] vfio-user: connect vfio proxy to remote server
From: |
John Johnson |
Subject: |
Re: [PATCH RFC v2 04/16] vfio-user: connect vfio proxy to remote server |
Date: |
Mon, 13 Sep 2021 17:23:33 +0000 |
>
>> On Sep 9, 2021, at 10:25 PM, John Johnson <john.g.johnson@oracle.com> wrote:
>>
>>
>>
>>> On Sep 8, 2021, at 11:29 PM, Stefan Hajnoczi <stefanha@redhat.com> wrote:
>>>
>>> On Thu, Sep 09, 2021 at 05:11:49AM +0000, John Johnson wrote:
>>>>
>>>>
>>>> I did look at coroutines, but they seemed to work when the sender
>>>> is triggering the coroutine on send, not when request packets are arriving
>>>> asynchronously to the sends.
>>>
>>> This can be done with a receiver coroutine. Its job is to be the only
>>> thing that reads vfio-user messages from the socket. A receiver
>>> coroutine reads messages from the socket and wakes up the waiting
>>> coroutine that yielded from vfio_user_send_recv() or
>>> vfio_user_pci_process_req().
>>>
>>> (Although vfio_user_pci_process_req() could be called directly from the
>>> receiver coroutine, it seems safer to have a separate coroutine that
>>> processes requests so that the receiver isn't blocked in case
>>> vfio_user_pci_process_req() yields while processing a request.)
>>>
>>> Going back to what you mentioned above, the receiver coroutine does
>>> something like this:
>>>
>>> if it's a reply
>>> reply = find_reply(...)
>>> qemu_coroutine_enter(reply->co) // instead of signalling reply->cv
>>> else
>>> QSIMPLEQ_INSERT_TAIL(&pending_reqs, request, next);
>>> if (pending_reqs_was_empty) {
>>> qemu_coroutine_enter(process_request_co);
>>> }
>>>
>>> The pending_reqs queue holds incoming requests that the
>>> process_request_co coroutine processes.
>>>
>>
>>
>> How do coroutines work across threads? There can be multiple vCPU
>> threads waiting for replies, and I think the receiver coroutine will be
>> running in the main loop thread. Where would a vCPU block waiting for
>> a reply? I think coroutine_yield() returns to its coroutine_enter() caller
>
>
>
> A vCPU thread holding the BQL can iterate the event loop if it has
> reached a synchronous point that needs to wait for a reply before
> returning. I think we have this situation when a MemoryRegion is
> accessed on the proxy device.
>
> For example, block/block-backend.c:blk_prw() kicks off a coroutine and
> then runs the event loop until the coroutine finishes:
>
> Coroutine *co = qemu_coroutine_create(co_entry, &rwco);
> bdrv_coroutine_enter(blk_bs(blk), co);
> BDRV_POLL_WHILE(blk_bs(blk), rwco.ret == NOT_DONE);
>
> BDRV_POLL_WHILE() boils down to a loop like this:
>
> while ((cond)) {
> aio_poll(ctx, true);
> }
>
I think that would make vCPUs sending requests and the
receiver coroutine all poll on the same socket. If the “wrong”
routine reads the message, I’d need a second level of synchronization
to pass the message to the “right” one. e.g., if the vCPU coroutine
reads a request, it needs to pass it to the receiver; if the receiver
coroutine reads a reply, it needs to pass it to a vCPU.
Avoiding this complexity is one of the reasons I went with
a separate thread that only reads the socket over the mp-qemu model,
which does have the sender poll, but doesn’t need to handle incoming
requests.
> I also want to check that I understand the scenarios in which the
> vfio-user communication code is used:
>
> 1. vhost-user-server
>
> The vfio-user communication code should run in a given AioContext (it
> will be the main loop by default but maybe the user will be able to
> configure a specific IOThread in the future).
>
Jag would know more, but I believe it runs off the main loop.
Running it in an iothread doesn’t gain much, since it needs BQL to
run the device emulation code.
> 2. vCPU thread vfio-user clients
>
> The vfio-user communication code is called from the vCPU thread where
> the proxy device executes. The MemoryRegion->read()/write() callbacks
> are synchronous, so the thread needs to wait for a vfio-user reply
> before it can return.
>
> Is this what you had in mind?
The client is also called from the main thread - the GET_*
messages from vfio_user_pci_realize() as well as MAP/DEMAP messages
from guest address space change transactions. It is also called by
the migration thread, which is a separate thread that does not run
holding BQL.
JJ
- Re: [PATCH RFC v2 04/16] vfio-user: connect vfio proxy to remote server, Stefan Hajnoczi, 2021/09/07
- Re: [PATCH RFC v2 04/16] vfio-user: connect vfio proxy to remote server, John Johnson, 2021/09/09
- Re: [PATCH RFC v2 04/16] vfio-user: connect vfio proxy to remote server, Stefan Hajnoczi, 2021/09/09
- Re: [PATCH RFC v2 04/16] vfio-user: connect vfio proxy to remote server, John Johnson, 2021/09/10
- Re: [PATCH RFC v2 04/16] vfio-user: connect vfio proxy to remote server, Stefan Hajnoczi, 2021/09/13
- Re: [PATCH RFC v2 04/16] vfio-user: connect vfio proxy to remote server,
John Johnson <=
- Re: [PATCH RFC v2 04/16] vfio-user: connect vfio proxy to remote server, Stefan Hajnoczi, 2021/09/14
- Re: [PATCH RFC v2 04/16] vfio-user: connect vfio proxy to remote server, John Johnson, 2021/09/14
- Re: [PATCH RFC v2 04/16] vfio-user: connect vfio proxy to remote server, Stefan Hajnoczi, 2021/09/15
- Re: [PATCH RFC v2 04/16] vfio-user: connect vfio proxy to remote server, John Johnson, 2021/09/15
- Re: [PATCH RFC v2 04/16] vfio-user: connect vfio proxy to remote server, Stefan Hajnoczi, 2021/09/16