aboutsummaryrefslogtreecommitdiffstats
path: root/net/tipc
diff options
context:
space:
mode:
Diffstat (limited to 'net/tipc')
-rw-r--r--net/tipc/bcast.c9
-rw-r--r--net/tipc/bearer.c18
-rw-r--r--net/tipc/bearer.h4
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
52struct tipc_bearer *bearer_list[MAX_BEARERS + 1]; 52struct tipc_bearer __rcu *bearer_list[MAX_BEARERS + 1];
53 53
54static void bearer_disable(struct tipc_bearer *b_ptr, bool shutting_down); 54static 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
396int tipc_disable_bearer(const char *name) 396int 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
151struct tipc_link; 153struct tipc_link;
152 154
153extern struct tipc_bearer *bearer_list[]; 155extern 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