Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > linux.kernel > #1600052 > unrolled thread

Re: [PATCH v3 4/7] xen/9pfs: connect to the backend

Started byJuergen Gross <jgross@suse.com>
First post2017-03-14 07:50 +0100
Last post2017-03-17 22:10 +0100
Articles 9 — 3 participants

Back to article view | Back to linux.kernel

This discussion starts older than the indexed window; earlier articles aren't shown. The article labeled Started by below is the oldest one visible, not the original post.


Contents

  Re: [PATCH v3 4/7] xen/9pfs: connect to the backend Juergen Gross <jgross@suse.com> - 2017-03-14 07:50 +0100
    Re: [PATCH v3 4/7] xen/9pfs: connect to the backend Stefano Stabellini <sstabellini@kernel.org> - 2017-03-14 22:30 +0100
      Re: [PATCH v3 4/7] xen/9pfs: connect to the backend Juergen Gross <jgross@suse.com> - 2017-03-15 06:10 +0100
        Re: [PATCH v3 4/7] xen/9pfs: connect to the backend Stefano Stabellini <sstabellini@kernel.org> - 2017-03-15 19:50 +0100
          Re: [PATCH v3 4/7] xen/9pfs: connect to the backend Juergen Gross <jgross@suse.com> - 2017-03-16 07:00 +0100
            Re: [PATCH v3 4/7] xen/9pfs: connect to the backend Stefano Stabellini <sstabellini@kernel.org> - 2017-03-16 19:10 +0100
              Re: [PATCH v3 4/7] xen/9pfs: connect to the backend Juergen Gross <jgross@suse.com> - 2017-03-17 06:00 +0100
                Re: [Xen-devel] [PATCH v3 4/7] xen/9pfs: connect to the backend Konrad Rzeszutek Wilk <konrad.wilk@oracle.com> - 2017-03-17 16:20 +0100
                  Re: [Xen-devel] [PATCH v3 4/7] xen/9pfs: connect to the backend Stefano Stabellini <sstabellini@kernel.org> - 2017-03-17 22:10 +0100

#1600052 — Re: [PATCH v3 4/7] xen/9pfs: connect to the backend

FromJuergen Gross <jgross@suse.com>
Date2017-03-14 07:50 +0100
SubjectRe: [PATCH v3 4/7] xen/9pfs: connect to the backend
Message-ID<tkOrn-4C0-3@gated-at.bofh.it>
On 14/03/17 00:50, Stefano Stabellini wrote:
> Implement functions to handle the xenbus handshake. Upon connection,
> allocate the rings according to the protocol specification.
> 
> Initialize a work_struct and a wait_queue. The work_struct will be used
> to schedule work upon receiving an event channel notification from the
> backend. The wait_queue will be used to wait when the ring is full and
> we need to send a new request.
> 
> Signed-off-by: Stefano Stabellini <stefano@aporeto.com>
> CC: boris.ostrovsky@oracle.com
> CC: jgross@suse.com
> CC: Eric Van Hensbergen <ericvh@gmail.com>
> CC: Ron Minnich <rminnich@sandia.gov>
> CC: Latchesar Ionkov <lucho@ionkov.net>
> CC: v9fs-developer@lists.sourceforge.net
> ---
>  net/9p/trans_xen.c | 240 +++++++++++++++++++++++++++++++++++++++++++++++++++++
>  1 file changed, 240 insertions(+)
> 
> diff --git a/net/9p/trans_xen.c b/net/9p/trans_xen.c
> index f072876..974bac3 100644
> --- a/net/9p/trans_xen.c
> +++ b/net/9p/trans_xen.c
> @@ -41,6 +41,35 @@
>  #include <net/9p/client.h>
>  #include <net/9p/transport.h>
>  
> +#define XEN_9PFS_NUM_RINGS 2
> +
> +/* One per ring, more than one per 9pfs share */
> +struct xen_9pfs_dataring {
> +	struct xen_9pfs_front_priv *priv;
> +
> +	struct xen_9pfs_data_intf *intf;
> +	grant_ref_t ref;
> +	int evtchn;
> +	int irq;
> +	spinlock_t lock;
> +
> +	struct xen_9pfs_data data;
> +	wait_queue_head_t wq;
> +	struct work_struct work;
> +};
> +
> +/* One per 9pfs share */
> +struct xen_9pfs_front_priv {
> +	struct list_head list;
> +	struct xenbus_device *dev;
> +	char *tag;
> +	struct p9_client *client;
> +
> +	int num_rings;
> +	struct xen_9pfs_dataring *rings;
> +};
> +static LIST_HEAD(xen_9pfs_devs);
> +
>  static int p9_xen_cancel(struct p9_client *client, struct p9_req_t *req)
>  {
>  	return 0;
> @@ -60,6 +89,21 @@ static int p9_xen_request(struct p9_client *client, struct p9_req_t *p9_req)
>  	return 0;
>  }
>  
> +static void p9_xen_response(struct work_struct *work)
> +{
> +}
> +
> +static irqreturn_t xen_9pfs_front_event_handler(int irq, void *r)
> +{
> +	struct xen_9pfs_dataring *ring = r;
> +	BUG_ON(!ring || !ring->priv->client);
> +
> +	wake_up_interruptible(&ring->wq);
> +	schedule_work(&ring->work);
> +
> +	return IRQ_HANDLED;
> +}
> +
>  static struct p9_trans_module p9_xen_trans = {
>  	.name = "xen",
>  	.maxsize = (1 << (XEN_9PFS_RING_ORDER + XEN_PAGE_SHIFT)),
> @@ -76,25 +120,221 @@ static int p9_xen_request(struct p9_client *client, struct p9_req_t *p9_req)
>  	{ "" }
>  };
>  
> +static int xen_9pfs_front_free(struct xen_9pfs_front_priv *priv)

Return type void? You are always returning 0.

> +{
> +	int i, j;
> +
> +	list_del(&priv->list);
> +
> +	for (i = 0; i < priv->num_rings; i++) {
> +		if (priv->rings[i].intf == NULL)
> +			break;
> +		if (priv->rings[i].irq > 0)
> +			unbind_from_irqhandler(priv->rings[i].irq, priv->dev);
> +		if (priv->rings[i].data.in != NULL) {
> +			for (j = 0; j < (1 << XEN_9PFS_RING_ORDER); j++)
> +				gnttab_end_foreign_access(priv->rings[i].intf->ref[j], 0, 0);
> +			free_pages((unsigned long)priv->rings[i].data.in,
> +					XEN_9PFS_RING_ORDER - (PAGE_SHIFT - XEN_PAGE_SHIFT));
> +		}
> +		gnttab_end_foreign_access(priv->rings[i].ref, 0, 0);
> +		free_page((unsigned long)priv->rings[i].intf);
> +	}
> +	kfree(priv->rings);
> +	kfree(priv);
> +
> +	return 0;
> +}
> +
>  static int xen_9pfs_front_remove(struct xenbus_device *dev)
>  {
> +	int ret;
> +	struct xen_9pfs_front_priv *priv = dev_get_drvdata(&dev->dev);
> +
> +	dev_set_drvdata(&dev->dev, NULL);
> +	ret = xen_9pfs_front_free(priv);
> +	return ret;
> +}
> +
> +static int xen_9pfs_front_alloc_dataring(struct xenbus_device *dev,
> +		struct xen_9pfs_dataring *ring)
> +{
> +	int i = 0;
> +	int ret = -ENOMEM;
> +	void *bytes = NULL;
> +
> +	init_waitqueue_head(&ring->wq);
> +	spin_lock_init(&ring->lock);
> +	INIT_WORK(&ring->work, p9_xen_response);
> +
> +	ring->intf = (struct xen_9pfs_data_intf *) get_zeroed_page(GFP_KERNEL | __GFP_ZERO);

I don't think you need __GFP_ZERO here.

> +	if (!ring->intf)
> +		return ret;
> +	ret = ring->ref = gnttab_grant_foreign_access(dev->otherend_id,
> +			virt_to_gfn(ring->intf), 0);
> +	if (ret < 0)
> +		goto out;
> +	bytes = (void*)__get_free_pages(GFP_KERNEL | __GFP_ZERO,

Coding style: (void *)

> +			XEN_9PFS_RING_ORDER - (PAGE_SHIFT - XEN_PAGE_SHIFT));
> +	if (bytes == NULL)
> +		goto out;
> +	for (; i < (1 << XEN_9PFS_RING_ORDER); i++) {
> +		ret = ring->intf->ref[i] = gnttab_grant_foreign_access(
> +				dev->otherend_id, virt_to_gfn(bytes) + i, 0);
> +		if (ret < 0)
> +			goto out;
> +	}
> +	ring->data.in = bytes;
> +	ring->data.out = bytes + XEN_9PFS_RING_SIZE;
> +
> +	ret = xenbus_alloc_evtchn(dev, &ring->evtchn);
> +	if (ret)
> +		goto out;
> +	ring->irq = bind_evtchn_to_irqhandler(ring->evtchn, xen_9pfs_front_event_handler,
> +					0, "xen_9pfs-frontend", ring);

Did you think about using request_threaded_irq() instead of a workqueue?
For an example see e.g. drivers/scsi/xen-scsifront.c

> +	if (ring->irq < 0) {
> +		xenbus_free_evtchn(dev, ring->evtchn);
> +		ret = ring->irq;
> +		goto out;
> +	}
>  	return 0;
> +
> +out:
> +	if (bytes != NULL) {
> +		for (i--; i >= 0; i--)
> +			gnttab_end_foreign_access(ring->intf->ref[i], 0, 0);
> +		free_pages((unsigned long)bytes,
> +				XEN_9PFS_RING_ORDER - (PAGE_SHIFT - XEN_PAGE_SHIFT));
> +	}
> +	gnttab_end_foreign_access(ring->ref, 0, 0);
> +	free_page((unsigned long)ring->intf);
> +	return ret;
>  }
>  
>  static int xen_9pfs_front_probe(struct xenbus_device *dev,
>  		const struct xenbus_device_id *id)
>  {
> +	int ret, i;
> +	struct xenbus_transaction xbt;
> +	struct xen_9pfs_front_priv *priv = NULL;
> +	char *versions;
> +	unsigned int max_rings, max_ring_order, len;
> +
> +	versions = xenbus_read(XBT_NIL, dev->otherend, "versions", &len);
> +	if (!len || strcmp(versions, "1"))

You are leaking versions in case of not being "1".

Can't you use xenbus_read_unsigned() instead of xenbus_read()?

> +		return -EINVAL;
> +	kfree(versions);
> +	ret = xenbus_scanf(XBT_NIL, dev->otherend, "max-rings", "%u", &max_rings);

xenbus_read_unsigned()?

> +	if (ret < 0 || max_rings < XEN_9PFS_NUM_RINGS)
> +		return -EINVAL;
> +	ret = xenbus_scanf(XBT_NIL, dev->otherend, "max-ring-page-order", "%u", &max_ring_order);

xenbus_read_unsigned()

> +	if (ret < 0|| max_ring_order < XEN_9PFS_RING_ORDER)

Coding style (missing space before ||)

> +		return -EINVAL;
> +
> +
> +	priv = kzalloc(sizeof(struct xen_9pfs_front_priv), GFP_KERNEL);
> +	if (!priv)
> +		return -ENOMEM;
> +
> +	priv->dev = dev;
> +	priv->num_rings = XEN_9PFS_NUM_RINGS;
> +	priv->rings = kzalloc(sizeof(struct xen_9pfs_dataring) * priv->num_rings,
> +						GFP_KERNEL);

Coding style: please align the second line to the first parameter of
kzalloc().

> +	if (!priv->rings) {
> +		kfree(priv);
> +		return -ENOMEM;
> +	}
> +
> +	for (i = 0; i < priv->num_rings; i++) {
> +		priv->rings[i].priv = priv;
> +		ret = xen_9pfs_front_alloc_dataring(dev, &priv->rings[i]);
> +		if (ret < 0)
> +			goto error;
> +	}
> +
> + again:
> +	ret = xenbus_transaction_start(&xbt);
> +	if (ret) {
> +		xenbus_dev_fatal(dev, ret, "starting transaction");
> +		goto error;
> +	}
> +	ret = xenbus_printf(xbt, dev->nodename, "version", "%u", 1);
> +	if (ret)
> +		goto error_xenbus;
> +	ret = xenbus_printf(xbt, dev->nodename, "num-rings", "%u", priv->num_rings);
> +	if (ret)
> +		goto error_xenbus;
> +	for (i = 0; i < priv->num_rings; i++) {
> +		char str[16];
> +
> +		sprintf(str, "ring-ref%u", i);
> +		ret = xenbus_printf(xbt, dev->nodename, str, "%d", priv->rings[i].ref);
> +		if (ret)
> +			goto error_xenbus;
> +
> +		sprintf(str, "event-channel-%u", i);

This is dangerous: you are hard coding num_rings always being less than
10 here. Otherwise str[] isn't large enough. Mind adding
BUILD_BUG_ON(XEN_9PFS_NUM_RINGS > 9)?

> +		ret = xenbus_printf(xbt, dev->nodename, str, "%u", priv->rings[i].evtchn);
> +		if (ret)
> +			goto error_xenbus;
> +	}
> +	priv->tag = xenbus_read(xbt, dev->nodename, "tag", NULL);
> +	if (ret)
> +		goto error_xenbus;
> +	ret = xenbus_transaction_end(xbt, 0);
> +	if (ret) {
> +		if (ret == -EAGAIN)
> +			goto again;
> +		xenbus_dev_fatal(dev, ret, "completing transaction");
> +		goto error;
> +	}
> +
> +	list_add_tail(&priv->list, &xen_9pfs_devs);

Don't you need some kind of lock protecting the list?

> +	dev_set_drvdata(&dev->dev, priv);
> +	xenbus_switch_state(dev, XenbusStateInitialised);
> +
>  	return 0;
> +
> + error_xenbus:
> +	xenbus_transaction_end(xbt, 1);
> +	xenbus_dev_fatal(dev, ret, "writing xenstore");
> + error:
> +	dev_set_drvdata(&dev->dev, NULL);
> +	xen_9pfs_front_free(priv);
> +	return ret;
>  }
>  
>  static int xen_9pfs_front_resume(struct xenbus_device *dev)
>  {
> +	dev_warn(&dev->dev, "suspsend/resume unsupported\n");
>  	return 0;
>  }
>  
>  static void xen_9pfs_front_changed(struct xenbus_device *dev,
>  			    enum xenbus_state backend_state)
>  {
> +	switch (backend_state) {
> +	case XenbusStateReconfiguring:
> +	case XenbusStateReconfigured:
> +	case XenbusStateInitialising:
> +	case XenbusStateInitialised:
> +	case XenbusStateUnknown:
> +		break;
> +
> +	case XenbusStateInitWait:
> +		break;
> +
> +	case XenbusStateConnected:
> +		xenbus_switch_state(dev, XenbusStateConnected);
> +		break;
> +
> +	case XenbusStateClosed:
> +		if (dev->state == XenbusStateClosed)
> +			break;
> +		/* Missed the backend's CLOSING state -- fallthrough */
> +	case XenbusStateClosing:
> +		xenbus_frontend_closed(dev);
> +		break;
> +	}
>  }
>  
>  static struct xenbus_driver xen_9pfs_front_driver = {
> 


Juergen

[toc] | [next] | [standalone]


#1600922

FromStefano Stabellini <sstabellini@kernel.org>
Date2017-03-14 22:30 +0100
Message-ID<tl2b1-66f-45@gated-at.bofh.it>
In reply to#1600052
Hi Juergen,

thank you for the review!

On Tue, 14 Mar 2017, Juergen Gross wrote:
> On 14/03/17 00:50, Stefano Stabellini wrote:
> > Implement functions to handle the xenbus handshake. Upon connection,
> > allocate the rings according to the protocol specification.
> > 
> > Initialize a work_struct and a wait_queue. The work_struct will be used
> > to schedule work upon receiving an event channel notification from the
> > backend. The wait_queue will be used to wait when the ring is full and
> > we need to send a new request.
> > 
> > Signed-off-by: Stefano Stabellini <stefano@aporeto.com>
> > CC: boris.ostrovsky@oracle.com
> > CC: jgross@suse.com
> > CC: Eric Van Hensbergen <ericvh@gmail.com>
> > CC: Ron Minnich <rminnich@sandia.gov>
> > CC: Latchesar Ionkov <lucho@ionkov.net>
> > CC: v9fs-developer@lists.sourceforge.net
> > ---
> >  net/9p/trans_xen.c | 240 +++++++++++++++++++++++++++++++++++++++++++++++++++++
> >  1 file changed, 240 insertions(+)
> > 
> > diff --git a/net/9p/trans_xen.c b/net/9p/trans_xen.c
> > index f072876..974bac3 100644
> > --- a/net/9p/trans_xen.c
> > +++ b/net/9p/trans_xen.c
> > @@ -41,6 +41,35 @@
> >  #include <net/9p/client.h>
> >  #include <net/9p/transport.h>
> >  
> > +#define XEN_9PFS_NUM_RINGS 2
> > +
> > +/* One per ring, more than one per 9pfs share */
> > +struct xen_9pfs_dataring {
> > +	struct xen_9pfs_front_priv *priv;
> > +
> > +	struct xen_9pfs_data_intf *intf;
> > +	grant_ref_t ref;
> > +	int evtchn;
> > +	int irq;
> > +	spinlock_t lock;
> > +
> > +	struct xen_9pfs_data data;
> > +	wait_queue_head_t wq;
> > +	struct work_struct work;
> > +};
> > +
> > +/* One per 9pfs share */
> > +struct xen_9pfs_front_priv {
> > +	struct list_head list;
> > +	struct xenbus_device *dev;
> > +	char *tag;
> > +	struct p9_client *client;
> > +
> > +	int num_rings;
> > +	struct xen_9pfs_dataring *rings;
> > +};
> > +static LIST_HEAD(xen_9pfs_devs);
> > +
> >  static int p9_xen_cancel(struct p9_client *client, struct p9_req_t *req)
> >  {
> >  	return 0;
> > @@ -60,6 +89,21 @@ static int p9_xen_request(struct p9_client *client, struct p9_req_t *p9_req)
> >  	return 0;
> >  }
> >  
> > +static void p9_xen_response(struct work_struct *work)
> > +{
> > +}
> > +
> > +static irqreturn_t xen_9pfs_front_event_handler(int irq, void *r)
> > +{
> > +	struct xen_9pfs_dataring *ring = r;
> > +	BUG_ON(!ring || !ring->priv->client);
> > +
> > +	wake_up_interruptible(&ring->wq);
> > +	schedule_work(&ring->work);
> > +
> > +	return IRQ_HANDLED;
> > +}
> > +
> >  static struct p9_trans_module p9_xen_trans = {
> >  	.name = "xen",
> >  	.maxsize = (1 << (XEN_9PFS_RING_ORDER + XEN_PAGE_SHIFT)),
> > @@ -76,25 +120,221 @@ static int p9_xen_request(struct p9_client *client, struct p9_req_t *p9_req)
> >  	{ "" }
> >  };
> >  
> > +static int xen_9pfs_front_free(struct xen_9pfs_front_priv *priv)
> 
> Return type void? You are always returning 0.

Good point


> > +{
> > +	int i, j;
> > +
> > +	list_del(&priv->list);
> > +
> > +	for (i = 0; i < priv->num_rings; i++) {
> > +		if (priv->rings[i].intf == NULL)
> > +			break;
> > +		if (priv->rings[i].irq > 0)
> > +			unbind_from_irqhandler(priv->rings[i].irq, priv->dev);
> > +		if (priv->rings[i].data.in != NULL) {
> > +			for (j = 0; j < (1 << XEN_9PFS_RING_ORDER); j++)
> > +				gnttab_end_foreign_access(priv->rings[i].intf->ref[j], 0, 0);
> > +			free_pages((unsigned long)priv->rings[i].data.in,
> > +					XEN_9PFS_RING_ORDER - (PAGE_SHIFT - XEN_PAGE_SHIFT));
> > +		}
> > +		gnttab_end_foreign_access(priv->rings[i].ref, 0, 0);
> > +		free_page((unsigned long)priv->rings[i].intf);
> > +	}
> > +	kfree(priv->rings);
> > +	kfree(priv);
> > +
> > +	return 0;
> > +}
> > +
> >  static int xen_9pfs_front_remove(struct xenbus_device *dev)
> >  {
> > +	int ret;
> > +	struct xen_9pfs_front_priv *priv = dev_get_drvdata(&dev->dev);
> > +
> > +	dev_set_drvdata(&dev->dev, NULL);
> > +	ret = xen_9pfs_front_free(priv);
> > +	return ret;
> > +}
> > +
> > +static int xen_9pfs_front_alloc_dataring(struct xenbus_device *dev,
> > +		struct xen_9pfs_dataring *ring)
> > +{
> > +	int i = 0;
> > +	int ret = -ENOMEM;
> > +	void *bytes = NULL;
> > +
> > +	init_waitqueue_head(&ring->wq);
> > +	spin_lock_init(&ring->lock);
> > +	INIT_WORK(&ring->work, p9_xen_response);
> > +
> > +	ring->intf = (struct xen_9pfs_data_intf *) get_zeroed_page(GFP_KERNEL | __GFP_ZERO);
> 
> I don't think you need __GFP_ZERO here.

You are right


> > +	if (!ring->intf)
> > +		return ret;
> > +	ret = ring->ref = gnttab_grant_foreign_access(dev->otherend_id,
> > +			virt_to_gfn(ring->intf), 0);
> > +	if (ret < 0)
> > +		goto out;
> > +	bytes = (void*)__get_free_pages(GFP_KERNEL | __GFP_ZERO,
> 
> Coding style: (void *)

OK


> > +			XEN_9PFS_RING_ORDER - (PAGE_SHIFT - XEN_PAGE_SHIFT));
> > +	if (bytes == NULL)
> > +		goto out;
> > +	for (; i < (1 << XEN_9PFS_RING_ORDER); i++) {
> > +		ret = ring->intf->ref[i] = gnttab_grant_foreign_access(
> > +				dev->otherend_id, virt_to_gfn(bytes) + i, 0);
> > +		if (ret < 0)
> > +			goto out;
> > +	}
> > +	ring->data.in = bytes;
> > +	ring->data.out = bytes + XEN_9PFS_RING_SIZE;
> > +
> > +	ret = xenbus_alloc_evtchn(dev, &ring->evtchn);
> > +	if (ret)
> > +		goto out;
> > +	ring->irq = bind_evtchn_to_irqhandler(ring->evtchn, xen_9pfs_front_event_handler,
> > +					0, "xen_9pfs-frontend", ring);
> 
> Did you think about using request_threaded_irq() instead of a workqueue?
> For an example see e.g. drivers/scsi/xen-scsifront.c

I like workqueues :-)  It might come down to personal preferences, but I
think workqueues are more flexible and a better fit for this use case.
Not only it is easy to schedule work in a workqueue from the interrupt
handler, but also they can be used for sleeping in the request function
if there is not enough room on the ring. Besides, they can easily be
configured to share a single thread or to have multiple independent
threads.


> > +	if (ring->irq < 0) {
> > +		xenbus_free_evtchn(dev, ring->evtchn);
> > +		ret = ring->irq;
> > +		goto out;
> > +	}
> >  	return 0;
> > +
> > +out:
> > +	if (bytes != NULL) {
> > +		for (i--; i >= 0; i--)
> > +			gnttab_end_foreign_access(ring->intf->ref[i], 0, 0);
> > +		free_pages((unsigned long)bytes,
> > +				XEN_9PFS_RING_ORDER - (PAGE_SHIFT - XEN_PAGE_SHIFT));
> > +	}
> > +	gnttab_end_foreign_access(ring->ref, 0, 0);
> > +	free_page((unsigned long)ring->intf);
> > +	return ret;
> >  }
> >  
> >  static int xen_9pfs_front_probe(struct xenbus_device *dev,
> >  		const struct xenbus_device_id *id)
> >  {
> > +	int ret, i;
> > +	struct xenbus_transaction xbt;
> > +	struct xen_9pfs_front_priv *priv = NULL;
> > +	char *versions;
> > +	unsigned int max_rings, max_ring_order, len;
> > +
> > +	versions = xenbus_read(XBT_NIL, dev->otherend, "versions", &len);
> > +	if (!len || strcmp(versions, "1"))
> 
> You are leaking versions in case of not being "1".

I'll fix


> Can't you use xenbus_read_unsigned() instead of xenbus_read()?

I can use xenbus_read_unsigned in the other cases below, but not here,
because versions is in the form: "1,3,4"


> > +		return -EINVAL;
> > +	kfree(versions);
> > +	ret = xenbus_scanf(XBT_NIL, dev->otherend, "max-rings", "%u", &max_rings);
> 
> xenbus_read_unsigned()?

Good idea, I'll use it


> > +	if (ret < 0 || max_rings < XEN_9PFS_NUM_RINGS)
> > +		return -EINVAL;
> > +	ret = xenbus_scanf(XBT_NIL, dev->otherend, "max-ring-page-order", "%u", &max_ring_order);
> 
> xenbus_read_unsigned()

Yep


> > +	if (ret < 0|| max_ring_order < XEN_9PFS_RING_ORDER)
> 
> Coding style (missing space before ||)

OK


> > +		return -EINVAL;
> > +
> > +
> > +	priv = kzalloc(sizeof(struct xen_9pfs_front_priv), GFP_KERNEL);
> > +	if (!priv)
> > +		return -ENOMEM;
> > +
> > +	priv->dev = dev;
> > +	priv->num_rings = XEN_9PFS_NUM_RINGS;
> > +	priv->rings = kzalloc(sizeof(struct xen_9pfs_dataring) * priv->num_rings,
> > +						GFP_KERNEL);
> 
> Coding style: please align the second line to the first parameter of
> kzalloc().

OK


> > +	if (!priv->rings) {
> > +		kfree(priv);
> > +		return -ENOMEM;
> > +	}
> > +
> > +	for (i = 0; i < priv->num_rings; i++) {
> > +		priv->rings[i].priv = priv;
> > +		ret = xen_9pfs_front_alloc_dataring(dev, &priv->rings[i]);
> > +		if (ret < 0)
> > +			goto error;
> > +	}
> > +
> > + again:
> > +	ret = xenbus_transaction_start(&xbt);
> > +	if (ret) {
> > +		xenbus_dev_fatal(dev, ret, "starting transaction");
> > +		goto error;
> > +	}
> > +	ret = xenbus_printf(xbt, dev->nodename, "version", "%u", 1);
> > +	if (ret)
> > +		goto error_xenbus;
> > +	ret = xenbus_printf(xbt, dev->nodename, "num-rings", "%u", priv->num_rings);
> > +	if (ret)
> > +		goto error_xenbus;
> > +	for (i = 0; i < priv->num_rings; i++) {
> > +		char str[16];
> > +
> > +		sprintf(str, "ring-ref%u", i);
> > +		ret = xenbus_printf(xbt, dev->nodename, str, "%d", priv->rings[i].ref);
> > +		if (ret)
> > +			goto error_xenbus;
> > +
> > +		sprintf(str, "event-channel-%u", i);
> 
> This is dangerous: you are hard coding num_rings always being less than
> 10 here. Otherwise str[] isn't large enough. Mind adding
> BUILD_BUG_ON(XEN_9PFS_NUM_RINGS > 9)?

Yes, good idea.


> > +		ret = xenbus_printf(xbt, dev->nodename, str, "%u", priv->rings[i].evtchn);
> > +		if (ret)
> > +			goto error_xenbus;
> > +	}
> > +	priv->tag = xenbus_read(xbt, dev->nodename, "tag", NULL);
> > +	if (ret)
> > +		goto error_xenbus;
> > +	ret = xenbus_transaction_end(xbt, 0);
> > +	if (ret) {
> > +		if (ret == -EAGAIN)
> > +			goto again;
> > +		xenbus_dev_fatal(dev, ret, "completing transaction");
> > +		goto error;
> > +	}
> > +
> > +	list_add_tail(&priv->list, &xen_9pfs_devs);
> 
> Don't you need some kind of lock protecting the list?

I think I do, I'll add one.


> > +	dev_set_drvdata(&dev->dev, priv);
> > +	xenbus_switch_state(dev, XenbusStateInitialised);
> > +
> >  	return 0;
> > +
> > + error_xenbus:
> > +	xenbus_transaction_end(xbt, 1);
> > +	xenbus_dev_fatal(dev, ret, "writing xenstore");
> > + error:
> > +	dev_set_drvdata(&dev->dev, NULL);
> > +	xen_9pfs_front_free(priv);
> > +	return ret;
> >  }
> >  
> >  static int xen_9pfs_front_resume(struct xenbus_device *dev)
> >  {
> > +	dev_warn(&dev->dev, "suspsend/resume unsupported\n");
> >  	return 0;
> >  }
> >  
> >  static void xen_9pfs_front_changed(struct xenbus_device *dev,
> >  			    enum xenbus_state backend_state)
> >  {
> > +	switch (backend_state) {
> > +	case XenbusStateReconfiguring:
> > +	case XenbusStateReconfigured:
> > +	case XenbusStateInitialising:
> > +	case XenbusStateInitialised:
> > +	case XenbusStateUnknown:
> > +		break;
> > +
> > +	case XenbusStateInitWait:
> > +		break;
> > +
> > +	case XenbusStateConnected:
> > +		xenbus_switch_state(dev, XenbusStateConnected);
> > +		break;
> > +
> > +	case XenbusStateClosed:
> > +		if (dev->state == XenbusStateClosed)
> > +			break;
> > +		/* Missed the backend's CLOSING state -- fallthrough */
> > +	case XenbusStateClosing:
> > +		xenbus_frontend_closed(dev);
> > +		break;
> > +	}
> >  }
> >  
> >  static struct xenbus_driver xen_9pfs_front_driver = {
> > 

[toc] | [prev] | [next] | [standalone]


#1601055

FromJuergen Gross <jgross@suse.com>
Date2017-03-15 06:10 +0100
Message-ID<tl9m9-2KE-1@gated-at.bofh.it>
In reply to#1600922
On 14/03/17 22:22, Stefano Stabellini wrote:
> Hi Juergen,
> 
> thank you for the review!
> 
> On Tue, 14 Mar 2017, Juergen Gross wrote:
>> On 14/03/17 00:50, Stefano Stabellini wrote:
>>> Implement functions to handle the xenbus handshake. Upon connection,
>>> allocate the rings according to the protocol specification.
>>>
>>> Initialize a work_struct and a wait_queue. The work_struct will be used
>>> to schedule work upon receiving an event channel notification from the
>>> backend. The wait_queue will be used to wait when the ring is full and
>>> we need to send a new request.
>>>
>>> Signed-off-by: Stefano Stabellini <stefano@aporeto.com>
>>> CC: boris.ostrovsky@oracle.com
>>> CC: jgross@suse.com
>>> CC: Eric Van Hensbergen <ericvh@gmail.com>
>>> CC: Ron Minnich <rminnich@sandia.gov>
>>> CC: Latchesar Ionkov <lucho@ionkov.net>
>>> CC: v9fs-developer@lists.sourceforge.net
>>> ---

>> Did you think about using request_threaded_irq() instead of a workqueue?
>> For an example see e.g. drivers/scsi/xen-scsifront.c
> 
> I like workqueues :-)  It might come down to personal preferences, but I
> think workqueues are more flexible and a better fit for this use case.
> Not only it is easy to schedule work in a workqueue from the interrupt
> handler, but also they can be used for sleeping in the request function
> if there is not enough room on the ring. Besides, they can easily be
> configured to share a single thread or to have multiple independent
> threads.

I'm fine with the workqueues as long as you have decided to use them
considering the alternatives. :-)

>> Can't you use xenbus_read_unsigned() instead of xenbus_read()?
> 
> I can use xenbus_read_unsigned in the other cases below, but not here,
> because versions is in the form: "1,3,4"

Is this documented somewhere?

Hmm, are any of the Xenstore entries documented? Shouldn't this be done
in xen_9pfs.h ?


Juergen

[toc] | [prev] | [next] | [standalone]


#1601648

FromStefano Stabellini <sstabellini@kernel.org>
Date2017-03-15 19:50 +0100
Message-ID<tlm9I-3am-21@gated-at.bofh.it>
In reply to#1601055
On Wed, 15 Mar 2017, Juergen Gross wrote:
> On 14/03/17 22:22, Stefano Stabellini wrote:
> > Hi Juergen,
> > 
> > thank you for the review!
> > 
> > On Tue, 14 Mar 2017, Juergen Gross wrote:
> >> On 14/03/17 00:50, Stefano Stabellini wrote:
> >>> Implement functions to handle the xenbus handshake. Upon connection,
> >>> allocate the rings according to the protocol specification.
> >>>
> >>> Initialize a work_struct and a wait_queue. The work_struct will be used
> >>> to schedule work upon receiving an event channel notification from the
> >>> backend. The wait_queue will be used to wait when the ring is full and
> >>> we need to send a new request.
> >>>
> >>> Signed-off-by: Stefano Stabellini <stefano@aporeto.com>
> >>> CC: boris.ostrovsky@oracle.com
> >>> CC: jgross@suse.com
> >>> CC: Eric Van Hensbergen <ericvh@gmail.com>
> >>> CC: Ron Minnich <rminnich@sandia.gov>
> >>> CC: Latchesar Ionkov <lucho@ionkov.net>
> >>> CC: v9fs-developer@lists.sourceforge.net
> >>> ---
> 
> >> Did you think about using request_threaded_irq() instead of a workqueue?
> >> For an example see e.g. drivers/scsi/xen-scsifront.c
> > 
> > I like workqueues :-)  It might come down to personal preferences, but I
> > think workqueues are more flexible and a better fit for this use case.
> > Not only it is easy to schedule work in a workqueue from the interrupt
> > handler, but also they can be used for sleeping in the request function
> > if there is not enough room on the ring. Besides, they can easily be
> > configured to share a single thread or to have multiple independent
> > threads.
> 
> I'm fine with the workqueues as long as you have decided to use them
> considering the alternatives. :-)
> 
> >> Can't you use xenbus_read_unsigned() instead of xenbus_read()?
> > 
> > I can use xenbus_read_unsigned in the other cases below, but not here,
> > because versions is in the form: "1,3,4"
> 
> Is this documented somewhere?
> 
> Hmm, are any of the Xenstore entries documented? Shouldn't this be done
> in xen_9pfs.h ?
 
They are documented in docs/misc/9pfs.markdown, under "Xenstore". Given
that it's all written there, especially the semantics, I didn't repeat
it in xen_9pfs.h

[toc] | [prev] | [next] | [standalone]


#1601962

FromJuergen Gross <jgross@suse.com>
Date2017-03-16 07:00 +0100
Message-ID<tlwC5-2c1-3@gated-at.bofh.it>
In reply to#1601648
On 15/03/17 19:44, Stefano Stabellini wrote:
> On Wed, 15 Mar 2017, Juergen Gross wrote:
>> On 14/03/17 22:22, Stefano Stabellini wrote:
>>> Hi Juergen,
>>>
>>> thank you for the review!
>>>
>>> On Tue, 14 Mar 2017, Juergen Gross wrote:
>>>> On 14/03/17 00:50, Stefano Stabellini wrote:
>>>>> Implement functions to handle the xenbus handshake. Upon connection,
>>>>> allocate the rings according to the protocol specification.
>>>>>
>>>>> Initialize a work_struct and a wait_queue. The work_struct will be used
>>>>> to schedule work upon receiving an event channel notification from the
>>>>> backend. The wait_queue will be used to wait when the ring is full and
>>>>> we need to send a new request.
>>>>>
>>>>> Signed-off-by: Stefano Stabellini <stefano@aporeto.com>
>>>>> CC: boris.ostrovsky@oracle.com
>>>>> CC: jgross@suse.com
>>>>> CC: Eric Van Hensbergen <ericvh@gmail.com>
>>>>> CC: Ron Minnich <rminnich@sandia.gov>
>>>>> CC: Latchesar Ionkov <lucho@ionkov.net>
>>>>> CC: v9fs-developer@lists.sourceforge.net
>>>>> ---
>>
>>>> Did you think about using request_threaded_irq() instead of a workqueue?
>>>> For an example see e.g. drivers/scsi/xen-scsifront.c
>>>
>>> I like workqueues :-)  It might come down to personal preferences, but I
>>> think workqueues are more flexible and a better fit for this use case.
>>> Not only it is easy to schedule work in a workqueue from the interrupt
>>> handler, but also they can be used for sleeping in the request function
>>> if there is not enough room on the ring. Besides, they can easily be
>>> configured to share a single thread or to have multiple independent
>>> threads.
>>
>> I'm fine with the workqueues as long as you have decided to use them
>> considering the alternatives. :-)
>>
>>>> Can't you use xenbus_read_unsigned() instead of xenbus_read()?
>>>
>>> I can use xenbus_read_unsigned in the other cases below, but not here,
>>> because versions is in the form: "1,3,4"
>>
>> Is this documented somewhere?
>>
>> Hmm, are any of the Xenstore entries documented? Shouldn't this be done
>> in xen_9pfs.h ?
>  
> They are documented in docs/misc/9pfs.markdown, under "Xenstore". Given
> that it's all written there, especially the semantics, I didn't repeat
> it in xen_9pfs.h

Looking at it from the Linux kernel perspective this documentation is
not really highly visible. For me it is okay, but there have been
multiple examples in the past where documentation in the Xen repository
wasn't regarded as being sufficient.

I recommend moving the documentation regarding the interface into the
header file like for the other pv interfaces.


Juergen

[toc] | [prev] | [next] | [standalone]


#1602723

FromStefano Stabellini <sstabellini@kernel.org>
Date2017-03-16 19:10 +0100
Message-ID<tlI0x-25v-7@gated-at.bofh.it>
In reply to#1601962
On Thu, 16 Mar 2017, Juergen Gross wrote:
> On 15/03/17 19:44, Stefano Stabellini wrote:
> > On Wed, 15 Mar 2017, Juergen Gross wrote:
> >> On 14/03/17 22:22, Stefano Stabellini wrote:
> >>> Hi Juergen,
> >>>
> >>> thank you for the review!
> >>>
> >>> On Tue, 14 Mar 2017, Juergen Gross wrote:
> >>>> On 14/03/17 00:50, Stefano Stabellini wrote:
> >>>>> Implement functions to handle the xenbus handshake. Upon connection,
> >>>>> allocate the rings according to the protocol specification.
> >>>>>
> >>>>> Initialize a work_struct and a wait_queue. The work_struct will be used
> >>>>> to schedule work upon receiving an event channel notification from the
> >>>>> backend. The wait_queue will be used to wait when the ring is full and
> >>>>> we need to send a new request.
> >>>>>
> >>>>> Signed-off-by: Stefano Stabellini <stefano@aporeto.com>
> >>>>> CC: boris.ostrovsky@oracle.com
> >>>>> CC: jgross@suse.com
> >>>>> CC: Eric Van Hensbergen <ericvh@gmail.com>
> >>>>> CC: Ron Minnich <rminnich@sandia.gov>
> >>>>> CC: Latchesar Ionkov <lucho@ionkov.net>
> >>>>> CC: v9fs-developer@lists.sourceforge.net
> >>>>> ---
> >>
> >>>> Did you think about using request_threaded_irq() instead of a workqueue?
> >>>> For an example see e.g. drivers/scsi/xen-scsifront.c
> >>>
> >>> I like workqueues :-)  It might come down to personal preferences, but I
> >>> think workqueues are more flexible and a better fit for this use case.
> >>> Not only it is easy to schedule work in a workqueue from the interrupt
> >>> handler, but also they can be used for sleeping in the request function
> >>> if there is not enough room on the ring. Besides, they can easily be
> >>> configured to share a single thread or to have multiple independent
> >>> threads.
> >>
> >> I'm fine with the workqueues as long as you have decided to use them
> >> considering the alternatives. :-)
> >>
> >>>> Can't you use xenbus_read_unsigned() instead of xenbus_read()?
> >>>
> >>> I can use xenbus_read_unsigned in the other cases below, but not here,
> >>> because versions is in the form: "1,3,4"
> >>
> >> Is this documented somewhere?
> >>
> >> Hmm, are any of the Xenstore entries documented? Shouldn't this be done
> >> in xen_9pfs.h ?
> >  
> > They are documented in docs/misc/9pfs.markdown, under "Xenstore". Given
> > that it's all written there, especially the semantics, I didn't repeat
> > it in xen_9pfs.h
> 
> Looking at it from the Linux kernel perspective this documentation is
> not really highly visible. For me it is okay, but there have been
> multiple examples in the past where documentation in the Xen repository
> wasn't regarded as being sufficient.
> 
> I recommend moving the documentation regarding the interface into the
> header file like for the other pv interfaces.

What about adding a link such as:

http://xenbits.xen.org/gitweb/?p=xen.git;a=blob_plain;f=docs/misc/9pfs.markdown;hb=HEAD

that should be easily accessible, right? For other specifications, such
as 9p, only links are provided (see Documentation/filesystems/9p.txt).
I am suggesting a link, because then we are sure the specs don't go out
of sync. I realize that older PV protocols were described in header
files, but that was before Xen Project had a formal process for getting
new specifications accepted, and a formal place where to publish them.

[toc] | [prev] | [next] | [standalone]


#1603035

FromJuergen Gross <jgross@suse.com>
Date2017-03-17 06:00 +0100
Message-ID<tlS9z-Ec-1@gated-at.bofh.it>
In reply to#1602723
On 16/03/17 19:03, Stefano Stabellini wrote:
> On Thu, 16 Mar 2017, Juergen Gross wrote:
>> On 15/03/17 19:44, Stefano Stabellini wrote:
>>> On Wed, 15 Mar 2017, Juergen Gross wrote:
>>>> On 14/03/17 22:22, Stefano Stabellini wrote:
>>>>> Hi Juergen,
>>>>>
>>>>> thank you for the review!
>>>>>
>>>>> On Tue, 14 Mar 2017, Juergen Gross wrote:
>>>>>> On 14/03/17 00:50, Stefano Stabellini wrote:
>>>>>>> Implement functions to handle the xenbus handshake. Upon connection,
>>>>>>> allocate the rings according to the protocol specification.
>>>>>>>
>>>>>>> Initialize a work_struct and a wait_queue. The work_struct will be used
>>>>>>> to schedule work upon receiving an event channel notification from the
>>>>>>> backend. The wait_queue will be used to wait when the ring is full and
>>>>>>> we need to send a new request.
>>>>>>>
>>>>>>> Signed-off-by: Stefano Stabellini <stefano@aporeto.com>
>>>>>>> CC: boris.ostrovsky@oracle.com
>>>>>>> CC: jgross@suse.com
>>>>>>> CC: Eric Van Hensbergen <ericvh@gmail.com>
>>>>>>> CC: Ron Minnich <rminnich@sandia.gov>
>>>>>>> CC: Latchesar Ionkov <lucho@ionkov.net>
>>>>>>> CC: v9fs-developer@lists.sourceforge.net
>>>>>>> ---
>>>>
>>>>>> Did you think about using request_threaded_irq() instead of a workqueue?
>>>>>> For an example see e.g. drivers/scsi/xen-scsifront.c
>>>>>
>>>>> I like workqueues :-)  It might come down to personal preferences, but I
>>>>> think workqueues are more flexible and a better fit for this use case.
>>>>> Not only it is easy to schedule work in a workqueue from the interrupt
>>>>> handler, but also they can be used for sleeping in the request function
>>>>> if there is not enough room on the ring. Besides, they can easily be
>>>>> configured to share a single thread or to have multiple independent
>>>>> threads.
>>>>
>>>> I'm fine with the workqueues as long as you have decided to use them
>>>> considering the alternatives. :-)
>>>>
>>>>>> Can't you use xenbus_read_unsigned() instead of xenbus_read()?
>>>>>
>>>>> I can use xenbus_read_unsigned in the other cases below, but not here,
>>>>> because versions is in the form: "1,3,4"
>>>>
>>>> Is this documented somewhere?
>>>>
>>>> Hmm, are any of the Xenstore entries documented? Shouldn't this be done
>>>> in xen_9pfs.h ?
>>>  
>>> They are documented in docs/misc/9pfs.markdown, under "Xenstore". Given
>>> that it's all written there, especially the semantics, I didn't repeat
>>> it in xen_9pfs.h
>>
>> Looking at it from the Linux kernel perspective this documentation is
>> not really highly visible. For me it is okay, but there have been
>> multiple examples in the past where documentation in the Xen repository
>> wasn't regarded as being sufficient.
>>
>> I recommend moving the documentation regarding the interface into the
>> header file like for the other pv interfaces.
> 
> What about adding a link such as:
> 
> http://xenbits.xen.org/gitweb/?p=xen.git;a=blob_plain;f=docs/misc/9pfs.markdown;hb=HEAD
> 
> that should be easily accessible, right? For other specifications, such
> as 9p, only links are provided (see Documentation/filesystems/9p.txt).
> I am suggesting a link, because then we are sure the specs don't go out
> of sync. I realize that older PV protocols were described in header
> files, but that was before Xen Project had a formal process for getting
> new specifications accepted, and a formal place where to publish them.

Fine with me. Lets see if other maintainers are okay with it, too.


Juergen

[toc] | [prev] | [next] | [standalone]


#1603396 — Re: [Xen-devel] [PATCH v3 4/7] xen/9pfs: connect to the backend

FromKonrad Rzeszutek Wilk <konrad.wilk@oracle.com>
Date2017-03-17 16:20 +0100
SubjectRe: [Xen-devel] [PATCH v3 4/7] xen/9pfs: connect to the backend
Message-ID<tm1PA-8o8-13@gated-at.bofh.it>
In reply to#1603035
On Fri, Mar 17, 2017 at 05:54:47AM +0100, Juergen Gross wrote:
> On 16/03/17 19:03, Stefano Stabellini wrote:
> > On Thu, 16 Mar 2017, Juergen Gross wrote:
> >> On 15/03/17 19:44, Stefano Stabellini wrote:
> >>> On Wed, 15 Mar 2017, Juergen Gross wrote:
> >>>> On 14/03/17 22:22, Stefano Stabellini wrote:
> >>>>> Hi Juergen,
> >>>>>
> >>>>> thank you for the review!
> >>>>>
> >>>>> On Tue, 14 Mar 2017, Juergen Gross wrote:
> >>>>>> On 14/03/17 00:50, Stefano Stabellini wrote:
> >>>>>>> Implement functions to handle the xenbus handshake. Upon connection,
> >>>>>>> allocate the rings according to the protocol specification.
> >>>>>>>
> >>>>>>> Initialize a work_struct and a wait_queue. The work_struct will be used
> >>>>>>> to schedule work upon receiving an event channel notification from the
> >>>>>>> backend. The wait_queue will be used to wait when the ring is full and
> >>>>>>> we need to send a new request.
> >>>>>>>
> >>>>>>> Signed-off-by: Stefano Stabellini <stefano@aporeto.com>
> >>>>>>> CC: boris.ostrovsky@oracle.com
> >>>>>>> CC: jgross@suse.com
> >>>>>>> CC: Eric Van Hensbergen <ericvh@gmail.com>
> >>>>>>> CC: Ron Minnich <rminnich@sandia.gov>
> >>>>>>> CC: Latchesar Ionkov <lucho@ionkov.net>
> >>>>>>> CC: v9fs-developer@lists.sourceforge.net
> >>>>>>> ---
> >>>>
> >>>>>> Did you think about using request_threaded_irq() instead of a workqueue?
> >>>>>> For an example see e.g. drivers/scsi/xen-scsifront.c
> >>>>>
> >>>>> I like workqueues :-)  It might come down to personal preferences, but I
> >>>>> think workqueues are more flexible and a better fit for this use case.
> >>>>> Not only it is easy to schedule work in a workqueue from the interrupt
> >>>>> handler, but also they can be used for sleeping in the request function
> >>>>> if there is not enough room on the ring. Besides, they can easily be
> >>>>> configured to share a single thread or to have multiple independent
> >>>>> threads.
> >>>>
> >>>> I'm fine with the workqueues as long as you have decided to use them
> >>>> considering the alternatives. :-)
> >>>>
> >>>>>> Can't you use xenbus_read_unsigned() instead of xenbus_read()?
> >>>>>
> >>>>> I can use xenbus_read_unsigned in the other cases below, but not here,
> >>>>> because versions is in the form: "1,3,4"
> >>>>
> >>>> Is this documented somewhere?
> >>>>
> >>>> Hmm, are any of the Xenstore entries documented? Shouldn't this be done
> >>>> in xen_9pfs.h ?
> >>>  
> >>> They are documented in docs/misc/9pfs.markdown, under "Xenstore". Given
> >>> that it's all written there, especially the semantics, I didn't repeat
> >>> it in xen_9pfs.h
> >>
> >> Looking at it from the Linux kernel perspective this documentation is
> >> not really highly visible. For me it is okay, but there have been
> >> multiple examples in the past where documentation in the Xen repository
> >> wasn't regarded as being sufficient.
> >>
> >> I recommend moving the documentation regarding the interface into the
> >> header file like for the other pv interfaces.
> > 
> > What about adding a link such as:
> > 
> > http://xenbits.xen.org/gitweb/?p=xen.git;a=blob_plain;f=docs/misc/9pfs.markdown;hb=HEAD

Ewww.


How about https://xenbits.xen.org/docs/unstable/misc/9pfs.html

which gets updated daily.

> > 
> > that should be easily accessible, right? For other specifications, such
> > as 9p, only links are provided (see Documentation/filesystems/9p.txt).
> > I am suggesting a link, because then we are sure the specs don't go out
> > of sync. I realize that older PV protocols were described in header
> > files, but that was before Xen Project had a formal process for getting
> > new specifications accepted, and a formal place where to publish them.
> 
> Fine with me. Lets see if other maintainers are okay with it, too.
> 
> 
> Juergen
> 
> 
> _______________________________________________
> Xen-devel mailing list
> Xen-devel@lists.xen.org
> https://lists.xen.org/xen-devel

[toc] | [prev] | [next] | [standalone]


#1603623 — Re: [Xen-devel] [PATCH v3 4/7] xen/9pfs: connect to the backend

FromStefano Stabellini <sstabellini@kernel.org>
Date2017-03-17 22:10 +0100
SubjectRe: [Xen-devel] [PATCH v3 4/7] xen/9pfs: connect to the backend
Message-ID<tm7ih-45y-7@gated-at.bofh.it>
In reply to#1603396
On Fri, 17 Mar 2017, Konrad Rzeszutek Wilk wrote:
> On Fri, Mar 17, 2017 at 05:54:47AM +0100, Juergen Gross wrote:
> > On 16/03/17 19:03, Stefano Stabellini wrote:
> > > On Thu, 16 Mar 2017, Juergen Gross wrote:
> > >> On 15/03/17 19:44, Stefano Stabellini wrote:
> > >>> On Wed, 15 Mar 2017, Juergen Gross wrote:
> > >>>> On 14/03/17 22:22, Stefano Stabellini wrote:
> > >>>>> Hi Juergen,
> > >>>>>
> > >>>>> thank you for the review!
> > >>>>>
> > >>>>> On Tue, 14 Mar 2017, Juergen Gross wrote:
> > >>>>>> On 14/03/17 00:50, Stefano Stabellini wrote:
> > >>>>>>> Implement functions to handle the xenbus handshake. Upon connection,
> > >>>>>>> allocate the rings according to the protocol specification.
> > >>>>>>>
> > >>>>>>> Initialize a work_struct and a wait_queue. The work_struct will be used
> > >>>>>>> to schedule work upon receiving an event channel notification from the
> > >>>>>>> backend. The wait_queue will be used to wait when the ring is full and
> > >>>>>>> we need to send a new request.
> > >>>>>>>
> > >>>>>>> Signed-off-by: Stefano Stabellini <stefano@aporeto.com>
> > >>>>>>> CC: boris.ostrovsky@oracle.com
> > >>>>>>> CC: jgross@suse.com
> > >>>>>>> CC: Eric Van Hensbergen <ericvh@gmail.com>
> > >>>>>>> CC: Ron Minnich <rminnich@sandia.gov>
> > >>>>>>> CC: Latchesar Ionkov <lucho@ionkov.net>
> > >>>>>>> CC: v9fs-developer@lists.sourceforge.net
> > >>>>>>> ---
> > >>>>
> > >>>>>> Did you think about using request_threaded_irq() instead of a workqueue?
> > >>>>>> For an example see e.g. drivers/scsi/xen-scsifront.c
> > >>>>>
> > >>>>> I like workqueues :-)  It might come down to personal preferences, but I
> > >>>>> think workqueues are more flexible and a better fit for this use case.
> > >>>>> Not only it is easy to schedule work in a workqueue from the interrupt
> > >>>>> handler, but also they can be used for sleeping in the request function
> > >>>>> if there is not enough room on the ring. Besides, they can easily be
> > >>>>> configured to share a single thread or to have multiple independent
> > >>>>> threads.
> > >>>>
> > >>>> I'm fine with the workqueues as long as you have decided to use them
> > >>>> considering the alternatives. :-)
> > >>>>
> > >>>>>> Can't you use xenbus_read_unsigned() instead of xenbus_read()?
> > >>>>>
> > >>>>> I can use xenbus_read_unsigned in the other cases below, but not here,
> > >>>>> because versions is in the form: "1,3,4"
> > >>>>
> > >>>> Is this documented somewhere?
> > >>>>
> > >>>> Hmm, are any of the Xenstore entries documented? Shouldn't this be done
> > >>>> in xen_9pfs.h ?
> > >>>  
> > >>> They are documented in docs/misc/9pfs.markdown, under "Xenstore". Given
> > >>> that it's all written there, especially the semantics, I didn't repeat
> > >>> it in xen_9pfs.h
> > >>
> > >> Looking at it from the Linux kernel perspective this documentation is
> > >> not really highly visible. For me it is okay, but there have been
> > >> multiple examples in the past where documentation in the Xen repository
> > >> wasn't regarded as being sufficient.
> > >>
> > >> I recommend moving the documentation regarding the interface into the
> > >> header file like for the other pv interfaces.
> > > 
> > > What about adding a link such as:
> > > 
> > > http://xenbits.xen.org/gitweb/?p=xen.git;a=blob_plain;f=docs/misc/9pfs.markdown;hb=HEAD
> 
> Ewww.
> 
> 
> How about https://xenbits.xen.org/docs/unstable/misc/9pfs.html
> 
> which gets updated daily.

Great idea, I'll do that


> > > 
> > > that should be easily accessible, right? For other specifications, such
> > > as 9p, only links are provided (see Documentation/filesystems/9p.txt).
> > > I am suggesting a link, because then we are sure the specs don't go out
> > > of sync. I realize that older PV protocols were described in header
> > > files, but that was before Xen Project had a formal process for getting
> > > new specifications accepted, and a formal place where to publish them.
> > 
> > Fine with me. Lets see if other maintainers are okay with it, too.

[toc] | [prev] | [standalone]


Back to top | Article view | linux.kernel


csiph-web