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

   ## Summary
   
   `set_intr_wrapper()` in the Espressif Wi-Fi adapters allocates a new 
`intr_handle_data_t` from the kernel heap each time the Wi-Fi driver calls it, 
and the driver calls it on **every** `esp_wifi_start()` (twice per start on 
esp32s3, from `wifi_hw_start()`), not only the first one.
   
   `clear_intr_wrapper()` is a no-op, so the IRQ still holds the handle from 
the previous start. `esp_set_handle()` then refuses to replace it (`-EINVAL`), 
the return value is ignored, and the freshly allocated block is lost. Any 
application that stops and restarts Wi-Fi to save power loses a few bytes of 
kernel heap per cycle, without bound.
   
   Fix: look up the vector descriptor first, then reuse the handle already 
registered for the IRQ (`esp_get_handle()`), allocating and registering one 
only when there is none. A failed descriptor lookup no longer touches the 
registered handle.
   
   The same code is in the esp32, esp32s2, esp32s3, esp32c3 and esp32c6 
adapters (it came in with 8fb8c2dca50, "register Wi-Fi IRQs in non_iram mask 
for SPI flash"); all five are fixed the same way.
   
   ## Impact
   
   * Is new feature added? No, bug fix.
   * Is existing feature changed? No behavior change on the first 
`esp_wifi_start()`. On later starts the existing handle is updated in place 
instead of a new one being allocated and dropped.
   * Impact on hardware? esp32, esp32s2, esp32s3, esp32c3 and esp32c6 with 
Wi-Fi. Only matters to code that stops and restarts Wi-Fi; a single start at 
boot was never affected.
   
   ## 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` / 
`riscv-none-elf-gcc`.
   * Target: Seeed XIAO ESP32-S3 (esp32s3-xiao), Wi-Fi STA, light sleep.
   
   Wi-Fi was stopped and restarted every 120 s (disconnect + ifdown, then ifup 
+ associate), with `CONFIG_MM_BACKTRACE=8` and `CONFIG_MM_BACKTRACE_DEFAULT=y`, 
and `echo used > /proc/memdump` taken ten cycles apart.
   
   Before: the kernel heap dropped by the same amount on every cycle, and the 
second dump had exactly 20 new 16-byte blocks, all allocated from:
   
   ```
   kmm_calloc
   set_intr_wrapper                esp32s3_wifi_adapter.c
   ic_set_interrupt_handler        (Wi-Fi library)
   wifi_hw_start                   (Wi-Fi library)
   wifi_start_process              (Wi-Fi library)
   ieee80211_ioctl_process         (Wi-Fi library)
   ppTask                          (Wi-Fi library)
   ```
   
   After: the kernel heap stays flat from the second cycle on (one-time drop on 
the first start, when the handles are created).
   
   The hardware run used the equivalent esp32s3 change. This branch builds for 
`esp32s3-devkit:wifi`, `esp32-devkitc:wifi`, `esp32s2-saola-1:wifi`, 
`esp32c3-devkit:wifi` and `esp32c6-devkitc:wifi`; the other four chips are 
build-tested only. `checkpatch.sh` passes.
   


-- 
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