1 /* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
2 * vim:expandtab:shiftwidth=8:tabstop=8:
5 * Data movement routines
7 * Copyright (c) 2001-2003 Cluster File Systems, Inc.
9 * This file is part of Lustre, http://www.lustre.org
11 * Lustre is free software; you can redistribute it and/or
12 * modify it under the terms of version 2 of the GNU General Public
13 * License as published by the Free Software Foundation.
15 * Lustre is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
20 * You should have received a copy of the GNU General Public License
21 * along with Lustre; if not, write to the Free Software
22 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25 #define DEBUG_SUBSYSTEM S_LNET
27 #include <lnet/lib-lnet.h>
30 lnet_create_peer_table(void)
32 struct list_head *hash;
35 LASSERT (the_lnet.ln_peer_hash == NULL);
36 LIBCFS_ALLOC(hash, LNET_PEER_HASHSIZE * sizeof(struct list_head));
39 CERROR("Can't allocate peer hash table\n");
43 for (i = 0; i < LNET_PEER_HASHSIZE; i++)
44 CFS_INIT_LIST_HEAD(&hash[i]);
46 the_lnet.ln_peer_hash = hash;
51 lnet_destroy_peer_table(void)
55 if (the_lnet.ln_peer_hash == NULL)
58 for (i = 0; i < LNET_PEER_HASHSIZE; i++)
59 LASSERT (list_empty(&the_lnet.ln_peer_hash[i]));
61 LIBCFS_FREE(the_lnet.ln_peer_hash,
62 LNET_PEER_HASHSIZE * sizeof (struct list_head));
63 the_lnet.ln_peer_hash = NULL;
67 lnet_clear_peer_table(void)
71 LASSERT (the_lnet.ln_shutdown); /* i.e. no new peers */
73 for (i = 0; i < LNET_PEER_HASHSIZE; i++) {
74 struct list_head *peers = &the_lnet.ln_peer_hash[i];
77 while (!list_empty(peers)) {
78 lnet_peer_t *lp = list_entry(peers->next,
79 lnet_peer_t, lp_hashlist);
81 list_del(&lp->lp_hashlist);
82 lnet_peer_decref_locked(lp); /* lose hash table's ref */
88 for (i = 3; the_lnet.ln_npeers != 0;i++) {
92 CDEBUG(D_WARNING,"Waiting for %d peers\n",
94 cfs_pause(cfs_time_seconds(1));
102 lnet_destroy_peer_locked (lnet_peer_t *lp)
104 lnet_ni_decref_locked(lp->lp_ni);
107 LASSERT (lp->lp_refcount == 0);
108 LASSERT (lp->lp_rtr_refcount == 0);
109 LASSERT (list_empty(&lp->lp_txq));
110 LASSERT (lp->lp_txqnob == 0);
112 LIBCFS_FREE(lp, sizeof(*lp));
116 LASSERT(the_lnet.ln_npeers > 0);
117 the_lnet.ln_npeers--;
121 lnet_find_peer_locked (lnet_nid_t nid)
123 unsigned int idx = LNET_NIDADDR(nid) % LNET_PEER_HASHSIZE;
124 struct list_head *peers = &the_lnet.ln_peer_hash[idx];
125 struct list_head *tmp;
128 if (the_lnet.ln_shutdown)
131 list_for_each (tmp, peers) {
132 lp = list_entry(tmp, lnet_peer_t, lp_hashlist);
134 if (lp->lp_nid == nid) {
135 lnet_peer_addref_locked(lp);
144 lnet_nid2peer_locked(lnet_peer_t **lpp, lnet_nid_t nid)
149 lp = lnet_find_peer_locked(nid);
157 LIBCFS_ALLOC(lp, sizeof(*lp));
164 memset(lp, 0, sizeof(*lp)); /* zero counters etc */
166 CFS_INIT_LIST_HEAD(&lp->lp_txq);
167 CFS_INIT_LIST_HEAD(&lp->lp_rtrq);
169 lp->lp_alive = !lnet_peers_start_down(); /* 1 bit!! */
171 lp->lp_notifylnd = 0;
172 lp->lp_notifying = 0;
173 lp->lp_alive_count = 0;
174 lp->lp_timestamp = 0;
175 lp->lp_ping_timestamp = 0;
177 lp->lp_refcount = 2; /* 1 for caller; 1 for hash */
178 lp->lp_rtr_refcount = 0;
182 lp2 = lnet_find_peer_locked(nid);
185 LIBCFS_FREE(lp, sizeof(*lp));
192 lp->lp_ni = lnet_net2ni_locked(LNET_NIDNET(nid));
193 if (lp->lp_ni == NULL) {
195 LIBCFS_FREE(lp, sizeof(*lp));
199 return the_lnet.ln_shutdown ? -ESHUTDOWN : -EHOSTUNREACH;
203 lp->lp_mintxcredits = lp->lp_ni->ni_peertxcredits;
205 /* As a first approximation; allow this peer the same number of router
206 * buffers as it is allowed outstanding sends */
207 lp->lp_rtrcredits = lp->lp_minrtrcredits = lp->lp_txcredits;
209 LASSERT (!the_lnet.ln_shutdown);
210 /* can't add peers after shutdown starts */
212 list_add_tail(&lp->lp_hashlist, lnet_nid2peerhash(nid));
213 the_lnet.ln_npeers++;
214 the_lnet.ln_peertable_version++;
220 lnet_debug_peer(lnet_nid_t nid)
227 rc = lnet_nid2peer_locked(&lp, nid);
230 CDEBUG(D_WARNING, "No peer %s\n", libcfs_nid2str(nid));
234 CDEBUG(D_WARNING, "%-24s %4d %5s %5d %5d %5d %5d %5d %ld\n",
235 libcfs_nid2str(lp->lp_nid), lp->lp_refcount,
236 !lnet_isrouter(lp) ? "~rtr" : (lp->lp_alive ? "up" : "down"),
237 lp->lp_ni->ni_peertxcredits,
238 lp->lp_rtrcredits, lp->lp_minrtrcredits,
239 lp->lp_txcredits, lp->lp_mintxcredits, lp->lp_txqnob);
241 lnet_peer_decref_locked(lp);