From: lorenzo.pieralisi@arm.com (Lorenzo Pieralisi)
To: linux-arm-kernel@lists.infradead.org
Subject: [PATCH v3 6/7] arm64: hibernate: Resume on the CPU that created the hibernate image
Date: Fri, 8 Jul 2016 11:57:43 +0100 [thread overview]
Message-ID: <20160708105743.GB3784@red-moon> (raw)
In-Reply-To: <577E8A42.1020609@arm.com>
On Thu, Jul 07, 2016 at 05:58:42PM +0100, James Morse wrote:
> Hi Lorenzo,
>
> On 05/07/16 15:55, Lorenzo Pieralisi wrote:
> > On Tue, Jun 28, 2016 at 03:51:49PM +0100, James Morse wrote:
> >> On arm64 the cpu with logical id 0 is assumed to be the boot CPU. If a
> >> user hotplugs this CPU out, then uses kexec to boot a new kernel, the new
> >> kernel will assign logical id 0 to a different physical CPU.
> >> This breaks hibernate as hibernate and resume will be attempted on different
> >> CPUs. A previous patch detects this situation when we come to resume,
> >> and returns an error. (data stored in the hibernate image is lost)
> >>
> >> We currently forbid hibernate if CPU0 has been hotplugged out to avoid
> >> this situation without kexec.
> >>
> >> Use arch_hibernation_disable_cpus() to direct which CPU we should resume
> >> on based on the MPIDR of the CPU we hibernated on. This allows us to
> >> hibernate/resume on any CPU, even if the logical numbers have been
> >> shuffled by kexec.
>
> >> diff --git a/arch/arm64/kernel/hibernate.c b/arch/arm64/kernel/hibernate.c
> >> index 8c7c6d7d4cd4..cbcc8243575e 100644
> >> --- a/arch/arm64/kernel/hibernate.c
> >> +++ b/arch/arm64/kernel/hibernate.c
>
> >> +int _arch_hibernation_disable_cpus(bool suspend)
> >> +{
> >> + int cpu, ret;
> >> +
> >> + if (suspend) {
> >> + /*
> >> + * During hibernate we need frozen_cpus to be updated and saved.
> >> + */
> >> + ret = disable_nonboot_cpus();
> >> + } else {
> >> + /*
> >> + * Resuming from hibernate. From here, we can't race with
> >> + * userspace, and don't need to update frozen_cpus.
> >
> > Yes, but...
> >
> >> + */
> >> + pr_info("Disabling secondary CPUs ...\n");
> >> +
> >> + /* sleep_cpu must have been loaded from the arch header */
> >> + BUG_ON(sleep_cpu < 0);
> >> +
> >> + for_each_online_cpu(cpu) {
> >> + if (cpu == sleep_cpu)
> >> + continue;
> >> + ret = cpu_down(cpu);
> >
> > This has a side effect, in that tasks are frozen here but we are now
> > calling _cpu_down() through:
> >
> > cpu_down() -> do_cpu_down()
> >
> > and we are telling the kernel that tasks are _not_ frozen, which
> > AFAIK changes the cpuhp_tasks_frozen variable and related actions
> > (eg __cpu_notify()), I suspect this may confuse some notifiers
> > state machines that depend on CPU_TASKS_FROZEN to be set, maybe
> > not but it is worth a look.
>
> Thanks for this - I missed that implication.
>
> I've been through all the cpu notifiers in the core code, almost all of them
> either mask out the frozen bits, or do something symmetric.
>
> The exceptions are:
> __zcomp_cpu_notifier() and __zswap_cpu_dstmem_notifier(), which will free memory
> in this scenario.
> evtchn_fifo_cpu_notification() which could end up in generic_handle_irq().
> nmi_timer_cpu_notifier() (part of oprofile), will disable a perf timer.
> bcm2836_arm_irqchip_cpu_notify() will mask IPIs, but will still unmask them on
> CPU_STARTING_FROZEN.
>
> coretemp_cpu_callback(), via_cputemp_cpu_callback() and
> powerclamp_cpu_callback() would remove platform devices, or stop threads, but
> these three are x86 specific.
> All the rest live under /arch.
>
> I haven't found any that are a problem, but this doesn't feel like the right
> thing to do. I will look for a way to tidy this up.
Thanks for that. I do not think there is any problem, the only thing
that nags me is that we are using the cpu_down() interface
inconsistently with the rest of the kernel, agreed the issues are quite
theoretical but still the code is inconsistent.
I wonder what's the best way to clean this up, possibly adding code
that allows us to define what logical index the boot cpu is to
disable_nonboot_cpus() (ie with disable_nonboot_cpus() falling back
to first online cpu to keep current behaviour).
Just tossing around ideas, something has to be changed in core code
anyway if we wanted to keep things consistent.
Other solution would be setting cpuhp_tasks_frozen in
_arch_hibernation_disable_cpus() but I think that should be done
within a cpu_hotplug_begin() protected region of code.
Lorenzo
next prev parent reply other threads:[~2016-07-08 10:57 UTC|newest]
Thread overview: 16+ messages / expand[flat|nested] mbox.gz Atom feed top
2016-06-28 14:51 [PATCH v3 0/7] arm64: hibernate: Support DEBUG_PAGEALLOC and hibernate on non-boot cpu James Morse
2016-06-28 14:51 ` [PATCH v3 1/7] arm64: Create sections.h James Morse
2016-06-28 14:51 ` [PATCH v3 2/7] arm64: vmlinux.ld: Add .mmuoff.{text,data} sections James Morse
2016-06-28 17:16 ` Mark Rutland
2016-06-28 14:51 ` [PATCH v3 3/7] arm64: hibernate: Support DEBUG_PAGEALLOC James Morse
2016-06-28 14:51 ` [PATCH v3 4/7] arm64: hibernate: Detect hibernate image created on non-boot CPU James Morse
2016-06-28 14:51 ` [PATCH v3 5/7] PM / Hibernate: Allow arch code to influence CPU hotplug during hibernate James Morse
2016-06-29 0:10 ` Rafael J. Wysocki
2016-06-29 10:02 ` Chen Yu
2016-07-04 9:04 ` James Morse
2016-07-04 12:04 ` Rafael J. Wysocki
2016-06-28 14:51 ` [PATCH v3 6/7] arm64: hibernate: Resume on the CPU that created the hibernate image James Morse
2016-07-05 14:55 ` Lorenzo Pieralisi
2016-07-07 16:58 ` James Morse
2016-07-08 10:57 ` Lorenzo Pieralisi [this message]
2016-06-28 14:51 ` [PATCH v3 7/7] Revert "arm64: hibernate: Refuse to hibernate if the boot cpu is offline" James Morse
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=20160708105743.GB3784@red-moon \
--to=lorenzo.pieralisi@arm.com \
--cc=linux-arm-kernel@lists.infradead.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;
as well as URLs for NNTP newsgroup(s).