mirror of
https://github.com/RIOT-OS/RIOT.git
synced 2025-01-18 12:52:44 +01:00
cpu/esp32: fix esp_wifi stability issues
Fixes sporadic blocking of the wifi thread in esp_wifi_recv_cb function under heavy network load conditions when frames are coming in faster than they can be processed. Since esp_wifi_recv_cb function is not executed in interrupt context, the msg_send function used for ISR event can block when the message queue is full. With this change esp_wifi can be flooded with icmpv6 packets of maximum size without any problems over hours.
This commit is contained in:
parent
6caead7bbc
commit
f788928b27
@ -72,6 +72,11 @@ extern esp_err_t esp_system_event_add_handler (system_event_cb_t handler,
|
||||
|
||||
esp_err_t _esp_wifi_rx_cb(void *buffer, uint16_t len, void *eb)
|
||||
{
|
||||
/*
|
||||
* This callback function is executed in interrupt context but in the
|
||||
* context of the wifi thread. That is, mutex_lock or msg_send can block.
|
||||
*/
|
||||
|
||||
DEBUG("%s: buf=%p len=%d eb=%p\n", __func__, buffer, len, eb);
|
||||
|
||||
if ((buffer == NULL) || (len >= ETHERNET_DATA_LEN)) {
|
||||
@ -82,18 +87,33 @@ esp_err_t _esp_wifi_rx_cb(void *buffer, uint16_t len, void *eb)
|
||||
}
|
||||
|
||||
mutex_lock(&_esp_wifi_dev.dev_lock);
|
||||
critical_enter();
|
||||
|
||||
/* copy the buffer and free WiFi driver buffer */
|
||||
memcpy(_esp_wifi_dev.rx_buf, buffer, len);
|
||||
if (eb) {
|
||||
esp_wifi_internal_free_rx_buffer(eb);
|
||||
esp_wifi_internal_free_rx_buffer(eb);
|
||||
}
|
||||
|
||||
/*
|
||||
* Because this function is not executed in interrupt context but in thread
|
||||
* context, following msg_send could block on heavy network load, if frames
|
||||
* are coming in faster than the ISR events can be handled. To avoid
|
||||
* blocking during msg_send, we pretend we are in an ISR by incrementing
|
||||
* the IRQ nesting counter. If IRQ nesting counter is greater 0, function
|
||||
* irq_is_in returns true and the non-blocking version of msg_send is used.
|
||||
*/
|
||||
irq_interrupt_nesting++;
|
||||
|
||||
/* trigger netdev event to read the data */
|
||||
_esp_wifi_dev.rx_len = len;
|
||||
_esp_wifi_dev.event = SYSTEM_EVENT_WIFI_RX_DONE;
|
||||
_esp_wifi_dev.netdev.event_callback(&_esp_wifi_dev.netdev, NETDEV_EVENT_ISR);
|
||||
|
||||
/* reset IRQ nesting counter */
|
||||
irq_interrupt_nesting--;
|
||||
|
||||
critical_exit();
|
||||
mutex_unlock(&_esp_wifi_dev.dev_lock);
|
||||
|
||||
return ESP_OK;
|
||||
|
Loading…
Reference in New Issue
Block a user