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

Reply via email to