Netdev List
 help / color / mirror / Atom feed
* [BUG] can: RX frames silently dropped in raw_rcv() with RPS enabled since d4fb6514ff8e
       [not found] <VI1P18901MB0640EC60F0E40E18EED92A0AAA8D2@VI1P18901MB0640.EURP189.PROD.OUTLOOK.COM>
@ 2026-09-28 11:55 ` Jörg Willmann
  2026-09-28 12:16   ` Oliver Hartkopp
  0 siblings, 1 reply; 3+ messages in thread
From: Jörg Willmann @ 2026-09-28 11:55 UTC (permalink / raw)
  To: linux-can; +Cc: socketcan, mkl, netdev



Hi Oliver, hi Marc,

since commit d4fb6514ff8e ("can: use skb hash instead of private
 variable in headroom") we are losing received CAN frames on raw sockets
 when RPS is enabled on the CAN interface. The problem also shows up in
 the stable backports (seen on [6.12.109]).

 Setup:
 - Kernel: 6.12.109
 - Platform: OpenWrt 25.12.5, 4 CPU cores
 - CAN controller / driver: mcp251xfd
 - OpenWrt enables packet steering (RPS) by default on multi-core
 systems, so rps_cpus is non-zero on can0

 Symptom:
 The application on a CAN_RAW socket misses frames. /proc/net/can/stats
 counts more RX frames than the application receives. With

 echo 0 > /sys/class/net/can0/queues/rx-0/rps_cpus

 the losses disappear completely. [Optional: rate/amount of loss, number
 of filters on the socket, whether join_filters is used.]

 Analysis (as far as I understand it):
 1. RX skbs from the driver start with skb->hash == 0.
 2. With RPS enabled, get_rps_cpu() calls skb_get_hash() in the
 netif_rx() path before can_rcv() is reached. The flow dissector
 finds no L3/L4 headers in CAN skbs, so every CAN frame gets the
 same non-zero hash with sw_hash = 1.
 3. can_set_skb_uid() only assigns a new counter value while
 skb->hash is 0, so the RPS hash is kept and the frame gets no
 unique identifier.
 4. raw_rcv() treats a frame as a duplicate when both the skb pointer
 and skb->hash match the per-CPU uniq entry. Since the slab
 allocator often returns the same address for the next skb, a new
 frame with the same (constant) hash is dropped as a duplicate.

 Before d4fb6514ff8e this could not happen because the unique id was
 kept in can_skb_priv::skbcnt, independent of skb->hash.

 Thanks,
 Joerg

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [BUG] can: RX frames silently dropped in raw_rcv() with RPS enabled since d4fb6514ff8e
  2026-09-28 11:55 ` [BUG] can: RX frames silently dropped in raw_rcv() with RPS enabled since d4fb6514ff8e Jörg Willmann
@ 2026-09-28 12:16   ` Oliver Hartkopp
  2026-09-28 17:48     ` Oliver Hartkopp
  0 siblings, 1 reply; 3+ messages in thread
From: Oliver Hartkopp @ 2026-09-28 12:16 UTC (permalink / raw)
  To: Jörg Willmann, linux-can; +Cc: mkl, netdev

Hi Joerg,

many thanks for the report!

On 28.09.26 13:55, Jörg Willmann wrote:

> since commit d4fb6514ff8e ("can: use skb hash instead of private
>   variable in headroom") we are losing received CAN frames on raw sockets
>   when RPS is enabled on the CAN interface. The problem also shows up in
>   the stable backports (seen on [6.12.109]).
> 
>   Setup:
>   - Kernel: 6.12.109
>   - Platform: OpenWrt 25.12.5, 4 CPU cores
>   - CAN controller / driver: mcp251xfd
>   - OpenWrt enables packet steering (RPS) by default on multi-core
>   systems, so rps_cpus is non-zero on can0
> 
>   Symptom:
>   The application on a CAN_RAW socket misses frames. /proc/net/can/stats
>   counts more RX frames than the application receives. With
> 
>   echo 0 > /sys/class/net/can0/queues/rx-0/rps_cpus
> 
>   the losses disappear completely. [Optional: rate/amount of loss, number
>   of filters on the socket, whether join_filters is used.]
> 
>   Analysis (as far as I understand it):
>   1. RX skbs from the driver start with skb->hash == 0.
>   2. With RPS enabled, get_rps_cpu() calls skb_get_hash() in the
>   netif_rx() path before can_rcv() is reached. The flow dissector
>   finds no L3/L4 headers in CAN skbs, so every CAN frame gets the
>   same non-zero hash with sw_hash = 1.

Ouch! I wasn't aware of this.

>   3. can_set_skb_uid() only assigns a new counter value while
>   skb->hash is 0, so the RPS hash is kept and the frame gets no
>   unique identifier.

Correct! That's bad and not intended here.

>   4. raw_rcv() treats a frame as a duplicate when both the skb pointer
>   and skb->hash match the per-CPU uniq entry. Since the slab
>   allocator often returns the same address for the next skb, a new
>   frame with the same (constant) hash is dropped as a duplicate.

Right!

>   Before d4fb6514ff8e this could not happen because the unique id was
>   kept in can_skb_priv::skbcnt, independent of skb->hash.

Yes. We won't get can_skb_priv::skbcnt back but I will take a look at it.

Best regards,
Oliver


^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [BUG] can: RX frames silently dropped in raw_rcv() with RPS enabled since d4fb6514ff8e
  2026-09-28 12:16   ` Oliver Hartkopp
@ 2026-09-28 17:48     ` Oliver Hartkopp
  0 siblings, 0 replies; 3+ messages in thread
From: Oliver Hartkopp @ 2026-09-28 17:48 UTC (permalink / raw)
  To: Jörg Willmann, linux-can; +Cc: mkl, netdev

Hi Jörg!

I've sent out a v2 patch set where the third patch addresses your 
reported RPS related bug.

https://patchwork.kernel.org/series/1175458/

The third patch needs patch 2 as both are changing code in can*_rcv.

Can you please test the patch set in your setup?

Many thanks,
Oliver

On 28.09.26 14:16, Oliver Hartkopp wrote:
> Hi Joerg,
> 
> many thanks for the report!
> 
> On 28.09.26 13:55, Jörg Willmann wrote:
> 
>> since commit d4fb6514ff8e ("can: use skb hash instead of private
>>   variable in headroom") we are losing received CAN frames on raw sockets
>>   when RPS is enabled on the CAN interface. The problem also shows up in
>>   the stable backports (seen on [6.12.109]).
>>
>>   Setup:
>>   - Kernel: 6.12.109
>>   - Platform: OpenWrt 25.12.5, 4 CPU cores
>>   - CAN controller / driver: mcp251xfd
>>   - OpenWrt enables packet steering (RPS) by default on multi-core
>>   systems, so rps_cpus is non-zero on can0
>>
>>   Symptom:
>>   The application on a CAN_RAW socket misses frames. /proc/net/can/stats
>>   counts more RX frames than the application receives. With
>>
>>   echo 0 > /sys/class/net/can0/queues/rx-0/rps_cpus
>>
>>   the losses disappear completely. [Optional: rate/amount of loss, number
>>   of filters on the socket, whether join_filters is used.]
>>
>>   Analysis (as far as I understand it):
>>   1. RX skbs from the driver start with skb->hash == 0.
>>   2. With RPS enabled, get_rps_cpu() calls skb_get_hash() in the
>>   netif_rx() path before can_rcv() is reached. The flow dissector
>>   finds no L3/L4 headers in CAN skbs, so every CAN frame gets the
>>   same non-zero hash with sw_hash = 1.
> 
> Ouch! I wasn't aware of this.
> 
>>   3. can_set_skb_uid() only assigns a new counter value while
>>   skb->hash is 0, so the RPS hash is kept and the frame gets no
>>   unique identifier.
> 
> Correct! That's bad and not intended here.
> 
>>   4. raw_rcv() treats a frame as a duplicate when both the skb pointer
>>   and skb->hash match the per-CPU uniq entry. Since the slab
>>   allocator often returns the same address for the next skb, a new
>>   frame with the same (constant) hash is dropped as a duplicate.
> 
> Right!
> 
>>   Before d4fb6514ff8e this could not happen because the unique id was
>>   kept in can_skb_priv::skbcnt, independent of skb->hash.
> 
> Yes. We won't get can_skb_priv::skbcnt back but I will take a look at it.
> 
> Best regards,
> Oliver
> 
> 


^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2026-09-28 18:12 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
     [not found] <VI1P18901MB0640EC60F0E40E18EED92A0AAA8D2@VI1P18901MB0640.EURP189.PROD.OUTLOOK.COM>
2026-09-28 11:55 ` [BUG] can: RX frames silently dropped in raw_rcv() with RPS enabled since d4fb6514ff8e Jörg Willmann
2026-09-28 12:16   ` Oliver Hartkopp
2026-09-28 17:48     ` Oliver Hartkopp

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox