On 03/16/2017 11:33 AM, Greg Kurz wrote: > According to the 9P spec [*], when a client wants to cancel a pending I/O > request identified by a given tag (uint16), it must send a Tflush message > and wait for the server to respond with a Rflush message before reusing this > tag for another I/O. The server may still send a completion message for the > I/O if it wasn't actually cancelled but the Rflush message must arrive after > that. > > QEMU hence waits for the flushed PDU to complete before sending the Rflush > message back to the client. > > If a client sends 'Tflush tag oldtag' and tag == oldtag, QEMU will then > allocate a PDU identified by tag, find it in the PDU list and wait for > this same PDU to complete... i.e. wait for a completion that will never > happen. This causes a tag and ring slot leak in the guest, and a PDU > leak in QEMU, all of them limited by the maximal number of PDUs (128). > But, worse, this causes QEMU to hang on device reset since v9fs_reset() > wants to drain all pending I/O. > > This insane behavior is likely to denote a bug in the client, and it would > deserve an Rerror message to be sent back. Unfortunately, the protocol > allows it and requires all flush requests to suceed (only a Tflush response
s/suceed/succeed/ > is expected). > > The only option is to detect when we have to handle a self-referencing > flush request and report success to the client right away. > > [*] http://man.cat-v.org/plan_9/5/flush > > Reported-by: Al Viro <v...@zeniv.linux.org.uk> > Signed-off-by: Greg Kurz <gr...@kaod.org> > --- > hw/9pfs/9p.c | 2 +- > 1 file changed, 1 insertion(+), 1 deletion(-) > Reviewed-by: Eric Blake <ebl...@redhat.com> -- Eric Blake eblake redhat com +1-919-301-3266 Libvirt virtualization library http://libvirt.org
signature.asc
Description: OpenPGP digital signature