From: James Simmons <jsimmons@infradead.org>
To: Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
devel@driverdev.osuosl.org, Oleg Drokin <oleg.drokin@intel.com>,
Andreas Dilger <andreas.dilger@intel.com>
Cc: Linux Kernel Mailing List <linux-kernel@vger.kernel.org>,
lustre-devel@lists.lustre.org,
Amir Shehata <amir.shehata@intel.com>
Subject: [PATCH 09/40] staging: lustre: Dynamic LNet Configuration (DLC)
Date: Fri, 20 Nov 2015 18:35:45 -0500 [thread overview]
Message-ID: <1448062576-23757-10-git-send-email-jsimmons@infradead.org> (raw)
In-Reply-To: <1448062576-23757-1-git-send-email-jsimmons@infradead.org>
From: Amir Shehata <amir.shehata@intel.com>
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: Amir 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: Liang Zhen <liang.zhen@intel.com>
Reviewed-by: James Simmons <uja.ornl@gmail.com>
Reviewed-by: Oleg Drokin <oleg.drokin@intel.com>
---
.../staging/lustre/include/linux/lnet/lib-lnet.h | 2 +-
.../staging/lustre/include/linux/lnet/lib-types.h | 5 +-
drivers/staging/lustre/lnet/lnet/api-ni.c | 8 +-
drivers/staging/lustre/lnet/lnet/config.c | 29 ++++-
drivers/staging/lustre/lnet/lnet/peer.c | 134 ++++++++++++++------
5 files changed, 124 insertions(+), 54 deletions(-)
diff --git a/drivers/staging/lustre/include/linux/lnet/lib-lnet.h b/drivers/staging/lustre/include/linux/lnet/lib-lnet.h
index 09c6bfe..1e0b236 100644
--- a/drivers/staging/lustre/include/linux/lnet/lib-lnet.h
+++ b/drivers/staging/lustre/include/linux/lnet/lib-lnet.h
@@ -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);
diff --git a/drivers/staging/lustre/include/linux/lnet/lib-types.h b/drivers/staging/lustre/include/linux/lnet/lib-types.h
index d792c4a..39381d9 100644
--- a/drivers/staging/lustre/include/linux/lnet/lib-types.h
+++ b/drivers/staging/lustre/include/linux/lnet/lib-types.h
@@ -343,6 +343,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 */
};
@@ -600,9 +602,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;
diff --git a/drivers/staging/lustre/lnet/lnet/api-ni.c b/drivers/staging/lustre/lnet/lnet/api-ni.c
index 284150f..f3c9937 100644
--- a/drivers/staging/lustre/lnet/lnet/api-ni.c
+++ b/drivers/staging/lustre/lnet/lnet/api-ni.c
@@ -882,7 +882,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);
/* Now wait for the NI's I just nuked to show up on ln_zombie_nis
@@ -939,12 +939,6 @@ lnet_shutdown_lndnis(void)
the_lnet.ln_shutdown = 0;
lnet_net_unlock(LNET_LOCK_EX);
-
- if (the_lnet.ln_network_tokens != NULL) {
- LIBCFS_FREE(the_lnet.ln_network_tokens,
- the_lnet.ln_network_tokens_nob);
- the_lnet.ln_network_tokens = NULL;
- }
}
static int
diff --git a/drivers/staging/lustre/lnet/lnet/config.c b/drivers/staging/lustre/lnet/lnet/config.c
index 867c96e..7bb140b 100644
--- a/drivers/staging/lustre/lnet/lnet/config.c
+++ b/drivers/staging/lustre/lnet/lnet/config.c
@@ -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 != NULL)
cfs_percpt_free(ni->ni_refs);
@@ -105,6 +107,10 @@ lnet_ni_free(struct lnet_ni *ni)
if (ni->ni_cpts != NULL)
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);
str = tmp = tokens;
@@ -319,7 +323,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 != NULL);
@@ -344,6 +364,8 @@ lnet_parse_networks(struct list_head *nilist, char *networks)
}
LASSERT(!list_empty(nilist));
+
+ LIBCFS_FREE(tokens, tokensize);
return 0;
failed_syntax:
@@ -360,7 +382,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;
}
diff --git a/drivers/staging/lustre/lnet/lnet/peer.c b/drivers/staging/lustre/lnet/lnet/peer.c
index 1fceed3..bb5a0bb 100644
--- a/drivers/staging/lustre/lnet/lnet/peer.c
+++ b/drivers/staging/lustre/lnet/lnet/peer.c
@@ -103,62 +103,116 @@ lnet_peer_tables_destroy(void)
the_lnet.ln_peer_tables = NULL;
}
+static void
+lnet_peer_table_cleanup_locked(lnet_ni_t *ni, struct lnet_peer_table *ptable)
+{
+ int i;
+ lnet_peer_t *lp;
+ lnet_peer_t *tmp;
+
+ 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);
+ }
+ }
+}
+
+static void
+lnet_peer_table_deathrow_wait_locked(struct lnet_peer_table *ptable,
+ int cpt_locked)
+{
+ int i;
+
+ for (i = 3; ptable->pt_zombies != 0; i++) {
+ lnet_net_unlock(cpt_locked);
+
+ if (IS_PO2(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);
+ }
+}
+
+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 == 0)
+ 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);
+ }
+ }
+}
+
void
-lnet_peer_tables_cleanup(void)
+lnet_peer_tables_cleanup(lnet_ni_t *ni)
{
struct lnet_peer_table *ptable;
+ struct list_head deathrow;
+ lnet_peer_t *lp;
int i;
- int j;
- LASSERT(the_lnet.ln_shutdown); /* i.e. no new peers */
+ INIT_LIST_HEAD(&deathrow);
+ 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);
-
- for (j = 0; j < LNET_PEER_HASH_SIZE; j++) {
- struct list_head *peers = &ptable->pt_hash[j];
-
- 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);
- }
- }
-
+ lnet_peer_table_del_rtrs_locked(ni, ptable, i);
lnet_net_unlock(i);
}
+ /*
+ * Start the process of moving the applicable peers to
+ * deathrow.
+ */
cfs_percpt_for_each(ptable, i, the_lnet.ln_peer_tables) {
- LIST_HEAD(deathrow);
- lnet_peer_t *lp;
-
lnet_net_lock(i);
+ lnet_peer_table_cleanup_locked(ni, ptable);
+ lnet_net_unlock(i);
+ }
- for (j = 3; ptable->pt_number != 0; j++) {
- lnet_net_unlock(i);
-
- if ((j & (j - 1)) == 0) {
- 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);
- lnet_net_lock(i);
- }
+ /* 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);
- list_del(&lp->lp_hashlist);
- LIBCFS_FREE(lp, sizeof(*lp));
- }
+ while (!list_empty(&deathrow)) {
+ lp = list_entry(deathrow.next, lnet_peer_t, lp_hashlist);
+ list_del(&lp->lp_hashlist);
+ LIBCFS_FREE(lp, sizeof(*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 *
--
1.7.1
next prev parent reply other threads:[~2015-11-20 23:46 UTC|newest]
Thread overview: 65+ messages / expand[flat|nested] mbox.gz Atom feed top
2015-11-20 23:35 [PATCH 00/40] Sync upstream lustre client LNet core James Simmons
2015-11-20 23:35 ` [PATCH 01/40] staging: lustre: drop *_t from end of struct lnet_text_buf James Simmons
2015-11-20 23:35 ` [PATCH 02/40] staging: lustre: fix 'NULL pointer dereference' errors for LNet James Simmons
2015-12-02 7:46 ` Dan Carpenter
2015-12-15 18:08 ` Simmons, James A.
2015-11-20 23:35 ` [PATCH 03/40] staging: lustre: reflect down routes in /proc/sys/lnet/routes James Simmons
2015-12-02 7:54 ` Dan Carpenter
2015-11-20 23:35 ` [PATCH 04/40] staging: lustre: fix failure handle of create reply James Simmons
2015-11-20 23:35 ` [PATCH 05/40] staging: lustre: eliminate obsolete Cray SeaStar support James Simmons
2015-11-20 23:35 ` [PATCH 06/40] staging: lustre: remove uses of IS_ERR_VALUE() James Simmons
2015-11-21 18:45 ` Dan Carpenter
2015-11-20 23:35 ` [PATCH 07/40] staging: lustre: return +ve for blocked lnet message James Simmons
2015-11-20 23:35 ` [PATCH 08/40] staging: lustre: do not memset after LIBCFS_ALLOC James Simmons
2015-11-20 23:35 ` James Simmons [this message]
2015-11-20 23:35 ` [PATCH 10/40] staging: lustre: Dynamic LNet Configuration (DLC) dynamic routing James Simmons
2015-11-20 23:35 ` [PATCH 11/40] staging: lustre: DLC Feature dynamic net config James Simmons
2015-12-02 9:23 ` Dan Carpenter
2015-11-20 23:35 ` [PATCH 12/40] staging: lustre: Dynamic LNet Configuration (DLC) IOCTL changes James Simmons
2015-12-02 9:48 ` Dan Carpenter
2015-11-20 23:35 ` [PATCH 13/40] staging: lustre: Dynamic LNet Configuration (DLC) show command James Simmons
2015-12-02 11:20 ` Dan Carpenter
2015-12-15 18:14 ` Simmons, James A.
2015-12-15 18:19 ` Dan Carpenter
2015-12-15 18:39 ` Simmons, James A.
2015-12-15 18:48 ` Greg Kroah-Hartman
2015-12-15 19:48 ` Simmons, James A.
2015-12-15 19:55 ` 'Greg Kroah-Hartman'
2015-12-02 12:00 ` Dan Carpenter
2015-11-20 23:35 ` [PATCH 14/40] staging: lustre: fix crash due to NULL networks string James Simmons
2015-12-02 11:27 ` Dan Carpenter
2015-11-20 23:35 ` [PATCH 15/40] staging: lustre: DLC user/kernel space glue code James Simmons
2015-12-02 12:11 ` Dan Carpenter
2015-11-20 23:35 ` [PATCH 16/40] staging: lustre: make local functions static for LNet ni James Simmons
2015-11-20 23:35 ` [PATCH 17/40] staging: lustre: add sparse annotation __user wherever needed for lnet James Simmons
2015-11-20 23:35 ` [PATCH 18/40] staging: lustre: remove LUSTRE_{,SRV_}LNET_PID James Simmons
2015-11-20 23:35 ` [PATCH 19/40] staging: lustre: copy out libcfs ioctl inline buffer James Simmons
2015-12-02 12:34 ` Dan Carpenter
2015-11-20 23:35 ` [PATCH 20/40] staging: lustre: fix kernel crash when network failed to start James Simmons
2015-12-02 12:44 ` Dan Carpenter
2015-11-20 23:35 ` [PATCH 21/40] staging: lustre: improve LNet clean up code and API James Simmons
2015-12-02 12:59 ` Dan Carpenter
2015-12-02 13:20 ` [lustre-devel] " Alexander Zarochentsev
2015-12-02 13:59 ` Dan Carpenter
2015-12-15 17:10 ` Simmons, James A.
2015-12-15 17:41 ` Dan Carpenter
2015-11-20 23:35 ` [PATCH 22/40] staging: lustre: Fixes to make lnetctl function as expected James Simmons
2015-11-20 23:35 ` [PATCH 23/40] staging: lustre: return appropriate errno when adding route James Simmons
2015-11-20 23:36 ` [PATCH 24/40] staging: lustre: make some lnet functions static James Simmons
2015-11-20 23:36 ` [PATCH 25/40] staging: lustre: missed a few cases of using NULL instead of 0 James Simmons
2015-11-20 23:36 ` [PATCH 26/40] staging: lustre: startup lnet acceptor thread dynamically James Simmons
2015-11-20 23:36 ` [PATCH 27/40] staging: lustre: reject invalid net configuration for lnet James Simmons
2015-11-20 23:36 ` [PATCH 28/40] staging: lustre: return -EEXIST if NI is not unique James Simmons
2015-11-20 23:36 ` [PATCH 29/40] staging: lustre: handle lnet_check_routes() errors James Simmons
2015-11-20 23:36 ` [PATCH 30/40] staging: lustre: improvement to router checker James Simmons
2015-11-20 23:36 ` [PATCH 31/40] staging: lustre: assume a kernel build James Simmons
2015-11-20 23:36 ` [PATCH 32/40] staging: lustre: prevent assert on LNet module unload James Simmons
2015-11-20 23:36 ` [PATCH 33/40] staging: lustre: remove messages from lazy portal on NI shutdown James Simmons
2015-11-20 23:36 ` [PATCH 34/40] staging: lustre: remove unnecessary EXPORT_SYMBOL from lnet layer James Simmons
2015-11-20 23:36 ` [PATCH 35/40] staging: lustre: avoid race during lnet acceptor thread termination James Simmons
2015-11-20 23:36 ` [PATCH 36/40] staging: lustre: test for sk_sleep presence in compact-2.6.h James Simmons
2015-11-20 23:36 ` [PATCH 37/40] staging: lustre: remove unnecessary NULL check in IOC_LIBCFS_GET_NET James Simmons
2015-11-20 23:36 ` [PATCH 38/40] staging: lustre: Allocate the correct number of rtr buffers James Simmons
2015-11-20 23:36 ` [PATCH 39/40] staging: lustre: Use lnet_is_route_alive for router aliveness James Simmons
2015-11-20 23:36 ` [PATCH 40/40] staging: lustre: Remove LASSERTS from router checker James Simmons
2015-12-21 23:41 ` [PATCH 00/40] Sync upstream lustre client LNet core Greg Kroah-Hartman
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1448062576-23757-10-git-send-email-jsimmons@infradead.org \
--to=jsimmons@infradead.org \
--cc=amir.shehata@intel.com \
--cc=andreas.dilger@intel.com \
--cc=devel@driverdev.osuosl.org \
--cc=gregkh@linuxfoundation.org \
--cc=linux-kernel@vger.kernel.org \
--cc=lustre-devel@lists.lustre.org \
--cc=oleg.drokin@intel.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®