Skip to content

Commit 4813d58

Browse files
committed
net: Only process 1 packet per ethernet RX interrupt
Previously the packet_rx() function would wait on the RxSem and when signalled it would process all available inbound packets. This used to cause no problem but once the thread synchronization was turned on via SYS_LIGHTWEIGHT_PROT, the semaphore actually started to overflow its maximum token count of 65535. This caused the mbed_die() flashing LEDs of death. The old code was really breaking the producer/consumer pattern that I typically see with a semaphore since the consumer was written to consume more than 1 produced object per semaphore wait. Before the thread synchronization was enabled, the packet_rx() thread could use a single time slice to process all of these packets and then loop back around a few more times to decrement the semaphore count while skipping the packet processing since it had all been done. Now the packet processing code would cause the thread to give up its time slice as it hit newly enabled critical sections. In the end it was possible for the code to leak 2 semaphore signals for every 1 by which the thread was awaken. After about 10 seconds of load, this would cause a leak of 65535 signals. NOTE: Two potential issues with this change: 1) The LPC_EMAC->RxConsumeIndex != LPC_EMAC->RxProduceIndex check was removed from packet_rx(). I believe that this is Ok since the same condition is later checked in lpc_low_level_input() anyway so it won't now try to process more packets than what exist. 2) What if ENET_IRQHandler(void) ends up not signalling the RxSem for every packet received? When would that happen? I could see it happening if the ethernet hardware would try to pend more than 1 interrupt when the priority was too elevated to process the pending requests. Putting the consumer loop back in packet_rx() and using a Signal instead of a Semaphore might be a better solution?
1 parent 4c33f73 commit 4813d58

File tree

1 file changed

+2
-3
lines changed

1 file changed

+2
-3
lines changed

libraries/net/eth/lwip-eth/arch/lpc17_emac.c

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -809,9 +809,8 @@ static void packet_rx(void* pvParameters) {
809809
/* Wait for receive task to wakeup */
810810
sys_arch_sem_wait(&lpc_enetif->RxSem, 0);
811811

812-
/* Process packets until all empty */
813-
while (LPC_EMAC->RxConsumeIndex != LPC_EMAC->RxProduceIndex)
814-
lpc_enetif_input(lpc_enetif->netif);
812+
/* Process packet for this semaphore signal */
813+
lpc_enetif_input(lpc_enetif->netif);
815814
}
816815
}
817816

0 commit comments

Comments
 (0)