All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH net-next v2 0/2] net: dsa: fix host fdb refcount when an entry roams
@ 2026-11-14 22:53 Julius Bairaktaris
  2026-11-14 22:53 ` [PATCH net-next v2 1/2] net: bridge: switchdev: add br_switchdev_fdb_find_port() Julius Bairaktaris
  2026-11-14 22:53 ` [PATCH net-next v2 2/2] net: dsa: fix host fdb refcount when a bridge fdb entry roams Julius Bairaktaris
  0 siblings, 2 replies; 3+ messages in thread
From: Julius Bairaktaris @ 2026-11-14 22:53 UTC (permalink / raw)
  To: Nikolay Aleksandrov, Ido Schimmel, Andrew Lunn, Vladimir Oltean
  Cc: netdev, bridge, David S . Miller, Eric Dumazet, Jakub Kicinski,
	Paolo Abeni, Simon Horman, linux-kernel

When a bridge FDB entry roams between ports, br_fdb_update() notifies
switchdev of the deletion and the addition without a lock. With two
CPUs learning one address on different ports, DSA counts the host
address on its CPU port more or fewer times than the bridge has it,
which ends in "failed to delete ... from fdb: -2" or an address left on
the CPU port.

The earlier attempt took hash_lock in br_fdb_update(); Nikolay rejected
it because it slows down learning and roaming. This series leaves
br_fdb_update() and the rest of the bridge's learning path unchanged
and fixes DSA instead: each user port records the host addresses it
holds and, on every event, checks where the bridge has the entry now.
Patch 1 is the only bridge change: an RCU lookup that DSA calls from
its workqueue. Patch 2 replaces the counting.

The counting has been exposed to the race since commit 90dc8fd36078
("net: bridge: notify switchdev of disappearance of old FDB entry upon
migration"). The change redesigns how DSA tracks host addresses, so it
goes to net-next without a Fixes: tag.

Tested in QEMU with dsa_loop given FDB operations and assisted
learning, PROVE_LOCKING, PROVE_RCU and DEBUG_ATOMIC_SLEEP enabled, one
source address sent from two veth ports on two CPUs for 5 s, 5 boots
per kernel: net-next logs the -2 error and leaves the address on the
CPU port in 4 of 5 boots, this series in none, and it removes the
address when the user ports leave the bridge. A "bridge fdb replace" of
the address onto a user port leaves it on the CPU port in 5 of 5 boots
on net-next and removes it in 5 of 5 with this series. In a second
test the N-th allocation of "ip link set lan1 master br0" fails for
N = 1 to 150 while the bridge has 40 FDB entries to replay: v1 oopses
in dsa_user_switchdev_event_work() in 2 of 2 boots, this version in
none of 5 boots, and no address stays on the CPU port. The kernel log
of every boot has no lockdep, RCU or atomic sleep reports.

Changes in v2 (Sashiko's review of v1):
- An addition on a user port releases the address on every user port
  of the bridge, also of another tree, and before the entry is
  installed: the release no longer walks one tree, and no longer erases
  the entry on switches that keep one entry per address.
- Local entries use the same lookup, so a "bridge fdb replace" between
  a local and a foreign entry leaves no address behind.
- The lookup applies assisted_learning_on_cpu_port, and reports whether
  the entry was added by the user.
- The release is scheduled before the lag_fdb_add check, and only for
  ports that hold an address for a foreign entry when a learned entry
  moved.
- An entry is not reported as offloaded when its host address could
  not be added; the conduit's unicast reference is undone when the
  switch add fails, and a failed delete drops its record instead of
  repeating the conduit delete.
- Queued events no longer dereference dp->bridge after a failed join:
  they read it once and drop themselves, the FDB helpers take the
  bridge from the caller, and dp->bridge is accessed with
  READ_ONCE()/WRITE_ONCE().
- Patch 1: kernel-doc and message state what the lookup returns for
  local, locked, "master dynamic" and driver-learned entries, and name
  the DSA caller.

Changes since the hash_lock patch:
- Leave br_fdb_update() unchanged (Nikolay).
- Sashiko's finding on that patch, a deletion that races the locked
  roam, has no counterpart here: DSA looks the entry up when it handles
  each event and treats a deleted entry as gone.
- Of the three findings it lists as pre-existing, the MAB and
  BR_FDB_LOCAL ones are in the bridge, which this series does not
  change; the peer-site one, a "bridge fdb replace" onto a DSA user port
  that notifies no deletion, is handled in patch 2.

Link: https://lore.kernel.org/netdev/20261004124254.3525496-1-julius@bairaktaris.de/
Link: https://lore.kernel.org/netdev/cover.1794134495.git.julius@bairaktaris.de/

I used Claude (Anthropic) to help write these patches.

Julius Bairaktaris (2):
  net: bridge: switchdev: add br_switchdev_fdb_find_port()
  net: dsa: fix host fdb refcount when a bridge fdb entry roams

 include/linux/if_bridge.h |  14 ++
 include/net/dsa.h         |   4 +-
 net/bridge/br_switchdev.c |  72 +++++++-
 net/dsa/port.c            |  50 ++++--
 net/dsa/port.h            |  26 +--
 net/dsa/user.c            | 353 +++++++++++++++++++++++++++++++++++---
 net/dsa/user.h            |  22 +++
 7 files changed, 473 insertions(+), 68 deletions(-)


base-commit: 6964ff21c5d8b75649211a52dbfd92753e605649
-- 
2.53.0


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

end of thread, other threads:[~2026-11-14 22:53 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-11-14 22:53 [PATCH net-next v2 0/2] net: dsa: fix host fdb refcount when an entry roams Julius Bairaktaris
2026-11-14 22:53 ` [PATCH net-next v2 1/2] net: bridge: switchdev: add br_switchdev_fdb_find_port() Julius Bairaktaris
2026-11-14 22:53 ` [PATCH net-next v2 2/2] net: dsa: fix host fdb refcount when a bridge fdb entry roams Julius Bairaktaris

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.