Re: [PATCH] can: vcan: use per-CPU device stats

From: Yogesh Gaur

Date: Thu Oct 08 2026 - 00:15:35 EST


On Wed, Oct 7, 2026 at 6:50 PM Marc Kleine-Budde <mkl@xxxxxxxxxxxxxx> wrote:
>
> On 07.10.2026 17:06:11, Yogesh Gaur wrote:
> > vcan_tx() and vcan_rx() update dev->stats with plain increments and
> > rely on the tx queue lock to serialise them. That only holds for a
> > single tx queue. vcan does not implement get_num_tx_queues(), so
> > rtnl_create_link() honours IFLA_NUM_TX_QUEUES and a vcan device can be
> > created with several queues, each with its own xmit lock. Two CPUs
> > transmitting on different queues then update the same counters
> > concurrently and lose increments:
> >
> > BUG: KCSAN: data-race in vcan_tx / vcan_tx
> > read-write to 0xffff88811aad8228 of 8 bytes by interrupt on cpu 1:
> > vcan_tx+0x325/0x5d0 drivers/net/can/vcan.c:110
> > dev_hard_start_xmit+0x10c/0x380 net/core/dev.c:3969
> > __dev_queue_xmit+0xbfd/0x1ec0 net/core/dev.c:4958
> > can_send+0x584/0x720 net/can/af_can.c:279
> > bcm_can_tx+0x3ba/0x5b0 net/can/bcm.c:367
> > read-write to 0xffff88811aad8228 of 8 bytes by interrupt on cpu 0:
> > vcan_tx+0x325/0x5d0 drivers/net/can/vcan.c:110
> > value changed: 0x00000000000025ef -> 0x00000000000025f0
> >
> > Switch the packet and byte counters to the core's per-CPU dstats.
> > The core allocates them for NETDEV_PCPU_STAT_DSTATS and folds them
> > together with dev->stats in dev_get_stats(), so tx_dropped from
> > can_dropped_invalid_skb() is still reported.
> >
> > Reported-by: syzbot+937a3a1fbfbc99d6fcaf@xxxxxxxxxxxxxxxxxxxxxxxxx
> > Closes: https://syzkaller.appspot.com/bug?extid=937a3a1fbfbc99d6fcaf
> > Assisted-by: LLM
> > Signed-off-by: Yogesh Gaur <yogeshgaur.83@xxxxxxxxx>
>
> So far all drivers use the classic stats, and the CAN dev helper code
> (in drivers/net/can/dev) also modifies these fields. A quick search
> shows these places:
>
> drivers/net/can/dev/rx-offload.c:48: struct net_device_stats *stats = &dev->stats;
> drivers/net/can/dev/rx-offload.c:162: offload->dev->stats.rx_dropped++;
> drivers/net/can/dev/rx-offload.c:163: offload->dev->stats.rx_fifo_errors++;
> drivers/net/can/dev/rx-offload.c:249: struct net_device_stats *stats = &dev->stats;
> drivers/net/can/dev/rx-offload.c:289: struct net_device_stats *stats = &dev->stats;
> drivers/net/can/dev/skb.c:29: struct net_device_stats *stats = &dev->stats;
> drivers/net/can/dev/skb.c:402: dev->stats.tx_dropped++;
>
> Can you modify the code to update the dstats if they are active?

Yes and as per Oliver's suggestion send race fix along with dstats
work on top for can-next.

Yogesh
>
> regards,
> Marc
>
> --
> Pengutronix e.K. | Marc Kleine-Budde |
> Embedded Linux | https://www.pengutronix.de |
> Vertretung Nürnberg | Phone: +49-5121-206917-129 |
> Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-9 |