Skip to content

Commit 6a4f30e

Browse files
committed
batman-adv: replace non-atomic meshif config fields with (READ|WRITE)_ONCE
The meshif configuration values are only accessed as plain loads/stores and do not require full atomic_t semantics. Convert these fields to native integer types and replace their users with READ_ONCE()/WRITE_ONCE() to avoid load/store tearing. Signed-off-by: Sven Eckelmann <sven@narfation.org>
1 parent c055946 commit 6a4f30e

16 files changed

Lines changed: 127 additions & 121 deletions

net/batman-adv/bat_iv_ogm.c

Lines changed: 15 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
#include <linux/bug.h>
1414
#include <linux/byteorder/generic.h>
1515
#include <linux/cache.h>
16+
#include <linux/compiler.h>
1617
#include <linux/container_of.h>
1718
#include <linux/errno.h>
1819
#include <linux/etherdevice.h>
@@ -274,7 +275,7 @@ batadv_iv_ogm_emit_send_time(const struct batadv_priv *bat_priv)
274275
{
275276
unsigned int msecs;
276277

277-
msecs = atomic_read(&bat_priv->orig_interval) - BATADV_JITTER;
278+
msecs = READ_ONCE(bat_priv->orig_interval) - BATADV_JITTER;
278279
msecs += get_random_u32_below(2 * BATADV_JITTER);
279280

280281
return jiffies + msecs_to_jiffies(msecs);
@@ -289,7 +290,7 @@ static unsigned long batadv_iv_ogm_fwd_send_time(void)
289290
/* apply hop penalty for a normal link */
290291
static u8 batadv_hop_penalty(u8 tq, const struct batadv_priv *bat_priv)
291292
{
292-
int hop_penalty = atomic_read(&bat_priv->hop_penalty);
293+
int hop_penalty = READ_ONCE(bat_priv->hop_penalty);
293294
int new_tq;
294295

295296
new_tq = tq * (BATADV_TQ_MAX_VALUE - hop_penalty);
@@ -555,7 +556,7 @@ static bool batadv_iv_ogm_aggregate_new(const unsigned char *packet_buff,
555556
unsigned int skb_size;
556557
atomic_t *queue_left = own_packet ? NULL : &bat_priv->batman_queue_left;
557558

558-
if (atomic_read(&bat_priv->aggregated_ogms))
559+
if (READ_ONCE(bat_priv->aggregated_ogms))
559560
skb_size = max_t(unsigned int, BATADV_MAX_AGGREGATION_BYTES,
560561
packet_len);
561562
else
@@ -641,15 +642,18 @@ static bool batadv_iv_ogm_queue_add(struct batadv_priv *bat_priv,
641642
struct batadv_ogm_packet *batadv_ogm_packet;
642643
bool direct_link;
643644
unsigned long max_aggregation_jiffies;
645+
bool aggregated_ogms;
644646

645647
batadv_ogm_packet = (struct batadv_ogm_packet *)packet_buff;
646648
direct_link = !!(batadv_ogm_packet->flags & BATADV_DIRECTLINK);
647649
max_aggregation_jiffies = msecs_to_jiffies(BATADV_MAX_AGGREGATION_MS);
648650

649651
/* find position for the packet in the forward queue */
650652
spin_lock_bh(&bat_priv->forw_bat_list_lock);
653+
aggregated_ogms = READ_ONCE(bat_priv->aggregated_ogms);
654+
651655
/* own packets are not to be aggregated */
652-
if (atomic_read(&bat_priv->aggregated_ogms) && !own_packet) {
656+
if (aggregated_ogms && !own_packet) {
653657
hlist_for_each_entry(forw_packet_pos,
654658
&bat_priv->forw_bat_list, list) {
655659
if (batadv_iv_ogm_can_aggregate(batadv_ogm_packet,
@@ -675,7 +679,7 @@ static bool batadv_iv_ogm_queue_add(struct batadv_priv *bat_priv,
675679
* we hold it back for a while, so that it might be aggregated
676680
* later on
677681
*/
678-
if (!own_packet && atomic_read(&bat_priv->aggregated_ogms))
682+
if (!own_packet && aggregated_ogms)
679683
send_time += max_aggregation_jiffies;
680684

681685
return batadv_iv_ogm_aggregate_new(packet_buff, packet_len,
@@ -888,7 +892,7 @@ static void batadv_iv_ogm_schedule_buff(struct batadv_hard_iface *hard_iface)
888892
*/
889893
queue_delayed_work(batadv_event_workqueue,
890894
&hard_iface->bat_iv.reschedule_work,
891-
msecs_to_jiffies(atomic_read(&bat_priv->orig_interval)));
895+
msecs_to_jiffies(READ_ONCE(bat_priv->orig_interval)));
892896
}
893897

894898
batadv_hardif_put(primary_if);
@@ -2321,7 +2325,7 @@ static void batadv_iv_iface_enabled(struct batadv_hard_iface *hard_iface)
23212325
static void batadv_iv_init_sel_class(struct batadv_priv *bat_priv)
23222326
{
23232327
/* set default TQ difference threshold to 20 */
2324-
atomic_set(&bat_priv->gw.sel_class, 20);
2328+
WRITE_ONCE(bat_priv->gw.sel_class, 20);
23252329
}
23262330

23272331
static struct batadv_gw_node *
@@ -2353,7 +2357,7 @@ batadv_iv_gw_get_best_gw_node(struct batadv_priv *bat_priv)
23532357

23542358
tq_avg = router_ifinfo->bat_iv.tq_avg;
23552359

2356-
switch (atomic_read(&bat_priv->gw.sel_class)) {
2360+
switch (READ_ONCE(bat_priv->gw.sel_class)) {
23572361
case 1: /* fast connection */
23582362
tmp_gw_factor = tq_avg * tq_avg;
23592363
tmp_gw_factor *= gw_node->bandwidth_down;
@@ -2407,13 +2411,14 @@ static bool batadv_iv_gw_is_eligible(struct batadv_priv *bat_priv,
24072411
{
24082412
struct batadv_neigh_ifinfo *router_orig_ifinfo = NULL;
24092413
struct batadv_neigh_ifinfo *router_gw_ifinfo = NULL;
2414+
u32 sel_class = READ_ONCE(bat_priv->gw.sel_class);
24102415
struct batadv_neigh_node *router_gw = NULL;
24112416
struct batadv_neigh_node *router_orig = NULL;
24122417
u8 gw_tq_avg, orig_tq_avg;
24132418
bool ret = false;
24142419

24152420
/* dynamic re-election is performed only on fast or late switch */
2416-
if (atomic_read(&bat_priv->gw.sel_class) <= 2)
2421+
if (sel_class <= 2)
24172422
return false;
24182423

24192424
router_gw = batadv_orig_router_get(curr_gw_orig, BATADV_IF_DEFAULT);
@@ -2448,8 +2453,7 @@ static bool batadv_iv_gw_is_eligible(struct batadv_priv *bat_priv,
24482453
/* if the routing class is greater than 3 the value tells us how much
24492454
* greater the TQ value of the new gateway must be
24502455
*/
2451-
if ((atomic_read(&bat_priv->gw.sel_class) > 3) &&
2452-
(orig_tq_avg - gw_tq_avg < atomic_read(&bat_priv->gw.sel_class)))
2456+
if (sel_class > 3 && orig_tq_avg - gw_tq_avg < sel_class)
24532457
goto out;
24542458

24552459
batadv_dbg(BATADV_DBG_BATMAN, bat_priv,

net/batman-adv/bat_v.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99

1010
#include <linux/atomic.h>
1111
#include <linux/cache.h>
12+
#include <linux/compiler.h>
1213
#include <linux/errno.h>
1314
#include <linux/if_ether.h>
1415
#include <linux/init.h>
@@ -505,7 +506,7 @@ static bool batadv_v_neigh_is_sob(struct batadv_neigh_node *neigh1,
505506
static void batadv_v_init_sel_class(struct batadv_priv *bat_priv)
506507
{
507508
/* set default throughput difference threshold to 5Mbps */
508-
atomic_set(&bat_priv->gw.sel_class, 50);
509+
WRITE_ONCE(bat_priv->gw.sel_class, 50);
509510
}
510511

511512
/**
@@ -602,7 +603,7 @@ static bool batadv_v_gw_is_eligible(struct batadv_priv *bat_priv,
602603
u32 gw_throughput, orig_throughput, threshold;
603604
bool ret = false;
604605

605-
threshold = atomic_read(&bat_priv->gw.sel_class);
606+
threshold = READ_ONCE(bat_priv->gw.sel_class);
606607

607608
curr_gw = batadv_gw_node_get(bat_priv, curr_gw_orig);
608609
if (!curr_gw) {

net/batman-adv/bat_v_ogm.c

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
#include <linux/atomic.h>
1111
#include <linux/bug.h>
1212
#include <linux/byteorder/generic.h>
13+
#include <linux/compiler.h>
1314
#include <linux/container_of.h>
1415
#include <linux/errno.h>
1516
#include <linux/etherdevice.h>
@@ -106,7 +107,7 @@ static void batadv_v_ogm_start_timer(struct batadv_priv *bat_priv)
106107
if (delayed_work_pending(&bat_priv->bat_v.ogm_wq))
107108
return;
108109

109-
msecs = atomic_read(&bat_priv->orig_interval) - BATADV_JITTER;
110+
msecs = READ_ONCE(bat_priv->orig_interval) - BATADV_JITTER;
110111
msecs += get_random_u32_below(2 * BATADV_JITTER);
111112
queue_delayed_work(batadv_event_workqueue, &bat_priv->bat_v.ogm_wq,
112113
msecs_to_jiffies(msecs));
@@ -247,7 +248,7 @@ static void batadv_v_ogm_queue_on_if(struct batadv_priv *bat_priv,
247248
return;
248249
}
249250

250-
if (!atomic_read(&bat_priv->aggregated_ogms)) {
251+
if (!READ_ONCE(bat_priv->aggregated_ogms)) {
251252
batadv_v_ogm_send_to_if(bat_priv, skb, hard_iface);
252253
return;
253254
}
@@ -486,7 +487,7 @@ static u32 batadv_v_forward_penalty(struct batadv_priv *bat_priv,
486487
u32 throughput)
487488
{
488489
int if_hop_penalty = atomic_read(&if_incoming->hop_penalty);
489-
int hop_penalty = atomic_read(&bat_priv->hop_penalty);
490+
int hop_penalty = READ_ONCE(bat_priv->hop_penalty);
490491
int hop_penalty_max = BATADV_TQ_MAX_VALUE;
491492

492493
/* Apply per hardif hop penalty */

net/batman-adv/bridge_loop_avoidance.c

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1380,7 +1380,7 @@ void batadv_bla_update_orig_address(struct batadv_priv *bat_priv,
13801380
bat_priv->bla.claim_dest.group = group;
13811381

13821382
/* purge everything when bridge loop avoidance is turned off */
1383-
if (!atomic_read(&bat_priv->bridge_loop_avoidance))
1383+
if (!READ_ONCE(bat_priv->bridge_loop_avoidance))
13841384
oldif = NULL;
13851385

13861386
if (!oldif) {
@@ -1484,7 +1484,7 @@ static void batadv_bla_periodic_work(struct work_struct *work)
14841484
batadv_bla_purge_claims(bat_priv, primary_if, 0);
14851485
batadv_bla_purge_backbone_gw(bat_priv, 0);
14861486

1487-
if (!atomic_read(&bat_priv->bridge_loop_avoidance))
1487+
if (!READ_ONCE(bat_priv->bridge_loop_avoidance))
14881488
goto out;
14891489

14901490
if (atomic_dec_and_test(&bat_priv->bla.loopdetect_next)) {
@@ -1783,7 +1783,7 @@ bool batadv_bla_is_backbone_gw_orig(struct batadv_priv *bat_priv, u8 *orig,
17831783
struct batadv_bla_backbone_gw *backbone_gw;
17841784
int i;
17851785

1786-
if (!atomic_read(&bat_priv->bridge_loop_avoidance))
1786+
if (!READ_ONCE(bat_priv->bridge_loop_avoidance))
17871787
return false;
17881788

17891789
if (!hash)
@@ -1821,7 +1821,7 @@ bool batadv_bla_is_backbone_gw(struct sk_buff *skb,
18211821
struct batadv_bla_backbone_gw *backbone_gw;
18221822
unsigned short vid;
18231823

1824-
if (!atomic_read(&orig_node->bat_priv->bridge_loop_avoidance))
1824+
if (!READ_ONCE(orig_node->bat_priv->bridge_loop_avoidance))
18251825
return false;
18261826

18271827
/* first, find out the vid. */
@@ -1953,7 +1953,7 @@ bool batadv_bla_rx(struct batadv_priv *bat_priv, struct sk_buff *skb,
19531953
if (!primary_if)
19541954
goto handled;
19551955

1956-
if (!atomic_read(&bat_priv->bridge_loop_avoidance))
1956+
if (!READ_ONCE(bat_priv->bridge_loop_avoidance))
19571957
goto allow;
19581958

19591959
if (batadv_bla_loopdetect_check(bat_priv, skb, primary_if, vid))
@@ -2085,7 +2085,7 @@ bool batadv_bla_tx(struct batadv_priv *bat_priv, struct sk_buff *skb,
20852085
if (!primary_if)
20862086
goto out;
20872087

2088-
if (!atomic_read(&bat_priv->bridge_loop_avoidance))
2088+
if (!READ_ONCE(bat_priv->bridge_loop_avoidance))
20892089
goto allow;
20902090

20912091
if (batadv_bla_process_claim(bat_priv, primary_if, skb))
@@ -2505,7 +2505,7 @@ bool batadv_bla_check_claim(struct batadv_priv *bat_priv,
25052505
struct batadv_hard_iface *primary_if = NULL;
25062506
bool ret = true;
25072507

2508-
if (!atomic_read(&bat_priv->bridge_loop_avoidance))
2508+
if (!READ_ONCE(bat_priv->bridge_loop_avoidance))
25092509
return ret;
25102510

25112511
primary_if = batadv_primary_if_get_selected(bat_priv);

net/batman-adv/distributed-arp-table.c

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -743,7 +743,7 @@ static void batadv_dat_tvlv_container_update(struct batadv_priv *bat_priv)
743743
{
744744
char dat_mode;
745745

746-
dat_mode = atomic_read(&bat_priv->distributed_arp_table);
746+
dat_mode = READ_ONCE(bat_priv->distributed_arp_table);
747747

748748
switch (dat_mode) {
749749
case 0:
@@ -1139,7 +1139,7 @@ bool batadv_dat_snoop_outgoing_arp_request(struct batadv_priv *bat_priv,
11391139
int hdr_size = 0;
11401140
unsigned short vid;
11411141

1142-
if (!atomic_read(&bat_priv->distributed_arp_table))
1142+
if (!READ_ONCE(bat_priv->distributed_arp_table))
11431143
goto out;
11441144

11451145
vid = batadv_dat_get_vid(skb, &hdr_size);
@@ -1234,7 +1234,7 @@ bool batadv_dat_snoop_incoming_arp_request(struct batadv_priv *bat_priv,
12341234
unsigned short vid;
12351235
int err;
12361236

1237-
if (!atomic_read(&bat_priv->distributed_arp_table))
1237+
if (!READ_ONCE(bat_priv->distributed_arp_table))
12381238
goto out;
12391239

12401240
vid = batadv_dat_get_vid(skb, &hdr_size);
@@ -1296,7 +1296,7 @@ void batadv_dat_snoop_outgoing_arp_reply(struct batadv_priv *bat_priv,
12961296
int hdr_size = 0;
12971297
unsigned short vid;
12981298

1299-
if (!atomic_read(&bat_priv->distributed_arp_table))
1299+
if (!READ_ONCE(bat_priv->distributed_arp_table))
13001300
return;
13011301

13021302
vid = batadv_dat_get_vid(skb, &hdr_size);
@@ -1344,7 +1344,7 @@ bool batadv_dat_snoop_incoming_arp_reply(struct batadv_priv *bat_priv,
13441344
bool dropped = false;
13451345
unsigned short vid;
13461346

1347-
if (!atomic_read(&bat_priv->distributed_arp_table))
1347+
if (!READ_ONCE(bat_priv->distributed_arp_table))
13481348
goto out;
13491349

13501350
vid = batadv_dat_get_vid(skb, &hdr_size);
@@ -1714,7 +1714,7 @@ void batadv_dat_snoop_outgoing_dhcp_ack(struct batadv_priv *bat_priv,
17141714
u8 chaddr[BATADV_DHCP_CHADDR_LEN];
17151715
__be32 ip_src, yiaddr;
17161716

1717-
if (!atomic_read(&bat_priv->distributed_arp_table))
1717+
if (!READ_ONCE(bat_priv->distributed_arp_table))
17181718
return;
17191719

17201720
if (!batadv_dat_check_dhcp_ack(skb, proto, &ip_src, chaddr, &yiaddr))
@@ -1744,7 +1744,7 @@ void batadv_dat_snoop_incoming_dhcp_ack(struct batadv_priv *bat_priv,
17441744
__be16 proto;
17451745
u8 *hw_src;
17461746

1747-
if (!atomic_read(&bat_priv->distributed_arp_table))
1747+
if (!READ_ONCE(bat_priv->distributed_arp_table))
17481748
return;
17491749

17501750
if (unlikely(!pskb_may_pull(skb, hdr_size + ETH_HLEN)))
@@ -1789,7 +1789,7 @@ bool batadv_dat_drop_broadcast_packet(struct batadv_priv *bat_priv,
17891789
int hdr_size = sizeof(struct batadv_bcast_packet);
17901790
unsigned short vid;
17911791

1792-
if (!atomic_read(&bat_priv->distributed_arp_table))
1792+
if (!READ_ONCE(bat_priv->distributed_arp_table))
17931793
goto out;
17941794

17951795
/* If this packet is an ARP_REQUEST and the node already has the

net/batman-adv/gateway_client.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -171,7 +171,7 @@ void batadv_gw_check_client_stop(struct batadv_priv *bat_priv)
171171
{
172172
struct batadv_gw_node *curr_gw;
173173

174-
if (atomic_read(&bat_priv->gw.mode) != BATADV_GW_MODE_CLIENT)
174+
if (READ_ONCE(bat_priv->gw.mode) != BATADV_GW_MODE_CLIENT)
175175
return;
176176

177177
curr_gw = batadv_gw_get_selected_gw_node(bat_priv);
@@ -203,7 +203,7 @@ void batadv_gw_election(struct batadv_priv *bat_priv)
203203
struct batadv_neigh_ifinfo *router_ifinfo = NULL;
204204
char gw_addr[18] = { '\0' };
205205

206-
if (atomic_read(&bat_priv->gw.mode) != BATADV_GW_MODE_CLIENT)
206+
if (READ_ONCE(bat_priv->gw.mode) != BATADV_GW_MODE_CLIENT)
207207
goto out;
208208

209209
if (!bat_priv->algo_ops->gw.get_best_gw_node)
@@ -703,7 +703,7 @@ bool batadv_gw_out_of_range(struct batadv_priv *bat_priv,
703703
if (!gw_node)
704704
goto out;
705705

706-
switch (atomic_read(&bat_priv->gw.mode)) {
706+
switch (READ_ONCE(bat_priv->gw.mode)) {
707707
case BATADV_GW_MODE_SERVER:
708708
/* If we are a GW then we are our best GW. We can artificially
709709
* set the tq towards ourself as the maximum value

net/batman-adv/gateway_common.c

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,8 @@
77
#include "gateway_common.h"
88
#include "main.h"
99

10-
#include <linux/atomic.h>
1110
#include <linux/byteorder/generic.h>
11+
#include <linux/compiler.h>
1212
#include <linux/stddef.h>
1313
#include <linux/types.h>
1414
#include <uapi/linux/batadv_packet.h>
@@ -25,19 +25,19 @@
2525
void batadv_gw_tvlv_container_update(struct batadv_priv *bat_priv)
2626
{
2727
struct batadv_tvlv_gateway_data gw;
28+
enum batadv_gw_modes gw_mode;
2829
u32 down, up;
29-
char gw_mode;
3030

31-
gw_mode = atomic_read(&bat_priv->gw.mode);
31+
gw_mode = READ_ONCE(bat_priv->gw.mode);
3232

3333
switch (gw_mode) {
3434
case BATADV_GW_MODE_OFF:
3535
case BATADV_GW_MODE_CLIENT:
3636
batadv_tvlv_container_unregister(bat_priv, BATADV_TVLV_GW, 1);
3737
break;
3838
case BATADV_GW_MODE_SERVER:
39-
down = atomic_read(&bat_priv->gw.bandwidth_down);
40-
up = atomic_read(&bat_priv->gw.bandwidth_up);
39+
down = READ_ONCE(bat_priv->gw.bandwidth_down);
40+
up = READ_ONCE(bat_priv->gw.bandwidth_up);
4141
gw.bandwidth_down = htonl(down);
4242
gw.bandwidth_up = htonl(up);
4343
batadv_tvlv_container_register(bat_priv, BATADV_TVLV_GW, 1,
@@ -83,7 +83,7 @@ static void batadv_gw_tvlv_ogm_handler_v1(struct batadv_priv *bat_priv,
8383

8484
/* restart gateway selection */
8585
if (gateway.bandwidth_down != 0 &&
86-
atomic_read(&bat_priv->gw.mode) == BATADV_GW_MODE_CLIENT)
86+
READ_ONCE(bat_priv->gw.mode) == BATADV_GW_MODE_CLIENT)
8787
batadv_gw_check_election(bat_priv, orig);
8888
}
8989

@@ -96,7 +96,7 @@ void batadv_gw_init(struct batadv_priv *bat_priv)
9696
if (bat_priv->algo_ops->gw.init_sel_class)
9797
bat_priv->algo_ops->gw.init_sel_class(bat_priv);
9898
else
99-
atomic_set(&bat_priv->gw.sel_class, 1);
99+
WRITE_ONCE(bat_priv->gw.sel_class, 1);
100100

101101
batadv_tvlv_handler_register(bat_priv, batadv_gw_tvlv_ogm_handler_v1,
102102
NULL, NULL, BATADV_TVLV_GW, 1,

0 commit comments

Comments
 (0)