From: Sven Eckelmann Date: Tue, 12 May 2026 17:37:05 +0000 (+0200) Subject: batman-adv: replace non-atomic mesh state with (READ|WRITE)_ONCE X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=2b2450e3266ad01feb5ad0adb6ec3cd5b830c511;p=thirdparty%2Flinux.git batman-adv: replace non-atomic mesh state with (READ|WRITE)_ONCE The mesh state is only accessed as plain loads/stores and does not require full atomic_t semantics. Convert to an enum and replace its users with READ_ONCE()/WRITE_ONCE() to avoid load/store tearing. Signed-off-by: Sven Eckelmann --- diff --git a/net/batman-adv/bat_iv_ogm.c b/net/batman-adv/bat_iv_ogm.c index df8e64588e1e..c436b77674a5 100644 --- a/net/batman-adv/bat_iv_ogm.c +++ b/net/batman-adv/bat_iv_ogm.c @@ -1777,7 +1777,7 @@ static void batadv_iv_send_outstanding_bat_ogm_packet(struct work_struct *work) delayed_work); bat_priv = netdev_priv(forw_packet->if_incoming->mesh_iface); - if (atomic_read(&bat_priv->mesh_state) == BATADV_MESH_DEACTIVATING) { + if (READ_ONCE(bat_priv->mesh_state) == BATADV_MESH_DEACTIVATING) { dropped = true; goto out; } diff --git a/net/batman-adv/bat_v_elp.c b/net/batman-adv/bat_v_elp.c index 0190fafcbed2..d53485d17220 100644 --- a/net/batman-adv/bat_v_elp.c +++ b/net/batman-adv/bat_v_elp.c @@ -307,7 +307,7 @@ static void batadv_v_elp_periodic_work(struct work_struct *work) hard_iface = container_of(bat_v, struct batadv_hard_iface, bat_v); bat_priv = netdev_priv(hard_iface->mesh_iface); - if (atomic_read(&bat_priv->mesh_state) == BATADV_MESH_DEACTIVATING) + if (READ_ONCE(bat_priv->mesh_state) == BATADV_MESH_DEACTIVATING) goto out; /* we are in the process of shutting this interface down */ diff --git a/net/batman-adv/bat_v_ogm.c b/net/batman-adv/bat_v_ogm.c index f4cd8cad97e0..b337bd8e58e7 100644 --- a/net/batman-adv/bat_v_ogm.c +++ b/net/batman-adv/bat_v_ogm.c @@ -279,7 +279,7 @@ static void batadv_v_ogm_send_meshif(struct batadv_priv *bat_priv) lockdep_assert_held(&bat_priv->bat_v.ogm_buff_mutex); - if (atomic_read(&bat_priv->mesh_state) == BATADV_MESH_DEACTIVATING) + if (READ_ONCE(bat_priv->mesh_state) == BATADV_MESH_DEACTIVATING) goto out; ogm_buff = &bat_priv->bat_v.ogm_buff; diff --git a/net/batman-adv/main.c b/net/batman-adv/main.c index a5398c5df263..60d4f60066c8 100644 --- a/net/batman-adv/main.c +++ b/net/batman-adv/main.c @@ -200,31 +200,31 @@ int batadv_mesh_init(struct net_device *mesh_iface) ret = batadv_originator_init(bat_priv); if (ret < 0) { - atomic_set(&bat_priv->mesh_state, BATADV_MESH_DEACTIVATING); + WRITE_ONCE(bat_priv->mesh_state, BATADV_MESH_DEACTIVATING); goto err_orig; } ret = batadv_tt_init(bat_priv); if (ret < 0) { - atomic_set(&bat_priv->mesh_state, BATADV_MESH_DEACTIVATING); + WRITE_ONCE(bat_priv->mesh_state, BATADV_MESH_DEACTIVATING); goto err_tt; } ret = batadv_v_mesh_init(bat_priv); if (ret < 0) { - atomic_set(&bat_priv->mesh_state, BATADV_MESH_DEACTIVATING); + WRITE_ONCE(bat_priv->mesh_state, BATADV_MESH_DEACTIVATING); goto err_v; } ret = batadv_bla_init(bat_priv); if (ret < 0) { - atomic_set(&bat_priv->mesh_state, BATADV_MESH_DEACTIVATING); + WRITE_ONCE(bat_priv->mesh_state, BATADV_MESH_DEACTIVATING); goto err_bla; } ret = batadv_dat_init(bat_priv); if (ret < 0) { - atomic_set(&bat_priv->mesh_state, BATADV_MESH_DEACTIVATING); + WRITE_ONCE(bat_priv->mesh_state, BATADV_MESH_DEACTIVATING); goto err_dat; } @@ -232,7 +232,7 @@ int batadv_mesh_init(struct net_device *mesh_iface) batadv_mcast_init(bat_priv); atomic_set(&bat_priv->gw.reselect, 0); - atomic_set(&bat_priv->mesh_state, BATADV_MESH_ACTIVE); + WRITE_ONCE(bat_priv->mesh_state, BATADV_MESH_ACTIVE); return 0; @@ -246,7 +246,7 @@ err_tt: batadv_originator_free(bat_priv); err_orig: batadv_purge_outstanding_packets(bat_priv, NULL); - atomic_set(&bat_priv->mesh_state, BATADV_MESH_INACTIVE); + WRITE_ONCE(bat_priv->mesh_state, BATADV_MESH_INACTIVE); return ret; } @@ -259,7 +259,7 @@ void batadv_mesh_free(struct net_device *mesh_iface) { struct batadv_priv *bat_priv = netdev_priv(mesh_iface); - atomic_set(&bat_priv->mesh_state, BATADV_MESH_DEACTIVATING); + WRITE_ONCE(bat_priv->mesh_state, BATADV_MESH_DEACTIVATING); batadv_purge_outstanding_packets(bat_priv, NULL); batadv_tp_stop_all(bat_priv); @@ -290,7 +290,7 @@ void batadv_mesh_free(struct net_device *mesh_iface) free_percpu(bat_priv->bat_counters); bat_priv->bat_counters = NULL; - atomic_set(&bat_priv->mesh_state, BATADV_MESH_INACTIVE); + WRITE_ONCE(bat_priv->mesh_state, BATADV_MESH_INACTIVE); } /** @@ -454,7 +454,7 @@ int batadv_batman_skb_recv(struct sk_buff *skb, struct net_device *dev, bat_priv = netdev_priv(hard_iface->mesh_iface); - if (atomic_read(&bat_priv->mesh_state) != BATADV_MESH_ACTIVE) + if (READ_ONCE(bat_priv->mesh_state) != BATADV_MESH_ACTIVE) goto err_free; /* discard frames on not active interfaces */ diff --git a/net/batman-adv/mesh-interface.c b/net/batman-adv/mesh-interface.c index 58cbb4f8a5ab..7497f307c10d 100644 --- a/net/batman-adv/mesh-interface.c +++ b/net/batman-adv/mesh-interface.c @@ -125,7 +125,7 @@ static int batadv_interface_set_mac_addr(struct net_device *dev, void *p) eth_hw_addr_set(dev, addr->sa_data); /* only modify transtable if it has been initialized before */ - if (atomic_read(&bat_priv->mesh_state) != BATADV_MESH_ACTIVE) + if (READ_ONCE(bat_priv->mesh_state) != BATADV_MESH_ACTIVE) return 0; rcu_read_lock(); @@ -192,7 +192,7 @@ static netdev_tx_t batadv_interface_tx(struct sk_buff *skb, int network_offset = ETH_HLEN; __be16 proto; - if (atomic_read(&bat_priv->mesh_state) != BATADV_MESH_ACTIVE) + if (READ_ONCE(bat_priv->mesh_state) != BATADV_MESH_ACTIVE) goto dropped; /* reset control block to avoid left overs from previous users */ @@ -783,7 +783,7 @@ static int batadv_meshif_init_late(struct net_device *dev) atomic_set(&bat_priv->bcast_queue_left, BATADV_BCAST_QUEUE_LEN); atomic_set(&bat_priv->batman_queue_left, BATADV_BATMAN_QUEUE_LEN); - atomic_set(&bat_priv->mesh_state, BATADV_MESH_INACTIVE); + WRITE_ONCE(bat_priv->mesh_state, BATADV_MESH_INACTIVE); atomic_set(&bat_priv->bcast_seqno, 1); atomic_set(&bat_priv->tt.vn, 0); atomic_set(&bat_priv->tt.ogm_append_cnt, 0); diff --git a/net/batman-adv/send.c b/net/batman-adv/send.c index 62ae98eef81e..c7e86c83242a 100644 --- a/net/batman-adv/send.c +++ b/net/batman-adv/send.c @@ -1047,7 +1047,7 @@ static void batadv_send_outstanding_bcast_packet(struct work_struct *work) delayed_work); bat_priv = netdev_priv(forw_packet->if_incoming->mesh_iface); - if (atomic_read(&bat_priv->mesh_state) == BATADV_MESH_DEACTIVATING) { + if (READ_ONCE(bat_priv->mesh_state) == BATADV_MESH_DEACTIVATING) { dropped = true; goto out; } diff --git a/net/batman-adv/tp_meter.c b/net/batman-adv/tp_meter.c index 0fc4ca78e84e..aefe757277b2 100644 --- a/net/batman-adv/tp_meter.c +++ b/net/batman-adv/tp_meter.c @@ -999,7 +999,7 @@ void batadv_tp_start(struct batadv_priv *bat_priv, const u8 *dst, /* look for an already existing test towards this node */ spin_lock_bh(&bat_priv->tp_list_lock); - if (atomic_read(&bat_priv->mesh_state) != BATADV_MESH_ACTIVE) { + if (READ_ONCE(bat_priv->mesh_state) != BATADV_MESH_ACTIVE) { spin_unlock_bh(&bat_priv->tp_list_lock); batadv_tp_batctl_error_notify(BATADV_TP_REASON_DST_UNREACHABLE, dst, bat_priv, session_cookie); @@ -1387,7 +1387,7 @@ batadv_tp_init_recv(struct batadv_priv *bat_priv, struct batadv_tp_vars *tp_vars = NULL; spin_lock_bh(&bat_priv->tp_list_lock); - if (atomic_read(&bat_priv->mesh_state) != BATADV_MESH_ACTIVE) + if (READ_ONCE(bat_priv->mesh_state) != BATADV_MESH_ACTIVE) goto out_unlock; tp_vars = batadv_tp_list_find_session(bat_priv, icmp->orig, @@ -1518,7 +1518,7 @@ void batadv_tp_meter_recv(struct batadv_priv *bat_priv, struct sk_buff *skb) { struct batadv_icmp_tp_packet *icmp; - if (atomic_read(&bat_priv->mesh_state) != BATADV_MESH_ACTIVE) + if (READ_ONCE(bat_priv->mesh_state) != BATADV_MESH_ACTIVE) goto out; icmp = (struct batadv_icmp_tp_packet *)skb->data; diff --git a/net/batman-adv/types.h b/net/batman-adv/types.h index cf01a670d825..58375c0a643b 100644 --- a/net/batman-adv/types.h +++ b/net/batman-adv/types.h @@ -1504,7 +1504,7 @@ struct batadv_priv { * @mesh_state: current status of the mesh * (inactive/active/deactivating) */ - atomic_t mesh_state; + enum batadv_mesh_state mesh_state; /** @mesh_iface: net device which holds this struct as private data */ struct net_device *mesh_iface;