Skip to content

Commit 54ee939

Browse files
aviralgarg05fdcavalcanti
authored andcommitted
arch/espressif: serialize Wi-Fi RX queue access.
Protect the common Espressif Wi-Fi netdev RX queue with a spinlock. The Wi-Fi RX callback enqueues packets while the netdev upper-half RX thread dequeues them, and the IOB queue helpers are not internally serialized. Under sustained receive traffic that race can corrupt the queue state, strand IOBs, and degrade throughput over time as reported in issue #16915. Initialize the lock during device setup and use it when clearing the queue on ifup, enqueueing received packets, and dequeuing them for the upper half. Signed-off-by: aviralgarg05 <gargaviral99@gmail.com>
1 parent 92b8bc1 commit 54ee939

2 files changed

Lines changed: 30 additions & 2 deletions

File tree

arch/risc-v/src/common/espressif/esp_wlan_netdev.c

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,7 @@ struct esp_wlan_priv_s
117117
struct esp_common_wifi_s *common;
118118
uint32_t mode;
119119

120+
spinlock_t rx_lock;
120121
netpkt_queue_t netdev_rx_queue;
121122
uint8_t flatbuf[CONFIG_NET_ETH_PKTSIZE];
122123
};
@@ -212,6 +213,7 @@ static int esp_wlan_ifup(struct netdev_lowerhalf_s *dev)
212213
{
213214
struct esp_wlan_priv_s *priv = (struct esp_wlan_priv_s *)dev;
214215
struct net_driver_s *netdev = &priv->dev.netdev;
216+
irqstate_t flags;
215217
int ret = OK;
216218

217219
#ifdef CONFIG_NET_IPv4
@@ -228,7 +230,9 @@ static int esp_wlan_ifup(struct netdev_lowerhalf_s *dev)
228230

229231
/* Clear RX queue */
230232

233+
flags = spin_lock_irqsave(&priv->rx_lock);
231234
netpkt_free_queue(&priv->netdev_rx_queue);
235+
spin_unlock_irqrestore(&priv->rx_lock, flags);
232236

233237
/* Start Wi-Fi interface */
234238

@@ -349,7 +353,13 @@ static int esp_wlan_transmit(struct netdev_lowerhalf_s *dev,
349353
static netpkt_t *esp_wlan_receive(struct netdev_lowerhalf_s *dev)
350354
{
351355
struct esp_wlan_priv_s *priv = (struct esp_wlan_priv_s *)dev;
352-
netpkt_t *pkt = netpkt_remove_queue(&priv->netdev_rx_queue);
356+
irqstate_t flags;
357+
netpkt_t *pkt;
358+
359+
flags = spin_lock_irqsave(&priv->rx_lock);
360+
pkt = netpkt_remove_queue(&priv->netdev_rx_queue);
361+
spin_unlock_irqrestore(&priv->rx_lock, flags);
362+
353363
return pkt;
354364
}
355365

@@ -1008,6 +1018,7 @@ void IRAM_ATTR esp_wifi_tx_done_cb(uint8_t ifidx,
10081018
static int wlan_rx_done(struct esp_wlan_priv_s *priv,
10091019
void *buffer, uint16_t len, void *eb)
10101020
{
1021+
irqstate_t flags;
10111022
int ret = OK;
10121023
netpkt_t *pkt = NULL;
10131024

@@ -1025,7 +1036,9 @@ static int wlan_rx_done(struct esp_wlan_priv_s *priv,
10251036
goto out;
10261037
}
10271038

1039+
flags = spin_lock_irqsave(&priv->rx_lock);
10281040
ret = netpkt_tryadd_queue(pkt, &priv->netdev_rx_queue);
1041+
spin_unlock_irqrestore(&priv->rx_lock, flags);
10291042
if (ret < 0)
10301043
{
10311044
wlerr("ERROR: Failed to add packet to queue\n");
@@ -1221,6 +1234,7 @@ static int esp_wlan_initialize(uint32_t mode)
12211234
priv->dev.rxtype = NETDEV_RX_THREAD;
12221235
priv->dev.priority = 100;
12231236

1237+
spin_lock_init(&priv->rx_lock);
12241238
IOB_QINIT(&priv->netdev_rx_queue);
12251239

12261240
/* Register RX done callback. Called when the RX packet is received. */

arch/xtensa/src/common/espressif/esp_wlan_netdev.c

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,7 @@ struct esp_wlan_priv_s
117117
struct esp_common_wifi_s *common;
118118
uint32_t mode;
119119

120+
spinlock_t rx_lock;
120121
netpkt_queue_t netdev_rx_queue;
121122
uint8_t flatbuf[CONFIG_NET_ETH_PKTSIZE];
122123
};
@@ -212,6 +213,7 @@ static int esp_wlan_ifup(struct netdev_lowerhalf_s *dev)
212213
{
213214
struct esp_wlan_priv_s *priv = (struct esp_wlan_priv_s *)dev;
214215
struct net_driver_s *netdev = &priv->dev.netdev;
216+
irqstate_t flags;
215217
int ret = OK;
216218

217219
#ifdef CONFIG_NET_IPv4
@@ -228,7 +230,9 @@ static int esp_wlan_ifup(struct netdev_lowerhalf_s *dev)
228230

229231
/* Clear RX queue */
230232

233+
flags = spin_lock_irqsave(&priv->rx_lock);
231234
netpkt_free_queue(&priv->netdev_rx_queue);
235+
spin_unlock_irqrestore(&priv->rx_lock, flags);
232236

233237
/* Start Wi-Fi interface */
234238

@@ -349,7 +353,13 @@ static int esp_wlan_transmit(struct netdev_lowerhalf_s *dev,
349353
static netpkt_t *esp_wlan_receive(struct netdev_lowerhalf_s *dev)
350354
{
351355
struct esp_wlan_priv_s *priv = (struct esp_wlan_priv_s *)dev;
352-
netpkt_t *pkt = netpkt_remove_queue(&priv->netdev_rx_queue);
356+
irqstate_t flags;
357+
netpkt_t *pkt;
358+
359+
flags = spin_lock_irqsave(&priv->rx_lock);
360+
pkt = netpkt_remove_queue(&priv->netdev_rx_queue);
361+
spin_unlock_irqrestore(&priv->rx_lock, flags);
362+
353363
return pkt;
354364
}
355365

@@ -1008,6 +1018,7 @@ void IRAM_ATTR esp_wifi_tx_done_cb(uint8_t ifidx,
10081018
static int wlan_rx_done(struct esp_wlan_priv_s *priv,
10091019
void *buffer, uint16_t len, void *eb)
10101020
{
1021+
irqstate_t flags;
10111022
int ret = OK;
10121023
netpkt_t *pkt = NULL;
10131024

@@ -1025,7 +1036,9 @@ static int wlan_rx_done(struct esp_wlan_priv_s *priv,
10251036
goto out;
10261037
}
10271038

1039+
flags = spin_lock_irqsave(&priv->rx_lock);
10281040
ret = netpkt_tryadd_queue(pkt, &priv->netdev_rx_queue);
1041+
spin_unlock_irqrestore(&priv->rx_lock, flags);
10291042
if (ret != OK)
10301043
{
10311044
wlerr("ERROR: Failed to add packet to queue\n");
@@ -1224,6 +1237,7 @@ static int esp_wlan_initialize(uint32_t mode)
12241237
priv->dev.rxtype = NETDEV_RX_THREAD;
12251238
priv->dev.priority = 100;
12261239

1240+
spin_lock_init(&priv->rx_lock);
12271241
IOB_QINIT(&priv->netdev_rx_queue);
12281242

12291243
/* Register RX done callback. Called when the RX packet is received. */

0 commit comments

Comments
 (0)