All of lore.kernel.org
 help / color / mirror / Atom feed
From: BVK Chaitanya <bayapuneni_chaitanya@symantec.com>
To: Xen-devel@lists.xensource.com
Subject: [PATCH] serialize suspend-resume process
Date: Thu, 31 Jul 2008 16:39:09 +0530	[thread overview]
Message-ID: <48919D55.5000005@symantec.com> (raw)

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

Hi,


With current suspend-resume code, there is no way for DOM-0 to identify 
that DOM-U resume is completed.  It can potentially trigger suspend 
again before resume is completed.

Below patch makes suspend-resume process serialized.


regards,
--
bvk-chaitanya

[-- Attachment #2: serialize-suspend.patch --]
[-- Type: text/x-patch, Size: 6055 bytes --]

suspend-resume process is serialized.

Under heavy load a suspend interrupt can create a new kthread and
start suspend process before old kthread's resuming completes.  This
patch serialzes suspend-resume using a counting semaphore and a
separate kthread.  Suspend interrupts up the semaphore and suspend
kthread downs the semaphore in a while(1) loop.

diff -r c2850a7f279d drivers/xen/core/reboot.c
--- a/drivers/xen/core/reboot.c	Wed Jul 30 20:15:23 2008 +0530
+++ b/drivers/xen/core/reboot.c	Thu Jul 31 21:35:46 2008 +0530
@@ -11,6 +11,7 @@
 #include <linux/kmod.h>
 #include <linux/slab.h>
 #include <linux/workqueue.h>
+#include <linux/kthread.h>
 
 #ifdef HAVE_XEN_PLATFORM_COMPAT_H
 #include <xen/platform-compat.h>
@@ -20,8 +21,6 @@ MODULE_LICENSE("Dual BSD/GPL");
 
 #define SHUTDOWN_INVALID  -1
 #define SHUTDOWN_POWEROFF  0
-#define SHUTDOWN_SUSPEND   2
-#define SHUTDOWN_RESUMING  3
 #define SHUTDOWN_HALT      4
 
 /* Ignore multiple shutdown requests. */
@@ -32,6 +31,11 @@ static int fast_suspend;
 
 static void __shutdown_handler(void *unused);
 static DECLARE_WORK(shutdown_work, __shutdown_handler, NULL);
+
+static struct suspend_info {
+        struct semaphore nrequest; /* no. of suspend reqs */
+        atomic_t         resuming; /* is domain resuming ? */
+} suspend_info;
 
 int __xen_suspend(int fast_suspend, void (*resume_notifier)(void));
 
@@ -62,58 +66,11 @@ static int shutdown_process(void *__unus
 	return 0;
 }
 
-static void xen_resume_notifier(void)
-{
-	int old_state = xchg(&shutting_down, SHUTDOWN_RESUMING);
-	BUG_ON(old_state != SHUTDOWN_SUSPEND);
-}
-
-static int xen_suspend(void *__unused)
-{
-	int err, old_state;
-
-	daemonize("suspend");
-	err = set_cpus_allowed(current, cpumask_of_cpu(0));
-	if (err) {
-		printk(KERN_ERR "Xen suspend can't run on CPU0 (%d)\n", err);
-		goto fail;
-	}
-
-	do {
-		err = __xen_suspend(fast_suspend, xen_resume_notifier);
-		if (err) {
-			printk(KERN_ERR "Xen suspend failed (%d)\n", err);
-			goto fail;
-		}
-		old_state = cmpxchg(
-			&shutting_down, SHUTDOWN_RESUMING, SHUTDOWN_INVALID);
-	} while (old_state == SHUTDOWN_SUSPEND);
-
-	switch (old_state) {
-	case SHUTDOWN_INVALID:
-	case SHUTDOWN_SUSPEND:
-		BUG();
-	case SHUTDOWN_RESUMING:
-		break;
-	default:
-		schedule_work(&shutdown_work);
-		break;
-	}
-
-	return 0;
-
- fail:
-	old_state = xchg(&shutting_down, SHUTDOWN_INVALID);
-	BUG_ON(old_state != SHUTDOWN_SUSPEND);
-	return 0;
-}
-
 static void __shutdown_handler(void *unused)
 {
 	int err;
 
-	err = kernel_thread((shutting_down == SHUTDOWN_SUSPEND) ?
-			    xen_suspend : shutdown_process,
+	err = kernel_thread(shutdown_process,
 			    NULL, CLONE_FS | CLONE_FILES);
 
 	if (err < 0) {
@@ -131,8 +88,8 @@ static void shutdown_handler(struct xenb
 	struct xenbus_transaction xbt;
 	int err, old_state, new_state = SHUTDOWN_INVALID;
 
-	if ((shutting_down != SHUTDOWN_INVALID) &&
-	    (shutting_down != SHUTDOWN_RESUMING))
+	if ((shutting_down != SHUTDOWN_INVALID) ||
+            atomic_read(&suspend_info.resuming))
 		return;
 
  again:
@@ -155,12 +112,12 @@ static void shutdown_handler(struct xenb
 		goto again;
 	}
 
-	if (strcmp(str, "poweroff") == 0)
-		new_state = SHUTDOWN_POWEROFF;
+        if (strcmp(str, "suspend") == 0)
+                up(&suspend_info.nrequest); /* backward compatibility */
 	else if (strcmp(str, "reboot") == 0)
 		ctrl_alt_del();
-	else if (strcmp(str, "suspend") == 0)
-		new_state = SHUTDOWN_SUSPEND;
+	else if (strcmp(str, "poweroff") == 0)
+		new_state = SHUTDOWN_POWEROFF;
 	else if (strcmp(str, "halt") == 0)
 		new_state = SHUTDOWN_HALT;
 	else
@@ -168,10 +125,8 @@ static void shutdown_handler(struct xenb
 
 	if (new_state != SHUTDOWN_INVALID) {
 		old_state = xchg(&shutting_down, new_state);
-		if (old_state == SHUTDOWN_INVALID)
-			schedule_work(&shutdown_work);
-		else
-			BUG_ON(old_state != SHUTDOWN_RESUMING);
+                BUG_ON(old_state != SHUTDOWN_INVALID);
+                schedule_work(&shutdown_work);
 	}
 
 	kfree(str);
@@ -218,10 +173,41 @@ static struct xenbus_watch sysrq_watch =
 	.callback = sysrq_handler
 };
 
+static void suspend_resume_notifier(void)
+{
+        atomic_set(&suspend_info.resuming, 1);
+        return;
+}
+
+static int suspend_machine(void *unused)
+{
+        int err = 0;
+        struct sched_param param = { .sched_priority = MAX_RT_PRIO-1 };
+
+        err = set_cpus_allowed(current, cpumask_of_cpu(0));
+        if (err) {
+                printk(KERN_ERR "Suspend thread couldn't switch to CPU0 (%d)\n", err);
+                return err;
+        }
+
+        sched_setscheduler(current, SCHED_FIFO, &param);
+
+        while (1) {
+                /* decrement no. of suspend requests */
+                down(&suspend_info.nrequest);
+
+                err = __xen_suspend(fast_suspend, &suspend_resume_notifier);
+                if (err)
+                        printk(KERN_ERR "Domain suspend failed (%d)\n", err);
+
+                atomic_set(&suspend_info.resuming, 0);
+        }
+}
+
 static irqreturn_t suspend_int(int irq, void* dev_id, struct pt_regs *ptregs)
 {
-	shutting_down = SHUTDOWN_SUSPEND;
-	schedule_work(&shutdown_work);
+        /* increment no. of suspend requests */
+        up(&suspend_info.nrequest);
 
 	return IRQ_HANDLED;
 }
@@ -251,6 +237,7 @@ static int setup_shutdown_watcher(void)
 static int setup_shutdown_watcher(void)
 {
 	int err;
+        struct task_struct *t = NULL;
 
 	xenbus_scanf(XBT_NIL, "control",
 		     "platform-feature-multiprocessor-suspend",
@@ -267,6 +254,15 @@ static int setup_shutdown_watcher(void)
 		printk(KERN_ERR "Failed to set sysrq watcher\n");
 		return err;
 	}
+
+        sema_init(&suspend_info.nrequest, 0);
+        atomic_set(&suspend_info.resuming, 0);
+        t = kthread_create(suspend_machine, &suspend_info, "ksuspend");
+        if (IS_ERR(t)) {
+                printk(KERN_ERR "Suspend thread creation failed\n");
+                return PTR_ERR(t);
+        }
+        wake_up_process(t);
 
 	/* suspend event channel */
 	err = setup_suspend_evtchn();

[-- 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:[~2008-07-31 11:09 UTC|newest]

Thread overview: 16+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2008-07-31 11:09 BVK Chaitanya [this message]
2008-07-31 11:17 ` [PATCH] serialize suspend-resume process Keir Fraser
2008-07-31 11:57   ` BVK Chaitanya
2008-07-31 12:23     ` Keir Fraser
2008-07-31 13:04       ` BVK Chaitanya
2008-07-31 13:07         ` Keir Fraser
2008-07-31 13:34           ` BVK Chaitanya
2008-07-31 13:46             ` Keir Fraser
2008-07-31 14:10               ` BVK Chaitanya
2008-07-31 14:12                 ` Neil Turton
2008-07-31 14:36                 ` Keir Fraser
2008-07-31 15:27                   ` BVK Chaitanya
2008-07-31 15:24                     ` Keir Fraser
2008-08-01  5:31                       ` BVK Chaitanya
2008-08-01  5:58                         ` BVK Chaitanya
2008-08-01  8:01                           ` Keir Fraser

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=48919D55.5000005@symantec.com \
    --to=bayapuneni_chaitanya@symantec.com \
    --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.