From 9635c4c49274c19033af850f48544eb0a1a68212 Mon Sep 17 00:00:00 2001 From: Cla Mattia Galliard Date: Mon, 20 Oct 2025 19:18:48 +0200 Subject: [PATCH 1/2] net: tc_mapping: Use preprocessor Avoid token pasting and use preprocessor more for additional flexibility. Signed-off-by: Cla Mattia Galliard --- subsys/net/ip/net_tc.c | 4 + subsys/net/ip/net_tc_mapping.h | 174 ++++++++++++++------------------- 2 files changed, 79 insertions(+), 99 deletions(-) diff --git a/subsys/net/ip/net_tc.c b/subsys/net/ip/net_tc.c index c38004532619d..b9536fcdcd115 100644 --- a/subsys/net/ip/net_tc.c +++ b/subsys/net/ip/net_tc.c @@ -120,6 +120,8 @@ enum net_verdict net_tc_submit_to_rx_queue(uint8_t tc, struct net_pkt *pkt) int net_tx_priority2tc(enum net_priority prio) { #if NET_TC_TX_COUNT > 0 + static const uint8_t tx_prio2tc_map[] = PRIORITY2TC_TX; + if (prio > NET_PRIORITY_NC) { /* Use default value suggested in 802.1Q */ prio = NET_PRIORITY_BE; @@ -136,6 +138,8 @@ int net_tx_priority2tc(enum net_priority prio) int net_rx_priority2tc(enum net_priority prio) { #if NET_TC_RX_COUNT > 0 + static const uint8_t rx_prio2tc_map[] = PRIORITY2TC_RX; + if (prio > NET_PRIORITY_NC) { /* Use default value suggested in 802.1Q */ prio = NET_PRIORITY_BE; diff --git a/subsys/net/ip/net_tc_mapping.h b/subsys/net/ip/net_tc_mapping.h index c5ac0febbeed9..343269b2fe242 100644 --- a/subsys/net/ip/net_tc_mapping.h +++ b/subsys/net/ip/net_tc_mapping.h @@ -13,7 +13,7 @@ #ifndef __TC_MAPPING_H #define __TC_MAPPING_H -#include +#include "zephyr/net/net_core.h" /* All the maps below use priorities and indexes, below is the list of them * according to 802.1Q - table I-2. @@ -29,122 +29,98 @@ * 7 (highest) NC Network control */ -/* Helper macros used to generate the map to use */ -#define PRIORITY2TC_GEN_INNER(TYPE, COUNT) priority2tc_ ## TYPE ## _ ## COUNT -#define PRIORITY2TC_GEN(TYPE, COUNT) PRIORITY2TC_GEN_INNER(TYPE, COUNT) - -#if defined(CONFIG_NET_TC_MAPPING_STRICT) && (NET_TC_COUNT > 0) /* This is the recommended priority to traffic class mapping for * implementations that do not support the credit-based shaper transmission * selection algorithm. * Ref: 802.1Q - chapter 8.6.6 - table 8-4 */ +#if defined(CONFIG_NET_TC_MAPPING_STRICT) +#define PRIORITY2TC_1 {0, 0, 0, 0, 0, 0, 0, 0} +#define PRIORITY2TC_2 {0, 0, 0, 0, 1, 1, 1, 1} +#define PRIORITY2TC_3 {0, 0, 0, 0, 1, 1, 2, 2} +#define PRIORITY2TC_4 {0, 0, 1, 1, 2, 2, 3, 3} +#define PRIORITY2TC_5 {0, 0, 1, 1, 2, 2, 3, 4} +#define PRIORITY2TC_6 {1, 0, 2, 2, 3, 3, 4, 5} +#define PRIORITY2TC_7 {1, 0, 2, 3, 4, 4, 5, 6} +#define PRIORITY2TC_8 {1, 0, 2, 3, 4, 5, 6, 7} -#if NET_TC_TX_COUNT == 1 || NET_TC_RX_COUNT == 1 -static const uint8_t priority2tc_strict_1[] = {0, 0, 0, 0, 0, 0, 0, 0}; -#endif -#if NET_TC_TX_COUNT == 2 || NET_TC_RX_COUNT == 2 -static const uint8_t priority2tc_strict_2[] = {0, 0, 0, 0, 1, 1, 1, 1}; -#endif -#if NET_TC_TX_COUNT == 3 || NET_TC_RX_COUNT == 3 -static const uint8_t priority2tc_strict_3[] = {0, 0, 0, 0, 1, 1, 2, 2}; -#endif -#if NET_TC_TX_COUNT == 4 || NET_TC_RX_COUNT == 4 -static const uint8_t priority2tc_strict_4[] = {0, 0, 1, 1, 2, 2, 3, 3}; -#endif -#if NET_TC_TX_COUNT == 5 || NET_TC_RX_COUNT == 5 -static const uint8_t priority2tc_strict_5[] = {0, 0, 1, 1, 2, 2, 3, 4}; -#endif -#if NET_TC_TX_COUNT == 6 || NET_TC_RX_COUNT == 6 -static const uint8_t priority2tc_strict_6[] = {1, 0, 2, 2, 3, 3, 4, 5}; -#endif -#if NET_TC_TX_COUNT == 7 || NET_TC_RX_COUNT == 7 -static const uint8_t priority2tc_strict_7[] = {1, 0, 2, 3, 4, 4, 5, 6}; -#endif -#if NET_TC_TX_COUNT == 8 || NET_TC_RX_COUNT == 8 -static const uint8_t priority2tc_strict_8[] = {1, 0, 2, 3, 4, 5, 6, 7}; -#endif - -#if NET_TC_TX_COUNT > 0 -static const uint8_t *tx_prio2tc_map = PRIORITY2TC_GEN(strict, NET_TC_TX_COUNT); -#endif -#if NET_TC_RX_COUNT > 0 -static const uint8_t *rx_prio2tc_map = PRIORITY2TC_GEN(strict, NET_TC_RX_COUNT); -#endif - -#elif defined(CONFIG_NET_TC_MAPPING_SR_CLASS_A_AND_B) && (NET_TC_COUNT > 0) /* This is the recommended priority to traffic class mapping for a system that * supports SR (Stream Reservation) class A and SR class B. * Ref: 802.1Q - chapter 34.5 - table 34-1 */ +#elif defined(CONFIG_NET_TC_MAPPING_SR_CLASS_A_AND_B) +#define PRIORITY2TC_1 {0, 0, 0, 0, 0, 0, 0, 0} +#define PRIORITY2TC_2 {0, 0, 1, 1, 0, 0, 0, 0} +#define PRIORITY2TC_3 {0, 0, 1, 2, 0, 0, 0, 0} +#define PRIORITY2TC_4 {0, 0, 2, 3, 1, 1, 1, 1} +#define PRIORITY2TC_5 {0, 0, 3, 4, 1, 1, 2, 2} +#define PRIORITY2TC_6 {0, 0, 4, 5, 1, 1, 2, 3} +#define PRIORITY2TC_7 {0, 0, 5, 6, 1, 2, 3, 4} +#define PRIORITY2TC_8 {1, 0, 6, 7, 2, 3, 4, 5} -#if NET_TC_TX_COUNT == 2 || NET_TC_RX_COUNT == 2 -static const uint8_t priority2tc_sr_ab_2[] = {0, 0, 1, 1, 0, 0, 0, 0}; -#endif -#if NET_TC_TX_COUNT == 3 || NET_TC_RX_COUNT == 3 -static const uint8_t priority2tc_sr_ab_3[] = {0, 0, 1, 2, 0, 0, 0, 0}; -#endif -#if NET_TC_TX_COUNT == 4 || NET_TC_RX_COUNT == 4 -static const uint8_t priority2tc_sr_ab_4[] = {0, 0, 2, 3, 1, 1, 1, 1}; -#endif -#if NET_TC_TX_COUNT == 5 || NET_TC_RX_COUNT == 5 -static const uint8_t priority2tc_sr_ab_5[] = {0, 0, 3, 4, 1, 1, 2, 2}; -#endif -#if NET_TC_TX_COUNT == 6 || NET_TC_RX_COUNT == 6 -static const uint8_t priority2tc_sr_ab_6[] = {0, 0, 4, 5, 1, 1, 2, 3}; -#endif -#if NET_TC_TX_COUNT == 7 || NET_TC_RX_COUNT == 7 -static const uint8_t priority2tc_sr_ab_7[] = {0, 0, 5, 6, 1, 2, 3, 4}; -#endif -#if NET_TC_TX_COUNT == 8 || NET_TC_RX_COUNT == 8 -static const uint8_t priority2tc_sr_ab_8[] = {1, 0, 6, 7, 2, 3, 4, 5}; -#endif - -#if NET_TC_TX_COUNT > 0 -static const uint8_t *tx_prio2tc_map = PRIORITY2TC_GEN(sr_ab, NET_TC_TX_COUNT); -#endif -#if NET_TC_RX_COUNT > 0 -static const uint8_t *rx_prio2tc_map = PRIORITY2TC_GEN(sr_ab, NET_TC_RX_COUNT); -#endif - -#elif defined(CONFIG_NET_TC_MAPPING_SR_CLASS_B_ONLY) && (NET_TC_COUNT > 0) /* This is the recommended priority to traffic class mapping for a system that * supports SR (Stream Reservation) class B only. * Ref: 802.1Q - chapter 34.5 - table 34-2 */ - -#if NET_TC_TX_COUNT == 2 || NET_TC_RX_COUNT == 2 -static const uint8_t priority2tc_sr_b_2[] = {0, 0, 1, 0, 0, 0, 0, 0}; -#endif -#if NET_TC_TX_COUNT == 3 || NET_TC_RX_COUNT == 3 -static const uint8_t priority2tc_sr_b_3[] = {0, 0, 2, 0, 1, 1, 1, 1}; -#endif -#if NET_TC_TX_COUNT == 4 || NET_TC_RX_COUNT == 4 -static const uint8_t priority2tc_sr_b_4[] = {0, 0, 3, 0, 1, 1, 2, 2}; -#endif -#if NET_TC_TX_COUNT == 5 || NET_TC_RX_COUNT == 5 -static const uint8_t priority2tc_sr_b_5[] = {0, 0, 4, 1, 2, 2, 3, 3}; -#endif -#if NET_TC_TX_COUNT == 6 || NET_TC_RX_COUNT == 6 -static const uint8_t priority2tc_sr_b_6[] = {0, 0, 5, 1, 2, 2, 3, 4}; -#endif -#if NET_TC_TX_COUNT == 7 || NET_TC_RX_COUNT == 7 -static const uint8_t priority2tc_sr_b_7[] = {1, 0, 6, 2, 3, 3, 4, 5}; -#endif -#if NET_TC_TX_COUNT == 8 || NET_TC_RX_COUNT == 8 -static const uint8_t priority2tc_sr_b_8[] = {1, 0, 7, 2, 3, 4, 5, 6}; -#endif - -#if NET_TC_TX_COUNT > 0 -static const uint8_t *tx_prio2tc_map = PRIORITY2TC_GEN(sr_b, NET_TC_TX_COUNT); -#endif -#if NET_TC_RX_COUNT > 0 -static const uint8_t *rx_prio2tc_map = PRIORITY2TC_GEN(sr_b, NET_TC_RX_COUNT); -#endif - +#elif defined(CONFIG_NET_TC_MAPPING_SR_CLASS_B_ONLY) +#define PRIORITY2TC_1 {0, 0, 0, 0, 0, 0, 0, 0} +#define PRIORITY2TC_2 {0, 0, 1, 0, 0, 0, 0, 0} +#define PRIORITY2TC_3 {0, 0, 2, 0, 1, 1, 1, 1} +#define PRIORITY2TC_4 {0, 0, 3, 0, 1, 1, 2, 2} +#define PRIORITY2TC_5 {0, 0, 4, 1, 2, 2, 3, 3} +#define PRIORITY2TC_6 {0, 0, 5, 1, 2, 2, 3, 4} +#define PRIORITY2TC_7 {1, 0, 6, 2, 3, 3, 4, 5} +#define PRIORITY2TC_8 {1, 0, 7, 2, 3, 4, 5, 6} +#endif + + +#if NET_TC_TX_COUNT == 0 +#elif NET_TC_TX_COUNT == 1 +#define PRIORITY2TC_TX PRIORITY2TC_1 +#elif NET_TC_TX_COUNT == 2 +#define PRIORITY2TC_TX PRIORITY2TC_2 +#elif NET_TC_TX_COUNT == 3 +#define PRIORITY2TC_TX PRIORITY2TC_3 +#elif NET_TC_TX_COUNT == 4 +#define PRIORITY2TC_TX PRIORITY2TC_4 +#elif NET_TC_TX_COUNT == 5 +#define PRIORITY2TC_TX PRIORITY2TC_5 +#elif NET_TC_TX_COUNT == 6 +#define PRIORITY2TC_TX PRIORITY2TC_6 +#elif NET_TC_TX_COUNT == 7 +#define PRIORITY2TC_TX PRIORITY2TC_7 +#elif NET_TC_TX_COUNT == 8 +#define PRIORITY2TC_TX PRIORITY2TC_8 +#else +BUILD_ASSERT(false, "Too many effective tx traffic class queues, either reduce " + "CONFIG_NET_TC_TX_COUNT or disable " + "CONFIG_NET_TC_TX_SKIP_FOR_HIGH_PRIO"); +#endif + +#if NET_TC_RX_COUNT == 0 +#elif NET_TC_RX_COUNT == 1 +#define PRIORITY2TC_RX PRIORITY2TC_1 +#elif NET_TC_RX_COUNT == 2 +#define PRIORITY2TC_RX PRIORITY2TC_2 +#elif NET_TC_RX_COUNT == 3 +#define PRIORITY2TC_RX PRIORITY2TC_3 +#elif NET_TC_RX_COUNT == 4 +#define PRIORITY2TC_RX PRIORITY2TC_4 +#elif NET_TC_RX_COUNT == 5 +#define PRIORITY2TC_RX PRIORITY2TC_5 +#elif NET_TC_RX_COUNT == 6 +#define PRIORITY2TC_RX PRIORITY2TC_6 +#elif NET_TC_RX_COUNT == 7 +#define PRIORITY2TC_RX PRIORITY2TC_7 +#elif NET_TC_RX_COUNT == 8 +#define PRIORITY2TC_RX PRIORITY2TC_8 +#else +BUILD_ASSERT(false, "Too many effective rx traffic class queues, either reduce " + "CONFIG_NET_TC_RX_COUNT or disable " + "CONFIG_NET_TC_RX_SKIP_FOR_HIGH_PRIO"); #endif #endif /* __TC_MAPPING_H */ From 9d635e09423ccd73cac930e56ca2d8b4bcd50f04 Mon Sep 17 00:00:00 2001 From: Cla Mattia Galliard Date: Sun, 19 Oct 2025 21:03:59 +0200 Subject: [PATCH 2/2] net: tc-mapping: Fix SKIP_FOR_HIGH_PRIO Adjust the way the SKIP option worked. Before this patch, a constant priority offset was considered "high priority" this had the effect, that the threads assigned to work on the priority were effectively usesless. To fix it, consider this immediate handling as a pseudo-queue and compute the tc-thead-mapping based on the effective count (+1 if skipping is enabled). This makes it so that all threads are usefull and the high-priority skip-path is considered as a pseudo tc-thread. Signed-off-by: Cla Mattia Galliard --- include/zephyr/net/net_core.h | 12 +++++++++++ subsys/net/ip/net_private.h | 9 +++++---- subsys/net/ip/net_tc.c | 5 ----- subsys/net/ip/net_tc_mapping.h | 37 +++++++++++++++++----------------- 4 files changed, 36 insertions(+), 27 deletions(-) diff --git a/include/zephyr/net/net_core.h b/include/zephyr/net/net_core.h index 505683eb139b3..cedc2686ff7ec 100644 --- a/include/zephyr/net/net_core.h +++ b/include/zephyr/net/net_core.h @@ -181,6 +181,18 @@ static inline int net_send_data(struct net_pkt *pkt) #define NET_TC_COUNT 0 #endif /* CONFIG_NET_TC_TX_COUNT && CONFIG_NET_TC_RX_COUNT */ +#if CONFIG_NET_TC_TX_SKIP_FOR_HIGH_PRIO +#define NET_TC_TX_EFFECTIVE_COUNT (NET_TC_TX_COUNT + 1) +#else +#define NET_TC_TX_EFFECTIVE_COUNT NET_TC_TX_COUNT +#endif + +#if CONFIG_NET_TC_RX_SKIP_FOR_HIGH_PRIO +#define NET_TC_RX_EFFECTIVE_COUNT (NET_TC_RX_COUNT + 1) +#else +#define NET_TC_RX_EFFECTIVE_COUNT NET_TC_RX_COUNT +#endif + /** * @brief Registration information for a given L3 handler. Note that * the layer number (L3) just refers to something that is on top diff --git a/subsys/net/ip/net_private.h b/subsys/net/ip/net_private.h index 7723365a71434..624f61d889349 100644 --- a/subsys/net/ip/net_private.h +++ b/subsys/net/ip/net_private.h @@ -15,6 +15,7 @@ #include #include #include +#include #ifdef CONFIG_NET_MGMT_EVENT_INFO @@ -212,8 +213,8 @@ extern int net_tc_tx_thread_priority(int tc); extern int net_tc_rx_thread_priority(int tc); static inline bool net_tc_tx_is_immediate(int tc, int prio) { - ARG_UNUSED(tc); - bool high_prio = (prio >= NET_PRIORITY_CA); + ARG_UNUSED(prio); + bool high_prio = (tc == NET_TC_TX_EFFECTIVE_COUNT - 1); bool skipping = IS_ENABLED(CONFIG_NET_TC_TX_SKIP_FOR_HIGH_PRIO); bool no_queues = (0 == NET_TC_TX_COUNT); @@ -221,8 +222,8 @@ static inline bool net_tc_tx_is_immediate(int tc, int prio) } static inline bool net_tc_rx_is_immediate(int tc, int prio) { - ARG_UNUSED(tc); - bool high_prio = (prio >= NET_PRIORITY_CA); + ARG_UNUSED(prio); + bool high_prio = (tc == NET_TC_RX_EFFECTIVE_COUNT - 1); bool skipping = IS_ENABLED(CONFIG_NET_TC_RX_SKIP_FOR_HIGH_PRIO); bool no_queues = (0 == NET_TC_RX_COUNT); diff --git a/subsys/net/ip/net_tc.c b/subsys/net/ip/net_tc.c index b9536fcdcd115..fad0150563aec 100644 --- a/subsys/net/ip/net_tc.c +++ b/subsys/net/ip/net_tc.c @@ -18,9 +18,6 @@ LOG_MODULE_REGISTER(net_tc, CONFIG_NET_TC_LOG_LEVEL); #include "net_stats.h" #include "net_tc_mapping.h" -#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, @@ -29,8 +26,6 @@ BUILD_ASSERT(NET_TC_RX_SLOTS > 0, "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_TX_SKIP_FOR_HIGH_PRIO, (1), (0))) -#define NET_TC_TX_EFFECTIVE_COUNT (NET_TC_TX_COUNT + TC_TX_PSEUDO_QUEUE) #if NET_TC_TX_EFFECTIVE_COUNT > 1 #define NET_TC_TX_SLOTS (CONFIG_NET_PKT_TX_COUNT / NET_TC_TX_EFFECTIVE_COUNT) diff --git a/subsys/net/ip/net_tc_mapping.h b/subsys/net/ip/net_tc_mapping.h index 343269b2fe242..7fc53e4d97fdb 100644 --- a/subsys/net/ip/net_tc_mapping.h +++ b/subsys/net/ip/net_tc_mapping.h @@ -77,22 +77,22 @@ #endif -#if NET_TC_TX_COUNT == 0 -#elif NET_TC_TX_COUNT == 1 +#if NET_TC_TX_EFFECTIVE_COUNT == 0 +#elif NET_TC_TX_EFFECTIVE_COUNT == 1 #define PRIORITY2TC_TX PRIORITY2TC_1 -#elif NET_TC_TX_COUNT == 2 +#elif NET_TC_TX_EFFECTIVE_COUNT == 2 #define PRIORITY2TC_TX PRIORITY2TC_2 -#elif NET_TC_TX_COUNT == 3 +#elif NET_TC_TX_EFFECTIVE_COUNT == 3 #define PRIORITY2TC_TX PRIORITY2TC_3 -#elif NET_TC_TX_COUNT == 4 +#elif NET_TC_TX_EFFECTIVE_COUNT == 4 #define PRIORITY2TC_TX PRIORITY2TC_4 -#elif NET_TC_TX_COUNT == 5 +#elif NET_TC_TX_EFFECTIVE_COUNT == 5 #define PRIORITY2TC_TX PRIORITY2TC_5 -#elif NET_TC_TX_COUNT == 6 +#elif NET_TC_TX_EFFECTIVE_COUNT == 6 #define PRIORITY2TC_TX PRIORITY2TC_6 -#elif NET_TC_TX_COUNT == 7 +#elif NET_TC_TX_EFFECTIVE_COUNT == 7 #define PRIORITY2TC_TX PRIORITY2TC_7 -#elif NET_TC_TX_COUNT == 8 +#elif NET_TC_TX_EFFECTIVE_COUNT == 8 #define PRIORITY2TC_TX PRIORITY2TC_8 #else BUILD_ASSERT(false, "Too many effective tx traffic class queues, either reduce " @@ -100,22 +100,23 @@ BUILD_ASSERT(false, "Too many effective tx traffic class queues, either reduce " "CONFIG_NET_TC_TX_SKIP_FOR_HIGH_PRIO"); #endif -#if NET_TC_RX_COUNT == 0 -#elif NET_TC_RX_COUNT == 1 + +#if NET_TC_RX_EFFECTIVE_COUNT == 0 +#elif NET_TC_RX_EFFECTIVE_COUNT == 1 #define PRIORITY2TC_RX PRIORITY2TC_1 -#elif NET_TC_RX_COUNT == 2 +#elif NET_TC_RX_EFFECTIVE_COUNT == 2 #define PRIORITY2TC_RX PRIORITY2TC_2 -#elif NET_TC_RX_COUNT == 3 +#elif NET_TC_RX_EFFECTIVE_COUNT == 3 #define PRIORITY2TC_RX PRIORITY2TC_3 -#elif NET_TC_RX_COUNT == 4 +#elif NET_TC_RX_EFFECTIVE_COUNT == 4 #define PRIORITY2TC_RX PRIORITY2TC_4 -#elif NET_TC_RX_COUNT == 5 +#elif NET_TC_RX_EFFECTIVE_COUNT == 5 #define PRIORITY2TC_RX PRIORITY2TC_5 -#elif NET_TC_RX_COUNT == 6 +#elif NET_TC_RX_EFFECTIVE_COUNT == 6 #define PRIORITY2TC_RX PRIORITY2TC_6 -#elif NET_TC_RX_COUNT == 7 +#elif NET_TC_RX_EFFECTIVE_COUNT == 7 #define PRIORITY2TC_RX PRIORITY2TC_7 -#elif NET_TC_RX_COUNT == 8 +#elif NET_TC_RX_EFFECTIVE_COUNT == 8 #define PRIORITY2TC_RX PRIORITY2TC_8 #else BUILD_ASSERT(false, "Too many effective rx traffic class queues, either reduce "