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

Commit 21602c7d authored by Amir Shehata's avatar Amir Shehata Committed by Greg Kroah-Hartman
Browse files

staging: lustre: Dynamic LNet Configuration (DLC)



This is the first patch of a set of patches that enables DLC.

This patch adds some cleanup in the config.c as well as some
preparatory changes in peer.c to enable dynamic network
configuration

Signed-off-by: default avatarAmir Shehata <amir.shehata@intel.com>
Intel-bug-id: https://jira.hpdd.intel.com/browse/LU-2456
Change-Id: I8c8bbf3b55acf4d76f22a8be587b553a70d31889
Reviewed-on: http://review.whamcloud.com/9830


Reviewed-by: default avatarLiang Zhen <liang.zhen@intel.com>
Reviewed-by: default avatarJames Simmons <uja.ornl@gmail.com>
Reviewed-by: default avatarOleg Drokin <oleg.drokin@intel.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 4407f610
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -685,7 +685,7 @@ int lnet_parse_networks(struct list_head *nilist, char *networks);
int lnet_nid2peer_locked(lnet_peer_t **lpp, lnet_nid_t nid, int cpt);
lnet_peer_t *lnet_find_peer_locked(struct lnet_peer_table *ptable,
				   lnet_nid_t nid);
void lnet_peer_tables_cleanup(void);
void lnet_peer_tables_cleanup(lnet_ni_t *ni);
void lnet_peer_tables_destroy(void);
int lnet_peer_tables_create(void);
void lnet_debug_peer(lnet_nid_t nid);
+2 −3
Original line number Diff line number Diff line
@@ -351,6 +351,8 @@ typedef struct lnet_peer {
struct lnet_peer_table {
	int			 pt_version;	/* /proc validity stamp */
	int			 pt_number;	/* # peers extant */
	/* # zombies to go to deathrow (and not there yet) */
	int			 pt_zombies;
	struct list_head	 pt_deathrow;	/* zombie peers */
	struct list_head	*pt_hash;	/* NID->peer hash */
};
@@ -616,9 +618,6 @@ typedef struct {
	/* registered LNDs */
	struct list_head		  ln_lnds;

	/* space for network names */
	char				 *ln_network_tokens;
	int				  ln_network_tokens_nob;
	/* test protocol compatibility flags */
	int				  ln_testprotocompat;

+1 −7
Original line number Diff line number Diff line
@@ -892,7 +892,7 @@ lnet_shutdown_lndnis(void)
	 * Clear the peer table and wait for all peers to go (they hold refs on
	 * their NIs)
	 */
	lnet_peer_tables_cleanup();
	lnet_peer_tables_cleanup(NULL);

	lnet_net_lock(LNET_LOCK_EX);
	/*
@@ -952,12 +952,6 @@ lnet_shutdown_lndnis(void)

	the_lnet.ln_shutdown = 0;
	lnet_net_unlock(LNET_LOCK_EX);

	if (the_lnet.ln_network_tokens) {
		LIBCFS_FREE(the_lnet.ln_network_tokens,
			    the_lnet.ln_network_tokens_nob);
		the_lnet.ln_network_tokens = NULL;
	}
}

static int
+25 −4
Original line number Diff line number Diff line
@@ -96,6 +96,8 @@ lnet_net_unique(__u32 net, struct list_head *nilist)
void
lnet_ni_free(struct lnet_ni *ni)
{
	int i;

	if (ni->ni_refs)
		cfs_percpt_free(ni->ni_refs);

@@ -105,6 +107,10 @@ lnet_ni_free(struct lnet_ni *ni)
	if (ni->ni_cpts)
		cfs_expr_list_values_free(ni->ni_cpts, ni->ni_ncpts);

	for (i = 0; i < LNET_MAX_INTERFACES && ni->ni_interfaces[i]; i++) {
		LIBCFS_FREE(ni->ni_interfaces[i],
			    strlen(ni->ni_interfaces[i]) + 1);
	}
	LIBCFS_FREE(ni, sizeof(*ni));
}

@@ -199,8 +205,6 @@ lnet_parse_networks(struct list_head *nilist, char *networks)
		return -ENOMEM;
	}

	the_lnet.ln_network_tokens = tokens;
	the_lnet.ln_network_tokens_nob = tokensize;
	memcpy(tokens, networks, tokensize);
	tmp = tokens;
	str = tokens;
@@ -321,7 +325,23 @@ lnet_parse_networks(struct list_head *nilist, char *networks)
				goto failed;
			}

			ni->ni_interfaces[niface++] = iface;
			/*
			 * Allocate a separate piece of memory and copy
			 * into it the string, so we don't have
			 * a depencency on the tokens string.  This way we
			 * can free the tokens at the end of the function.
			 * The newly allocated ni_interfaces[] can be
			 * freed when freeing the NI
			 */
			LIBCFS_ALLOC(ni->ni_interfaces[niface],
				     strlen(iface) + 1);
			if (!ni->ni_interfaces[niface]) {
				CERROR("Can't allocate net interface name\n");
				goto failed;
			}
			strncpy(ni->ni_interfaces[niface], iface,
				strlen(iface));
			niface++;
			iface = comma;
		} while (iface);

@@ -346,6 +366,8 @@ lnet_parse_networks(struct list_head *nilist, char *networks)
	}

	LASSERT(!list_empty(nilist));

	LIBCFS_FREE(tokens, tokensize);
	return 0;

 failed_syntax:
@@ -362,7 +384,6 @@ lnet_parse_networks(struct list_head *nilist, char *networks)
		cfs_expr_list_free(el);

	LIBCFS_FREE(tokens, tokensize);
	the_lnet.ln_network_tokens = NULL;

	return -EINVAL;
}
+95 −39
Original line number Diff line number Diff line
@@ -103,64 +103,118 @@ lnet_peer_tables_destroy(void)
	the_lnet.ln_peer_tables = NULL;
}

void
lnet_peer_tables_cleanup(void)
static void
lnet_peer_table_cleanup_locked(lnet_ni_t *ni, struct lnet_peer_table *ptable)
{
	struct lnet_peer_table *ptable;
	int i;
	int j;
	lnet_peer_t *lp;
	lnet_peer_t *tmp;

	LASSERT(the_lnet.ln_shutdown);	/* i.e. no new peers */
	for (i = 0; i < LNET_PEER_HASH_SIZE; i++) {
		list_for_each_entry_safe(lp, tmp, &ptable->pt_hash[i],
					 lp_hashlist) {
			if (ni && ni != lp->lp_ni)
				continue;
			list_del_init(&lp->lp_hashlist);
			/* Lose hash table's ref */
			ptable->pt_zombies++;
			lnet_peer_decref_locked(lp);
		}
	}
}

	cfs_percpt_for_each(ptable, i, the_lnet.ln_peer_tables) {
		lnet_net_lock(i);
static void
lnet_peer_table_deathrow_wait_locked(struct lnet_peer_table *ptable,
				     int cpt_locked)
{
	int i;

		for (j = 0; j < LNET_PEER_HASH_SIZE; j++) {
			struct list_head *peers = &ptable->pt_hash[j];
	for (i = 3; ptable->pt_zombies; i++) {
		lnet_net_unlock(cpt_locked);

			while (!list_empty(peers)) {
				lnet_peer_t *lp = list_entry(peers->next,
								 lnet_peer_t,
								 lp_hashlist);
				list_del_init(&lp->lp_hashlist);
				/* lose hash table's ref */
				lnet_peer_decref_locked(lp);
		if (is_power_of_2(i)) {
			CDEBUG(D_WARNING,
			       "Waiting for %d zombies on peer table\n",
			       ptable->pt_zombies);
		}
		set_current_state(TASK_UNINTERRUPTIBLE);
		schedule_timeout(cfs_time_seconds(1) >> 1);
		lnet_net_lock(cpt_locked);
	}
}

		lnet_net_unlock(i);
static void
lnet_peer_table_del_rtrs_locked(lnet_ni_t *ni, struct lnet_peer_table *ptable,
				int cpt_locked)
{
	lnet_peer_t *lp;
	lnet_peer_t *tmp;
	lnet_nid_t lp_nid;
	int i;

	for (i = 0; i < LNET_PEER_HASH_SIZE; i++) {
		list_for_each_entry_safe(lp, tmp, &ptable->pt_hash[i],
					 lp_hashlist) {
			if (ni != lp->lp_ni)
				continue;

			if (!lp->lp_rtr_refcount)
				continue;

			lp_nid = lp->lp_nid;

			lnet_net_unlock(cpt_locked);
			lnet_del_route(LNET_NIDNET(LNET_NID_ANY), lp_nid);
			lnet_net_lock(cpt_locked);
		}
	}
}

	cfs_percpt_for_each(ptable, i, the_lnet.ln_peer_tables) {
		LIST_HEAD(deathrow);
void
lnet_peer_tables_cleanup(lnet_ni_t *ni)
{
	struct lnet_peer_table *ptable;
	struct list_head deathrow;
	lnet_peer_t *lp;
	int i;

		lnet_net_lock(i);
	INIT_LIST_HEAD(&deathrow);

		for (j = 3; ptable->pt_number; j++) {
	LASSERT(the_lnet.ln_shutdown || ni);
	/*
	 * If just deleting the peers for a NI, get rid of any routes these
	 * peers are gateways for.
	 */
	cfs_percpt_for_each(ptable, i, the_lnet.ln_peer_tables) {
		lnet_net_lock(i);
		lnet_peer_table_del_rtrs_locked(ni, ptable, i);
		lnet_net_unlock(i);

			if (!(j & (j - 1))) {
				CDEBUG(D_WARNING,
				       "Waiting for %d peers on peer table\n",
				       ptable->pt_number);
	}
			set_current_state(TASK_UNINTERRUPTIBLE);
			schedule_timeout(cfs_time_seconds(1) / 2);

	/*
	 * Start the process of moving the applicable peers to
	 * deathrow.
	 */
	cfs_percpt_for_each(ptable, i, the_lnet.ln_peer_tables) {
		lnet_net_lock(i);
		lnet_peer_table_cleanup_locked(ni, ptable);
		lnet_net_unlock(i);
	}
		list_splice_init(&ptable->pt_deathrow, &deathrow);

	/* Cleanup all entries on deathrow. */
	cfs_percpt_for_each(ptable, i, the_lnet.ln_peer_tables) {
		lnet_net_lock(i);
		lnet_peer_table_deathrow_wait_locked(ptable, i);
		list_splice_init(&ptable->pt_deathrow, &deathrow);
		lnet_net_unlock(i);
	}

	while (!list_empty(&deathrow)) {
			lp = list_entry(deathrow.next,
					lnet_peer_t, lp_hashlist);
		lp = list_entry(deathrow.next, lnet_peer_t, lp_hashlist);
		list_del(&lp->lp_hashlist);
		LIBCFS_FREE(lp, sizeof(*lp));
	}
}
}

void
lnet_destroy_peer_locked(lnet_peer_t *lp)
@@ -181,6 +235,8 @@ lnet_destroy_peer_locked(lnet_peer_t *lp)
	lp->lp_ni = NULL;

	list_add(&lp->lp_hashlist, &ptable->pt_deathrow);
	LASSERT(ptable->pt_zombies > 0);
	ptable->pt_zombies--;
}

lnet_peer_t *