From: Boris Ostrovsky <boris.ostrovsky@oracle.com>
To: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
Cc: Ian.Campbell@citrix.com, xen-devel@lists.xenproject.org,
linux-kernel@vger.kernel.org, JBeulich@suse.com,
david.vrabel@citrix.com
Subject: Re: [PATCH 3/4] xen/manage: Guard against user-space initiated poweroff and XenBus.
Date: Wed, 20 Nov 2013 16:40:31 -0500 [thread overview]
Message-ID: <528D2C4F.7070104@oracle.com> (raw)
In-Reply-To: <1383932286-25080-4-git-send-email-konrad.wilk@oracle.com>
On 11/08/2013 12:38 PM, Konrad Rzeszutek Wilk wrote:
> There is a race case where the user does 'poweroff'
> and at the same time the system admin does 'xl shutdown'.
>
> Depending on the race, the system_state will be SYSTEM_RUNNING or
> SYSTEM_POWER_OFF. If SYSTEM_RUNNING we just end up making
> a duplicate call to 'poweroff' (while it is running).
>
> That will fail or execute (And if executed then it will be
> stuck in the reboot_mutex mutex). But nobody will care b/c the
> machine is in poweroff sequence.
>
> If the system_state is SYSTEM_POWER_OFF then we end up making
> a duplicate call to kernel_power_off. There is no locking
> there so we walk in the same steps as what 'poweroff'
> has been doing.
>
> The code in kernel/reboot.c has a mutex guarding against multiple
> 'poweroff' operations. But not against the kernel 'orderly_poweroff'.
>
> As such, lets detect this so that we don't invoke orderly_poweroff
> if the user had initiated a poweroff.
>
> This is code by changing the 'shutting_down' to an atomic and
> having a reboot notifier. If the 'shutting_down' is set to anything
> but SHUTDOWN_INVALID the XenBus handler will not run.
>
> That is exactly what we do in the reboot notifier - we set the
> 'shutting_down' to SHUTDOWN_POWEROFF.
>
> The reason we change the 'shutting_down' to an atomic is that
> the changes to said variable were normally guarded by the XenBus
> mutex - "xenwatch_mutex" - guarantting only one caller changing
> shutting_down. Since we have now the reboot notifier we have
> another user of this variable. Surfacing the 'xenwatch_mutex'
> out of XenBus is not a nice way of doing it. Having the
> variable however be atomic solves the problem easily.
>
> Signed-off-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
> [v2: Don't expose xenwatch_mutex, add comments]
Reviewed-by: Boris Ostrovsky <boris.ostrovsky@oracle.com>
> ---
> drivers/xen/manage.c | 51 ++++++++++++++++++++++++++++++++++++++++++---------
> 1 file changed, 42 insertions(+), 9 deletions(-)
>
> diff --git a/drivers/xen/manage.c b/drivers/xen/manage.c
> index 3f8496c..323703a 100644
> --- a/drivers/xen/manage.c
> +++ b/drivers/xen/manage.c
> @@ -36,8 +36,16 @@ enum shutdown_state {
> SHUTDOWN_HALT = 4,
> };
>
> -/* Ignore multiple shutdown requests. */
> -static enum shutdown_state shutting_down = SHUTDOWN_INVALID;
> +/* Ignore multiple shutdown requests. There are two potential race conditions:
> + * - Multiple XenStore 'shutdown' requests. We don't want to run any off
> + * the callbacks in parallel.
> + * - In progress 'poweroff' (initiated inside the guest) and a XenStore
> + * 'shutdown' request. If the poweroff has transitioned 'system_state' to
> + * SYSTEM_POWER_OFF we do not want to call orderly_poweroff. 'system_state'
> + * is not SMP safe so we depend on reboot notifiers to set 'shutting_down'
> + * so that we will ignore XenBus shutdown requests.
> + */
> +static atomic_t shutting_down = ATOMIC_INIT(SHUTDOWN_INVALID);
>
> struct suspend_info {
> int cancelled;
> @@ -109,7 +117,7 @@ static void do_suspend(void)
> int err;
> struct suspend_info si;
>
> - shutting_down = SHUTDOWN_SUSPEND;
> + atomic_set(&shutting_down, SHUTDOWN_SUSPEND);
>
> #ifdef CONFIG_PREEMPT
> /* If the kernel is preemptible, we need to freeze all the processes
> @@ -173,7 +181,7 @@ out_thaw:
> thaw_processes();
> out:
> #endif
> - shutting_down = SHUTDOWN_INVALID;
> + atomic_set(&shutting_down, SHUTDOWN_INVALID);
> }
> #endif /* CONFIG_HIBERNATE_CALLBACKS */
>
> @@ -184,7 +192,7 @@ struct shutdown_handler {
>
> static void do_poweroff(void)
> {
> - shutting_down = SHUTDOWN_POWEROFF;
> + atomic_set(&shutting_down, SHUTDOWN_POWEROFF);
> switch (system_state) {
> case SYSTEM_BOOTING:
> orderly_poweroff(true);
> @@ -201,7 +209,7 @@ static void do_poweroff(void)
>
> static void do_reboot(void)
> {
> - shutting_down = SHUTDOWN_POWEROFF; /* ? */
> + atomic_set(&shutting_down, SHUTDOWN_POWEROFF); /* ? */
> ctrl_alt_del();
> }
>
> @@ -222,7 +230,7 @@ static void shutdown_handler(struct xenbus_watch *watch,
> };
> static struct shutdown_handler *handler;
>
> - if (shutting_down != SHUTDOWN_INVALID)
> + if (atomic_read(&shutting_down) != SHUTDOWN_INVALID)
> return;
>
> again:
> @@ -256,12 +264,29 @@ static void shutdown_handler(struct xenbus_watch *watch,
> handler->cb();
> } else {
> pr_info("Ignoring shutdown request: %s\n", str);
> - shutting_down = SHUTDOWN_INVALID;
> + atomic_set(&shutting_down, SHUTDOWN_INVALID);
> }
>
> kfree(str);
> }
> +/*
> + * This function is called when the system is being rebooted.
> + */
> +static int
> +xen_system_reboot(struct notifier_block *nb, unsigned long event, void *unused)
> +{
> + switch (event) {
> + case SYS_RESTART:
> + case SYS_HALT:
> + case SYS_POWER_OFF:
> + atomic_set(&shutting_down, SHUTDOWN_POWEROFF);
> + break;
> + default:
> + break;
> + }
>
> + return NOTIFY_DONE;
> +}
> #ifdef CONFIG_MAGIC_SYSRQ
> static void sysrq_handler(struct xenbus_watch *watch, const char **vec,
> unsigned int len)
> @@ -302,6 +327,10 @@ static struct xenbus_watch shutdown_watch = {
> .callback = shutdown_handler
> };
>
> +static struct notifier_block xen_shutdown_notifier = {
> + .notifier_call = xen_system_reboot,
> +};
> +
> static int setup_shutdown_watcher(void)
> {
> int err;
> @@ -319,7 +348,11 @@ static int setup_shutdown_watcher(void)
> return err;
> }
> #endif
> -
> + err = register_reboot_notifier(&xen_shutdown_notifier);
> + if (err) {
> + pr_warn("Failed to register shutdown notifier\n");
> + return err;
> + }
> return 0;
> }
>
next prev parent reply other threads:[~2013-11-20 21:38 UTC|newest]
Thread overview: 27+ messages / expand[flat|nested] mbox.gz Atom feed top
2013-11-08 17:38 [PATCH] Fixes to Linux v3.13 - bugs.xenproject.org ones. (v1) Konrad Rzeszutek Wilk
2013-11-08 17:38 ` [PATCH 1/4] xen/mcfg: Call PHYSDEVOP_pci_mmcfg_reserved for MCFG areas Konrad Rzeszutek Wilk
2013-11-21 10:37 ` David Vrabel
2013-11-08 17:38 ` [PATCH 2/4] xen/manage: Poweroff forcefully if user-space is not yet up Konrad Rzeszutek Wilk
2013-11-20 21:11 ` Boris Ostrovsky
2013-11-21 11:33 ` David Vrabel
2013-11-26 16:47 ` Konrad Rzeszutek Wilk
2014-04-01 15:43 ` Konrad Rzeszutek Wilk
2013-11-08 17:38 ` [PATCH 3/4] xen/manage: Guard against user-space initiated poweroff and XenBus Konrad Rzeszutek Wilk
2013-11-20 21:40 ` Boris Ostrovsky [this message]
2013-11-21 11:09 ` David Vrabel
2013-11-26 16:45 ` Konrad Rzeszutek Wilk
2013-12-02 11:27 ` David Vrabel
2014-03-31 19:09 ` Konrad Rzeszutek Wilk
2014-04-01 13:18 ` David Vrabel
2014-04-01 14:03 ` Konrad Rzeszutek Wilk
2013-11-08 17:38 ` [PATCH 4/4] xen/xenbus: Avoid synchronous wait on XenBus stalling shutdown/restart Konrad Rzeszutek Wilk
2013-11-21 17:52 ` [Xen-devel] " David Vrabel
2013-11-22 9:30 ` Ian Campbell
2013-11-26 16:50 ` Konrad Rzeszutek Wilk
2013-12-02 11:41 ` David Vrabel
2014-03-31 20:33 ` Konrad Rzeszutek Wilk
2014-04-01 12:53 ` David Vrabel
2014-01-26 1:13 ` Zhang, Yang Z
2014-01-26 3:44 ` Konrad Rzeszutek Wilk
2014-04-03 11:59 ` [PATCH] Fixes to Linux v3.13 - bugs.xenproject.org ones. (v1) David Vrabel
2014-04-03 18:07 ` Konrad Rzeszutek Wilk
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=528D2C4F.7070104@oracle.com \
--to=boris.ostrovsky@oracle.com \
--cc=Ian.Campbell@citrix.com \
--cc=JBeulich@suse.com \
--cc=david.vrabel@citrix.com \
--cc=konrad.wilk@oracle.com \
--cc=linux-kernel@vger.kernel.org \
--cc=xen-devel@lists.xenproject.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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
Powered by JetHome