4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 only,
8 * as published by the Free Software Foundation.
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * General Public License version 2 for more details (a copy is included
14 * in the LICENSE file that accompanied this code).
16 * You should have received a copy of the GNU General Public License
17 * version 2 along with this program; If not, see
18 * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
20 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
21 * CA 95054 USA or visit www.sun.com if you need additional information or
27 * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
28 * Use is subject to license terms.
31 * This file is part of Lustre, http://www.lustre.org/
32 * Lustre is a trademark of Sun Microsystems, Inc.
37 #define DEBUG_SUBSYSTEM S_LNET
39 #include <lnet/lib-lnet.h>
42 lnet_create_peer_table(void)
47 LASSERT (the_lnet.ln_peer_hash == NULL);
48 LIBCFS_ALLOC(hash, LNET_PEER_HASHSIZE * sizeof(cfs_list_t));
51 CERROR("Can't allocate peer hash table\n");
55 for (i = 0; i < LNET_PEER_HASHSIZE; i++)
56 CFS_INIT_LIST_HEAD(&hash[i]);
58 the_lnet.ln_peer_hash = hash;
63 lnet_destroy_peer_table(void)
67 if (the_lnet.ln_peer_hash == NULL)
70 for (i = 0; i < LNET_PEER_HASHSIZE; i++)
71 LASSERT (cfs_list_empty(&the_lnet.ln_peer_hash[i]));
73 LIBCFS_FREE(the_lnet.ln_peer_hash,
74 LNET_PEER_HASHSIZE * sizeof (cfs_list_t));
75 the_lnet.ln_peer_hash = NULL;
79 lnet_clear_peer_table(void)
83 LASSERT (the_lnet.ln_shutdown); /* i.e. no new peers */
85 for (i = 0; i < LNET_PEER_HASHSIZE; i++) {
86 cfs_list_t *peers = &the_lnet.ln_peer_hash[i];
89 while (!cfs_list_empty(peers)) {
90 lnet_peer_t *lp = cfs_list_entry(peers->next,
94 cfs_list_del(&lp->lp_hashlist);
95 lnet_peer_decref_locked(lp); /* lose hash table's ref */
101 for (i = 3; the_lnet.ln_npeers != 0;i++) {
104 if ((i & (i-1)) == 0)
105 CDEBUG(D_WARNING,"Waiting for %d peers\n",
107 cfs_pause(cfs_time_seconds(1));
115 lnet_destroy_peer_locked (lnet_peer_t *lp)
117 lnet_ni_decref_locked(lp->lp_ni);
120 LASSERT (lp->lp_refcount == 0);
121 LASSERT (lp->lp_rtr_refcount == 0);
122 LASSERT (cfs_list_empty(&lp->lp_txq));
123 LASSERT (lp->lp_txqnob == 0);
124 LASSERT (lp->lp_rcd == NULL);
126 LIBCFS_FREE(lp, sizeof(*lp));
130 LASSERT(the_lnet.ln_npeers > 0);
131 the_lnet.ln_npeers--;
135 lnet_find_peer_locked (lnet_nid_t nid)
137 unsigned int idx = LNET_NIDADDR(nid) % LNET_PEER_HASHSIZE;
138 cfs_list_t *peers = &the_lnet.ln_peer_hash[idx];
142 if (the_lnet.ln_shutdown)
145 cfs_list_for_each (tmp, peers) {
146 lp = cfs_list_entry(tmp, lnet_peer_t, lp_hashlist);
148 if (lp->lp_nid == nid) {
149 lnet_peer_addref_locked(lp);
158 lnet_nid2peer_locked(lnet_peer_t **lpp, lnet_nid_t nid)
163 lp = lnet_find_peer_locked(nid);
171 LIBCFS_ALLOC(lp, sizeof(*lp));
178 memset(lp, 0, sizeof(*lp)); /* zero counters etc */
180 CFS_INIT_LIST_HEAD(&lp->lp_txq);
181 CFS_INIT_LIST_HEAD(&lp->lp_rtrq);
184 lp->lp_notifylnd = 0;
185 lp->lp_notifying = 0;
186 lp->lp_alive_count = 0;
187 lp->lp_timestamp = 0;
188 lp->lp_alive = !lnet_peers_start_down(); /* 1 bit!! */
189 lp->lp_last_alive = cfs_time_current(); /* assumes alive */
190 lp->lp_last_query = 0; /* haven't asked NI yet */
191 lp->lp_ping_timestamp = 0;
193 lp->lp_refcount = 2; /* 1 for caller; 1 for hash */
194 lp->lp_rtr_refcount = 0;
198 lp2 = lnet_find_peer_locked(nid);
201 LIBCFS_FREE(lp, sizeof(*lp));
204 if (the_lnet.ln_shutdown) {
205 lnet_peer_decref_locked(lp2);
214 lp->lp_ni = lnet_net2ni_locked(LNET_NIDNET(nid));
215 if (lp->lp_ni == NULL) {
217 LIBCFS_FREE(lp, sizeof(*lp));
221 return the_lnet.ln_shutdown ? -ESHUTDOWN : -EHOSTUNREACH;
225 lp->lp_mintxcredits = lp->lp_ni->ni_peertxcredits;
227 lp->lp_minrtrcredits = lnet_peer_buffer_credits(lp->lp_ni);
229 /* can't add peers after shutdown starts */
230 LASSERT (!the_lnet.ln_shutdown);
232 cfs_list_add_tail(&lp->lp_hashlist, lnet_nid2peerhash(nid));
233 the_lnet.ln_npeers++;
234 the_lnet.ln_peertable_version++;
240 lnet_debug_peer(lnet_nid_t nid)
242 char *aliveness = "NA";
248 rc = lnet_nid2peer_locked(&lp, nid);
251 CDEBUG(D_WARNING, "No peer %s\n", libcfs_nid2str(nid));
255 if (lnet_isrouter(lp) || lnet_peer_aliveness_enabled(lp))
256 aliveness = lp->lp_alive ? "up" : "down";
258 CDEBUG(D_WARNING, "%-24s %4d %5s %5d %5d %5d %5d %5d %ld\n",
259 libcfs_nid2str(lp->lp_nid), lp->lp_refcount,
260 aliveness, lp->lp_ni->ni_peertxcredits,
261 lp->lp_rtrcredits, lp->lp_minrtrcredits,
262 lp->lp_txcredits, lp->lp_mintxcredits, lp->lp_txqnob);
264 lnet_peer_decref_locked(lp);