From: Sebastian Capella <sebastian.capella@linaro.org> To: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com> Cc: Len Brown <len.brown@intel.com>, "linaro-kernel@lists.linaro.org" <linaro-kernel@lists.linaro.org>, Russell King <linux@arm.linux.org.uk>, Jonathan Austin <Jonathan.Austin@arm.com>, "linux-pm@vger.kernel.org" <linux-pm@vger.kernel.org>, Will Deacon <Will.Deacon@arm.com>, Nicolas Pitre <nico@linaro.org>, "Rafael J. Wysocki" <rjw@rjwysocki.net>, "linux-kernel@vger.kernel.org" <linux-kernel@vger.kernel.org>, Uwe Kleine-K?nig <u.kleine-koenig@pengutronix.de>, Russ Dill <Russ.Dill@ti.com>, Pavel Machek <pavel@ucw.cz>, Cyril Chemparathy <cyril@ti.com>, Santosh Shilimkar <santosh.shilimkar@ti.com>, Catalin Marinas <Catalin.Marinas@arm.com>, Stephen Boyd <sboyd@codeaurora.org>, "linux-arm-kernel@lists.infradead.org" <linux-arm-kernel@lists.infradead.org> Subject: Re: [PATCH RFC v1 3/3] ARM hibernation / suspend-to-disk Date: Wed, 19 Feb 2014 11:33:15 -0800 [thread overview] Message-ID: <20140219193315.3732.21819@capellas-linux> (raw) In-Reply-To: <20140219161254.GB19343@e102568-lin.cambridge.arm.com> Quoting Lorenzo Pieralisi (2014-02-19 08:12:54) > On Wed, Feb 19, 2014 at 01:52:09AM +0000, Sebastian Capella wrote: > [...] > > diff --git a/arch/arm/kernel/hibernate.c b/arch/arm/kernel/hibernate.c > > new file mode 100644 > > index 0000000..16f406f > > --- /dev/null > > +++ b/arch/arm/kernel/hibernate.c > > +void notrace save_processor_state(void) > > +{ > > + WARN_ON(num_online_cpus() != 1); > > + flush_thread(); > > Can you explain to me please why we need to call flush_thread() here ? > At this point in time syscore_suspend() was already called and CPU > peripheral state saved through CPU PM notifiers. Copying Russ' response here: "I think the idea here is to get the CPU into a state so that later when we resume from the resume kernel, the actual CPU state matches the state we have in kernel. The main thing flush_thread does is clear out any and all FP state." - Russ Dill > > > + local_fiq_disable(); > > To me it looks like we are using this hook to disable fiqs, since it is > not done in generic code. > > > + > > +/* > > + * Snapshot kernel memory and reset the system. > > + * After resume, the hibernation snapshot is written out. > > + */ > > +static int notrace __swsusp_arch_save_image(unsigned long unused) > > +{ > > + int ret; > > + > > + ret = swsusp_save(); > > + if (ret == 0) > > + soft_restart(virt_to_phys(cpu_resume)); > > By the time the suspend finisher (ie this function) is run, the > processor state has been saved and I think that's all you have to do, > function can just return after calling swsusp_save(), unless I am missing > something. > > I do not understand why a soft_restart is required here. Let me try skipping the restart, it sounds like a good idea, thanks! I'll let you know. > On a side note, > finisher is called with irqs disabled so, since you added a function for > soft restart noirq, it should be used, if needed, but I have to understand > why in the first place. Thanks, will have a look at this also > > +/* > > + * Save the current CPU state before suspend / poweroff. > > + */ > > +int notrace swsusp_arch_suspend(void) > > +{ > > + return cpu_suspend(0, __swsusp_arch_save_image); > > If the goal of soft_restart is to return 0 on success from this call, > you can still do that without requiring a soft_restart in the first > place. IIUC all you want to achieve is to save processor context > registers so that when you resume from image you will actually return > from here. I think you're right, but I need to verify. Here, we want to snapshot the system's suspended state to the hibernation buffer, that way when we restore the image, we resume from the saved suspended state. This state is already saved to the buffer after the swsusp_save call in __swsusp_arch_save_image. We resume and then write the saved buffer to the resume partition. Once we're done saving the image to the buffer I can't think why we actually need the restart. There's only one tricky bit that I can think of, and that's the use of the nosave area to distinguish the path of completing hibernation entry from resume from hibernation, but I believe this would be handled correctly without a restart. Let me try it out and see. > > +/* > > + * The framework loads the hibernation image into a linked list anchored > > + * at restore_pblist, for swsusp_arch_resume() to copy back to the proper > > + * destinations. > > + * > > + * To make this work if resume is triggered from initramfs, the > > + * pagetables need to be switched to allow writes to kernel mem. > > Can you elaborate a bit more on this please ? > > > + */ > > +static void notrace __swsusp_arch_restore_image(void *unused) > > +{ > > + struct pbe *pbe; > > + > > + cpu_switch_mm(idmap_pgd, &init_mm); > > Same here, thanks. At restore time, we take the save buffer data and restore it to the same physical locations used in the previous execution. This will require having write access to all of memory, which may not be generally granted by the current mm. So we switch to 1-1 init_mm to restore memory. At hibernation entry, the system is writing only to save buffer memory, so we don't have this problem. It has read access to all of the memory, and can copy to the save buffer. Hopefully my comment above addressed this, but please let me know if I need to provide more info. > > +/* > > + * Resume from the hibernation image. > > + * Due to the kernel heap / data restore, stack contents change underneath > > + * and that would make function calls impossible; switch to a temporary > > + * stack within the nosave region to avoid that problem. > > + */ > > +int __naked swsusp_arch_resume(void) > > +{ > > + extern void call_with_stack(void (*fn)(void *), void *arg, void *sp); > > Ok, a function with attribute __naked that still calls C functions, is > attr __naked really needed here ? I will need to look at this more carefully and get back to you. I can > > > + cpu_init(); /* get a clean PSR */ > > cpu_init is called in the cpu_resume path, why is this call needed here ? I'll look more into this and get back with further comments. Thanks Lorenzo! Sebastian
WARNING: multiple messages have this Message-ID (diff)
From: sebastian.capella@linaro.org (Sebastian Capella) To: linux-arm-kernel@lists.infradead.org Subject: [PATCH RFC v1 3/3] ARM hibernation / suspend-to-disk Date: Wed, 19 Feb 2014 11:33:15 -0800 [thread overview] Message-ID: <20140219193315.3732.21819@capellas-linux> (raw) In-Reply-To: <20140219161254.GB19343@e102568-lin.cambridge.arm.com> Quoting Lorenzo Pieralisi (2014-02-19 08:12:54) > On Wed, Feb 19, 2014 at 01:52:09AM +0000, Sebastian Capella wrote: > [...] > > diff --git a/arch/arm/kernel/hibernate.c b/arch/arm/kernel/hibernate.c > > new file mode 100644 > > index 0000000..16f406f > > --- /dev/null > > +++ b/arch/arm/kernel/hibernate.c > > +void notrace save_processor_state(void) > > +{ > > + WARN_ON(num_online_cpus() != 1); > > + flush_thread(); > > Can you explain to me please why we need to call flush_thread() here ? > At this point in time syscore_suspend() was already called and CPU > peripheral state saved through CPU PM notifiers. Copying Russ' response here: "I think the idea here is to get the CPU into a state so that later when we resume from the resume kernel, the actual CPU state matches the state we have in kernel. The main thing flush_thread does is clear out any and all FP state." - Russ Dill > > > + local_fiq_disable(); > > To me it looks like we are using this hook to disable fiqs, since it is > not done in generic code. > > > + > > +/* > > + * Snapshot kernel memory and reset the system. > > + * After resume, the hibernation snapshot is written out. > > + */ > > +static int notrace __swsusp_arch_save_image(unsigned long unused) > > +{ > > + int ret; > > + > > + ret = swsusp_save(); > > + if (ret == 0) > > + soft_restart(virt_to_phys(cpu_resume)); > > By the time the suspend finisher (ie this function) is run, the > processor state has been saved and I think that's all you have to do, > function can just return after calling swsusp_save(), unless I am missing > something. > > I do not understand why a soft_restart is required here. Let me try skipping the restart, it sounds like a good idea, thanks! I'll let you know. > On a side note, > finisher is called with irqs disabled so, since you added a function for > soft restart noirq, it should be used, if needed, but I have to understand > why in the first place. Thanks, will have a look at this also > > +/* > > + * Save the current CPU state before suspend / poweroff. > > + */ > > +int notrace swsusp_arch_suspend(void) > > +{ > > + return cpu_suspend(0, __swsusp_arch_save_image); > > If the goal of soft_restart is to return 0 on success from this call, > you can still do that without requiring a soft_restart in the first > place. IIUC all you want to achieve is to save processor context > registers so that when you resume from image you will actually return > from here. I think you're right, but I need to verify. Here, we want to snapshot the system's suspended state to the hibernation buffer, that way when we restore the image, we resume from the saved suspended state. This state is already saved to the buffer after the swsusp_save call in __swsusp_arch_save_image. We resume and then write the saved buffer to the resume partition. Once we're done saving the image to the buffer I can't think why we actually need the restart. There's only one tricky bit that I can think of, and that's the use of the nosave area to distinguish the path of completing hibernation entry from resume from hibernation, but I believe this would be handled correctly without a restart. Let me try it out and see. > > +/* > > + * The framework loads the hibernation image into a linked list anchored > > + * at restore_pblist, for swsusp_arch_resume() to copy back to the proper > > + * destinations. > > + * > > + * To make this work if resume is triggered from initramfs, the > > + * pagetables need to be switched to allow writes to kernel mem. > > Can you elaborate a bit more on this please ? > > > + */ > > +static void notrace __swsusp_arch_restore_image(void *unused) > > +{ > > + struct pbe *pbe; > > + > > + cpu_switch_mm(idmap_pgd, &init_mm); > > Same here, thanks. At restore time, we take the save buffer data and restore it to the same physical locations used in the previous execution. This will require having write access to all of memory, which may not be generally granted by the current mm. So we switch to 1-1 init_mm to restore memory. At hibernation entry, the system is writing only to save buffer memory, so we don't have this problem. It has read access to all of the memory, and can copy to the save buffer. Hopefully my comment above addressed this, but please let me know if I need to provide more info. > > +/* > > + * Resume from the hibernation image. > > + * Due to the kernel heap / data restore, stack contents change underneath > > + * and that would make function calls impossible; switch to a temporary > > + * stack within the nosave region to avoid that problem. > > + */ > > +int __naked swsusp_arch_resume(void) > > +{ > > + extern void call_with_stack(void (*fn)(void *), void *arg, void *sp); > > Ok, a function with attribute __naked that still calls C functions, is > attr __naked really needed here ? I will need to look at this more carefully and get back to you. I can > > > + cpu_init(); /* get a clean PSR */ > > cpu_init is called in the cpu_resume path, why is this call needed here ? I'll look more into this and get back with further comments. Thanks Lorenzo! Sebastian
next prev parent reply other threads:[~2014-02-19 19:33 UTC|newest] Thread overview: 91+ messages / expand[flat|nested] mbox.gz Atom feed top 2014-02-19 1:52 [PATCH RFC v1 0/3] hibernation support on ARM Sebastian Capella 2014-02-19 1:52 ` Sebastian Capella 2014-02-19 1:52 ` [PATCH RFC v1 1/3] ARM: Add irq disabled version of soft_restart Sebastian Capella 2014-02-19 1:52 ` Sebastian Capella 2014-02-22 10:26 ` Russell King - ARM Linux 2014-02-22 10:26 ` Russell King - ARM Linux 2014-02-24 23:13 ` Sebastian Capella 2014-02-24 23:13 ` Sebastian Capella 2014-02-25 0:22 ` Sebastian Capella 2014-02-25 0:22 ` Sebastian Capella 2014-02-25 7:56 ` Russ Dill 2014-02-25 7:56 ` Russ Dill 2014-02-25 7:56 ` Russ Dill 2014-02-25 10:27 ` Thomas Gleixner 2014-02-25 10:27 ` Thomas Gleixner 2014-02-25 17:15 ` Russ Dill 2014-02-25 17:15 ` Russ Dill 2014-02-25 17:15 ` Russ Dill 2014-02-25 23:24 ` Sebastian Capella 2014-02-25 23:24 ` Sebastian Capella 2014-02-19 1:52 ` [PATCH RFC v1 2/3] Fix hibernation restore hang in freeze_processes Sebastian Capella 2014-02-19 1:52 ` Sebastian Capella 2014-02-24 7:09 ` Ming Lei 2014-02-24 7:09 ` Ming Lei 2014-02-19 1:52 ` [PATCH RFC v1 3/3] ARM hibernation / suspend-to-disk Sebastian Capella 2014-02-19 1:52 ` Sebastian Capella 2014-02-19 16:12 ` Lorenzo Pieralisi 2014-02-19 16:12 ` Lorenzo Pieralisi 2014-02-19 16:12 ` Lorenzo Pieralisi 2014-02-19 19:10 ` Russ Dill 2014-02-19 19:10 ` Russ Dill 2014-02-19 19:10 ` Russ Dill 2014-02-20 10:37 ` Lorenzo Pieralisi 2014-02-20 10:37 ` Lorenzo Pieralisi 2014-02-20 10:37 ` Lorenzo Pieralisi 2014-02-19 19:33 ` Sebastian Capella [this message] 2014-02-19 19:33 ` Sebastian Capella 2014-02-20 16:27 ` Lorenzo Pieralisi 2014-02-20 16:27 ` Lorenzo Pieralisi 2014-02-20 16:27 ` Lorenzo Pieralisi 2014-02-21 18:39 ` Sebastian Capella 2014-02-21 18:39 ` Sebastian Capella 2014-02-21 23:59 ` Sebastian Capella 2014-02-21 23:59 ` Sebastian Capella 2014-02-22 4:37 ` Sebastian Capella 2014-02-22 4:37 ` Sebastian Capella 2014-02-22 6:46 ` Russ Dill 2014-02-22 6:46 ` Russ Dill 2014-02-22 6:46 ` Russ Dill 2014-02-22 10:22 ` Russell King - ARM Linux 2014-02-22 10:22 ` Russell King - ARM Linux 2014-02-22 10:22 ` Russell King - ARM Linux 2014-02-22 10:16 ` Russell King - ARM Linux 2014-02-22 10:16 ` Russell King - ARM Linux 2014-02-22 10:16 ` Russell King - ARM Linux 2014-02-22 12:13 ` Lorenzo Pieralisi 2014-02-22 12:13 ` Lorenzo Pieralisi 2014-02-22 12:13 ` Lorenzo Pieralisi 2014-02-22 22:30 ` Pavel Machek 2014-02-22 22:30 ` Pavel Machek 2014-02-22 22:30 ` Pavel Machek 2014-02-21 1:01 ` Sebastian Capella 2014-02-21 1:01 ` Sebastian Capella 2014-02-22 10:38 ` Russell King - ARM Linux 2014-02-22 10:38 ` Russell King - ARM Linux 2014-02-22 10:38 ` Russell King - ARM Linux 2014-02-22 12:09 ` Lorenzo Pieralisi 2014-02-22 12:09 ` Lorenzo Pieralisi 2014-02-22 12:09 ` Lorenzo Pieralisi 2014-02-22 22:28 ` Pavel Machek 2014-02-22 22:28 ` Pavel Machek 2014-02-22 22:28 ` Pavel Machek 2014-02-23 19:52 ` Sebastian Capella 2014-02-23 19:52 ` Sebastian Capella 2014-02-23 19:52 ` Sebastian Capella 2014-02-23 20:02 ` Sebastian Capella 2014-02-23 20:02 ` Sebastian Capella 2014-02-23 20:02 ` Sebastian Capella 2014-02-25 11:32 ` Lorenzo Pieralisi 2014-02-25 11:32 ` Lorenzo Pieralisi 2014-02-25 11:32 ` Lorenzo Pieralisi 2014-02-25 17:55 ` Sebastian Capella 2014-02-25 17:55 ` Sebastian Capella 2014-02-26 10:24 ` Lorenzo Pieralisi 2014-02-26 10:24 ` Lorenzo Pieralisi 2014-02-26 10:24 ` Lorenzo Pieralisi 2014-02-26 17:50 ` Sebastian Capella 2014-02-26 17:50 ` Sebastian Capella 2014-02-26 19:03 ` Lorenzo Pieralisi 2014-02-26 19:03 ` Lorenzo Pieralisi 2014-02-26 19:03 ` Lorenzo Pieralisi
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=20140219193315.3732.21819@capellas-linux \ --to=sebastian.capella@linaro.org \ --cc=Catalin.Marinas@arm.com \ --cc=Jonathan.Austin@arm.com \ --cc=Russ.Dill@ti.com \ --cc=Will.Deacon@arm.com \ --cc=cyril@ti.com \ --cc=len.brown@intel.com \ --cc=linaro-kernel@lists.linaro.org \ --cc=linux-arm-kernel@lists.infradead.org \ --cc=linux-kernel@vger.kernel.org \ --cc=linux-pm@vger.kernel.org \ --cc=linux@arm.linux.org.uk \ --cc=lorenzo.pieralisi@arm.com \ --cc=nico@linaro.org \ --cc=pavel@ucw.cz \ --cc=rjw@rjwysocki.net \ --cc=santosh.shilimkar@ti.com \ --cc=sboyd@codeaurora.org \ --cc=u.kleine-koenig@pengutronix.de \ /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: linkBe 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.