[PATCH batadv v2 7/7] batman-adv: replace non-atomic last_acked with (READ|WRITE)_ONCE

Sven Eckelmann <[email protected]>
Newsgroups org.open-mesh.lists.batman
Message-ID <[email protected]>
The last_acked of a tp_meter transfer is only accessed as plain
loads/stores and does not require full atomic_t semantics. Convert to an
native integer and replace its users with READ_ONCE()/WRITE_ONCE() to avoid
load/store tearing.

Signed-off-by: Sven Eckelmann <[email protected]>
---
 net/batman-adv/tp_meter.c | 22 +++++++++++-----------
 net/batman-adv/types.h    |  2 +-
 2 files changed, 12 insertions(+), 12 deletions(-)

diff --git a/net/batman-adv/tp_meter.c b/net/batman-adv/tp_meter.c
index fef98fbe..ec2b4d72 100644
--- a/net/batman-adv/tp_meter.c
+++ b/net/batman-adv/tp_meter.c
@@ -523,14 +523,14 @@ static void batadv_tp_sender_timeout(struct timer_list *t)
 	batadv_dbg(BATADV_DBG_TP_METER, bat_priv,
 		   "Meter: RTO fired during test towards %pM! cwnd=%u new ss_thr=%u, resetting last_sent to %u\n",
 		   tp_vars->other_end, tp_vars->cwnd, tp_vars->ss_threshold,
-		   atomic_read(&tp_vars->last_acked));
+		   READ_ONCE(tp_vars->last_acked));
 
 	tp_vars->cwnd = BATADV_TP_PLEN * 3;
 
 	spin_unlock_bh(&tp_vars->cwnd_lock);
 
 	/* resend the non-ACKed packets.. */
-	tp_vars->last_sent = atomic_read(&tp_vars->last_acked);
+	tp_vars->last_sent = READ_ONCE(tp_vars->last_acked);
 	wake_up(&tp_vars->more_bytes);
 
 	batadv_tp_reset_sender_timer(tp_vars);
@@ -645,6 +645,7 @@ static void batadv_tp_recv_ack(struct batadv_priv *bat_priv,
 	const unsigned char *dev_addr;
 	size_t packet_len, mss;
 	u32 rtt, recv_ack, cwnd;
+	u32 last_acked;
 
 	packet_len = BATADV_TP_PLEN;
 	mss = BATADV_TP_PLEN;
@@ -665,8 +666,8 @@ static void batadv_tp_recv_ack(struct batadv_priv *bat_priv,
 		goto out;
 
 	/* old ACK? silently drop it.. */
-	if (batadv_seq_before(ntohl(icmp->seqno),
-			      (u32)atomic_read(&tp_vars->last_acked)))
+	last_acked = READ_ONCE(tp_vars->last_acked);
+	if (batadv_seq_before(ntohl(icmp->seqno), last_acked))
 		goto out;
 
 	primary_if = batadv_primary_if_get_selected(bat_priv);
@@ -688,7 +689,7 @@ static void batadv_tp_recv_ack(struct batadv_priv *bat_priv,
 	recv_ack = ntohl(icmp->seqno);
 
 	/* check if this ACK is a duplicate */
-	if (atomic_read(&tp_vars->last_acked) == recv_ack) {
+	if (last_acked == recv_ack) {
 		atomic_inc(&tp_vars->dup_acks);
 		if (atomic_read(&tp_vars->dup_acks) != 3)
 			goto out;
@@ -723,8 +724,7 @@ static void batadv_tp_recv_ack(struct batadv_priv *bat_priv,
 		spin_unlock_bh(&tp_vars->cwnd_lock);
 	} else {
 		/* count the acked data */
-		atomic64_add(recv_ack - atomic_read(&tp_vars->last_acked),
-			     &tp_vars->tot_sent);
+		atomic64_add(recv_ack - last_acked, &tp_vars->tot_sent);
 		/* reset the duplicate ACKs counter */
 		atomic_set(&tp_vars->dup_acks, 0);
 
@@ -756,11 +756,11 @@ static void batadv_tp_recv_ack(struct batadv_priv *bat_priv,
 			goto move_twnd;
 		}
 
-		if (recv_ack - atomic_read(&tp_vars->last_acked) >= mss)
+		if (recv_ack - last_acked >= mss)
 			batadv_tp_update_cwnd(tp_vars, mss);
 move_twnd:
 		/* move the Transmit Window */
-		atomic_set(&tp_vars->last_acked, recv_ack);
+		WRITE_ONCE(tp_vars->last_acked, recv_ack);
 	}
 
 	wake_up(&tp_vars->more_bytes);
@@ -782,7 +782,7 @@ static bool batadv_tp_avail(struct batadv_tp_vars *tp_vars,
 {
 	u32 win_left, win_limit;
 
-	win_limit = atomic_read(&tp_vars->last_acked) + tp_vars->cwnd;
+	win_limit = READ_ONCE(tp_vars->last_acked) + tp_vars->cwnd;
 	win_left = win_limit - tp_vars->last_sent;
 
 	return win_left >= payload_len;
@@ -1011,7 +1011,7 @@ void batadv_tp_start(struct batadv_priv *bat_priv, const u8 *dst,
 	tp_vars->icmp_uid = icmp_uid;
 
 	tp_vars->last_sent = BATADV_TP_FIRST_SEQ;
-	atomic_set(&tp_vars->last_acked, BATADV_TP_FIRST_SEQ);
+	WRITE_ONCE(tp_vars->last_acked, BATADV_TP_FIRST_SEQ);
 	tp_vars->fast_recovery = false;
 	tp_vars->recover = BATADV_TP_FIRST_SEQ;
 
diff --git a/net/batman-adv/types.h b/net/batman-adv/types.h
index 154de214..87a835fe 100644
--- a/net/batman-adv/types.h
+++ b/net/batman-adv/types.h
@@ -1362,7 +1362,7 @@ struct batadv_tp_vars {
 	u32 ss_threshold;
 
 	/** @last_acked: last acked byte */
-	atomic_t last_acked;
+	u32 last_acked;
 
 	/** @last_sent: last sent byte, not yet acked */
 	u32 last_sent;

-- 
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.