net: Use k_fifo instead of k_work in RX and TX processing

The k_work handler cannot manipulate the used k_work. This means
that it is not easy to cleanup the net_pkt because it contains
k_work in it. Because of this, use k_fifo instead between
RX thread and network driver, and between application and TX
thread.

A echo-server/client run with IPv4 and UDP gave following
results:

Using k_work
------------
TX traffic class statistics:
TC  Priority	Sent pkts	bytes	time
[0] BK (1)	21922		5543071	103 us	[0->41->26->34=101 us]
[1] BE (0)	0		0	-
RX traffic class statistics:
TC  Priority	Recv pkts	bytes	time
[0] BK (0)	0		0	-
[1] BE (0)	21925		6039151	97 us	[0->21->16->37->20=94 us]

Using k_fifo
------------
TX traffic class statistics:
TC  Priority	Sent pkts	bytes	time
[0] BK (1)	15079		3811118	94 us	[0->36->23->32=91 us]
[1] BE (0)	0		0	-
RX traffic class statistics:
TC  Priority	Recv pkts	bytes	time
[0] BK (1)	0		0	-
[1] BE (0)	15073		4150947	79 us	[0->17->12->32->14=75 us]

So using k_fifo gives about 10% better performance with same workload.

Fixes #34690

Signed-off-by: Jukka Rissanen <jukka.rissanen@linux.intel.com>
This commit is contained in:
Jukka Rissanen 2021-04-29 15:58:54 +03:00 committed by Kumar Gala
commit bcdc762609
6 changed files with 96 additions and 54 deletions

View file

@ -396,15 +396,18 @@ struct net_if_config {
*
* Traffic classes are used when sending or receiving data that is classified
* with different priorities. So some traffic can be marked as high priority
* and it will be sent or received first. There is always at least one work
* queue in the system for Rx and Tx. Each network packet that is transmitted
* or received goes through a work queue thread that will transmit it.
* and it will be sent or received first. Each network packet that is
* transmitted or received goes through a fifo to a thread that will transmit
* it.
*/
struct net_traffic_class {
/** Work queue for handling this Tx or Rx packet */
struct k_work_q work_q;
/** Fifo for handling this Tx or Rx packet */
struct k_fifo fifo;
/** Stack for this work queue */
/** Traffic class handler thread */
struct k_thread handler;
/** Stack for this handler */
k_thread_stack_t *stack;
};