[PATCH batadv v2 6/6] batman-adv: tt: don't uncount never committed clients on pending purge

Sven Eckelmann <[email protected]>
Newsgroups org.open-mesh.lists.batman
Message-ID <[email protected]>
batadv_tt_local_purge_pending_clients() decreases vlan->tt.num_entries for
every entry it unlinks, but an entry which still carries
BATADV_TT_CLIENT_NEW was never counted by batadv_tt_local_transition_new().

batadv_tt_local_resize_to_mtu() calls batadv_tt_local_purge() and
batadv_tt_local_purge_pending_clients() directly, without committing in
between, and it halves its timeout down towards zero. Once the timeout is
short enough, batadv_tt_local_purge_list() marks even freshly added clients
as pending. And each of them decreases a counter it never increased.

Consume the BATADV_TT_CLIENT_NEW accounting token here as well, so that the
counter is only decreased for entries which were actually counted.

Signed-off-by: Sven Eckelmann <[email protected]>
---
 net/batman-adv/translation-table.c | 11 ++++++++++-
 1 file changed, 10 insertions(+), 1 deletion(-)

diff --git a/net/batman-adv/translation-table.c b/net/batman-adv/translation-table.c
index 28575051..a0ac7899 100644
--- a/net/batman-adv/translation-table.c
+++ b/net/batman-adv/translation-table.c
@@ -4013,6 +4013,7 @@ static void batadv_tt_local_purge_pending_clients(struct batadv_priv *bat_priv)
 	struct batadv_tt_local_entry *tt_local;
 	struct hlist_node *node_tmp;
 	struct hlist_head *head;
+	u16 old_flags;
 	u32 i;
 
 	if (!hash)
@@ -4033,8 +4034,16 @@ static void batadv_tt_local_purge_pending_clients(struct batadv_priv *bat_priv)
 				   tt_common->addr,
 				   batadv_print_vid(tt_common->vid));
 
-			batadv_tt_local_size_dec(bat_priv, tt_common->vid);
 			hlist_del_rcu(&tt_common->hash_entry);
+
+			/* An entry which still carries BATADV_TT_CLIENT_NEW was
+			 * never counted and must not be uncounted here.
+			 */
+			old_flags = atomic_fetch_andnot(BATADV_TT_CLIENT_NEW,
+							&tt_common->flags);
+			if (!(old_flags & BATADV_TT_CLIENT_NEW))
+				batadv_tt_local_size_dec(bat_priv, tt_common->vid);
+
 			tt_local = container_of(tt_common,
 						struct batadv_tt_local_entry,
 						common);

-- 
2.47.3
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.