Re: [PATCH net] net: dsa: fix flow dissection on Tx path

From: Alexander Lobakin
Date: Thu Dec 05 2019 - 08:34:40 EST


Andrew Lunn wrote 05.12.2019 15:58:
On Thu, Dec 05, 2019 at 01:02:35PM +0300, Alexander Lobakin wrote:
Commit 43e665287f93 ("net-next: dsa: fix flow dissection") added an
ability to override protocol and network offset during flow dissection
for DSA-enabled devices (i.e. controllers shipped as switch CPU ports)
in order to fix skb hashing for RPS on Rx path.

However, skb_hash() and added part of code can be invoked not only on
Rx, but also on Tx path if we have a multi-queued device and:
- kernel is running on UP system or
- XPS is not configured.

The call stack in this two cases will be like: dev_queue_xmit() ->
__dev_queue_xmit() -> netdev_core_pick_tx() -> netdev_pick_tx() ->
skb_tx_hash() -> skb_get_hash().

The problem is that skbs queued for Tx have both network offset and
correct protocol already set up even after inserting a CPU tag by DSA
tagger, so calling tag_ops->flow_dissect() on this path actually only
breaks flow dissection and hashing.

Hi Alexander

Hi,

What i'm missing here is an explanation why the flow dissector is
called here if the protocol is already set? It suggests there is a
case when the protocol is not correctly set, and we do need to look
into the frame?

If we have a device with multiple Tx queues, but XPS is not configured
or system is running on uniprocessor system, then networking core code
selects Tx queue depending on the flow to utilize as much Tx queues as
possible but without breaking frames order.
This selection happens in net/core/dev.c:skb_tx_hash() as:

reciprocal_scale(skb_get_hash(skb), qcount)

where 'qcount' is the total number of Tx queues on the network device.

If skb has not been hashed prior to this line, then skb_get_hash() will
call flow dissector to generate a new hash. That's why flow dissection
can occur on Tx path.

Andrew

Regards,
á á á á á á