]> www.infradead.org Git - users/dwmw2/linux.git/commit
net: renesas: rswitch: handle stop vs interrupt race
authorNikita Yushchenko <nikita.yoush@cogentembedded.com>
Mon, 9 Dec 2024 11:32:04 +0000 (16:32 +0500)
committerJakub Kicinski <kuba@kernel.org>
Wed, 11 Dec 2024 03:08:00 +0000 (19:08 -0800)
commit3dd002f20098b9569f8fd7f8703f364571e2e975
tree0125ac4fd4f29b65a5e232c3628bcb39ec219921
parent93763e68f1119d8bb09e1494004913a3ad137698
net: renesas: rswitch: handle stop vs interrupt race

Currently the stop routine of rswitch driver does not immediately
prevent hardware from continuing to update descriptors and requesting
interrupts.

It can happen that when rswitch_stop() executes the masking of
interrupts from the queues of the port being closed, napi poll for
that port is already scheduled or running on a different CPU. When
execution of this napi poll completes, it will unmask the interrupts.
And unmasked interrupt can fire after rswitch_stop() returns from
napi_disable() call. Then, the handler won't mask it, because
napi_schedule_prep() will return false, and interrupt storm will
happen.

This can't be fixed by making rswitch_stop() call napi_disable() before
masking interrupts. In this case, the interrupt storm will happen if
interrupt fires between napi_disable() and masking.

Fix this by checking for priv->opened_ports bit when unmasking
interrupts after napi poll. For that to be consistent, move
priv->opened_ports changes into spinlock-protected areas, and reorder
other operations in rswitch_open() and rswitch_stop() accordingly.

Signed-off-by: Nikita Yushchenko <nikita.yoush@cogentembedded.com>
Reviewed-by: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>
Fixes: 3590918b5d07 ("net: ethernet: renesas: Add support for "Ethernet Switch"")
Link: https://patch.msgid.link/20241209113204.175015-1-nikita.yoush@cogentembedded.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
drivers/net/ethernet/renesas/rswitch.c