From: Boris Ostrovsky <boris.ostrovsky@oracle.com>
To: Stefano Stabellini <sstabellini@kernel.org>, xen-devel@lists.xen.org
Cc: linux-kernel@vger.kernel.org, jgross@suse.com,
Stefano Stabellini <stefano@aporeto.com>
Subject: Re: [PATCH v2 03/13] xen/pvcalls: implement socket command and handle events
Date: Wed, 26 Jul 2017 10:27:47 -0400 [thread overview]
Message-ID: <5978A6E3.7010809@oracle.com> (raw)
In-Reply-To: <1501017730-12797-3-git-send-email-sstabellini@kernel.org>
On 7/25/2017 5:22 PM, Stefano Stabellini wrote:
> Send a PVCALLS_SOCKET command to the backend, use the masked
> req_prod_pvt as req_id. This way, req_id is guaranteed to be between 0
> and PVCALLS_NR_REQ_PER_RING. We already have a slot in the rsp array
> ready for the response, and there cannot be two outstanding responses
> with the same req_id.
>
> Wait for the response by waiting on the inflight_req waitqueue and
> check for the req_id field in rsp[req_id]. Use atomic accesses to
> read the field. Once a response is received, clear the corresponding rsp
> slot by setting req_id to PVCALLS_INVALID_ID. Note that
> PVCALLS_INVALID_ID is invalid only from the frontend point of view. It
> is not part of the PVCalls protocol.
>
> pvcalls_front_event_handler is in charge of copying responses from the
> ring to the appropriate rsp slot. It is done by copying the body of the
> response first, then by copying req_id atomically. After the copies,
> wake up anybody waiting on waitqueue.
>
> pvcallss_lock protects accesses to the ring.
>
> Signed-off-by: Stefano Stabellini <stefano@aporeto.com>
> CC: boris.ostrovsky@oracle.com
> CC: jgross@suse.com
> ---
> drivers/xen/pvcalls-front.c | 94 +++++++++++++++++++++++++++++++++++++++++++++
> drivers/xen/pvcalls-front.h | 8 ++++
> 2 files changed, 102 insertions(+)
> create mode 100644 drivers/xen/pvcalls-front.h
>
> diff --git a/drivers/xen/pvcalls-front.c b/drivers/xen/pvcalls-front.c
> index 5e0b265..d1dbcf1 100644
> --- a/drivers/xen/pvcalls-front.c
> +++ b/drivers/xen/pvcalls-front.c
> @@ -20,6 +20,8 @@
> #include <xen/xenbus.h>
> #include <xen/interface/io/pvcalls.h>
>
> +#include "pvcalls-front.h"
> +
> #define PVCALLS_INVALID_ID (UINT_MAX)
> #define RING_ORDER XENBUS_MAX_RING_GRANT_ORDER
> #define PVCALLS_NR_REQ_PER_RING __CONST_RING_SIZE(xen_pvcalls, XEN_PAGE_SIZE)
> @@ -40,9 +42,101 @@ struct pvcalls_bedata {
>
> static irqreturn_t pvcalls_front_event_handler(int irq, void *dev_id)
> {
> + struct xenbus_device *dev = dev_id;
> + struct pvcalls_bedata *bedata;
> + struct xen_pvcalls_response *rsp;
> + uint8_t *src, *dst;
> + int req_id = 0, more = 0, done = 0;
> +
> + if (dev == NULL)
> + return IRQ_HANDLED;
> +
> + bedata = dev_get_drvdata(&dev->dev);
> + if (bedata == NULL)
> + return IRQ_HANDLED;
> +
> +again:
> + while (RING_HAS_UNCONSUMED_RESPONSES(&bedata->ring)) {
> + rsp = RING_GET_RESPONSE(&bedata->ring, bedata->ring.rsp_cons);
> +
> + req_id = rsp->req_id;
> + src = (uint8_t *)&bedata->rsp[req_id];
> + src += sizeof(rsp->req_id);
> + dst = (uint8_t *)rsp;
> + dst += sizeof(rsp->req_id);
These two lines can be combined (both src and dst)
> + memcpy(dst, src, sizeof(*rsp) - sizeof(rsp->req_id));
> + /*
> + * First copy the rest of the data, then req_id. It is
> + * paired with the barrier when accessing bedata->rsp.
> + */
> + smp_wmb();
> + WRITE_ONCE(bedata->rsp[req_id].req_id, rsp->req_id);
> +
> + done = 1;
> + bedata->ring.rsp_cons++;
> + }
> +
> + RING_FINAL_CHECK_FOR_RESPONSES(&bedata->ring, more);
> + if (more)
> + goto again;
> + if (done)
> + wake_up(&bedata->inflight_req);
> return IRQ_HANDLED;
> }
>
> +int pvcalls_front_socket(struct socket *sock)
> +{
> + struct pvcalls_bedata *bedata;
> + struct xen_pvcalls_request *req;
> + int notify, req_id, ret;
> +
> + if (!pvcalls_front_dev)
> + return -EACCES;
> + /*
> + * PVCalls only supports domain AF_INET,
> + * type SOCK_STREAM and protocol 0 sockets for now.
> + *
> + * Check socket type here, AF_INET and protocol checks are done
> + * by the caller.
> + */
> + if (sock->type != SOCK_STREAM)
> + return -ENOTSUPP;
> +
> + bedata = dev_get_drvdata(&pvcalls_front_dev->dev);
> +
> + spin_lock(&bedata->pvcallss_lock);
> + req_id = bedata->ring.req_prod_pvt & (RING_SIZE(&bedata->ring) - 1);
> + if (RING_FULL(&bedata->ring) ||
> + READ_ONCE(bedata->rsp[req_id].req_id) != PVCALLS_INVALID_ID) {
> + spin_unlock(&bedata->pvcallss_lock);
> + return -EAGAIN;
> + }
> + req = RING_GET_REQUEST(&bedata->ring, req_id);
> + req->req_id = req_id;
> + req->cmd = PVCALLS_SOCKET;
> + req->u.socket.id = (uint64_t) sock;
> + req->u.socket.domain = AF_INET;
> + req->u.socket.type = SOCK_STREAM;
> + req->u.socket.protocol = 0;
> +
> + bedata->ring.req_prod_pvt++;
> + RING_PUSH_REQUESTS_AND_CHECK_NOTIFY(&bedata->ring, notify);
> + spin_unlock(&bedata->pvcallss_lock);
> + if (notify)
> + notify_remote_via_irq(bedata->irq);
> +
> + if (wait_event_interruptible(bedata->inflight_req,
> + READ_ONCE(bedata->rsp[req_id].req_id) == req_id) != 0)
"!= 0" can be dropped
-boris
> + return -EINTR;
> +
> + ret = bedata->rsp[req_id].ret;
> + /* read ret, then set this rsp slot to be reused */
> + smp_mb();
> + WRITE_ONCE(bedata->rsp[req_id].req_id, PVCALLS_INVALID_ID);
> +
> + return ret;
> +}
> +
> static const struct xenbus_device_id pvcalls_front_ids[] = {
> { "pvcalls" },
> { "" }
> diff --git a/drivers/xen/pvcalls-front.h b/drivers/xen/pvcalls-front.h
> new file mode 100644
> index 0000000..b7dabed
> --- /dev/null
> +++ b/drivers/xen/pvcalls-front.h
> @@ -0,0 +1,8 @@
> +#ifndef __PVCALLS_FRONT_H__
> +#define __PVCALLS_FRONT_H__
> +
> +#include <linux/net.h>
> +
> +int pvcalls_front_socket(struct socket *sock);
> +
> +#endif
next prev parent reply other threads:[~2017-07-26 14:28 UTC|newest]
Thread overview: 81+ messages / expand[flat|nested] mbox.gz Atom feed top
2017-07-25 21:21 [PATCH v2 00/13] introduce the Xen PV Calls frontend Stefano Stabellini
2017-07-25 21:21 ` [PATCH v2 01/13] xen/pvcalls: introduce the pvcalls xenbus frontend Stefano Stabellini
2017-07-25 21:21 ` Stefano Stabellini
2017-07-25 21:21 ` [PATCH v2 02/13] xen/pvcalls: connect to the backend Stefano Stabellini
2017-07-25 21:21 ` Stefano Stabellini
2017-07-26 13:35 ` Boris Ostrovsky
2017-07-27 0:26 ` Stefano Stabellini
2017-07-27 15:07 ` Boris Ostrovsky
2017-07-27 15:07 ` Boris Ostrovsky
2017-07-31 21:55 ` Stefano Stabellini
2017-07-31 21:55 ` Stefano Stabellini
2017-07-27 0:26 ` Stefano Stabellini
2017-07-26 13:35 ` Boris Ostrovsky
2017-07-25 21:22 ` [PATCH v2 03/13] xen/pvcalls: implement socket command and handle events Stefano Stabellini
2017-07-25 21:22 ` Stefano Stabellini
2017-07-26 14:27 ` Boris Ostrovsky [this message]
2017-07-26 23:19 ` Stefano Stabellini
2017-07-26 23:19 ` Stefano Stabellini
2017-07-26 14:27 ` Boris Ostrovsky
2017-07-25 21:22 ` [PATCH v2 04/13] xen/pvcalls: implement connect command Stefano Stabellini
2017-07-25 21:22 ` Stefano Stabellini
2017-07-26 14:51 ` Boris Ostrovsky
2017-07-26 14:51 ` Boris Ostrovsky
2017-07-26 23:22 ` Stefano Stabellini
2017-07-26 23:22 ` Stefano Stabellini
2017-07-25 21:22 ` [PATCH v2 05/13] xen/pvcalls: implement bind command Stefano Stabellini
2017-07-25 21:22 ` Stefano Stabellini
2017-07-26 14:56 ` Boris Ostrovsky
2017-07-26 23:59 ` Stefano Stabellini
2017-07-26 23:59 ` Stefano Stabellini
2017-07-27 14:43 ` Boris Ostrovsky
2017-07-31 22:17 ` Stefano Stabellini
2017-07-31 22:17 ` Stefano Stabellini
2017-07-27 14:43 ` Boris Ostrovsky
2017-07-26 14:56 ` Boris Ostrovsky
2017-07-25 21:22 ` [PATCH v2 06/13] xen/pvcalls: implement listen command Stefano Stabellini
2017-07-25 21:22 ` Stefano Stabellini
2017-07-25 21:22 ` [PATCH v2 07/13] xen/pvcalls: implement accept command Stefano Stabellini
2017-07-25 21:22 ` Stefano Stabellini
2017-07-26 17:52 ` Boris Ostrovsky
2017-07-26 23:24 ` Stefano Stabellini
2017-07-26 23:24 ` Stefano Stabellini
2017-07-26 17:52 ` Boris Ostrovsky
2017-07-25 21:22 ` [PATCH v2 08/13] xen/pvcalls: implement sendmsg Stefano Stabellini
2017-07-25 21:22 ` Stefano Stabellini
2017-07-25 21:22 ` [PATCH v2 09/13] xen/pvcalls: implement recvmsg Stefano Stabellini
2017-07-25 21:22 ` Stefano Stabellini
2017-07-26 21:21 ` Boris Ostrovsky
2017-07-26 21:33 ` Boris Ostrovsky
2017-07-26 21:33 ` [Xen-devel] " Boris Ostrovsky
2017-07-27 0:08 ` Stefano Stabellini
2017-07-27 14:59 ` Boris Ostrovsky
2017-07-27 14:59 ` [Xen-devel] " Boris Ostrovsky
2017-07-31 22:26 ` Stefano Stabellini
2017-07-31 22:26 ` Stefano Stabellini
2017-07-27 0:08 ` Stefano Stabellini
2017-07-26 21:21 ` Boris Ostrovsky
2017-07-25 21:22 ` [PATCH v2 10/13] xen/pvcalls: implement poll command Stefano Stabellini
2017-07-25 21:22 ` Stefano Stabellini
2017-07-26 23:23 ` Boris Ostrovsky
2017-07-26 23:23 ` Boris Ostrovsky
2017-07-27 0:21 ` Stefano Stabellini
2017-07-27 0:21 ` Stefano Stabellini
2017-07-25 21:22 ` [PATCH v2 11/13] xen/pvcalls: implement release command Stefano Stabellini
2017-07-25 21:22 ` Stefano Stabellini
2017-07-27 18:39 ` Boris Ostrovsky
2017-07-27 18:39 ` Boris Ostrovsky
2017-07-31 22:34 ` Stefano Stabellini
2017-07-31 22:34 ` Stefano Stabellini
2017-08-01 15:23 ` Boris Ostrovsky
2017-08-01 15:23 ` Boris Ostrovsky
2017-08-01 15:34 ` Juergen Gross
2017-08-01 15:34 ` Juergen Gross
2017-08-01 15:57 ` Boris Ostrovsky
2017-08-01 15:57 ` Boris Ostrovsky
2017-09-11 23:56 ` Stefano Stabellini
2017-09-11 23:56 ` Stefano Stabellini
2017-07-25 21:22 ` [PATCH v2 12/13] xen/pvcalls: implement frontend disconnect Stefano Stabellini
2017-07-25 21:22 ` Stefano Stabellini
2017-07-25 21:22 ` [PATCH v2 13/13] xen: introduce a Kconfig option to enable the pvcalls frontend Stefano Stabellini
2017-07-25 21:22 ` Stefano Stabellini
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=5978A6E3.7010809@oracle.com \
--to=boris.ostrovsky@oracle.com \
--cc=jgross@suse.com \
--cc=linux-kernel@vger.kernel.org \
--cc=sstabellini@kernel.org \
--cc=stefano@aporeto.com \
--cc=xen-devel@lists.xen.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.