Skip to content

Commit a69163e

Browse files
committed
net: core: Dynamic priority and deferred processing
To enable quality-of-service (QoS) applications, allow to reschedule/defer the processing of a network packet based on its properties. This means, that processing can be offloaded to tc-queue-threads with different priorities. Signed-off-by: Cla Mattia Galliard <[email protected]>
1 parent d0663f1 commit a69163e

File tree

3 files changed

+45
-5
lines changed

3 files changed

+45
-5
lines changed

subsys/net/ip/net_core.c

Lines changed: 29 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,27 @@ LOG_MODULE_REGISTER(net_core, CONFIG_NET_CORE_LOG_LEVEL);
6464
#include "net_stats.h"
6565

6666
#if defined(CONFIG_NET_NATIVE)
67+
static void net_queue_rx(struct net_if *iface, struct net_pkt *pkt);
68+
69+
static void update_priority_l2(struct net_pkt *pkt)
70+
{
71+
/* This is just an example.
72+
* Similar infrastructure with custom application rules like
73+
* net_pkt_filter could be established
74+
*/
75+
if (net_pkt_ll_proto_type(pkt) == NET_ETH_PTYPE_PTP) {
76+
net_pkt_set_priority(pkt, NET_PRIORITY_IC);
77+
}
78+
}
79+
80+
static bool being_processed_by_correct_thread(struct net_pkt *pkt)
81+
{
82+
uint8_t prio = net_pkt_priority(pkt);
83+
uint8_t tc = net_rx_priority2tc(prio);
84+
85+
return net_tc_rx_is_current_thread(tc);
86+
}
87+
6788
static inline enum net_verdict process_data(struct net_pkt *pkt)
6889
{
6990
int ret;
@@ -77,27 +98,30 @@ static inline enum net_verdict process_data(struct net_pkt *pkt)
7798
if (!pkt->frags) {
7899
NET_DBG("Corrupted packet (frags %p)", pkt->frags);
79100
net_stats_update_processing_error(net_pkt_iface(pkt));
80-
81101
return NET_DROP;
82102
}
83103

84104
if (!net_pkt_is_l2_processed(pkt)) {
85-
ret = net_if_recv_data(net_pkt_iface(pkt), pkt);
86105
net_pkt_set_l2_processed(pkt, true);
106+
ret = net_if_recv_data(net_pkt_iface(pkt), pkt);
87107
if (ret != NET_CONTINUE) {
88108
if (ret == NET_DROP) {
89109
NET_DBG("Packet %p discarded by L2", pkt);
90110
net_stats_update_processing_error(
91111
net_pkt_iface(pkt));
92112
}
93-
94113
return ret;
95114
}
96-
97115
/* L2 has modified the buffer starting point, it is easier
98116
* to re-initialize the cursor rather than updating it.
99117
*/
100118
net_pkt_cursor_init(pkt);
119+
120+
update_priority_l2(pkt);
121+
if (!being_processed_by_correct_thread(pkt)) {
122+
net_queue_rx(net_pkt_iface(pkt), pkt);
123+
return NET_OK;
124+
}
101125
}
102126

103127
if (IS_ENABLED(CONFIG_NET_SOCKETS_PACKET_DGRAM) &&
@@ -128,7 +152,6 @@ static inline enum net_verdict process_data(struct net_pkt *pkt)
128152
} else if (IS_ENABLED(CONFIG_NET_SOCKETS_CAN) && family == AF_CAN) {
129153
return net_canbus_socket_input(pkt);
130154
}
131-
132155
NET_DBG("Unknown protocol family packet (0x%x)", family);
133156
return NET_DROP;
134157
}
@@ -137,6 +160,7 @@ static inline enum net_verdict process_data(struct net_pkt *pkt)
137160

138161
}
139162

163+
140164
static void processing_data(struct net_pkt *pkt)
141165
{
142166
again:

subsys/net/ip/net_private.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -207,6 +207,7 @@ static inline void net_tc_rx_init(void) { }
207207
#endif
208208
enum net_verdict net_tc_try_submit_to_tx_queue(uint8_t tc, struct net_pkt *pkt,
209209
k_timeout_t timeout);
210+
bool net_tc_rx_is_current_thread(uint8_t tc);
210211
extern enum net_verdict net_tc_submit_to_rx_queue(uint8_t tc, struct net_pkt *pkt);
211212
extern enum net_verdict net_promisc_mode_input(struct net_pkt *pkt);
212213

subsys/net/ip/net_tc.c

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -235,6 +235,21 @@ static uint8_t rx_tc2thread(uint8_t tc)
235235
}
236236
#endif
237237

238+
bool net_tc_rx_is_current_thread(uint8_t tc)
239+
{
240+
uint8_t thread_priority;
241+
int priority;
242+
int desired_priority;
243+
244+
thread_priority = rx_tc2thread(tc);
245+
desired_priority = IS_ENABLED(CONFIG_NET_TC_THREAD_COOPERATIVE) ?
246+
K_PRIO_COOP(thread_priority) :
247+
K_PRIO_PREEMPT(thread_priority);
248+
priority = k_thread_priority_get(k_current_get());
249+
250+
return priority == desired_priority;
251+
}
252+
238253
#if defined(CONFIG_NET_STATISTICS)
239254
/* Fixup the traffic class statistics so that "net stats" shell command will
240255
* print output correctly.

0 commit comments

Comments
 (0)