Re: [PATCH 5/7] xen/9pfs: send requests to the backend

From: Stefano Stabellini
Date: Wed Mar 08 2017 - 14:41:47 EST


On Wed, 8 Mar 2017, Boris Ostrovsky wrote:
> >>> +}
> >>> +
> >>> +static int p9_xen_write_todo(struct xen_9pfs_dataring *ring, RING_IDX size)
> >>> +{
> >>> + RING_IDX cons, prod;
> >>> +
> >>> + cons = ring->intf->out_cons;
> >>> + prod = ring->intf->out_prod;
> >>> + mb();
> >>> +
> >>> + if (XEN_9PFS_RING_SIZE - xen_9pfs_queued(prod, cons, XEN_9PFS_RING_SIZE) >= size)
> >>> + return 1;
> >>> + else
> >>> + return 0;
> >>> }
> >>>
> >>> static int p9_xen_request(struct p9_client *client, struct p9_req_t *p9_req)
> >>> {
> >>> + struct xen_9pfs_front_priv *priv = NULL;
> >>> + RING_IDX cons, prod, masked_cons, masked_prod;
> >>> + unsigned long flags;
> >>> + uint32_t size = p9_req->tc->size;
> >>> + struct xen_9pfs_dataring *ring;
> >>> + int num;
> >>> +
> >>> + list_for_each_entry(priv, &xen_9pfs_devs, list) {
> >>> + if (priv->client == client)
> >>> + break;
> >>> + }
> >>> + if (priv == NULL || priv->client != client)
> >>> + return -EINVAL;
> >>> +
> >>> + num = p9_req->tc->tag % priv->num_rings;
> >>> + ring = &priv->rings[num];
> >>> +
> >>> +again:
> >>> + while (wait_event_interruptible(ring->wq,
> >>> + p9_xen_write_todo(ring, size) > 0) != 0);
> >>> +
> >>> + spin_lock_irqsave(&ring->lock, flags);
> >>> + cons = ring->intf->out_cons;
> >>> + prod = ring->intf->out_prod;
> >>> + mb();
> >>> +
> >>> + if (XEN_9PFS_RING_SIZE - xen_9pfs_queued(prod, cons, XEN_9PFS_RING_SIZE) < size) {
> >>
> >> This looks like p9_xen_write_todo().
> > p9_xen_write_todo is just a wrapper around xen_9pfs_queued to provide
> > a return value that works well with wait_event_interruptible.
> >
> > I would prefer not to call p9_xen_write_todo here, because it's simpler
> > if we don't read prod and cons twice.
>
> I was referring to the whole code fragment after spin_lock_irqsave(),
> not just the last line. Isn't it exactly !p9_xen_write_todo()?

Yes, it is true they are almost the same. The difference, and the reason
for p9_xen_write_todo to exist, is that p9_xen_write_todo is called in
the wait_event_interruptible loop, as such it needs to read prod and
cons every time. On the other end, here we want to read them once. Does
it make sense?