All of lore.kernel.org
 help / color / mirror / Atom feed
From: Gerd Hoffmann <kraxel@suse.de>
To: Xen devel list <xen-devel@lists.xensource.com>
Subject: [patch 5/6] frontend device shutdown
Date: Thu, 17 Aug 2006 16:03:48 +0200	[thread overview]
Message-ID: <44E47744.9070302@suse.de> (raw)

[-- Attachment #1: Type: text/plain, Size: 864 bytes --]

  Hi,

This patch makes xenbus and net/blkfront drivers correctly handle
device_shutdown().  Changes:

  * new xenbus_strstate() helper function for fancy debug output.
  * add xenbus_dev_shutdown() function which switches the devices
    into Closing state and waits for them to finish shutdown.
  * new helper function xenbus_closing_done(), which handles the
    final state transition and informs xenbus_dev_shutdown().

xenbus_closing_done() behaves differently depending on how the closing
was triggered.  If it was triggered by the backend the frontend acks the
removal by going to CLosed.  If it was triggered via device_shutdown()
the state is set back to "Initializing", to allow a possible new kernel
instance to reuse the devices (for domU kexec again ;)

cheers,

  Gerd

-- 
Gerd Hoffmann <kraxel@suse.de>
http://www.suse.de/~kraxel/julika-dora.jpeg

[-- Attachment #2: frontend-shutdown --]
[-- Type: text/plain, Size: 7583 bytes --]

Signed-off-by: Gerd Hoffmann <kraxel@suse.de>
Index: source-lnx-stable-22813/drivers/xen/blkfront/blkfront.c
===================================================================
--- source-lnx-stable-22813.orig/drivers/xen/blkfront/blkfront.c	2006-08-17 15:19:20.000000000 +0200
+++ source-lnx-stable-22813/drivers/xen/blkfront/blkfront.c	2006-08-17 15:20:17.000000000 +0200
@@ -272,10 +272,13 @@ static void backend_changed(struct xenbu
 			xenbus_dev_fatal(dev, -ENODEV, "bdget failed");
 
 		down(&bd->bd_sem);
-		if (info->users > 0)
+		if (info->users)
+			printk("%-20s: %s: %d user(s) left\n", __FUNCTION__,
+			       dev->nodename, info->users);
+		if (info->users > 0 && !dev->shutdown_in_progress) {
 			xenbus_dev_error(dev, -EBUSY,
 					 "Device in use; refusing to close");
-		else
+		} else
 			blkfront_closing(dev);
 		up(&bd->bd_sem);
 		bdput(bd);
@@ -359,7 +362,7 @@ static void blkfront_closing(struct xenb
 
 	xlvbd_del(info);
 
-	xenbus_switch_state(dev, XenbusStateClosed);
+	xenbus_closing_done(dev);
 }
 
 
Index: source-lnx-stable-22813/drivers/xen/netfront/netfront.c
===================================================================
--- source-lnx-stable-22813.orig/drivers/xen/netfront/netfront.c	2006-08-17 15:19:20.000000000 +0200
+++ source-lnx-stable-22813/drivers/xen/netfront/netfront.c	2006-08-17 15:20:33.000000000 +0200
@@ -436,7 +436,7 @@ static void backend_changed(struct xenbu
 	struct netfront_info *np = dev->dev.driver_data;
 	struct net_device *netdev = np->netdev;
 
-	DPRINTK("\n");
+	DPRINTK("%s\n", xenbus_strstate(backend_state));
 
 	switch (backend_state) {
 	case XenbusStateInitialising:
@@ -447,9 +447,11 @@ static void backend_changed(struct xenbu
 		break;
 
 	case XenbusStateInitWait:
-		network_connect(netdev);
-		xenbus_switch_state(dev, XenbusStateConnected);
-		(void)send_fake_arp(netdev);
+		if (!dev->shutdown_in_progress) {
+			network_connect(netdev);
+			xenbus_switch_state(dev, XenbusStateConnected);
+			(void)send_fake_arp(netdev);
+		}
 		break;
 
 	case XenbusStateClosing:
@@ -1720,11 +1722,10 @@ static void netfront_closing(struct xenb
 {
 	struct netfront_info *info = dev->dev.driver_data;
 
-	DPRINTK("netfront_closing: %s removed\n", dev->nodename);
+	DPRINTK("%s\n", dev->nodename);
 
 	close_netdev(info);
-
-	xenbus_switch_state(dev, XenbusStateClosed);
+	xenbus_closing_done(dev);
 }
 
 
Index: source-lnx-stable-22813/drivers/xen/xenbus/xenbus_client.c
===================================================================
--- source-lnx-stable-22813.orig/drivers/xen/xenbus/xenbus_client.c	2006-08-17 15:19:20.000000000 +0200
+++ source-lnx-stable-22813/drivers/xen/xenbus/xenbus_client.c	2006-08-17 15:20:17.000000000 +0200
@@ -41,6 +41,21 @@ extern char *kasprintf(const char *fmt, 
 #define DPRINTK(fmt, args...) \
     pr_debug("xenbus_client (%s:%d) " fmt ".\n", __FUNCTION__, __LINE__, ##args)
 
+char *xenbus_strstate(enum xenbus_state state)
+{
+	static char *name[] = {
+		[ XenbusStateUnknown      ] = "Unknown",
+		[ XenbusStateInitialising ] = "Initialising",
+		[ XenbusStateInitWait     ] = "InitWait",
+		[ XenbusStateInitialised  ] = "Initialised",
+		[ XenbusStateConnected    ] = "Connected",
+		[ XenbusStateClosing      ] = "Closing",
+		[ XenbusStateClosed	  ] = "Closed",
+	};
+	return state < sizeof(name)/sizeof(name[0])
+		? name[state] : "INVALID";
+}
+
 int xenbus_watch_path(struct xenbus_device *dev, const char *path,
 		      struct xenbus_watch *watch,
 		      void (*callback)(struct xenbus_watch *,
@@ -124,6 +139,23 @@ int xenbus_switch_state(struct xenbus_de
 }
 EXPORT_SYMBOL_GPL(xenbus_switch_state);
 
+int xenbus_closing_done(struct xenbus_device *dev)
+{
+	if (dev->shutdown_in_progress) {
+		/* frontend (we) triggered closing, because of devices_shutdown(),
+		 * prepare for possible re-connect */
+		printk("%-20s: %s: => Initialising\n", __FUNCTION__, dev->nodename);
+		xenbus_switch_state(dev, XenbusStateInitialising);
+	} else {
+		/* backend triggered closing, probably the device went away,
+		 * thus we are going to close down too. */
+		printk("%-20s: %s: => Closed\n", __FUNCTION__, dev->nodename);
+		xenbus_switch_state(dev, XenbusStateClosed);
+	}
+	complete(&dev->down);
+	return 0;
+}
+EXPORT_SYMBOL_GPL(xenbus_closing_done);
 
 /**
  * Return the path to the error node for the given device, or NULL on failure.
Index: source-lnx-stable-22813/drivers/xen/xenbus/xenbus_probe.c
===================================================================
--- source-lnx-stable-22813.orig/drivers/xen/xenbus/xenbus_probe.c	2006-08-17 15:20:17.000000000 +0200
+++ source-lnx-stable-22813/drivers/xen/xenbus/xenbus_probe.c	2006-08-17 15:20:17.000000000 +0200
@@ -67,6 +67,7 @@ static int xenbus_probe_backend(const ch
 
 static int xenbus_dev_probe(struct device *_dev);
 static int xenbus_dev_remove(struct device *_dev);
+static void xenbus_dev_shutdown(struct device *_dev);
 
 /* If something in array of ids matches this device, return it. */
 static const struct xenbus_device_id *
@@ -186,6 +187,7 @@ static struct xen_bus_type xenbus_fronte
 		.match    = xenbus_match,
 		.probe    = xenbus_dev_probe,
 		.remove   = xenbus_dev_remove,
+		.shutdown = xenbus_dev_shutdown,
 	},
 	.dev = {
 		.bus_id = "xen",
@@ -240,6 +242,7 @@ static struct xen_bus_type xenbus_backen
 		.match    = xenbus_match,
 		.probe    = xenbus_dev_probe,
 		.remove   = xenbus_dev_remove,
+//		.shutdown = xenbus_dev_shutdown,
 		.uevent   = xenbus_uevent_backend,
 	},
 	.dev = {
@@ -399,6 +402,26 @@ static int xenbus_dev_remove(struct devi
 	return 0;
 }
 
+static void xenbus_dev_shutdown(struct device *_dev)
+{
+	struct xenbus_device *dev = to_xenbus_device(_dev);
+	unsigned long timeout = 5*HZ;
+
+	get_device(&dev->dev);
+	if (dev->state != XenbusStateConnected) {
+		printk("%s: %s: %s != Connected, skipping\n", __FUNCTION__,
+		       dev->nodename, xenbus_strstate(dev->state));
+		goto out;
+	}
+	dev->shutdown_in_progress = 1;
+	xenbus_switch_state(dev, XenbusStateClosing);
+	timeout = wait_for_completion_timeout(&dev->down, timeout);
+	if (!timeout)
+		printk("%s: %s timeout closing device\n", __FUNCTION__, dev->nodename);
+ out:
+	put_device(&dev->dev);
+}
+
 static int xenbus_register_driver_common(struct xenbus_driver *drv,
 					 struct xen_bus_type *bus)
 {
@@ -581,6 +604,7 @@ static int xenbus_probe_node(struct xen_
 	tmpstring += strlen(tmpstring) + 1;
 	strcpy(tmpstring, type);
 	xendev->devicetype = tmpstring;
+	init_completion(&xendev->down);
 
 	xendev->dev.parent = &bus->dev;
 	xendev->dev.bus = &bus->bus;
Index: source-lnx-stable-22813/include/xen/xenbus.h
===================================================================
--- source-lnx-stable-22813.orig/include/xen/xenbus.h	2006-08-17 15:19:20.000000000 +0200
+++ source-lnx-stable-22813/include/xen/xenbus.h	2006-08-17 15:20:17.000000000 +0200
@@ -37,6 +37,7 @@
 #include <linux/device.h>
 #include <linux/notifier.h>
 #include <linux/mutex.h>
+#include <linux/completion.h>
 #include <xen/interface/xen.h>
 #include <xen/interface/grant_table.h>
 #include <xen/interface/io/xenbus.h>
@@ -74,6 +75,9 @@ struct xenbus_device {
 	struct xenbus_watch otherend_watch;
 	struct device dev;
 	enum xenbus_state state;
+
+	struct completion down;
+	int shutdown_in_progress;
 };
 
 static inline struct xenbus_device *to_xenbus_device(struct device *dev)
@@ -296,4 +300,7 @@ void xenbus_dev_fatal(struct xenbus_devi
 		      ...);
 
 
+int xenbus_closing_done(struct xenbus_device *dev);
+char *xenbus_strstate(enum xenbus_state state);
+
 #endif /* _XEN_XENBUS_H */

[-- Attachment #3: Type: text/plain, Size: 138 bytes --]

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

             reply	other threads:[~2006-08-17 14:03 UTC|newest]

Thread overview: 12+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2006-08-17 14:03 Gerd Hoffmann [this message]
2006-08-19 12:25 ` [patch 5/6] frontend device shutdown Keir Fraser
2006-08-19 12:29   ` Keir Fraser
2006-08-21 14:11   ` Gerd Hoffmann
2006-08-21 16:11     ` Keir Fraser
2006-08-22  8:04       ` Gerd Hoffmann
2006-08-22  8:30         ` Keir Fraser
2006-08-22  8:40           ` Keir Fraser
2006-08-22  9:12           ` Gerd Hoffmann
2006-08-22 10:22             ` Gerd Hoffmann
2006-08-19 12:52 ` Keir Fraser
2006-08-21  6:48   ` Gerd Hoffmann

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=44E47744.9070302@suse.de \
    --to=kraxel@suse.de \
    --cc=xen-devel@lists.xensource.com \
    /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.