diff options
| author | Peter Maydell <peter.maydell@linaro.org> | 2020-05-26 14:05:53 +0100 |
|---|---|---|
| committer | Peter Maydell <peter.maydell@linaro.org> | 2020-05-26 14:05:53 +0100 |
| commit | ddc760832fa8cf5e93b9d9e6e854a5114ac63510 (patch) | |
| tree | b23cd381e789a3b239b97b172291ceff529e5d9b /hw/9pfs/xen-9p-backend.c | |
| parent | 8f72c75cfc9b3c84a9b5e7a58ee5e471cb2f19c8 (diff) | |
| parent | 84af75577cceb195b044e2d5ba6d940206b169ca (diff) | |
| download | focaccia-qemu-ddc760832fa8cf5e93b9d9e6e854a5114ac63510.tar.gz focaccia-qemu-ddc760832fa8cf5e93b9d9e6e854a5114ac63510.zip | |
Merge remote-tracking branch 'remotes/gkurz/tags/9p-next-2020-05-26' into staging
- fix build with musl libc - fix potential deadlock of QEMU main event loop (cannot be hit with linux client) - revert 9pfs reply truncation (LP 1877688) - xen backend waits for client to free space on the reply ring instead of truncating or disconnecting # gpg: Signature made Tue 26 May 2020 10:36:23 BST # gpg: using RSA key B4828BAF943140CEF2A3491071D4D5E5822F73D6 # gpg: Good signature from "Greg Kurz <groug@kaod.org>" [full] # gpg: aka "Gregory Kurz <gregory.kurz@free.fr>" [full] # gpg: aka "[jpeg image of size 3330]" [full] # Primary key fingerprint: B482 8BAF 9431 40CE F2A3 4910 71D4 D5E5 822F 73D6 * remotes/gkurz/tags/9p-next-2020-05-26: xen/9pfs: increase max ring order to 9 xen/9pfs: yield when there isn't enough room on the ring Revert "9p: init_in_iov_from_pdu can truncate the size" 9p: Lock directory streams with a CoMutex 9pfs: include linux/limits.h for XATTR_SIZE_MAX Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Diffstat (limited to 'hw/9pfs/xen-9p-backend.c')
| -rw-r--r-- | hw/9pfs/xen-9p-backend.c | 40 |
1 files changed, 28 insertions, 12 deletions
diff --git a/hw/9pfs/xen-9p-backend.c b/hw/9pfs/xen-9p-backend.c index f04caabfe5..a969fcc54c 100644 --- a/hw/9pfs/xen-9p-backend.c +++ b/hw/9pfs/xen-9p-backend.c @@ -21,7 +21,7 @@ #define VERSIONS "1" #define MAX_RINGS 8 -#define MAX_RING_ORDER 8 +#define MAX_RING_ORDER 9 typedef struct Xen9pfsRing { struct Xen9pfsDev *priv; @@ -37,6 +37,7 @@ typedef struct Xen9pfsRing { struct iovec *sg; QEMUBH *bh; + Coroutine *co; /* local copies, so that we can read/write PDU data directly from * the ring */ @@ -188,7 +189,7 @@ static void xen_9pfs_init_out_iov_from_pdu(V9fsPDU *pdu, static void xen_9pfs_init_in_iov_from_pdu(V9fsPDU *pdu, struct iovec **piov, unsigned int *pniov, - size_t *size) + size_t size) { Xen9pfsDev *xen_9pfs = container_of(pdu->s, Xen9pfsDev, state); Xen9pfsRing *ring = &xen_9pfs->rings[pdu->tag % xen_9pfs->num_rings]; @@ -198,19 +199,20 @@ static void xen_9pfs_init_in_iov_from_pdu(V9fsPDU *pdu, g_free(ring->sg); ring->sg = g_new0(struct iovec, 2); - xen_9pfs_in_sg(ring, ring->sg, &num, pdu->idx, *size); + ring->co = qemu_coroutine_self(); + /* make sure other threads see ring->co changes before continuing */ + smp_wmb(); +again: + xen_9pfs_in_sg(ring, ring->sg, &num, pdu->idx, size); buf_size = iov_size(ring->sg, num); - if (buf_size < P9_IOHDRSZ) { - xen_pv_printf(&xen_9pfs->xendev, 0, "Xen 9pfs reply type %d needs " - "%zu bytes, buffer has %zu, less than minimum\n", - pdu->id + 1, *size, buf_size); - xen_be_set_state(&xen_9pfs->xendev, XenbusStateClosing); - xen_9pfs_disconnect(&xen_9pfs->xendev); - } - if (buf_size < *size) { - *size = buf_size; + if (buf_size < size) { + qemu_coroutine_yield(); + goto again; } + ring->co = NULL; + /* make sure other threads see ring->co changes before continuing */ + smp_wmb(); *piov = ring->sg; *pniov = num; @@ -295,6 +297,20 @@ static int xen_9pfs_receive(Xen9pfsRing *ring) static void xen_9pfs_bh(void *opaque) { Xen9pfsRing *ring = opaque; + bool wait; + +again: + wait = ring->co != NULL && qemu_coroutine_entered(ring->co); + /* paired with the smb_wmb barriers in xen_9pfs_init_in_iov_from_pdu */ + smp_rmb(); + if (wait) { + cpu_relax(); + goto again; + } + + if (ring->co != NULL) { + qemu_coroutine_enter_if_inactive(ring->co); + } xen_9pfs_receive(ring); } |