WARNING - OLD ARCHIVES

This is an archived copy of the Xen.org mailing list, which we have preserved to ensure that existing links to archives are not broken. The live archive, which contains the latest emails, can be found at http://lists.xen.org/
   
 
 
Xen 
 
Home Products Support Community News
 
   
 

xen-changelog

[Xen-changelog] [linux-2.6.18-xen] xenbus: Allow lazy init in case xenst

To: xen-changelog@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-changelog] [linux-2.6.18-xen] xenbus: Allow lazy init in case xenstored runs in a separate minios domain.
From: "Xen patchbot-linux-2.6.18-xen" <patchbot-linux-2.6.18-xen@xxxxxxxxxxxxxxxxxxx>
Date: Tue, 19 May 2009 16:35:05 -0700
Delivery-date: Tue, 19 May 2009 16:35:24 -0700
Envelope-to: www-data@xxxxxxxxxxxxxxxxxxx
List-help: <mailto:xen-changelog-request@lists.xensource.com?subject=help>
List-id: BK change log <xen-changelog.lists.xensource.com>
List-post: <mailto:xen-changelog@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=unsubscribe>
Reply-to: xen-devel@xxxxxxxxxxxxxxxxxxx
Sender: xen-changelog-bounces@xxxxxxxxxxxxxxxxxxx
# HG changeset patch
# User Keir Fraser <keir.fraser@xxxxxxxxxx>
# Date 1242740750 -3600
# Node ID bd7e30b58d125a64fc8388022a24f598068b95ec
# Parent  e17af34d4d90b034f229ebe6e504270200bf50e4
xenbus: Allow lazy init in case xenstored runs in a separate minios domain.

Here's an explanation of the states:

It starts out in XENBUS_XSD_UNCOMMITTED.

As the master xenbus (the one local to xenstored), it will receive an
mmap from xenstore, putting it in XENBUS_XSD_LOCAL_INIT. This enables
the wake_waiting IRQ, which will put it in XENBUS_XSD_LOCAL_READY.

Alternatively, as a slave xenbus, it will receive an ioctl from the
xenstore domain builder, putting it in XENBUS_XSD_FOREIGN_INIT. This
enables the wake_waiting IRQ, which will put it in
XENBUS_XSD_FOREIGN_READY.

DomU's are immediately initialized to XENBUS_XSD_FOREIGN_READY.

Signed-off-by: Diego Ongaro <diego.ongaro@xxxxxxxxxx>
Signed-off-by: Alex Zeffertt <alex.zeffertt@xxxxxxxxxxxxx>
---
 drivers/xen/core/xen_sysfs.c      |    6 +-
 drivers/xen/xenbus/xenbus_comms.c |   31 +++++++++--
 drivers/xen/xenbus/xenbus_comms.h |   16 ++++++
 drivers/xen/xenbus/xenbus_dev.c   |   62 +++++++++++++++++++++++
 drivers/xen/xenbus/xenbus_probe.c |  100 +++++++++++++++++++++++++++++++++++---
 drivers/xen/xenbus/xenbus_xs.c    |    6 --
 include/xen/public/xenbus.h       |   56 +++++++++++++++++++++
 7 files changed, 256 insertions(+), 21 deletions(-)

diff -r e17af34d4d90 -r bd7e30b58d12 drivers/xen/core/xen_sysfs.c
--- a/drivers/xen/core/xen_sysfs.c      Tue May 19 14:42:04 2009 +0100
+++ b/drivers/xen/core/xen_sysfs.c      Tue May 19 14:45:50 2009 +0100
@@ -16,6 +16,7 @@
 #include <xen/hypervisor_sysfs.h>
 #include <xen/xenbus.h>
 #include <xen/interface/kexec.h>
+#include "../xenbus/xenbus_comms.h"
 
 MODULE_LICENSE("GPL");
 MODULE_AUTHOR("Mike D. Day <ncmike@xxxxxxxxxx>");
@@ -105,9 +106,8 @@ static ssize_t uuid_show(struct hyp_sysf
 {
        char *vm, *val;
        int ret;
-       extern int xenstored_ready;
-
-       if (!xenstored_ready)
+
+       if (!is_xenstored_ready())
                return -EBUSY;
 
        vm = xenbus_read(XBT_NIL, "vm", "", NULL);
diff -r e17af34d4d90 -r bd7e30b58d12 drivers/xen/xenbus/xenbus_comms.c
--- a/drivers/xen/xenbus/xenbus_comms.c Tue May 19 14:42:04 2009 +0100
+++ b/drivers/xen/xenbus/xenbus_comms.c Tue May 19 14:45:50 2009 +0100
@@ -50,18 +50,39 @@ static int xenbus_irq;
 static int xenbus_irq;
 
 extern void xenbus_probe(void *);
-extern int xenstored_ready;
 static DECLARE_WORK(probe_work, xenbus_probe, NULL);
 
 static DECLARE_WAIT_QUEUE_HEAD(xb_waitq);
 
 static irqreturn_t wake_waiting(int irq, void *unused, struct pt_regs *regs)
 {
-       if (unlikely(xenstored_ready == 0)) {
-               xenstored_ready = 1;
+       int old, new;
+
+       old = atomic_read(&xenbus_xsd_state);
+       switch (old) {
+               case XENBUS_XSD_UNCOMMITTED:
+                       BUG();
+                       return IRQ_HANDLED;
+
+               case XENBUS_XSD_FOREIGN_INIT:
+                       new = XENBUS_XSD_FOREIGN_READY;
+                       break;
+               
+               case XENBUS_XSD_LOCAL_INIT:
+                       new = XENBUS_XSD_LOCAL_READY;
+                       break;
+
+               case XENBUS_XSD_FOREIGN_READY:
+               case XENBUS_XSD_LOCAL_READY:
+               default:
+                       goto wake;
+       }
+
+       old = atomic_cmpxchg(&xenbus_xsd_state, old, new);
+       if (old != new)
                schedule_work(&probe_work);
-       }
-
+
+wake:
        wake_up(&xb_waitq);
        return IRQ_HANDLED;
 }
diff -r e17af34d4d90 -r bd7e30b58d12 drivers/xen/xenbus/xenbus_comms.h
--- a/drivers/xen/xenbus/xenbus_comms.h Tue May 19 14:42:04 2009 +0100
+++ b/drivers/xen/xenbus/xenbus_comms.h Tue May 19 14:45:50 2009 +0100
@@ -43,4 +43,20 @@ extern struct xenstore_domain_interface 
 extern struct xenstore_domain_interface *xen_store_interface;
 extern int xen_store_evtchn;
 
+/* For xenbus internal use. */
+enum {
+       XENBUS_XSD_UNCOMMITTED = 0,
+       XENBUS_XSD_FOREIGN_INIT,
+       XENBUS_XSD_FOREIGN_READY,
+       XENBUS_XSD_LOCAL_INIT,
+       XENBUS_XSD_LOCAL_READY,
+};
+extern atomic_t xenbus_xsd_state;
+
+static inline int is_xenstored_ready(void)
+{
+       int s = atomic_read(&xenbus_xsd_state);
+       return s == XENBUS_XSD_FOREIGN_READY || s == XENBUS_XSD_LOCAL_READY;
+}
+
 #endif /* _XENBUS_COMMS_H */
diff -r e17af34d4d90 -r bd7e30b58d12 drivers/xen/xenbus/xenbus_dev.c
--- a/drivers/xen/xenbus/xenbus_dev.c   Tue May 19 14:42:04 2009 +0100
+++ b/drivers/xen/xenbus/xenbus_dev.c   Tue May 19 14:45:50 2009 +0100
@@ -53,6 +53,8 @@
 #include <xen/platform-compat.h>
 #endif
 
+#include <xen/public/xenbus.h>
+
 struct xenbus_dev_transaction {
        struct list_head list;
        struct xenbus_transaction handle;
@@ -95,6 +97,9 @@ static ssize_t xenbus_dev_read(struct fi
        struct xenbus_dev_data *u = filp->private_data;
        struct read_buffer *rb;
        int i, ret;
+
+       if (!is_xenstored_ready())
+               return -ENODEV;
 
        mutex_lock(&u->reply_mutex);
        while (list_empty(&u->read_buffers)) {
@@ -205,6 +210,9 @@ static ssize_t xenbus_dev_write(struct f
        char *path, *token;
        struct watch_adapter *watch, *tmp_watch;
        int err, rc = len;
+
+       if (!is_xenstored_ready())
+               return -ENODEV;
 
        if ((len + u->len) > sizeof(u->u.buffer)) {
                rc = -EINVAL;
@@ -370,10 +378,63 @@ static unsigned int xenbus_dev_poll(stru
 {
        struct xenbus_dev_data *u = file->private_data;
 
+       if (!is_xenstored_ready())
+               return -ENODEV;
+
        poll_wait(file, &u->read_waitq, wait);
        if (!list_empty(&u->read_buffers))
                return POLLIN | POLLRDNORM;
        return 0;
+}
+
+static long xenbus_dev_ioctl(struct file *file,
+                             unsigned int cmd, unsigned long data)
+{
+       extern int xenbus_conn(domid_t remote_dom, int *grant_ref,
+                              evtchn_port_t *local_port);
+       void __user *udata = (void __user *) data;
+       int ret = -ENOTTY;
+       
+       if (!is_initial_xendomain())
+               return -ENODEV;
+
+
+       switch (cmd) {
+       case IOCTL_XENBUS_ALLOC: {
+               xenbus_alloc_t xa;
+               int old;
+
+               old = atomic_cmpxchg(&xenbus_xsd_state,
+                                    XENBUS_XSD_UNCOMMITTED,
+                                    XENBUS_XSD_FOREIGN_INIT);
+               if (old != XENBUS_XSD_UNCOMMITTED)
+                       return -EBUSY;
+
+               if (copy_from_user(&xa, udata, sizeof(xa))) {
+                       ret = -EFAULT;
+                       atomic_set(&xenbus_xsd_state, XENBUS_XSD_UNCOMMITTED);
+                       break;
+               }
+
+               ret = xenbus_conn(xa.dom, &xa.grant_ref, &xa.port);
+               if (ret != 0) {
+                       atomic_set(&xenbus_xsd_state, XENBUS_XSD_UNCOMMITTED);
+                       break;
+               }
+
+               if (copy_to_user(udata, &xa, sizeof(xa))) {
+                       ret = -EFAULT;
+                       atomic_set(&xenbus_xsd_state, XENBUS_XSD_UNCOMMITTED);
+                       break;
+               }
+       }
+       break;
+
+       default:
+               break;
+       }
+
+       return ret;
 }
 
 static const struct file_operations xenbus_dev_file_ops = {
@@ -382,6 +443,7 @@ static const struct file_operations xenb
        .open = xenbus_dev_open,
        .release = xenbus_dev_release,
        .poll = xenbus_dev_poll,
+       .unlocked_ioctl = xenbus_dev_ioctl
 };
 
 int xenbus_dev_init(void)
diff -r e17af34d4d90 -r bd7e30b58d12 drivers/xen/xenbus/xenbus_probe.c
--- a/drivers/xen/xenbus/xenbus_probe.c Tue May 19 14:42:04 2009 +0100
+++ b/drivers/xen/xenbus/xenbus_probe.c Tue May 19 14:45:50 2009 +0100
@@ -44,6 +44,7 @@
 #include <linux/notifier.h>
 #include <linux/mutex.h>
 #include <linux/module.h>
+#include <xen/gnttab.h>
 
 #include <asm/io.h>
 #include <asm/page.h>
@@ -347,7 +348,12 @@ static void xenbus_dev_shutdown(struct d
 
        DPRINTK("%s", dev->nodename);
 
+/* Commented out since xenstored stubdom is now minios based not linux based
+#define XENSTORE_DOMAIN_SHARES_THIS_KERNEL 
+*/
+#ifndef XENSTORE_DOMAIN_SHARES_THIS_KERNEL 
        if (is_initial_xendomain())
+#endif
                return;
 
        get_device(&dev->dev);
@@ -820,14 +826,13 @@ EXPORT_SYMBOL_GPL(xenbus_suspend_cancel)
 EXPORT_SYMBOL_GPL(xenbus_suspend_cancel);
 
 /* A flag to determine if xenstored is 'ready' (i.e. has started) */
-int xenstored_ready = 0;
-
+atomic_t xenbus_xsd_state = ATOMIC_INIT(XENBUS_XSD_UNCOMMITTED);
 
 int register_xenstore_notifier(struct notifier_block *nb)
 {
        int ret = 0;
 
-       if (xenstored_ready > 0)
+       if (is_xenstored_ready())
                ret = nb->notifier_call(nb, 0, NULL);
        else
                blocking_notifier_chain_register(&xenstore_chain, nb);
@@ -845,7 +850,7 @@ EXPORT_SYMBOL_GPL(unregister_xenstore_no
 
 void xenbus_probe(void *unused)
 {
-       BUG_ON((xenstored_ready <= 0));
+       BUG_ON(!is_xenstored_ready());
 
        /* Enumerate devices in xenstore and watch for changes. */
        xenbus_probe_devices(&xenbus_frontend);
@@ -865,6 +870,28 @@ static int xsd_kva_mmap(struct file *fil
 static int xsd_kva_mmap(struct file *file, struct vm_area_struct *vma)
 {
        size_t size = vma->vm_end - vma->vm_start;
+       int old;
+       int rc;
+
+       old = atomic_cmpxchg(&xenbus_xsd_state,
+                          XENBUS_XSD_UNCOMMITTED,
+                          XENBUS_XSD_LOCAL_INIT);
+       switch (old) {
+               case XENBUS_XSD_UNCOMMITTED:
+                       rc = xb_init_comms();
+                       if (rc != 0)
+                               return rc;
+                       break;
+
+               case XENBUS_XSD_FOREIGN_INIT:
+               case XENBUS_XSD_FOREIGN_READY:
+                       return -EBUSY;
+               
+               case XENBUS_XSD_LOCAL_INIT:
+               case XENBUS_XSD_LOCAL_READY:
+               default:
+                       break;
+       }
 
        if ((size > PAGE_SIZE) || (vma->vm_pgoff != 0))
                return -EINVAL;
@@ -896,6 +923,62 @@ static int xsd_port_read(char *page, cha
        return len;
 }
 #endif
+
+static int xb_free_port(evtchn_port_t port)
+{
+       struct evtchn_close close;
+       close.port = port;
+       return HYPERVISOR_event_channel_op(EVTCHNOP_close, &close);
+}
+
+int xenbus_conn(domid_t remote_dom, unsigned long *grant_ref, evtchn_port_t 
*local_port)
+{
+       struct evtchn_alloc_unbound alloc_unbound;
+       int rc, rc2;
+
+       BUG_ON(atomic_read(&xenbus_xsd_state) != XENBUS_XSD_FOREIGN_INIT);
+       BUG_ON(!is_initial_xendomain());
+
+#if defined(CONFIG_PROC_FS) && defined(CONFIG_XEN_PRIVILEGED_GUEST)
+       remove_xen_proc_entry("xsd_kva");
+       remove_xen_proc_entry("xsd_port");
+#endif
+
+       rc = xb_free_port(xen_store_evtchn);
+       if (rc != 0)
+               goto fail0;
+
+       alloc_unbound.dom = DOMID_SELF;
+       alloc_unbound.remote_dom = remote_dom;
+       rc = HYPERVISOR_event_channel_op(EVTCHNOP_alloc_unbound,
+                                        &alloc_unbound);
+       if (rc != 0)
+               goto fail0;
+       *local_port = xen_store_evtchn = alloc_unbound.port;
+
+       /* keep the old page (xen_store_mfn, xen_store_interface) */
+       rc = gnttab_grant_foreign_access(remote_dom, xen_store_mfn,
+                                        GTF_permit_access);
+       if (rc < 0)
+               goto fail1;
+       *grant_ref = rc;
+
+       rc = xb_init_comms();
+       if (rc != 0)
+               goto fail1;
+
+       return 0;
+
+fail1:
+       rc2 = xb_free_port(xen_store_evtchn);
+       if (rc2 != 0)
+               printk(KERN_WARNING
+                      "XENBUS: Error freeing xenstore event channel: %d\n",
+                      rc2);
+fail0:
+       xen_store_evtchn = -1;
+       return rc;
+}
 
 static int xenbus_probe_init(void)
 {
@@ -958,7 +1041,7 @@ static int xenbus_probe_init(void)
 #endif
                xen_store_interface = mfn_to_virt(xen_store_mfn);
        } else {
-               xenstored_ready = 1;
+               atomic_set(&xenbus_xsd_state, XENBUS_XSD_FOREIGN_READY);
 #ifdef CONFIG_XEN
                xen_store_evtchn = xen_start_info->store_evtchn;
                xen_store_mfn = xen_start_info->store_mfn;
@@ -969,8 +1052,11 @@ static int xenbus_probe_init(void)
                xen_store_interface = ioremap(xen_store_mfn << PAGE_SHIFT,
                                              PAGE_SIZE);
 #endif
-       }
-
+               /* Initialize the shared memory rings to talk to xenstored */
+               err = xb_init_comms();
+               if (err)
+                       goto err;
+       }
 
        xenbus_dev_init();
 
diff -r e17af34d4d90 -r bd7e30b58d12 drivers/xen/xenbus/xenbus_xs.c
--- a/drivers/xen/xenbus/xenbus_xs.c    Tue May 19 14:42:04 2009 +0100
+++ b/drivers/xen/xenbus/xenbus_xs.c    Tue May 19 14:45:50 2009 +0100
@@ -872,7 +872,6 @@ static int xenbus_thread(void *unused)
 
 int xs_init(void)
 {
-       int err;
        struct task_struct *task;
 
        INIT_LIST_HEAD(&xs_state.reply_list);
@@ -884,11 +883,6 @@ int xs_init(void)
        init_rwsem(&xs_state.transaction_mutex);
        init_rwsem(&xs_state.watch_mutex);
 
-       /* Initialize the shared memory rings to talk to xenstored */
-       err = xb_init_comms();
-       if (err)
-               return err;
-
        task = kthread_run(xenwatch_thread, NULL, "xenwatch");
        if (IS_ERR(task))
                return PTR_ERR(task);
diff -r e17af34d4d90 -r bd7e30b58d12 include/xen/public/xenbus.h
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/include/xen/public/xenbus.h       Tue May 19 14:45:50 2009 +0100
@@ -0,0 +1,56 @@
+/******************************************************************************
+ * xenbus.h
+ * 
+ * Interface to /proc/xen/xenbus.
+ * 
+ * Copyright (c) 2008, Diego Ongaro <diego.ongaro@xxxxxxxxxx>
+ * 
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation; or, when distributed
+ * separately from the Linux kernel or incorporated into other
+ * software packages, subject to the following license:
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this source file (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy, modify,
+ * merge, publish, distribute, sublicense, and/or sell copies of the Software,
+ * and to permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+
+#ifndef __LINUX_PUBLIC_XENBUS_H__
+#define __LINUX_PUBLIC_XENBUS_H__
+
+#include <linux/types.h>
+
+#ifndef __user
+#define __user
+#endif
+
+typedef struct xenbus_alloc {
+       domid_t dom;
+       __u32 port;
+       __u32 grant_ref;
+} xenbus_alloc_t;
+
+/*
+ * @cmd: IOCTL_XENBUS_ALLOC
+ * @arg: &xenbus_alloc_t
+ * Return: 0, or -1 for error
+ */
+#define IOCTL_XENBUS_ALLOC                                     \
+       _IOC(_IOC_NONE, 'X', 0, sizeof(xenbus_alloc_t))
+
+#endif /* __LINUX_PUBLIC_XENBUS_H__ */

_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog

<Prev in Thread] Current Thread [Next in Thread>
  • [Xen-changelog] [linux-2.6.18-xen] xenbus: Allow lazy init in case xenstored runs in a separate minios domain., Xen patchbot-linux-2.6.18-xen <=