On Fri, Jul 31, 2020 at 02:20:14PM -0400, Jagannathan Raman wrote: > +/* > + * Create if needed and enter co-routine to send the message to the > + * remote channel ioc and wait for the reply. > + * Returns the value from the reply message, sets the error on failure. > + */ > + > +uint64_t mpqemu_msg_send_and_await_reply(MPQemuMsg *msg, QIOChannel *ioc, > + Error **errp) > +{ > + MPQemuRequest req = {0}; > + uint64_t ret = UINT64_MAX; > + > + req.ioc = ioc; > + if (!req.ioc) { > + error_setg(errp, "Channel is set to NULL"); > + return ret; > + } > + > + req.msg = msg; > + req.ret = 0; > + req.finished = false; > + > + req.co = qemu_coroutine_create(mpqemu_msg_send_co, &req); > + qemu_coroutine_enter(req.co); > + > + while (!req.finished) { > + aio_poll(qemu_get_aio_context(), true); > + } This is called from vcpu threads. aio_poll() does not release the global mutex so all other vcpu threads are blocked until mpqemu communication completes. The simplest solution is to unlock the global mutex and call blocking, non-coroutine versions of the send/recv code. That way other vcpu threads can execute. This means that the QEMU process would not use the mpqemu IOChannel in the event loop. The remote process would still use the IOChannel in the event loop, however. Stefan