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>
@@ -194,14 +195,17 @@ static int batadv_iv_ogm_iface_enable(struct batadv_hard_iface *hard_iface)
194195 get_random_bytes (& random_seqno , sizeof (random_seqno ));
195196 atomic_set (& hard_iface -> bat_iv .ogm_seqno , random_seqno );
196197
197- hard_iface -> bat_iv .ogm_buff_len = BATADV_OGM_HLEN ;
198- ogm_buff = kmalloc (hard_iface -> bat_iv .ogm_buff_len , GFP_ATOMIC );
198+ hard_iface -> bat_iv .ogm_buff .len = BATADV_OGM_HLEN ;
199+ hard_iface -> bat_iv .ogm_buff .capacity = BATADV_OGM_HLEN ;
200+ hard_iface -> bat_iv .ogm_buff .header_length = BATADV_OGM_HLEN ;
201+
202+ ogm_buff = kmalloc (hard_iface -> bat_iv .ogm_buff .capacity , GFP_ATOMIC );
199203 if (!ogm_buff ) {
200204 mutex_unlock (& hard_iface -> bat_iv .ogm_buff_mutex );
201205 return - ENOMEM ;
202206 }
203207
204- hard_iface -> bat_iv .ogm_buff = ogm_buff ;
208+ hard_iface -> bat_iv .ogm_buff . buf = ogm_buff ;
205209
206210 batadv_ogm_packet = (struct batadv_ogm_packet * )ogm_buff ;
207211 batadv_ogm_packet -> packet_type = BATADV_IV_OGM ;
@@ -220,8 +224,9 @@ static void batadv_iv_ogm_iface_disable(struct batadv_hard_iface *hard_iface)
220224{
221225 mutex_lock (& hard_iface -> bat_iv .ogm_buff_mutex );
222226
223- kfree (hard_iface -> bat_iv .ogm_buff );
224- hard_iface -> bat_iv .ogm_buff = NULL ;
227+ kfree (hard_iface -> bat_iv .ogm_buff .buf );
228+ memset (& hard_iface -> bat_iv .ogm_buff , 0 ,
229+ sizeof (hard_iface -> bat_iv .ogm_buff ));
225230
226231 mutex_unlock (& hard_iface -> bat_iv .ogm_buff_mutex );
227232
@@ -235,7 +240,7 @@ static void batadv_iv_ogm_iface_update_mac(struct batadv_hard_iface *hard_iface)
235240
236241 mutex_lock (& hard_iface -> bat_iv .ogm_buff_mutex );
237242
238- ogm_buff = hard_iface -> bat_iv .ogm_buff ;
243+ ogm_buff = hard_iface -> bat_iv .ogm_buff . buf ;
239244 if (!ogm_buff )
240245 goto unlock ;
241246
@@ -257,7 +262,7 @@ batadv_iv_ogm_primary_iface_set(struct batadv_hard_iface *hard_iface)
257262
258263 mutex_lock (& hard_iface -> bat_iv .ogm_buff_mutex );
259264
260- ogm_buff = hard_iface -> bat_iv .ogm_buff ;
265+ ogm_buff = hard_iface -> bat_iv .ogm_buff . buf ;
261266 if (!ogm_buff )
262267 goto unlock ;
263268
@@ -274,7 +279,7 @@ batadv_iv_ogm_emit_send_time(const struct batadv_priv *bat_priv)
274279{
275280 unsigned int msecs ;
276281
277- msecs = atomic_read ( & bat_priv -> orig_interval ) - BATADV_JITTER ;
282+ msecs = READ_ONCE ( bat_priv -> orig_interval ) - BATADV_JITTER ;
278283 msecs += get_random_u32_below (2 * BATADV_JITTER );
279284
280285 return jiffies + msecs_to_jiffies (msecs );
@@ -289,7 +294,7 @@ static unsigned long batadv_iv_ogm_fwd_send_time(void)
289294/* apply hop penalty for a normal link */
290295static u8 batadv_hop_penalty (u8 tq , const struct batadv_priv * bat_priv )
291296{
292- int hop_penalty = atomic_read ( & bat_priv -> hop_penalty );
297+ int hop_penalty = READ_ONCE ( bat_priv -> hop_penalty );
293298 int new_tq ;
294299
295300 new_tq = tq * (BATADV_TQ_MAX_VALUE - hop_penalty );
@@ -555,7 +560,7 @@ static bool batadv_iv_ogm_aggregate_new(const unsigned char *packet_buff,
555560 unsigned int skb_size ;
556561 atomic_t * queue_left = own_packet ? NULL : & bat_priv -> batman_queue_left ;
557562
558- if (atomic_read ( & bat_priv -> aggregated_ogms ))
563+ if (READ_ONCE ( bat_priv -> aggregated_ogms ))
559564 skb_size = max_t (unsigned int , BATADV_MAX_AGGREGATION_BYTES ,
560565 packet_len );
561566 else
@@ -641,15 +646,18 @@ static bool batadv_iv_ogm_queue_add(struct batadv_priv *bat_priv,
641646 struct batadv_ogm_packet * batadv_ogm_packet ;
642647 bool direct_link ;
643648 unsigned long max_aggregation_jiffies ;
649+ bool aggregated_ogms ;
644650
645651 batadv_ogm_packet = (struct batadv_ogm_packet * )packet_buff ;
646652 direct_link = !!(batadv_ogm_packet -> flags & BATADV_DIRECTLINK );
647653 max_aggregation_jiffies = msecs_to_jiffies (BATADV_MAX_AGGREGATION_MS );
648654
649655 /* find position for the packet in the forward queue */
650656 spin_lock_bh (& bat_priv -> forw_bat_list_lock );
657+ aggregated_ogms = READ_ONCE (bat_priv -> aggregated_ogms );
658+
651659 /* own packets are not to be aggregated */
652- if (atomic_read ( & bat_priv -> aggregated_ogms ) && !own_packet ) {
660+ if (aggregated_ogms && !own_packet ) {
653661 hlist_for_each_entry (forw_packet_pos ,
654662 & bat_priv -> forw_bat_list , list ) {
655663 if (batadv_iv_ogm_can_aggregate (batadv_ogm_packet ,
@@ -675,7 +683,7 @@ static bool batadv_iv_ogm_queue_add(struct batadv_priv *bat_priv,
675683 * we hold it back for a while, so that it might be aggregated
676684 * later on
677685 */
678- if (!own_packet && atomic_read ( & bat_priv -> aggregated_ogms ) )
686+ if (!own_packet && aggregated_ogms )
679687 send_time += max_aggregation_jiffies ;
680688
681689 return batadv_iv_ogm_aggregate_new (packet_buff , packet_len ,
@@ -792,10 +800,9 @@ batadv_iv_ogm_slide_own_bcast_window(struct batadv_hard_iface *hard_iface)
792800static void batadv_iv_ogm_schedule_buff (struct batadv_hard_iface * hard_iface )
793801{
794802 struct batadv_priv * bat_priv = netdev_priv (hard_iface -> mesh_iface );
795- unsigned char * * ogm_buff = & hard_iface -> bat_iv .ogm_buff ;
803+ struct batadv_ogm_buf * ogm_buff = & hard_iface -> bat_iv .ogm_buff ;
796804 struct batadv_ogm_packet * batadv_ogm_packet ;
797805 struct batadv_hard_iface * primary_if , * tmp_hard_iface ;
798- int * ogm_buff_len = & hard_iface -> bat_iv .ogm_buff_len ;
799806 struct list_head * iter ;
800807 u32 seqno ;
801808 u16 tvlv_len = 0 ;
@@ -807,7 +814,7 @@ static void batadv_iv_ogm_schedule_buff(struct batadv_hard_iface *hard_iface)
807814 lockdep_assert_held (& hard_iface -> bat_iv .ogm_buff_mutex );
808815
809816 /* interface already disabled by batadv_iv_ogm_iface_disable */
810- if (!* ogm_buff )
817+ if (!ogm_buff -> buf )
811818 return ;
812819
813820 /* the interface gets activated here to avoid race conditions between
@@ -826,9 +833,7 @@ static void batadv_iv_ogm_schedule_buff(struct batadv_hard_iface *hard_iface)
826833 * appended as it may alter the tt tvlv container
827834 */
828835 batadv_tt_local_commit_changes (bat_priv );
829- ret = batadv_tvlv_container_ogm_append (bat_priv , ogm_buff ,
830- ogm_buff_len ,
831- BATADV_OGM_HLEN );
836+ ret = batadv_tvlv_container_ogm_append (bat_priv , ogm_buff );
832837 if (ret < 0 ) {
833838 reschedule = true;
834839 goto out ;
@@ -837,7 +842,7 @@ static void batadv_iv_ogm_schedule_buff(struct batadv_hard_iface *hard_iface)
837842 tvlv_len = ret ;
838843 }
839844
840- batadv_ogm_packet = ( struct batadv_ogm_packet * )( * ogm_buff ) ;
845+ batadv_ogm_packet = ogm_buff -> buf ;
841846 batadv_ogm_packet -> tvlv_len = htons (tvlv_len );
842847
843848 /* change sequence number to network order */
@@ -853,7 +858,7 @@ static void batadv_iv_ogm_schedule_buff(struct batadv_hard_iface *hard_iface)
853858 /* OGMs from secondary interfaces are only scheduled on their
854859 * respective interfaces.
855860 */
856- scheduled = batadv_iv_ogm_queue_add (bat_priv , * ogm_buff , * ogm_buff_len ,
861+ scheduled = batadv_iv_ogm_queue_add (bat_priv , ogm_buff -> buf , ogm_buff -> len ,
857862 hard_iface , hard_iface , 1 , send_time );
858863 if (!scheduled )
859864 reschedule = true;
@@ -869,8 +874,8 @@ static void batadv_iv_ogm_schedule_buff(struct batadv_hard_iface *hard_iface)
869874 if (!kref_get_unless_zero (& tmp_hard_iface -> refcount ))
870875 continue ;
871876
872- scheduled = batadv_iv_ogm_queue_add (bat_priv , * ogm_buff ,
873- * ogm_buff_len , hard_iface ,
877+ scheduled = batadv_iv_ogm_queue_add (bat_priv , ogm_buff -> buf ,
878+ ogm_buff -> len , hard_iface ,
874879 tmp_hard_iface , 1 , send_time );
875880 batadv_hardif_put (tmp_hard_iface );
876881
@@ -888,7 +893,7 @@ static void batadv_iv_ogm_schedule_buff(struct batadv_hard_iface *hard_iface)
888893 */
889894 queue_delayed_work (batadv_event_workqueue ,
890895 & hard_iface -> bat_iv .reschedule_work ,
891- msecs_to_jiffies (atomic_read ( & bat_priv -> orig_interval )));
896+ msecs_to_jiffies (READ_ONCE ( bat_priv -> orig_interval )));
892897 }
893898
894899 batadv_hardif_put (primary_if );
@@ -1214,7 +1219,7 @@ static bool batadv_iv_ogm_calc_tq(struct batadv_orig_node *orig_node,
12141219 inv_asym_penalty = BATADV_TQ_MAX_VALUE * neigh_rq_inv_cube ;
12151220 inv_asym_penalty /= neigh_rq_max_cube ;
12161221 tq_asym_penalty = BATADV_TQ_MAX_VALUE - inv_asym_penalty ;
1217- tq_iface_hop_penalty -= atomic_read ( & if_incoming -> hop_penalty );
1222+ tq_iface_hop_penalty -= READ_ONCE ( if_incoming -> hop_penalty );
12181223
12191224 /* penalize if the OGM is forwarded on the same interface. WiFi
12201225 * interfaces and other half duplex devices suffer from throughput
@@ -1773,7 +1778,7 @@ static void batadv_iv_send_outstanding_bat_ogm_packet(struct work_struct *work)
17731778 delayed_work );
17741779 bat_priv = netdev_priv (forw_packet -> if_incoming -> mesh_iface );
17751780
1776- if (atomic_read ( & bat_priv -> mesh_state ) == BATADV_MESH_DEACTIVATING ) {
1781+ if (READ_ONCE ( bat_priv -> mesh_state ) == BATADV_MESH_DEACTIVATING ) {
17771782 dropped = true;
17781783 goto out ;
17791784 }
@@ -2321,7 +2326,7 @@ static void batadv_iv_iface_enabled(struct batadv_hard_iface *hard_iface)
23212326static void batadv_iv_init_sel_class (struct batadv_priv * bat_priv )
23222327{
23232328 /* set default TQ difference threshold to 20 */
2324- atomic_set ( & bat_priv -> gw .sel_class , 20 );
2329+ WRITE_ONCE ( bat_priv -> gw .sel_class , 20 );
23252330}
23262331
23272332static struct batadv_gw_node *
@@ -2353,7 +2358,7 @@ batadv_iv_gw_get_best_gw_node(struct batadv_priv *bat_priv)
23532358
23542359 tq_avg = router_ifinfo -> bat_iv .tq_avg ;
23552360
2356- switch (atomic_read ( & bat_priv -> gw .sel_class )) {
2361+ switch (READ_ONCE ( bat_priv -> gw .sel_class )) {
23572362 case 1 : /* fast connection */
23582363 tmp_gw_factor = tq_avg * tq_avg ;
23592364 tmp_gw_factor *= gw_node -> bandwidth_down ;
@@ -2407,13 +2412,14 @@ static bool batadv_iv_gw_is_eligible(struct batadv_priv *bat_priv,
24072412{
24082413 struct batadv_neigh_ifinfo * router_orig_ifinfo = NULL ;
24092414 struct batadv_neigh_ifinfo * router_gw_ifinfo = NULL ;
2415+ u32 sel_class = READ_ONCE (bat_priv -> gw .sel_class );
24102416 struct batadv_neigh_node * router_gw = NULL ;
24112417 struct batadv_neigh_node * router_orig = NULL ;
24122418 u8 gw_tq_avg , orig_tq_avg ;
24132419 bool ret = false;
24142420
24152421 /* dynamic re-election is performed only on fast or late switch */
2416- if (atomic_read ( & bat_priv -> gw . sel_class ) <= 2 )
2422+ if (sel_class <= 2 )
24172423 return false;
24182424
24192425 router_gw = batadv_orig_router_get (curr_gw_orig , BATADV_IF_DEFAULT );
@@ -2448,8 +2454,7 @@ static bool batadv_iv_gw_is_eligible(struct batadv_priv *bat_priv,
24482454 /* if the routing class is greater than 3 the value tells us how much
24492455 * greater the TQ value of the new gateway must be
24502456 */
2451- if ((atomic_read (& bat_priv -> gw .sel_class ) > 3 ) &&
2452- (orig_tq_avg - gw_tq_avg < atomic_read (& bat_priv -> gw .sel_class )))
2457+ if (sel_class > 3 && orig_tq_avg - gw_tq_avg < sel_class )
24532458 goto out ;
24542459
24552460 batadv_dbg (BATADV_DBG_BATMAN , bat_priv ,
0 commit comments