FelipeMdeO opened a new pull request, #20179:
URL: https://github.com/apache/nuttx/pull/20179

   ## Summary
   
   `up_idlepm()` (`arch/xtensa/src/esp32s3/esp32s3_idle.c`,
   `arch/xtensa/src/esp32/esp32_idle.c`, 
`arch/xtensa/src/esp32s2/esp32s2_idle.c`
   and the shared RISC-V `arch/risc-v/src/common/espressif/esp_idle.c`, used by
   esp32c3/esp32c6) has a recovery branch that forces the domain back to
   PM_NORMAL when `oldstate` is not PM_NORMAL and nothing is currently staying
   at it:
   
   ```c
   pm_stay(PM_IDLE_DOMAIN, PM_NORMAL);
   pm_changestate(PM_IDLE_DOMAIN, PM_NORMAL);
   newstate = PM_NORMAL;
   ```
   
   `pm_stay()` here has no matching `pm_relax()` anywhere in any of the four
   files. The first time this branch runs, the stay count for PM_NORMAL never
   returns to 0, and `pm_checkstate()` (called unconditionally right after
   this block) can never recommend anything deeper than PM_NORMAL again for
   the rest of uptime -- the idle loop keeps running, but the governor is
   permanently pinned at full power, with no further light or deep sleep.
   
   The trigger is timing-dependent (whether anything else already holds
   PM_NORMAL at the moment this branch runs), which is likely why it does not
   reproduce on every single boot.
   
   Fix: release the stay right after the one `pm_changestate()` call it exists
   to force, matching the comment already there ("Keep working in normal
   stage") -- a one-shot nudge, not a standing hold.
   
   ## Impact
   
   * Is new feature added? No -- pure bug fix.
   * Is existing feature changed? No behavior change for configs that never
     hit the leaking branch; for configs that do, this restores the intended
     ability to reach light/deep sleep after a PM_NORMAL recovery event.
   * Impact on hardware? Affects every board using `CONFIG_PM` +
     `CONFIG_SCHED_TICKLESS` on esp32, esp32s2, esp32s3, esp32c3 or esp32c6 --
     generic arch-level code, no board files touched.
   
   ## Testing
   
   I confirm that changes are verified on local setup and works as intended:
   
   * Build Host: Ubuntu 24.04, x86_64, `xtensa-esp-elf-gcc` (crosstool-NG
     esp-14.2.0_20241119, 14.2.0).
   * Target: Xtensa, Seeed XIAO ESP32-S3, out-of-tree defconfig with
     `CONFIG_PM=y`, `CONFIG_SCHED_TICKLESS=y`, `CONFIG_ESPRESSIF_WIFI=y`.
   
   Confirmed via JTAG (OpenOCD + GDB), reading `g_pmdomains[0]` live in memory:
   
   **Before the fix** -- a "system" wakelock stuck at `state=PM_NORMAL,
   count=1`, acquired a few seconds after boot (right when Wi-Fi coming up
   briefly moves the domain off PM_NORMAL and this branch forces it back).
   Over a 40+ minute run: `state = 0` (PM_NORMAL) the entire time, zero
   `newstate=2` (PM_STANDBY) transitions logged, zero light-sleep-return log
   lines.
   
   ```
   $1 = {state = 0 '\000', ...,
         wakelock = {{head = 0x3fca1684 <g_wakelock+44>, tail = 0x3fca1684 
<g_wakelock+44>}, ...},
         ...}
   $2 = {name = "system", '\000' <repeats 25 times>, domain = 0,
         state = PM_NORMAL, count = 1, ...,
         start = {tv_sec = 12, tv_nsec = 119949125}, ...}
   ```
   
   Console log before the fix (only two PM transitions ever logged, the
   second one being the leak):
   
   ```
   up_idlepm: newstate= 1 oldstate=0
   up_idlepm: newstate= 0 oldstate=1
   ```
   (nothing else for the following 40 minutes)
   
   **After the fix**, same board, same config, fresh boot -- reached
   PM_STANDBY (real light sleep) within seconds:
   
   ```
   up_idlepm: newstate= 1 oldstate=0
   up_idlepm: newstate= 2 oldstate=1
   ```
   
   And reading `g_pmdomains[0]` live again, caught mid-sleep:
   
   ```
   $1 = {state = 2 '\002', in_sleep = true,
         wakelock = {{head = 0x0, tail = 0x0},           /* PM_NORMAL: empty 
now */
                     {head = 0x0, tail = 0x0},           /* PM_IDLE: empty */
                     {head = 0x3fca1774 <g_wakelock+284>, ...}, /* PM_STANDBY: 
the board's own intentional floor blocking deep sleep, unrelated to this bug */
                     {head = 0x0, tail = 0x0}},
         ...}
   ```
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to