Skip to content

Commit

Permalink
xen/9pfs: receive requests from the frontend
Browse files Browse the repository at this point in the history
Upon receiving an event channel notification from the frontend, schedule
the bottom half. From the bottom half, read one request from the ring,
create a pdu and call pdu_submit to handle it.

For now, only handle one request per ring at a time.

Signed-off-by: Stefano Stabellini <stefano@aporeto.com>
CC: anthony.perard@citrix.com
CC: jgross@suse.com
CC: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
CC: Greg Kurz <groug@kaod.org>
  • Loading branch information
sstabellini committed Apr 25, 2017
1 parent f23ef34 commit 47b70fb
Showing 1 changed file with 50 additions and 0 deletions.
50 changes: 50 additions & 0 deletions hw/9pfs/xen-9p-backend.c
Expand Up @@ -100,12 +100,62 @@ static int xen_9pfs_init(struct XenDevice *xendev)
return 0;
}

static int xen_9pfs_receive(Xen9pfsRing *ring)
{
P9MsgHeader h;
RING_IDX cons, prod, masked_prod, masked_cons;
V9fsPDU *pdu;

if (ring->inprogress) {
return 0;
}

cons = ring->intf->out_cons;
prod = ring->intf->out_prod;
xen_rmb();

if (xen_9pfs_queued(prod, cons, XEN_FLEX_RING_SIZE(ring->ring_order)) <
sizeof(h)) {
return 0;
}
ring->inprogress = true;

masked_prod = xen_9pfs_mask(prod, XEN_FLEX_RING_SIZE(ring->ring_order));
masked_cons = xen_9pfs_mask(cons, XEN_FLEX_RING_SIZE(ring->ring_order));

xen_9pfs_read_packet((uint8_t *) &h, ring->ring.out, sizeof(h),
masked_prod, &masked_cons,
XEN_FLEX_RING_SIZE(ring->ring_order));

/* cannot fail, because we only handle one request per ring at a time */
pdu = pdu_alloc(&ring->priv->state);
pdu->size = le32_to_cpu(h.size_le);
pdu->id = h.id;
pdu->tag = le32_to_cpu(h.tag_le);
ring->out_size = le32_to_cpu(h.size_le);
ring->out_cons = cons + le32_to_cpu(h.size_le);

qemu_co_queue_init(&pdu->complete);
pdu_submit(pdu);

return 0;
}

static void xen_9pfs_bh(void *opaque)
{
Xen9pfsRing *ring = opaque;
xen_9pfs_receive(ring);
}

static void xen_9pfs_evtchn_event(void *opaque)
{
Xen9pfsRing *ring = opaque;
evtchn_port_t port;

port = xenevtchn_pending(ring->evtchndev);
xenevtchn_unmask(ring->evtchndev, port);

qemu_bh_schedule(ring->bh);
}

static int xen_9pfs_free(struct XenDevice *xendev)
Expand Down

0 comments on commit 47b70fb

Please sign in to comment.