Bug #474
Updated by Sven Eckelmann about 2 months ago
https://netdev-ai.bots.linux.dev/sashiko/#/patchset/20260831135117.574836-1-sw%40simonwunderlich.de?part=12 https://netdev-ai.bots.linux.dev/sashiko/#/patchset/20260831135117.574836-1-sw%40simonwunderlich.de?part=10 > Can deferring batadv_tt_global_del_orig_list() until after flags_lock is > dropped lose an originator entry added in between? > > The old code purged the originator list first and cleared > BATADV_TT_CLIENT_TEMP / BATADV_TT_CLIENT_ROAM afterwards, so a second > context still saw the flag and did its own purge. Now the cleared flag is > published before the list is wiped: <pre> CPU0 batadv_tt_global_add() CPU1 batadv_tt_global_add() spin_lock_bh(&common->flags_lock); delete = true; common->flags &= ~BATADV_TT_CLIENT_TEMP; spin_unlock_bh(&common->flags_lock); spin_lock_bh(&common->flags_lock); /* TEMP already clear, so * delete stays false */ spin_unlock_bh(&common->flags_lock); batadv_tt_global_orig_entry_add() batadv_tt_global_del_orig_list() /* drops every orig entry, * including CPU1's fresh one */ </pre> > batadv_tt_global_del_orig_list() takes tt_global_entry->list_lock and > removes all entries: <pre> spin_lock_bh(&tt_global_entry->list_lock); head = &tt_global_entry->orig_list; hlist_for_each_entry_safe(orig_entry, safe, head, list) _batadv_tt_global_del_orig_entry(tt_global_entry, orig_entry); </pre> > Both callers return true in that case, so does the route via CPU1's > originator silently disappear until the next global CRC mismatch triggers > a fresh TT request? batadv_tt_global_add() is reached from received TT > TVLV data (serialized only per originator by orig_node->tt_lock) and from > batadv_tt_add_temporary_global_entry(), so two CPUs can process > announcements for the same client from different originators at the same > time.