On Wed, Nov 28, 2012 at 16:42:26, Russell King - ARM Linux wrote: > On Tue, Nov 27, 2012 at 03:42:39PM -0800, Andrew Morton wrote: > > > + /* Do not allow to execute any other task */ > > > + spin_lock_irqsave(&lock, flags); > > > + while (1); > > > > I suspect this doesn't do what you want it to do. > > > > Firstly, please provide adequate code comments here so that code > > readers do not also need to be mind readers. > > > > If you want to stop this CPU dead in its tracks (why?) then > > > > local_irq_disable(); > > while (1) > > ; /* Note correct code layout */ > > > > will do it. But it means that the NMI watchdog (if present) will come > > along and whack the machine in the head a few seconds later. And this > > does nothing to stop other CPUs. > > > > But not being a mind reader, I'm really at a loss to suggest what > > should be done here.
Here intention is to disable all interrupts between rtc power_off request till system actually went to power off mode, max 2 seconds based on when the AM335x RTC alarm2 expires. The idea was that since the system is going to shutdown, it is better to not process any more interrupts. > It's hooking into the pm_power_off hook, which is called from kernel/sys.c > via arch code. We will have already stopped all other CPUs at this point. > > Why there's that while (1) there I don't know; when pm_power_off is not > hooked, we don't do anything like that - and what will happen in that > case is we'll return all the way back to sys_reboot(), which will call > do_exit(0) on us. When testing with v3.7-rc7, I saw the following BUG() triggered when I did not use a while(1). Logs below. Before calling do_exit(0), there is a reboot_mutex lock that is taken in reboot syscall. do_exit() function is , checking for any locks held by the processor and if yes then it is printing a BUG_ON from print_held_locks_bug() function along with the locks held information. Even though the BUG triggers, the system is going to power off because The hardware has been triggered. ==== (log) [root@arago /]# poweroff The system is going down NOW! Sent SIGTERM to all processes Sent SIGKILL to all processes Requesting system poweroff [ 32.125900] Disabling non-boot CPUs ... [ 32.130155] Power down. [ 32.132741] System will go to power_off state in approx. 2 secs [ 32.139994] [ 32.141575] ===================================== [ 32.146564] [ BUG: lock held at task exit time! ] [ 32.151522] 3.7.0-rc7-00015-g3f8bbe0 #32 Not tainted [ 32.156721] ------------------------------------- [ 32.161676] init/622 is exiting with locks still held! [ 32.167085] 1 lock held by init/622: [ 32.170831] #0: (reboot_mutex){+.+...}, at: [<c0056fb8>] sys_reboot+0xf4/0x1e8 [ 32.178679] [ 32.178679] stack backtrace: [ 32.183305] [<c001af24>] (unwind_backtrace+0x0/0xf0) from [<c0046978>] (do_exit+0x488/0x7e8) [ 32.192183] [<c0046978>] (do_exit+0x488/0x7e8) from [<c0056fc4>] (sys_reboot+0x100/0x1e8) [ 32.200797] [<c0056fc4>] (sys_reboot+0x100/0x1e8) from [<c0013320>] (ret_fast_syscall+0x0/0x3c) ===== It is not clear to me where reboot_mutex should have been unlocked before debug_check_no_locks_held() is called in do_exit()? Note: In latest linux-next tip I am *not* seeing this error. I have not bisected yet to see what fixed this. Since with latest linux-next I am not seeing an issue, I will remove spinlock and the while(1). Hope that will make the patch more acceptable. > I don't see a problem with that, and I don't see why we need to spin > (without any power saving too) waiting for some event. If we've called > sys_reboot with LINUX_REBOOT_CMD_POWER_OFF, we'd better have already > killed most of userspace off by that time anyway. > I did a search of various power-off implementations in *arch/arm*. Those that use a while(1): ========================= arch/arm/mach-at91/board-gsia18s.c arch/arm/mach-at91/setup.c doesn't arch/arm/mach-cns3xxx/cns3420vb.c arch/arm/mach-iop32x/glantank.c arch/arm/mach-iop32x/iq31244.c arch/arm/mach-iop32x/n2100.c local_irq_disable() and then a while(1) arch/arm/mach-kirkwood/board-lsxl.c arch/arm/mach-highbank/highbank.c does while(1) cpu_do_idle() Those that don't have a while(1): ================================ arch/arm/mach-imx/mach-mx31moboard.c arch/arm/mach-iop32x/em7210.c Doesn't have a while(1) but setting a gpio so presumably kills the system immediately: =========== arch/arm/mach-ixp4xx/dsmg600-setup.c arch/arm/mach-ixp4xx/nas100d-setup.c arch/arm/mach-ixp4xx/nslu2-setup.c arch/arm/mach-kirkwood/board-dnskw.c arch/arm/mach-kirkwood/board-ib62x0.c arch/arm/mach-kirkwood/board-dnskw.c arch/arm/mach-kirkwood/board-ib62x0.c arch/arm/mach-kirkwood/d2net_v2-setup.c arch/arm/mach-kirkwood/netspace_v2-setup.c arch/arm/mach-kirkwood/netxbig_v2-setup.c arch/arm/mach-kirkwood/t5325-setup.c arch/arm/mach-orion5x/dns323-setup.c arch/arm/mach-vexpress/v2m.c take a spinlock, not sure when it will shut down arch/arm/mach-kirkwood/board-ts219.c sends a character to PIC and potentially returns... arch/arm/mach-kirkwood/ts219-setup.c So it seems there is a plethora of variations of how this is implemented (probably driven also by hardware differences). Since what I mentioned above works for me (in linux-next), I will go ahead and submit at v4. Let me know if there are objections. Thanks AnilKumar _______________________________________________ devicetree-discuss mailing list devicetree-discuss@lists.ozlabs.org https://lists.ozlabs.org/listinfo/devicetree-discuss