From 2b2915bd9899a0b7bf845eb0ca8ff98531fdb4b5 Mon Sep 17 00:00:00 2001 From: Maochen Wang Date: Mon, 17 Feb 2025 18:56:48 +0800 Subject: [PATCH] net: ip: Fix low Zperf UDP throughput with -a When run the Zperf UDP throughput with '-a' (Asynchronous call), zperf_work_q thread will generate and send the packets to tx_q thread. When zperf_work_q and tx_q threads have same priority, if zperf_work_q fails to take the semaphore of fifo_slot, it will not wait and directly drop the net_pkt. Then it will allocate new net_pkt, repeat, and always occupy the CPU, which leads to extreme low throughput. For TX, when take the semaphore of fifo_slot, setting a wait time of K_FOREVER to let other thread to process and free these packets. For RX, when failed to take the semaphore of fifo_slot, yield the CPU to let the thread of data path with same priority to run to reduce dropping packets. Signed-off-by: Maochen Wang --- subsys/net/ip/net_tc.c | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/subsys/net/ip/net_tc.c b/subsys/net/ip/net_tc.c index 276fd01ff8b..8846ab15cc8 100644 --- a/subsys/net/ip/net_tc.c +++ b/subsys/net/ip/net_tc.c @@ -40,6 +40,9 @@ BUILD_ASSERT(NET_TC_TX_SLOTS > 0, "CONFIG_NET_TC_TX_COUNT or disable CONFIG_NET_TC_TX_SKIP_FOR_HIGH_PRIO"); #endif +#if NET_TC_RX_EFFECTIVE_COUNT > 1 +#define NET_TC_RETRY_CNT 1 +#endif /* Template for thread name. The "xx" is either "TX" denoting transmit thread, * or "RX" denoting receive thread. The "q[y]" denotes the traffic class queue * where y indicates the traffic class id. The value of y can be from 0 to 7. @@ -68,7 +71,7 @@ enum net_verdict net_tc_submit_to_tx_queue(uint8_t tc, struct net_pkt *pkt) net_pkt_set_tx_stats_tick(pkt, k_cycle_get_32()); #if NET_TC_TX_EFFECTIVE_COUNT > 1 - if (k_sem_take(&tx_classes[tc].fifo_slot, K_NO_WAIT) != 0) { + if (k_sem_take(&tx_classes[tc].fifo_slot, K_FOREVER) != 0) { return NET_DROP; } #endif @@ -85,11 +88,22 @@ enum net_verdict net_tc_submit_to_tx_queue(uint8_t tc, struct net_pkt *pkt) enum net_verdict net_tc_submit_to_rx_queue(uint8_t tc, struct net_pkt *pkt) { #if NET_TC_RX_COUNT > 0 +#if NET_TC_RX_EFFECTIVE_COUNT > 1 + uint8_t retry_cnt = NET_TC_RETRY_CNT; +#endif net_pkt_set_rx_stats_tick(pkt, k_cycle_get_32()); #if NET_TC_RX_EFFECTIVE_COUNT > 1 - if (k_sem_take(&rx_classes[tc].fifo_slot, K_NO_WAIT) != 0) { - return NET_DROP; + while (k_sem_take(&rx_classes[tc].fifo_slot, K_NO_WAIT) != 0) { + if (retry_cnt == 0) { + return NET_DROP; + } + + retry_cnt--; + /* Let thread with same priority run, + * try to reduce dropping packets + */ + k_yield(); } #endif