diff --git a/include/zephyr/net/net_if.h b/include/zephyr/net/net_if.h index 4e8aa607aee9..b3ca7de663d4 100644 --- a/include/zephyr/net/net_if.h +++ b/include/zephyr/net/net_if.h @@ -614,7 +614,8 @@ struct net_traffic_class { /** Fifo for handling this Tx or Rx packet */ struct k_fifo fifo; -#if NET_TC_COUNT > 1 || defined(CONFIG_NET_TC_SKIP_FOR_HIGH_PRIO) +#if NET_TC_COUNT > 1 || defined(CONFIG_NET_TC_SKIP_FOR_HIGH_PRIO) \ + || defined(CONFIG_NET_TC_RX_SKIP_FOR_HIGH_PRIO) /** Semaphore for tracking the available slots in the fifo */ struct k_sem fifo_slot; #endif diff --git a/subsys/net/ip/Kconfig b/subsys/net/ip/Kconfig index 6853869a3ccb..40c158e1be39 100644 --- a/subsys/net/ip/Kconfig +++ b/subsys/net/ip/Kconfig @@ -407,6 +407,19 @@ config NET_TC_SKIP_FOR_HIGH_PRIO be pushed directly to network driver and will skip the traffic class queues. This is currently not enabled by default. +config NET_TC_RX_SKIP_FOR_HIGH_PRIO + bool "Push high priority packets directly to the application" + help + If this is set, then high priority (>= NET_PRIORITY_CA) net_pkt will + be pushed directly to the application and will skip the traffic class + queues. If you select this option, then it means that high priority + network traffic is pushed from the driver to the application thread + without any intermediate RX queue. If the network device driver is + running in IRQ context, it will handle the packet all the way to the + application. This might cause other incoming packets to be lost if + the RX processing takes long time. + This is currently not enabled by default. + choice NET_TC_THREAD_TYPE prompt "How the network RX/TX threads should work" help diff --git a/subsys/net/ip/net_core.c b/subsys/net/ip/net_core.c index 6257a2954db6..4c22e10f35a2 100644 --- a/subsys/net/ip/net_core.c +++ b/subsys/net/ip/net_core.c @@ -475,7 +475,8 @@ static void net_queue_rx(struct net_if *iface, struct net_pkt *pkt) NET_DBG("TC %d with prio %d pkt %p", tc, prio, pkt); #endif - if (NET_TC_RX_COUNT == 0) { + if ((IS_ENABLED(CONFIG_NET_TC_RX_SKIP_FOR_HIGH_PRIO) && + prio >= NET_PRIORITY_CA) || NET_TC_RX_COUNT == 0) { net_process_rx_packet(pkt); } else { if (net_tc_submit_to_rx_queue(tc, pkt) != NET_OK) { diff --git a/subsys/net/ip/net_tc.c b/subsys/net/ip/net_tc.c index 046123aeb2f7..8cb203ad05a7 100644 --- a/subsys/net/ip/net_tc.c +++ b/subsys/net/ip/net_tc.c @@ -18,12 +18,15 @@ LOG_MODULE_REGISTER(net_tc, CONFIG_NET_TC_LOG_LEVEL); #include "net_stats.h" #include "net_tc_mapping.h" -#if NET_TC_RX_COUNT > 1 -#define NET_TC_RX_SLOTS (CONFIG_NET_PKT_RX_COUNT / NET_TC_RX_COUNT) +#define TC_RX_PSEUDO_QUEUE (COND_CODE_1(CONFIG_NET_TC_RX_SKIP_FOR_HIGH_PRIO, (1), (0))) +#define NET_TC_RX_EFFECTIVE_COUNT (NET_TC_RX_COUNT + TC_RX_PSEUDO_QUEUE) + +#if NET_TC_RX_EFFECTIVE_COUNT > 1 +#define NET_TC_RX_SLOTS (CONFIG_NET_PKT_RX_COUNT / NET_TC_RX_EFFECTIVE_COUNT) BUILD_ASSERT(NET_TC_RX_SLOTS > 0, "Misconfiguration: There are more traffic classes then packets, " "either increase CONFIG_NET_PKT_RX_COUNT or decrease " - "CONFIG_NET_TC_RX_COUNT"); + "CONFIG_NET_TC_RX_COUNT or disable CONFIG_NET_TC_RX_SKIP_FOR_HIGH_PRIO"); #endif #define TC_TX_PSEUDO_QUEUE (COND_CODE_1(CONFIG_NET_TC_SKIP_FOR_HIGH_PRIO, (1), (0))) @@ -84,7 +87,7 @@ enum net_verdict net_tc_submit_to_rx_queue(uint8_t tc, struct net_pkt *pkt) #if NET_TC_RX_COUNT > 0 net_pkt_set_rx_stats_tick(pkt, k_cycle_get_32()); -#if NET_TC_RX_COUNT > 1 +#if NET_TC_RX_EFFECTIVE_COUNT > 1 if (k_sem_take(&rx_classes[tc].fifo_slot, K_NO_WAIT) != 0) { return NET_DROP; } @@ -272,7 +275,7 @@ static void tc_rx_handler(void *p1, void *p2, void *p3) ARG_UNUSED(p3); struct k_fifo *fifo = p1; -#if NET_TC_RX_COUNT > 1 +#if NET_TC_RX_EFFECTIVE_COUNT > 1 struct k_sem *fifo_slot = p2; #else ARG_UNUSED(p2); @@ -285,7 +288,7 @@ static void tc_rx_handler(void *p1, void *p2, void *p3) continue; } -#if NET_TC_RX_COUNT > 1 +#if NET_TC_RX_EFFECTIVE_COUNT > 1 k_sem_give(fifo_slot); #endif @@ -429,7 +432,7 @@ void net_tc_rx_init(void) k_fifo_init(&rx_classes[i].fifo); -#if NET_TC_RX_COUNT > 1 +#if NET_TC_RX_EFFECTIVE_COUNT > 1 k_sem_init(&rx_classes[i].fifo_slot, NET_TC_RX_SLOTS, NET_TC_RX_SLOTS); #endif @@ -437,7 +440,7 @@ void net_tc_rx_init(void) K_KERNEL_STACK_SIZEOF(rx_stack[i]), tc_rx_handler, &rx_classes[i].fifo, -#if NET_TC_RX_COUNT > 1 +#if NET_TC_RX_EFFECTIVE_COUNT > 1 &rx_classes[i].fifo_slot, #else NULL,