Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit f8322dfc authored by Ying Xue's avatar Ying Xue Committed by David S. Miller
Browse files

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: default avatarYing Xue <ying.xue@windriver.com>
Reviewed-by: default avatarJon Maloy <jon.maloy@ericsson.com>
Reviewed-by: default avatarErik Hugne <erik.hugne@ericsson.com>
Tested-by: default avatarErik Hugne <erik.hugne@ericsson.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent f97e455a
Loading
Loading
Loading
Loading
+6 −3
Original line number Diff line number Diff line
@@ -659,6 +659,7 @@ void tipc_bcbearer_sort(void)
{
	struct tipc_bcbearer_pair *bp_temp = bcbearer->bpairs_temp;
	struct tipc_bcbearer_pair *bp_curr;
	struct tipc_bearer *b;
	int b_index;
	int pri;

@@ -667,8 +668,9 @@ void tipc_bcbearer_sort(void)
	/* Group bearers by priority (can assume max of two per priority) */
	memset(bp_temp, 0, sizeof(bcbearer->bpairs_temp));

	rcu_read_lock();
	for (b_index = 0; b_index < MAX_BEARERS; b_index++) {
		struct tipc_bearer *b = bearer_list[b_index];
		b = rcu_dereference_rtnl(bearer_list[b_index]);
		if (!b || !b->nodes.count)
			continue;

@@ -677,6 +679,7 @@ void tipc_bcbearer_sort(void)
		else
			bp_temp[b->priority].secondary = b;
	}
	rcu_read_unlock();

	/* Create array of bearer pairs for broadcasting */
	bp_curr = bcbearer->bpairs;
@@ -784,7 +787,7 @@ void tipc_bclink_init(void)
	bcl->max_pkt = MAX_PKT_DEFAULT_MCAST;
	tipc_link_set_queue_limits(bcl, BCLINK_WIN_DEFAULT);
	bcl->b_ptr = &bcbearer->bearer;
	bearer_list[BCBEARER] = &bcbearer->bearer;
	rcu_assign_pointer(bearer_list[MAX_BEARERS], &bcbearer->bearer);
	bcl->state = WORKING_WORKING;
	strlcpy(bcl->name, tipc_bclink_name, TIPC_MAX_LINK_NAME);
}
@@ -795,7 +798,7 @@ void tipc_bclink_stop(void)
	tipc_link_purge_queues(bcl);
	spin_unlock_bh(&bc_lock);

	bearer_list[BCBEARER] = NULL;
	RCU_INIT_POINTER(bearer_list[BCBEARER], NULL);
	memset(bclink, 0, sizeof(*bclink));
	memset(bcbearer, 0, sizeof(*bcbearer));
}
+9 −9
Original line number Diff line number Diff line
@@ -49,7 +49,7 @@ static struct tipc_media * const media_info_array[] = {
	NULL
};

struct tipc_bearer *bearer_list[MAX_BEARERS + 1];
struct tipc_bearer __rcu *bearer_list[MAX_BEARERS + 1];

static void bearer_disable(struct tipc_bearer *b_ptr, bool shutting_down);

@@ -178,7 +178,7 @@ struct tipc_bearer *tipc_bearer_find(const char *name)
	u32 i;

	for (i = 0; i < MAX_BEARERS; i++) {
		b_ptr = bearer_list[i];
		b_ptr = rtnl_dereference(bearer_list[i]);
		if (b_ptr && (!strcmp(b_ptr->name, name)))
			return b_ptr;
	}
@@ -201,7 +201,7 @@ struct sk_buff *tipc_bearer_get_names(void)
	read_lock_bh(&tipc_net_lock);
	for (i = 0; media_info_array[i] != NULL; i++) {
		for (j = 0; j < MAX_BEARERS; j++) {
			b = bearer_list[j];
			b = rtnl_dereference(bearer_list[j]);
			if (!b)
				continue;
			if (b->media == media_info_array[i]) {
@@ -287,7 +287,7 @@ int tipc_enable_bearer(const char *name, u32 disc_domain, u32 priority)
	bearer_id = MAX_BEARERS;
	with_this_prio = 1;
	for (i = MAX_BEARERS; i-- != 0; ) {
		b_ptr = bearer_list[i];
		b_ptr = rtnl_dereference(bearer_list[i]);
		if (!b_ptr) {
			bearer_id = i;
			continue;
@@ -344,7 +344,7 @@ int tipc_enable_bearer(const char *name, u32 disc_domain, u32 priority)
		goto exit;
	}

	bearer_list[bearer_id] = b_ptr;
	rcu_assign_pointer(bearer_list[bearer_id], b_ptr);

	pr_info("Enabled bearer <%s>, discovery domain %s, priority %u\n",
		name,
@@ -385,12 +385,12 @@ static void bearer_disable(struct tipc_bearer *b_ptr, bool shutting_down)
		tipc_disc_delete(b_ptr->link_req);

	for (i = 0; i < MAX_BEARERS; i++) {
		if (b_ptr == bearer_list[i]) {
			bearer_list[i] = NULL;
		if (b_ptr == rtnl_dereference(bearer_list[i])) {
			RCU_INIT_POINTER(bearer_list[i], NULL);
			break;
		}
	}
	kfree(b_ptr);
	kfree_rcu(b_ptr, rcu);
}

int tipc_disable_bearer(const char *name)
@@ -628,7 +628,7 @@ void tipc_bearer_stop(void)
	u32 i;

	for (i = 0; i < MAX_BEARERS; i++) {
		b_ptr = bearer_list[i];
		b_ptr = rtnl_dereference(bearer_list[i]);
		if (b_ptr) {
			bearer_disable(b_ptr, true);
			bearer_list[i] = NULL;
+3 −1
Original line number Diff line number Diff line
@@ -113,6 +113,7 @@ struct tipc_media {
 * @name: bearer name (format = media:interface)
 * @media: ptr to media structure associated with bearer
 * @bcast_addr: media address used in broadcasting
 * @rcu: rcu struct for tipc_bearer
 * @priority: default link priority for bearer
 * @window: default window size for bearer
 * @tolerance: default link tolerance for bearer
@@ -133,6 +134,7 @@ struct tipc_bearer {
	char name[TIPC_MAX_BEARER_NAME];
	struct tipc_media *media;
	struct tipc_media_addr bcast_addr;
	struct rcu_head rcu;
	u32 priority;
	u32 window;
	u32 tolerance;
@@ -150,7 +152,7 @@ struct tipc_bearer_names {

struct tipc_link;

extern struct tipc_bearer *bearer_list[];
extern struct tipc_bearer __rcu *bearer_list[];

/*
 * TIPC routines available to supported media types