1 /* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
2 * vim:expandtab:shiftwidth=8:tabstop=8:
6 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 only,
10 * as published by the Free Software Foundation.
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License version 2 for more details (a copy is included
16 * in the LICENSE file that accompanied this code).
18 * You should have received a copy of the GNU General Public License
19 * version 2 along with this program; If not, see
20 * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
22 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
23 * CA 95054 USA or visit www.sun.com if you need additional information or
29 * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
30 * Use is subject to license terms.
33 * This file is part of Lustre, http://www.lustre.org/
34 * Lustre is a trademark of Sun Microsystems, Inc.
39 #define DEBUG_SUBSYSTEM S_LNET
41 #include <lnet/lib-lnet.h>
44 lnet_create_peer_table(void)
49 LASSERT (the_lnet.ln_peer_hash == NULL);
50 LIBCFS_ALLOC(hash, LNET_PEER_HASHSIZE * sizeof(cfs_list_t));
53 CERROR("Can't allocate peer hash table\n");
57 for (i = 0; i < LNET_PEER_HASHSIZE; i++)
58 CFS_INIT_LIST_HEAD(&hash[i]);
60 the_lnet.ln_peer_hash = hash;
65 lnet_destroy_peer_table(void)
69 if (the_lnet.ln_peer_hash == NULL)
72 for (i = 0; i < LNET_PEER_HASHSIZE; i++)
73 LASSERT (cfs_list_empty(&the_lnet.ln_peer_hash[i]));
75 LIBCFS_FREE(the_lnet.ln_peer_hash,
76 LNET_PEER_HASHSIZE * sizeof (cfs_list_t));
77 the_lnet.ln_peer_hash = NULL;
81 lnet_clear_peer_table(void)
85 LASSERT (the_lnet.ln_shutdown); /* i.e. no new peers */
87 for (i = 0; i < LNET_PEER_HASHSIZE; i++) {
88 cfs_list_t *peers = &the_lnet.ln_peer_hash[i];
91 while (!cfs_list_empty(peers)) {
92 lnet_peer_t *lp = cfs_list_entry(peers->next,
96 cfs_list_del(&lp->lp_hashlist);
97 lnet_peer_decref_locked(lp); /* lose hash table's ref */
103 for (i = 3; the_lnet.ln_npeers != 0;i++) {
106 if ((i & (i-1)) == 0)
107 CDEBUG(D_WARNING,"Waiting for %d peers\n",
109 cfs_pause(cfs_time_seconds(1));
117 lnet_destroy_peer_locked (lnet_peer_t *lp)
119 lnet_ni_decref_locked(lp->lp_ni);
122 LASSERT (lp->lp_refcount == 0);
123 LASSERT (lp->lp_rtr_refcount == 0);
124 LASSERT (cfs_list_empty(&lp->lp_txq));
125 LASSERT (lp->lp_txqnob == 0);
126 LASSERT (lp->lp_rcd == NULL);
128 LIBCFS_FREE(lp, sizeof(*lp));
132 LASSERT(the_lnet.ln_npeers > 0);
133 the_lnet.ln_npeers--;
137 lnet_find_peer_locked (lnet_nid_t nid)
139 unsigned int idx = LNET_NIDADDR(nid) % LNET_PEER_HASHSIZE;
140 cfs_list_t *peers = &the_lnet.ln_peer_hash[idx];
144 if (the_lnet.ln_shutdown)
147 cfs_list_for_each (tmp, peers) {
148 lp = cfs_list_entry(tmp, lnet_peer_t, lp_hashlist);
150 if (lp->lp_nid == nid) {
151 lnet_peer_addref_locked(lp);
160 lnet_nid2peer_locked(lnet_peer_t **lpp, lnet_nid_t nid)
165 lp = lnet_find_peer_locked(nid);
173 LIBCFS_ALLOC(lp, sizeof(*lp));
180 memset(lp, 0, sizeof(*lp)); /* zero counters etc */
182 CFS_INIT_LIST_HEAD(&lp->lp_txq);
183 CFS_INIT_LIST_HEAD(&lp->lp_rtrq);
186 lp->lp_notifylnd = 0;
187 lp->lp_notifying = 0;
188 lp->lp_alive_count = 0;
189 lp->lp_timestamp = 0;
190 lp->lp_alive = !lnet_peers_start_down(); /* 1 bit!! */
191 lp->lp_last_alive = cfs_time_current(); /* assumes alive */
192 lp->lp_last_query = 0; /* haven't asked NI yet */
193 lp->lp_ping_timestamp = 0;
195 lp->lp_refcount = 2; /* 1 for caller; 1 for hash */
196 lp->lp_rtr_refcount = 0;
200 lp2 = lnet_find_peer_locked(nid);
203 LIBCFS_FREE(lp, sizeof(*lp));
206 if (the_lnet.ln_shutdown) {
207 lnet_peer_decref_locked(lp2);
216 lp->lp_ni = lnet_net2ni_locked(LNET_NIDNET(nid));
217 if (lp->lp_ni == NULL) {
219 LIBCFS_FREE(lp, sizeof(*lp));
223 return the_lnet.ln_shutdown ? -ESHUTDOWN : -EHOSTUNREACH;
227 lp->lp_mintxcredits = lp->lp_ni->ni_peertxcredits;
229 lp->lp_minrtrcredits = lnet_peer_buffer_credits(lp->lp_ni);
231 /* can't add peers after shutdown starts */
232 LASSERT (!the_lnet.ln_shutdown);
234 cfs_list_add_tail(&lp->lp_hashlist, lnet_nid2peerhash(nid));
235 the_lnet.ln_npeers++;
236 the_lnet.ln_peertable_version++;
242 lnet_debug_peer(lnet_nid_t nid)
244 char *aliveness = "NA";
250 rc = lnet_nid2peer_locked(&lp, nid);
253 CDEBUG(D_WARNING, "No peer %s\n", libcfs_nid2str(nid));
257 if (lnet_isrouter(lp) || lnet_peer_aliveness_enabled(lp))
258 aliveness = lp->lp_alive ? "up" : "down";
260 CDEBUG(D_WARNING, "%-24s %4d %5s %5d %5d %5d %5d %5d %ld\n",
261 libcfs_nid2str(lp->lp_nid), lp->lp_refcount,
262 aliveness, lp->lp_ni->ni_peertxcredits,
263 lp->lp_rtrcredits, lp->lp_minrtrcredits,
264 lp->lp_txcredits, lp->lp_mintxcredits, lp->lp_txqnob);
266 lnet_peer_decref_locked(lp);