diff options
author | Marek Lindner <lindner_marek@yahoo.de> | 2011-01-19 15:01:40 -0500 |
---|---|---|
committer | Marek Lindner <lindner_marek@yahoo.de> | 2011-03-05 06:49:58 -0500 |
commit | fb778ea173fcd58b8fc3d75c674f07fab187b55f (patch) | |
tree | b14cfc99b7ca61ddcb49cc56c9a8e2822675debc /net/batman-adv/vis.c | |
parent | a775eb847ae66211577d4fd2c46749b77c9993c9 (diff) |
batman-adv: protect each hash row with rcu locks
Signed-off-by: Marek Lindner <lindner_marek@yahoo.de>
Diffstat (limited to 'net/batman-adv/vis.c')
-rw-r--r-- | net/batman-adv/vis.c | 18 |
1 files changed, 14 insertions, 4 deletions
diff --git a/net/batman-adv/vis.c b/net/batman-adv/vis.c index a77b773b0868..8092eadcbdee 100644 --- a/net/batman-adv/vis.c +++ b/net/batman-adv/vis.c | |||
@@ -380,8 +380,10 @@ static struct vis_info *add_packet(struct bat_priv *bat_priv, | |||
380 | sizeof(struct vis_packet)); | 380 | sizeof(struct vis_packet)); |
381 | 381 | ||
382 | memcpy(search_packet->vis_orig, vis_packet->vis_orig, ETH_ALEN); | 382 | memcpy(search_packet->vis_orig, vis_packet->vis_orig, ETH_ALEN); |
383 | rcu_read_lock(); | ||
383 | old_info = hash_find(bat_priv->vis_hash, vis_info_cmp, vis_info_choose, | 384 | old_info = hash_find(bat_priv->vis_hash, vis_info_cmp, vis_info_choose, |
384 | &search_elem); | 385 | &search_elem); |
386 | rcu_read_unlock(); | ||
385 | kfree_skb(search_elem.skb_packet); | 387 | kfree_skb(search_elem.skb_packet); |
386 | 388 | ||
387 | if (old_info) { | 389 | if (old_info) { |
@@ -540,7 +542,8 @@ static int find_best_vis_server(struct bat_priv *bat_priv, | |||
540 | for (i = 0; i < hash->size; i++) { | 542 | for (i = 0; i < hash->size; i++) { |
541 | head = &hash->table[i]; | 543 | head = &hash->table[i]; |
542 | 544 | ||
543 | hlist_for_each_entry(bucket, walk, head, hlist) { | 545 | rcu_read_lock(); |
546 | hlist_for_each_entry_rcu(bucket, walk, head, hlist) { | ||
544 | orig_node = bucket->data; | 547 | orig_node = bucket->data; |
545 | if ((orig_node) && (orig_node->router) && | 548 | if ((orig_node) && (orig_node->router) && |
546 | (orig_node->flags & VIS_SERVER) && | 549 | (orig_node->flags & VIS_SERVER) && |
@@ -550,6 +553,7 @@ static int find_best_vis_server(struct bat_priv *bat_priv, | |||
550 | ETH_ALEN); | 553 | ETH_ALEN); |
551 | } | 554 | } |
552 | } | 555 | } |
556 | rcu_read_unlock(); | ||
553 | } | 557 | } |
554 | 558 | ||
555 | return best_tq; | 559 | return best_tq; |
@@ -605,7 +609,8 @@ static int generate_vis_packet(struct bat_priv *bat_priv) | |||
605 | for (i = 0; i < hash->size; i++) { | 609 | for (i = 0; i < hash->size; i++) { |
606 | head = &hash->table[i]; | 610 | head = &hash->table[i]; |
607 | 611 | ||
608 | hlist_for_each_entry(bucket, walk, head, hlist) { | 612 | rcu_read_lock(); |
613 | hlist_for_each_entry_rcu(bucket, walk, head, hlist) { | ||
609 | orig_node = bucket->data; | 614 | orig_node = bucket->data; |
610 | neigh_node = orig_node->router; | 615 | neigh_node = orig_node->router; |
611 | 616 | ||
@@ -632,10 +637,12 @@ static int generate_vis_packet(struct bat_priv *bat_priv) | |||
632 | packet->entries++; | 637 | packet->entries++; |
633 | 638 | ||
634 | if (vis_packet_full(info)) { | 639 | if (vis_packet_full(info)) { |
640 | rcu_read_unlock(); | ||
635 | spin_unlock_bh(&bat_priv->orig_hash_lock); | 641 | spin_unlock_bh(&bat_priv->orig_hash_lock); |
636 | return 0; | 642 | return 0; |
637 | } | 643 | } |
638 | } | 644 | } |
645 | rcu_read_unlock(); | ||
639 | } | 646 | } |
640 | 647 | ||
641 | spin_unlock_bh(&bat_priv->orig_hash_lock); | 648 | spin_unlock_bh(&bat_priv->orig_hash_lock); |
@@ -721,7 +728,8 @@ static void broadcast_vis_packet(struct bat_priv *bat_priv, | |||
721 | for (i = 0; i < hash->size; i++) { | 728 | for (i = 0; i < hash->size; i++) { |
722 | head = &hash->table[i]; | 729 | head = &hash->table[i]; |
723 | 730 | ||
724 | hlist_for_each_entry(bucket, walk, head, hlist) { | 731 | rcu_read_lock(); |
732 | hlist_for_each_entry_rcu(bucket, walk, head, hlist) { | ||
725 | orig_node = bucket->data; | 733 | orig_node = bucket->data; |
726 | 734 | ||
727 | /* if it's a vis server and reachable, send it. */ | 735 | /* if it's a vis server and reachable, send it. */ |
@@ -746,7 +754,7 @@ static void broadcast_vis_packet(struct bat_priv *bat_priv, | |||
746 | 754 | ||
747 | spin_lock_bh(&bat_priv->orig_hash_lock); | 755 | spin_lock_bh(&bat_priv->orig_hash_lock); |
748 | } | 756 | } |
749 | 757 | rcu_read_unlock(); | |
750 | } | 758 | } |
751 | 759 | ||
752 | spin_unlock_bh(&bat_priv->orig_hash_lock); | 760 | spin_unlock_bh(&bat_priv->orig_hash_lock); |
@@ -763,9 +771,11 @@ static void unicast_vis_packet(struct bat_priv *bat_priv, | |||
763 | 771 | ||
764 | spin_lock_bh(&bat_priv->orig_hash_lock); | 772 | spin_lock_bh(&bat_priv->orig_hash_lock); |
765 | packet = (struct vis_packet *)info->skb_packet->data; | 773 | packet = (struct vis_packet *)info->skb_packet->data; |
774 | rcu_read_lock(); | ||
766 | orig_node = ((struct orig_node *)hash_find(bat_priv->orig_hash, | 775 | orig_node = ((struct orig_node *)hash_find(bat_priv->orig_hash, |
767 | compare_orig, choose_orig, | 776 | compare_orig, choose_orig, |
768 | packet->target_orig)); | 777 | packet->target_orig)); |
778 | rcu_read_unlock(); | ||
769 | 779 | ||
770 | if ((!orig_node) || (!orig_node->router)) | 780 | if ((!orig_node) || (!orig_node->router)) |
771 | goto out; | 781 | goto out; |