From: Simon Wunderlich <sw@simonwunderlich.de>
To: netdev@vger.kernel.org
Cc: "David S. Miller" <davem@davemloft.net>,
Eric Dumazet <edumazet@google.com>,
Jakub Kicinski <kuba@kernel.org>, Paolo Abeni <pabeni@redhat.com>,
Simon Horman <horms@kernel.org>,
b.a.t.m.a.n@lists.open-mesh.org,
Sven Eckelmann <sven@narfation.org>,
stable@vger.kernel.org, Sashiko <sashiko-bot@kernel.org>,
Simon Wunderlich <sw@simonwunderlich.de>
Subject: [PATCH net 09/10] batman-adv: tt: don't drop local events queued during TVLV update
Date: Mon, 26 Oct 2026 09:53:08 +0100 [thread overview]
Message-ID: <20261026085309.1074911-10-sw@simonwunderlich.de> (raw)
In-Reply-To: <20261026085309.1074911-1-sw@simonwunderlich.de>
From: Sven Eckelmann <sven@narfation.org>
batadv_tt_tvlv_container_update() read the number of local changes without
holding changes_list_lock. batadv_tt_local_event() is not serialized by
the commit_lock and can queue new events before the changes_list is
flushed:
CPU0 CPU1
batadv_tt_tvlv_container_update()
num = ...local_changes;
batadv_tt_local_event()
list_add_tail(...);
...local_changes++;
spin_lock_bh(&...changes_list_lock);
/* only num events copied but all freed */
The additional events were freed without ever being sent. Other nodes will
only notice this via a CRC mismatch and must request the full table.
The number of changes and the changes_list must therefore be taken
atomically. Events queued afterwards then stay in the tt.changes_list for
the next TT round.
The changes can no longer be kept for the next round when the TVLV buffer
allocation fails. But they would be sent with a skipped TTVN anyway, so the
other nodes have to request the full table in this case either way.
This does not make the TTVN and CRC decisions in
batadv_tt_local_commit_changes_nolock() consistent with the announced
changeset. Events which are queued between these decisions and the
snapshot can still be announced under a TTVN or CRC which doesn't cover
them.
Cc: stable@vger.kernel.org
Reported-by: Sashiko <sashiko-bot@kernel.org>
Closes: https://sashiko.dev/#/bug/linux-fc286ddd-5bed-4683-b842-ee7a307eeb19
Fixes: a73105b8d4c7 ("batman-adv: improved client announcement mechanism")
Signed-off-by: Sven Eckelmann <sven@narfation.org>
Signed-off-by: Simon Wunderlich <sw@simonwunderlich.de>
---
net/batman-adv/translation-table.c | 24 +++++++++++++++++-------
1 file changed, 17 insertions(+), 7 deletions(-)
diff --git a/net/batman-adv/translation-table.c b/net/batman-adv/translation-table.c
index 24054077cf3db..6774484f1c573 100644
--- a/net/batman-adv/translation-table.c
+++ b/net/batman-adv/translation-table.c
@@ -1327,11 +1327,18 @@ static void batadv_tt_tvlv_container_update(struct batadv_priv *bat_priv)
int tt_diff_entries_num = 0;
bool drop_changes = false;
size_t tt_extra_len = 0;
+ LIST_HEAD(changes_list);
int tt_change_len = 0;
int tt_diff_len;
u16 tvlv_len;
+ /* atomically get the list of changes */
+ spin_lock_bh(&bat_priv->tt.changes_list_lock);
+ list_splice_init(&bat_priv->tt.changes_list, &changes_list);
tt_diff_entries_num = READ_ONCE(bat_priv->tt.local_changes);
+ WRITE_ONCE(bat_priv->tt.local_changes, 0);
+ spin_unlock_bh(&bat_priv->tt.changes_list_lock);
+
tt_diff_len = batadv_tt_len(tt_diff_entries_num);
/* if we have too many changes for one packet don't send any
@@ -1349,19 +1356,23 @@ static void batadv_tt_tvlv_container_update(struct batadv_priv *bat_priv)
tvlv_len = batadv_tt_prepare_tvlv_local_data(bat_priv, &tt_data,
&tt_change, &tt_diff_len);
- if (!tvlv_len)
+ if (!tvlv_len) {
+ /* the TTVN of the changes is lost and the other nodes will
+ * have to request the full table anyway
+ */
+ list_for_each_entry_safe(entry, safe, &changes_list, list) {
+ list_del(&entry->list);
+ kmem_cache_free(batadv_tt_change_cache, entry);
+ }
return;
+ }
tt_data->flags = BATADV_TT_OGM_DIFF;
if (!drop_changes && tt_diff_len == 0)
goto container_register;
- spin_lock_bh(&bat_priv->tt.changes_list_lock);
- WRITE_ONCE(bat_priv->tt.local_changes, 0);
-
- list_for_each_entry_safe(entry, safe, &bat_priv->tt.changes_list,
- list) {
+ list_for_each_entry_safe(entry, safe, &changes_list, list) {
if (tt_diff_entries_count < tt_diff_entries_num) {
memcpy(tt_change + tt_diff_entries_count,
&entry->change,
@@ -1371,7 +1382,6 @@ static void batadv_tt_tvlv_container_update(struct batadv_priv *bat_priv)
list_del(&entry->list);
kmem_cache_free(batadv_tt_change_cache, entry);
}
- spin_unlock_bh(&bat_priv->tt.changes_list_lock);
tt_extra_len = batadv_tt_len(tt_diff_entries_num -
tt_diff_entries_count);
--
2.47.3
next prev parent reply other threads:[~2026-10-26 8:53 UTC|newest]
Thread overview: 21+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-10-26 8:52 [PATCH net 00/10] pull request: batman-adv 2026-10-26 Simon Wunderlich
2026-10-26 8:53 ` [PATCH net 01/10] batman-adv: avoid WARN_ON for orig_ifinfo allocation failure Simon Wunderlich
2026-10-26 8:56 ` netdev-bot+sinfo
2026-10-26 8:53 ` [PATCH net 02/10] batman-adv: Close OGM aggregation before transmission Simon Wunderlich
2026-10-27 8:55 ` netdev-bot+sashiko
2026-10-27 12:19 ` Sven Eckelmann
2026-10-26 8:53 ` [PATCH net 03/10] batman-adv: tpmeter: fix u32 truncation of reported bytes Simon Wunderlich
2026-10-26 8:53 ` [PATCH net 04/10] batman-adv: dat: initialize orig_node of unfilled candidate slots Simon Wunderlich
2026-10-26 8:53 ` [PATCH net 05/10] batman-adv: fix skb leak when hard_iface is being released Simon Wunderlich
2026-10-26 8:53 ` [PATCH net 06/10] batman-adv: stop originator purge worker before freeing TT Simon Wunderlich
2026-10-26 8:53 ` [PATCH net 07/10] batman-adv: tt: only transmit local ROAM flag together with DEL Simon Wunderlich
2026-10-27 8:55 ` netdev-bot+sashiko
2026-10-27 12:11 ` Sven Eckelmann
2026-10-26 8:53 ` [PATCH net 08/10] batman-adv: tt: only update flags for TT events Simon Wunderlich
2026-10-29 0:46 ` Jakub Kicinski
2026-10-26 8:53 ` Simon Wunderlich [this message]
2026-10-27 8:55 ` [PATCH net 09/10] batman-adv: tt: don't drop local events queued during TVLV update netdev-bot+sashiko
2026-10-27 13:31 ` Sven Eckelmann
2026-10-26 8:53 ` [PATCH net 10/10] batman-adv: tt: limit local table to single TVLV response size Simon Wunderlich
2026-10-27 8:55 ` netdev-bot+sashiko
2026-10-27 12:35 ` Sven Eckelmann
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20261026085309.1074911-10-sw@simonwunderlich.de \
--to=sw@simonwunderlich.de \
--cc=b.a.t.m.a.n@lists.open-mesh.org \
--cc=davem@davemloft.net \
--cc=edumazet@google.com \
--cc=horms@kernel.org \
--cc=kuba@kernel.org \
--cc=netdev@vger.kernel.org \
--cc=pabeni@redhat.com \
--cc=sashiko-bot@kernel.org \
--cc=stable@vger.kernel.org \
--cc=sven@narfation.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox