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
