Skip to content

Commit d88b7ac

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 0630e2e commit d88b7ac

File tree

3 files changed

+46
-5
lines changed

3 files changed

+46
-5
lines changed

subsys/net/ip/net_core.c

Lines changed: 30 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,28 @@ LOG_MODULE_REGISTER(net_core, CONFIG_NET_CORE_LOG_LEVEL);
6363

6464
#include "net_stats.h"
6565

66+
static void net_queue_rx(struct net_if *iface, struct net_pkt *pkt);
67+
68+
static void update_priority_l2(struct net_pkt *pkt)
69+
{
70+
/* This is just an example.
71+
* Similar infrastructure with custom application rules like
72+
* net_pkt_filter could be established
73+
*/
74+
if (net_pkt_ll_proto_type(pkt) == NET_ETH_PTYPE_PTP) {
75+
net_pkt_set_priority(pkt, NET_PRIORITY_IC);
76+
}
77+
}
78+
79+
static bool being_processed_by_correct_thread(struct net_pkt *pkt)
80+
{
81+
uint8_t prio = net_pkt_priority(pkt);
82+
uint8_t tc = net_rx_priority2tc(prio);
83+
84+
return net_tc_rx_is_current_thread(tc);
85+
}
86+
87+
6688
#if defined(CONFIG_NET_NATIVE)
6789
static inline enum net_verdict process_data(struct net_pkt *pkt)
6890
{
@@ -77,27 +99,30 @@ static inline enum net_verdict process_data(struct net_pkt *pkt)
7799
if (!pkt->frags) {
78100
NET_DBG("Corrupted packet (frags %p)", pkt->frags);
79101
net_stats_update_processing_error(net_pkt_iface(pkt));
80-
81102
return NET_DROP;
82103
}
83104

84105
if (!net_pkt_is_l2_processed(pkt)) {
85-
ret = net_if_recv_data(net_pkt_iface(pkt), pkt);
86106
net_pkt_set_l2_processed(pkt, true);
107+
ret = net_if_recv_data(net_pkt_iface(pkt), pkt);
87108
if (ret != NET_CONTINUE) {
88109
if (ret == NET_DROP) {
89110
NET_DBG("Packet %p discarded by L2", pkt);
90111
net_stats_update_processing_error(
91112
net_pkt_iface(pkt));
92113
}
93-
94114
return ret;
95115
}
96-
97116
/* L2 has modified the buffer starting point, it is easier
98117
* to re-initialize the cursor rather than updating it.
99118
*/
100119
net_pkt_cursor_init(pkt);
120+
121+
update_priority_l2(pkt);
122+
if (!being_processed_by_correct_thread(pkt)) {
123+
net_queue_rx(net_pkt_iface(pkt), pkt);
124+
return NET_OK;
125+
}
101126
}
102127

103128
if (IS_ENABLED(CONFIG_NET_SOCKETS_PACKET_DGRAM) &&
@@ -128,7 +153,6 @@ static inline enum net_verdict process_data(struct net_pkt *pkt)
128153
} else if (IS_ENABLED(CONFIG_NET_SOCKETS_CAN) && family == AF_CAN) {
129154
return net_canbus_socket_input(pkt);
130155
}
131-
132156
NET_DBG("Unknown protocol family packet (0x%x)", family);
133157
return NET_DROP;
134158
}
@@ -137,6 +161,7 @@ static inline enum net_verdict process_data(struct net_pkt *pkt)
137161

138162
}
139163

164+
140165
static void processing_data(struct net_pkt *pkt)
141166
{
142167
again:

subsys/net/ip/net_private.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -201,6 +201,7 @@ static inline void net_tc_rx_init(void) { }
201201
#endif
202202
enum net_verdict net_tc_try_submit_to_tx_queue(uint8_t tc, struct net_pkt *pkt,
203203
k_timeout_t timeout);
204+
bool net_tc_rx_is_current_thread(uint8_t tc);
204205
extern enum net_verdict net_tc_submit_to_rx_queue(uint8_t tc, struct net_pkt *pkt);
205206
extern enum net_verdict net_promisc_mode_input(struct net_pkt *pkt);
206207

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)