diff options
author | Ying Xue <ying.xue@windriver.com> | 2014-04-20 22:55:45 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2014-04-22 21:17:52 -0400 |
commit | f8322dfce5766c8e26d9224cbcaf6fdc0b2eb04d (patch) | |
tree | 9631ad1e81d63e7199350788f997733a5eb873e9 /net/tipc | |
parent | f97e455abf0d83b7d69da295163db18e3ebb4d8b (diff) |
tipc: convert bearer_list to RCU list
Convert bearer_list to RCU list. It's protected by RTNL lock on
update side, and RCU read lock is applied to read side.
Signed-off-by: Ying Xue <ying.xue@windriver.com>
Reviewed-by: Jon Maloy <jon.maloy@ericsson.com>
Reviewed-by: Erik Hugne <erik.hugne@ericsson.com>
Tested-by: Erik Hugne <erik.hugne@ericsson.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/tipc')
-rw-r--r-- | net/tipc/bcast.c | 9 | ||||
-rw-r--r-- | net/tipc/bearer.c | 18 | ||||
-rw-r--r-- | net/tipc/bearer.h | 4 |
3 files changed, 18 insertions, 13 deletions
diff --git a/net/tipc/bcast.c b/net/tipc/bcast.c index 95ab5ef92920..223a19929024 100644 --- a/net/tipc/bcast.c +++ b/net/tipc/bcast.c | |||
@@ -659,6 +659,7 @@ void tipc_bcbearer_sort(void) | |||
659 | { | 659 | { |
660 | struct tipc_bcbearer_pair *bp_temp = bcbearer->bpairs_temp; | 660 | struct tipc_bcbearer_pair *bp_temp = bcbearer->bpairs_temp; |
661 | struct tipc_bcbearer_pair *bp_curr; | 661 | struct tipc_bcbearer_pair *bp_curr; |
662 | struct tipc_bearer *b; | ||
662 | int b_index; | 663 | int b_index; |
663 | int pri; | 664 | int pri; |
664 | 665 | ||
@@ -667,8 +668,9 @@ void tipc_bcbearer_sort(void) | |||
667 | /* Group bearers by priority (can assume max of two per priority) */ | 668 | /* Group bearers by priority (can assume max of two per priority) */ |
668 | memset(bp_temp, 0, sizeof(bcbearer->bpairs_temp)); | 669 | memset(bp_temp, 0, sizeof(bcbearer->bpairs_temp)); |
669 | 670 | ||
671 | rcu_read_lock(); | ||
670 | for (b_index = 0; b_index < MAX_BEARERS; b_index++) { | 672 | for (b_index = 0; b_index < MAX_BEARERS; b_index++) { |
671 | struct tipc_bearer *b = bearer_list[b_index]; | 673 | b = rcu_dereference_rtnl(bearer_list[b_index]); |
672 | if (!b || !b->nodes.count) | 674 | if (!b || !b->nodes.count) |
673 | continue; | 675 | continue; |
674 | 676 | ||
@@ -677,6 +679,7 @@ void tipc_bcbearer_sort(void) | |||
677 | else | 679 | else |
678 | bp_temp[b->priority].secondary = b; | 680 | bp_temp[b->priority].secondary = b; |
679 | } | 681 | } |
682 | rcu_read_unlock(); | ||
680 | 683 | ||
681 | /* Create array of bearer pairs for broadcasting */ | 684 | /* Create array of bearer pairs for broadcasting */ |
682 | bp_curr = bcbearer->bpairs; | 685 | bp_curr = bcbearer->bpairs; |
@@ -784,7 +787,7 @@ void tipc_bclink_init(void) | |||
784 | bcl->max_pkt = MAX_PKT_DEFAULT_MCAST; | 787 | bcl->max_pkt = MAX_PKT_DEFAULT_MCAST; |
785 | tipc_link_set_queue_limits(bcl, BCLINK_WIN_DEFAULT); | 788 | tipc_link_set_queue_limits(bcl, BCLINK_WIN_DEFAULT); |
786 | bcl->b_ptr = &bcbearer->bearer; | 789 | bcl->b_ptr = &bcbearer->bearer; |
787 | bearer_list[BCBEARER] = &bcbearer->bearer; | 790 | rcu_assign_pointer(bearer_list[MAX_BEARERS], &bcbearer->bearer); |
788 | bcl->state = WORKING_WORKING; | 791 | bcl->state = WORKING_WORKING; |
789 | strlcpy(bcl->name, tipc_bclink_name, TIPC_MAX_LINK_NAME); | 792 | strlcpy(bcl->name, tipc_bclink_name, TIPC_MAX_LINK_NAME); |
790 | } | 793 | } |
@@ -795,7 +798,7 @@ void tipc_bclink_stop(void) | |||
795 | tipc_link_purge_queues(bcl); | 798 | tipc_link_purge_queues(bcl); |
796 | spin_unlock_bh(&bc_lock); | 799 | spin_unlock_bh(&bc_lock); |
797 | 800 | ||
798 | bearer_list[BCBEARER] = NULL; | 801 | RCU_INIT_POINTER(bearer_list[BCBEARER], NULL); |
799 | memset(bclink, 0, sizeof(*bclink)); | 802 | memset(bclink, 0, sizeof(*bclink)); |
800 | memset(bcbearer, 0, sizeof(*bcbearer)); | 803 | memset(bcbearer, 0, sizeof(*bcbearer)); |
801 | } | 804 | } |
diff --git a/net/tipc/bearer.c b/net/tipc/bearer.c index dfb4c7fe4865..65b17639e43d 100644 --- a/net/tipc/bearer.c +++ b/net/tipc/bearer.c | |||
@@ -49,7 +49,7 @@ static struct tipc_media * const media_info_array[] = { | |||
49 | NULL | 49 | NULL |
50 | }; | 50 | }; |
51 | 51 | ||
52 | struct tipc_bearer *bearer_list[MAX_BEARERS + 1]; | 52 | struct tipc_bearer __rcu *bearer_list[MAX_BEARERS + 1]; |
53 | 53 | ||
54 | static void bearer_disable(struct tipc_bearer *b_ptr, bool shutting_down); | 54 | static void bearer_disable(struct tipc_bearer *b_ptr, bool shutting_down); |
55 | 55 | ||
@@ -178,7 +178,7 @@ struct tipc_bearer *tipc_bearer_find(const char *name) | |||
178 | u32 i; | 178 | u32 i; |
179 | 179 | ||
180 | for (i = 0; i < MAX_BEARERS; i++) { | 180 | for (i = 0; i < MAX_BEARERS; i++) { |
181 | b_ptr = bearer_list[i]; | 181 | b_ptr = rtnl_dereference(bearer_list[i]); |
182 | if (b_ptr && (!strcmp(b_ptr->name, name))) | 182 | if (b_ptr && (!strcmp(b_ptr->name, name))) |
183 | return b_ptr; | 183 | return b_ptr; |
184 | } | 184 | } |
@@ -201,7 +201,7 @@ struct sk_buff *tipc_bearer_get_names(void) | |||
201 | read_lock_bh(&tipc_net_lock); | 201 | read_lock_bh(&tipc_net_lock); |
202 | for (i = 0; media_info_array[i] != NULL; i++) { | 202 | for (i = 0; media_info_array[i] != NULL; i++) { |
203 | for (j = 0; j < MAX_BEARERS; j++) { | 203 | for (j = 0; j < MAX_BEARERS; j++) { |
204 | b = bearer_list[j]; | 204 | b = rtnl_dereference(bearer_list[j]); |
205 | if (!b) | 205 | if (!b) |
206 | continue; | 206 | continue; |
207 | if (b->media == media_info_array[i]) { | 207 | if (b->media == media_info_array[i]) { |
@@ -287,7 +287,7 @@ restart: | |||
287 | bearer_id = MAX_BEARERS; | 287 | bearer_id = MAX_BEARERS; |
288 | with_this_prio = 1; | 288 | with_this_prio = 1; |
289 | for (i = MAX_BEARERS; i-- != 0; ) { | 289 | for (i = MAX_BEARERS; i-- != 0; ) { |
290 | b_ptr = bearer_list[i]; | 290 | b_ptr = rtnl_dereference(bearer_list[i]); |
291 | if (!b_ptr) { | 291 | if (!b_ptr) { |
292 | bearer_id = i; | 292 | bearer_id = i; |
293 | continue; | 293 | continue; |
@@ -344,7 +344,7 @@ restart: | |||
344 | goto exit; | 344 | goto exit; |
345 | } | 345 | } |
346 | 346 | ||
347 | bearer_list[bearer_id] = b_ptr; | 347 | rcu_assign_pointer(bearer_list[bearer_id], b_ptr); |
348 | 348 | ||
349 | pr_info("Enabled bearer <%s>, discovery domain %s, priority %u\n", | 349 | pr_info("Enabled bearer <%s>, discovery domain %s, priority %u\n", |
350 | name, | 350 | name, |
@@ -385,12 +385,12 @@ static void bearer_disable(struct tipc_bearer *b_ptr, bool shutting_down) | |||
385 | tipc_disc_delete(b_ptr->link_req); | 385 | tipc_disc_delete(b_ptr->link_req); |
386 | 386 | ||
387 | for (i = 0; i < MAX_BEARERS; i++) { | 387 | for (i = 0; i < MAX_BEARERS; i++) { |
388 | if (b_ptr == bearer_list[i]) { | 388 | if (b_ptr == rtnl_dereference(bearer_list[i])) { |
389 | bearer_list[i] = NULL; | 389 | RCU_INIT_POINTER(bearer_list[i], NULL); |
390 | break; | 390 | break; |
391 | } | 391 | } |
392 | } | 392 | } |
393 | kfree(b_ptr); | 393 | kfree_rcu(b_ptr, rcu); |
394 | } | 394 | } |
395 | 395 | ||
396 | int tipc_disable_bearer(const char *name) | 396 | int tipc_disable_bearer(const char *name) |
@@ -628,7 +628,7 @@ void tipc_bearer_stop(void) | |||
628 | u32 i; | 628 | u32 i; |
629 | 629 | ||
630 | for (i = 0; i < MAX_BEARERS; i++) { | 630 | for (i = 0; i < MAX_BEARERS; i++) { |
631 | b_ptr = bearer_list[i]; | 631 | b_ptr = rtnl_dereference(bearer_list[i]); |
632 | if (b_ptr) { | 632 | if (b_ptr) { |
633 | bearer_disable(b_ptr, true); | 633 | bearer_disable(b_ptr, true); |
634 | bearer_list[i] = NULL; | 634 | bearer_list[i] = NULL; |
diff --git a/net/tipc/bearer.h b/net/tipc/bearer.h index ba48145e871d..b67b7ea4cc36 100644 --- a/net/tipc/bearer.h +++ b/net/tipc/bearer.h | |||
@@ -113,6 +113,7 @@ struct tipc_media { | |||
113 | * @name: bearer name (format = media:interface) | 113 | * @name: bearer name (format = media:interface) |
114 | * @media: ptr to media structure associated with bearer | 114 | * @media: ptr to media structure associated with bearer |
115 | * @bcast_addr: media address used in broadcasting | 115 | * @bcast_addr: media address used in broadcasting |
116 | * @rcu: rcu struct for tipc_bearer | ||
116 | * @priority: default link priority for bearer | 117 | * @priority: default link priority for bearer |
117 | * @window: default window size for bearer | 118 | * @window: default window size for bearer |
118 | * @tolerance: default link tolerance for bearer | 119 | * @tolerance: default link tolerance for bearer |
@@ -133,6 +134,7 @@ struct tipc_bearer { | |||
133 | char name[TIPC_MAX_BEARER_NAME]; | 134 | char name[TIPC_MAX_BEARER_NAME]; |
134 | struct tipc_media *media; | 135 | struct tipc_media *media; |
135 | struct tipc_media_addr bcast_addr; | 136 | struct tipc_media_addr bcast_addr; |
137 | struct rcu_head rcu; | ||
136 | u32 priority; | 138 | u32 priority; |
137 | u32 window; | 139 | u32 window; |
138 | u32 tolerance; | 140 | u32 tolerance; |
@@ -150,7 +152,7 @@ struct tipc_bearer_names { | |||
150 | 152 | ||
151 | struct tipc_link; | 153 | struct tipc_link; |
152 | 154 | ||
153 | extern struct tipc_bearer *bearer_list[]; | 155 | extern struct tipc_bearer __rcu *bearer_list[]; |
154 | 156 | ||
155 | /* | 157 | /* |
156 | * TIPC routines available to supported media types | 158 | * TIPC routines available to supported media types |