diff options
author | Marek Lindner <lindner_marek@yahoo.de> | 2011-01-19 15:01:42 -0500 |
---|---|---|
committer | Marek Lindner <lindner_marek@yahoo.de> | 2011-03-05 06:50:00 -0500 |
commit | 2ae2daf6c3f23364862a7d4f2ca79eab041b701b (patch) | |
tree | 8b4c15f4c7733d9d1d3aa58fd80b6f998b9eca2c /net/batman-adv | |
parent | 16b1aba849eeb45d51a5de731cf103143439ffe1 (diff) |
batman-adv: protect ogm counter arrays with spinlock
Signed-off-by: Marek Lindner <lindner_marek@yahoo.de>
Diffstat (limited to 'net/batman-adv')
-rw-r--r-- | net/batman-adv/originator.c | 11 | ||||
-rw-r--r-- | net/batman-adv/routing.c | 27 | ||||
-rw-r--r-- | net/batman-adv/types.h | 1 |
3 files changed, 33 insertions, 6 deletions
diff --git a/net/batman-adv/originator.c b/net/batman-adv/originator.c index fcdb0b7fe586..71dfc24e961b 100644 --- a/net/batman-adv/originator.c +++ b/net/batman-adv/originator.c | |||
@@ -207,6 +207,7 @@ struct orig_node *get_orig_node(struct bat_priv *bat_priv, uint8_t *addr) | |||
207 | return NULL; | 207 | return NULL; |
208 | 208 | ||
209 | INIT_HLIST_HEAD(&orig_node->neigh_list); | 209 | INIT_HLIST_HEAD(&orig_node->neigh_list); |
210 | spin_lock_init(&orig_node->ogm_cnt_lock); | ||
210 | spin_lock_init(&orig_node->neigh_list_lock); | 211 | spin_lock_init(&orig_node->neigh_list_lock); |
211 | kref_init(&orig_node->refcount); | 212 | kref_init(&orig_node->refcount); |
212 | 213 | ||
@@ -517,7 +518,7 @@ int orig_hash_add_if(struct batman_if *batman_if, int max_if_num) | |||
517 | struct hlist_head *head; | 518 | struct hlist_head *head; |
518 | struct element_t *bucket; | 519 | struct element_t *bucket; |
519 | struct orig_node *orig_node; | 520 | struct orig_node *orig_node; |
520 | int i; | 521 | int i, ret; |
521 | 522 | ||
522 | /* resize all orig nodes because orig_node->bcast_own(_sum) depend on | 523 | /* resize all orig nodes because orig_node->bcast_own(_sum) depend on |
523 | * if_num */ | 524 | * if_num */ |
@@ -530,7 +531,11 @@ int orig_hash_add_if(struct batman_if *batman_if, int max_if_num) | |||
530 | hlist_for_each_entry_rcu(bucket, walk, head, hlist) { | 531 | hlist_for_each_entry_rcu(bucket, walk, head, hlist) { |
531 | orig_node = bucket->data; | 532 | orig_node = bucket->data; |
532 | 533 | ||
533 | if (orig_node_add_if(orig_node, max_if_num) == -1) | 534 | spin_lock_bh(&orig_node->ogm_cnt_lock); |
535 | ret = orig_node_add_if(orig_node, max_if_num); | ||
536 | spin_unlock_bh(&orig_node->ogm_cnt_lock); | ||
537 | |||
538 | if (ret == -1) | ||
534 | goto err; | 539 | goto err; |
535 | } | 540 | } |
536 | rcu_read_unlock(); | 541 | rcu_read_unlock(); |
@@ -619,8 +624,10 @@ int orig_hash_del_if(struct batman_if *batman_if, int max_if_num) | |||
619 | hlist_for_each_entry_rcu(bucket, walk, head, hlist) { | 624 | hlist_for_each_entry_rcu(bucket, walk, head, hlist) { |
620 | orig_node = bucket->data; | 625 | orig_node = bucket->data; |
621 | 626 | ||
627 | spin_lock_bh(&orig_node->ogm_cnt_lock); | ||
622 | ret = orig_node_del_if(orig_node, max_if_num, | 628 | ret = orig_node_del_if(orig_node, max_if_num, |
623 | batman_if->if_num); | 629 | batman_if->if_num); |
630 | spin_unlock_bh(&orig_node->ogm_cnt_lock); | ||
624 | 631 | ||
625 | if (ret == -1) | 632 | if (ret == -1) |
626 | goto err; | 633 | goto err; |
diff --git a/net/batman-adv/routing.c b/net/batman-adv/routing.c index 1c31a0e9f90a..7627ebe50c4b 100644 --- a/net/batman-adv/routing.c +++ b/net/batman-adv/routing.c | |||
@@ -55,12 +55,14 @@ void slide_own_bcast_window(struct batman_if *batman_if) | |||
55 | rcu_read_lock(); | 55 | rcu_read_lock(); |
56 | hlist_for_each_entry_rcu(bucket, walk, head, hlist) { | 56 | hlist_for_each_entry_rcu(bucket, walk, head, hlist) { |
57 | orig_node = bucket->data; | 57 | orig_node = bucket->data; |
58 | spin_lock_bh(&orig_node->ogm_cnt_lock); | ||
58 | word_index = batman_if->if_num * NUM_WORDS; | 59 | word_index = batman_if->if_num * NUM_WORDS; |
59 | word = &(orig_node->bcast_own[word_index]); | 60 | word = &(orig_node->bcast_own[word_index]); |
60 | 61 | ||
61 | bit_get_packet(bat_priv, word, 1, 0); | 62 | bit_get_packet(bat_priv, word, 1, 0); |
62 | orig_node->bcast_own_sum[batman_if->if_num] = | 63 | orig_node->bcast_own_sum[batman_if->if_num] = |
63 | bit_packet_count(word); | 64 | bit_packet_count(word); |
65 | spin_unlock_bh(&orig_node->ogm_cnt_lock); | ||
64 | } | 66 | } |
65 | rcu_read_unlock(); | 67 | rcu_read_unlock(); |
66 | } | 68 | } |
@@ -278,8 +280,10 @@ static void update_orig(struct bat_priv *bat_priv, | |||
278 | char is_duplicate) | 280 | char is_duplicate) |
279 | { | 281 | { |
280 | struct neigh_node *neigh_node = NULL, *tmp_neigh_node = NULL; | 282 | struct neigh_node *neigh_node = NULL, *tmp_neigh_node = NULL; |
283 | struct orig_node *orig_node_tmp; | ||
281 | struct hlist_node *node; | 284 | struct hlist_node *node; |
282 | int tmp_hna_buff_len; | 285 | int tmp_hna_buff_len; |
286 | uint8_t bcast_own_sum_orig, bcast_own_sum_neigh; | ||
283 | 287 | ||
284 | bat_dbg(DBG_BATMAN, bat_priv, "update_originator(): " | 288 | bat_dbg(DBG_BATMAN, bat_priv, "update_originator(): " |
285 | "Searching and updating originator entry of received packet\n"); | 289 | "Searching and updating originator entry of received packet\n"); |
@@ -351,10 +355,22 @@ static void update_orig(struct bat_priv *bat_priv, | |||
351 | /* if the TQ is the same and the link not more symetric we | 355 | /* if the TQ is the same and the link not more symetric we |
352 | * won't consider it either */ | 356 | * won't consider it either */ |
353 | if ((orig_node->router) && | 357 | if ((orig_node->router) && |
354 | ((neigh_node->tq_avg == orig_node->router->tq_avg) && | 358 | (neigh_node->tq_avg == orig_node->router->tq_avg)) { |
355 | (orig_node->router->orig_node->bcast_own_sum[if_incoming->if_num] | 359 | orig_node_tmp = orig_node->router->orig_node; |
356 | >= neigh_node->orig_node->bcast_own_sum[if_incoming->if_num]))) | 360 | spin_lock_bh(&orig_node_tmp->ogm_cnt_lock); |
357 | goto update_hna; | 361 | bcast_own_sum_orig = |
362 | orig_node_tmp->bcast_own_sum[if_incoming->if_num]; | ||
363 | spin_unlock_bh(&orig_node_tmp->ogm_cnt_lock); | ||
364 | |||
365 | orig_node_tmp = neigh_node->orig_node; | ||
366 | spin_lock_bh(&orig_node_tmp->ogm_cnt_lock); | ||
367 | bcast_own_sum_neigh = | ||
368 | orig_node_tmp->bcast_own_sum[if_incoming->if_num]; | ||
369 | spin_unlock_bh(&orig_node_tmp->ogm_cnt_lock); | ||
370 | |||
371 | if (bcast_own_sum_orig >= bcast_own_sum_neigh) | ||
372 | goto update_hna; | ||
373 | } | ||
358 | 374 | ||
359 | update_routes(bat_priv, orig_node, neigh_node, | 375 | update_routes(bat_priv, orig_node, neigh_node, |
360 | hna_buff, tmp_hna_buff_len); | 376 | hna_buff, tmp_hna_buff_len); |
@@ -705,10 +721,13 @@ void receive_bat_packet(struct ethhdr *ethhdr, | |||
705 | batman_packet->orig) && | 721 | batman_packet->orig) && |
706 | (batman_packet->seqno - if_incoming_seqno + 2 == 0)) { | 722 | (batman_packet->seqno - if_incoming_seqno + 2 == 0)) { |
707 | offset = if_incoming->if_num * NUM_WORDS; | 723 | offset = if_incoming->if_num * NUM_WORDS; |
724 | |||
725 | spin_lock_bh(&orig_neigh_node->ogm_cnt_lock); | ||
708 | word = &(orig_neigh_node->bcast_own[offset]); | 726 | word = &(orig_neigh_node->bcast_own[offset]); |
709 | bit_mark(word, 0); | 727 | bit_mark(word, 0); |
710 | orig_neigh_node->bcast_own_sum[if_incoming->if_num] = | 728 | orig_neigh_node->bcast_own_sum[if_incoming->if_num] = |
711 | bit_packet_count(word); | 729 | bit_packet_count(word); |
730 | spin_unlock_bh(&orig_neigh_node->ogm_cnt_lock); | ||
712 | } | 731 | } |
713 | 732 | ||
714 | bat_dbg(DBG_BATMAN, bat_priv, "Drop packet: " | 733 | bat_dbg(DBG_BATMAN, bat_priv, "Drop packet: " |
diff --git a/net/batman-adv/types.h b/net/batman-adv/types.h index ca4d42d05912..ff70afc376da 100644 --- a/net/batman-adv/types.h +++ b/net/batman-adv/types.h | |||
@@ -89,6 +89,7 @@ struct orig_node { | |||
89 | struct kref refcount; | 89 | struct kref refcount; |
90 | struct bat_priv *bat_priv; | 90 | struct bat_priv *bat_priv; |
91 | unsigned long last_frag_packet; | 91 | unsigned long last_frag_packet; |
92 | spinlock_t ogm_cnt_lock; /* protects ogm counter */ | ||
92 | struct { | 93 | struct { |
93 | uint8_t candidates; | 94 | uint8_t candidates; |
94 | struct neigh_node *selected; | 95 | struct neigh_node *selected; |