/*
 * GPL HEADER START
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 only,
 * as published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * General Public License version 2 for more details (a copy is included
 * in the LICENSE file that accompanied this code).
 *
 * You should have received a copy of the GNU General Public License
 * version 2 along with this program; If not, see
 * http://www.gnu.org/licenses/gpl-2.0.html
 *
 * GPL HEADER END
 */
/*
 * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
 * Use is subject to license terms.
 *
 * Copyright (c) 2011, 2015, Intel Corporation.
 */
/*
 * This file is part of Lustre, http://www.lustre.org/
 * Lustre is a trademark of Sun Microsystems, Inc.
 */

#define DEBUG_SUBSYSTEM S_LNET
#include <linux/log2.h>
#include <linux/ktime.h>

#include <linux/lnet/lib-lnet.h>
#include <uapi/linux/lnet/lnet-dlc.h>

#define D_LNI D_CONSOLE

struct lnet the_lnet;		/* THE state of the network */
EXPORT_SYMBOL(the_lnet);

static char *ip2nets = "";
module_param(ip2nets, charp, 0444);
MODULE_PARM_DESC(ip2nets, "LNET network <- IP table");

static char *networks = "";
module_param(networks, charp, 0444);
MODULE_PARM_DESC(networks, "local networks");

static char *routes = "";
module_param(routes, charp, 0444);
MODULE_PARM_DESC(routes, "routes to non-local networks");

static int rnet_htable_size = LNET_REMOTE_NETS_HASH_DEFAULT;
module_param(rnet_htable_size, int, 0444);
MODULE_PARM_DESC(rnet_htable_size, "size of remote network hash table");

static int lnet_ping(struct lnet_process_id id, int timeout_ms,
		     struct lnet_process_id __user *ids, int n_ids);

static char *
lnet_get_routes(void)
{
	return routes;
}

static char *
lnet_get_networks(void)
{
	char *nets;
	int rc;

	if (*networks && *ip2nets) {
		LCONSOLE_ERROR_MSG(0x101, "Please specify EITHER 'networks' or 'ip2nets' but not both at once\n");
		return NULL;
	}

	if (*ip2nets) {
		rc = lnet_parse_ip2nets(&nets, ip2nets);
		return !rc ? nets : NULL;
	}

	if (*networks)
		return networks;

	return "tcp";
}

static void
lnet_init_locks(void)
{
	spin_lock_init(&the_lnet.ln_eq_wait_lock);
	init_waitqueue_head(&the_lnet.ln_eq_waitq);
	init_waitqueue_head(&the_lnet.ln_rc_waitq);
	mutex_init(&the_lnet.ln_lnd_mutex);
	mutex_init(&the_lnet.ln_api_mutex);
}

static int
lnet_create_remote_nets_table(void)
{
	int i;
	struct list_head *hash;

	LASSERT(!the_lnet.ln_remote_nets_hash);
	LASSERT(the_lnet.ln_remote_nets_hbits > 0);
	LIBCFS_ALLOC(hash, LNET_REMOTE_NETS_HASH_SIZE * sizeof(*hash));
	if (!hash) {
		CERROR("Failed to create remote nets hash table\n");
		return -ENOMEM;
	}

	for (i = 0; i < LNET_REMOTE_NETS_HASH_SIZE; i++)
		INIT_LIST_HEAD(&hash[i]);
	the_lnet.ln_remote_nets_hash = hash;
	return 0;
}

static void
lnet_destroy_remote_nets_table(void)
{
	int i;

	if (!the_lnet.ln_remote_nets_hash)
		return;

	for (i = 0; i < LNET_REMOTE_NETS_HASH_SIZE; i++)
		LASSERT(list_empty(&the_lnet.ln_remote_nets_hash[i]));

	LIBCFS_FREE(the_lnet.ln_remote_nets_hash,
		    LNET_REMOTE_NETS_HASH_SIZE *
		    sizeof(the_lnet.ln_remote_nets_hash[0]));
	the_lnet.ln_remote_nets_hash = NULL;
}

static void
lnet_destroy_locks(void)
{
	if (the_lnet.ln_res_lock) {
		cfs_percpt_lock_free(the_lnet.ln_res_lock);
		the_lnet.ln_res_lock = NULL;
	}

	if (the_lnet.ln_net_lock) {
		cfs_percpt_lock_free(the_lnet.ln_net_lock);
		the_lnet.ln_net_lock = NULL;
	}
}

static int
lnet_create_locks(void)
{
	lnet_init_locks();

	the_lnet.ln_res_lock = cfs_percpt_lock_alloc(lnet_cpt_table());
	if (!the_lnet.ln_res_lock)
		goto failed;

	the_lnet.ln_net_lock = cfs_percpt_lock_alloc(lnet_cpt_table());
	if (!the_lnet.ln_net_lock)
		goto failed;

	return 0;

 failed:
	lnet_destroy_locks();
	return -ENOMEM;
}

static void lnet_assert_wire_constants(void)
{
	/*
	 * Wire protocol assertions generated by 'wirecheck'
	 * running on Linux robert.bartonsoftware.com 2.6.8-1.521
	 * #1 Mon Aug 16 09:01:18 EDT 2004 i686 athlon i386 GNU/Linux
	 * with gcc version 3.3.3 20040412 (Red Hat Linux 3.3.3-7)
	 */

	/* Constants... */
	BUILD_BUG_ON(LNET_PROTO_TCP_MAGIC != 0xeebc0ded);
	BUILD_BUG_ON(LNET_PROTO_TCP_VERSION_MAJOR != 1);
	BUILD_BUG_ON(LNET_PROTO_TCP_VERSION_MINOR != 0);
	BUILD_BUG_ON(LNET_MSG_ACK != 0);
	BUILD_BUG_ON(LNET_MSG_PUT != 1);
	BUILD_BUG_ON(LNET_MSG_GET != 2);
	BUILD_BUG_ON(LNET_MSG_REPLY != 3);
	BUILD_BUG_ON(LNET_MSG_HELLO != 4);

	/* Checks for struct ptl_handle_wire_t */
	BUILD_BUG_ON((int)sizeof(struct lnet_handle_wire) != 16);
	BUILD_BUG_ON((int)offsetof(struct lnet_handle_wire, wh_interface_cookie) != 0);
	BUILD_BUG_ON((int)sizeof(((struct lnet_handle_wire *)0)->wh_interface_cookie) != 8);
	BUILD_BUG_ON((int)offsetof(struct lnet_handle_wire, wh_object_cookie) != 8);
	BUILD_BUG_ON((int)sizeof(((struct lnet_handle_wire *)0)->wh_object_cookie) != 8);

	/* Checks for struct struct lnet_magicversion */
	BUILD_BUG_ON((int)sizeof(struct lnet_magicversion) != 8);
	BUILD_BUG_ON((int)offsetof(struct lnet_magicversion, magic) != 0);
	BUILD_BUG_ON((int)sizeof(((struct lnet_magicversion *)0)->magic) != 4);
	BUILD_BUG_ON((int)offsetof(struct lnet_magicversion, version_major) != 4);
	BUILD_BUG_ON((int)sizeof(((struct lnet_magicversion *)0)->version_major) != 2);
	BUILD_BUG_ON((int)offsetof(struct lnet_magicversion, version_minor) != 6);
	BUILD_BUG_ON((int)sizeof(((struct lnet_magicversion *)0)->version_minor) != 2);

	/* Checks for struct struct lnet_hdr */
	BUILD_BUG_ON((int)sizeof(struct lnet_hdr) != 72);
	BUILD_BUG_ON((int)offsetof(struct lnet_hdr, dest_nid) != 0);
	BUILD_BUG_ON((int)sizeof(((struct lnet_hdr *)0)->dest_nid) != 8);
	BUILD_BUG_ON((int)offsetof(struct lnet_hdr, src_nid) != 8);
	BUILD_BUG_ON((int)sizeof(((struct lnet_hdr *)0)->src_nid) != 8);
	BUILD_BUG_ON((int)offsetof(struct lnet_hdr, dest_pid) != 16);
	BUILD_BUG_ON((int)sizeof(((struct lnet_hdr *)0)->dest_pid) != 4);
	BUILD_BUG_ON((int)offsetof(struct lnet_hdr, src_pid) != 20);
	BUILD_BUG_ON((int)sizeof(((struct lnet_hdr *)0)->src_pid) != 4);
	BUILD_BUG_ON((int)offsetof(struct lnet_hdr, type) != 24);
	BUILD_BUG_ON((int)sizeof(((struct lnet_hdr *)0)->type) != 4);
	BUILD_BUG_ON((int)offsetof(struct lnet_hdr, payload_length) != 28);
	BUILD_BUG_ON((int)sizeof(((struct lnet_hdr *)0)->payload_length) != 4);
	BUILD_BUG_ON((int)offsetof(struct lnet_hdr, msg) != 32);
	BUILD_BUG_ON((int)sizeof(((struct lnet_hdr *)0)->msg) != 40);

	/* Ack */
	BUILD_BUG_ON((int)offsetof(struct lnet_hdr, msg.ack.dst_wmd) != 32);
	BUILD_BUG_ON((int)sizeof(((struct lnet_hdr *)0)->msg.ack.dst_wmd) != 16);
	BUILD_BUG_ON((int)offsetof(struct lnet_hdr, msg.ack.match_bits) != 48);
	BUILD_BUG_ON((int)sizeof(((struct lnet_hdr *)0)->msg.ack.match_bits) != 8);
	BUILD_BUG_ON((int)offsetof(struct lnet_hdr, msg.ack.mlength) != 56);
	BUILD_BUG_ON((int)sizeof(((struct lnet_hdr *)0)->msg.ack.mlength) != 4);

	/* Put */
	BUILD_BUG_ON((int)offsetof(struct lnet_hdr, msg.put.ack_wmd) != 32);
	BUILD_BUG_ON((int)sizeof(((struct lnet_hdr *)0)->msg.put.ack_wmd) != 16);
	BUILD_BUG_ON((int)offsetof(struct lnet_hdr, msg.put.match_bits) != 48);
	BUILD_BUG_ON((int)sizeof(((struct lnet_hdr *)0)->msg.put.match_bits) != 8);
	BUILD_BUG_ON((int)offsetof(struct lnet_hdr, msg.put.hdr_data) != 56);
	BUILD_BUG_ON((int)sizeof(((struct lnet_hdr *)0)->msg.put.hdr_data) != 8);
	BUILD_BUG_ON((int)offsetof(struct lnet_hdr, msg.put.ptl_index) != 64);
	BUILD_BUG_ON((int)sizeof(((struct lnet_hdr *)0)->msg.put.ptl_index) != 4);
	BUILD_BUG_ON((int)offsetof(struct lnet_hdr, msg.put.offset) != 68);
	BUILD_BUG_ON((int)sizeof(((struct lnet_hdr *)0)->msg.put.offset) != 4);

	/* Get */
	BUILD_BUG_ON((int)offsetof(struct lnet_hdr, msg.get.return_wmd) != 32);
	BUILD_BUG_ON((int)sizeof(((struct lnet_hdr *)0)->msg.get.return_wmd) != 16);
	BUILD_BUG_ON((int)offsetof(struct lnet_hdr, msg.get.match_bits) != 48);
	BUILD_BUG_ON((int)sizeof(((struct lnet_hdr *)0)->msg.get.match_bits) != 8);
	BUILD_BUG_ON((int)offsetof(struct lnet_hdr, msg.get.ptl_index) != 56);
	BUILD_BUG_ON((int)sizeof(((struct lnet_hdr *)0)->msg.get.ptl_index) != 4);
	BUILD_BUG_ON((int)offsetof(struct lnet_hdr, msg.get.src_offset) != 60);
	BUILD_BUG_ON((int)sizeof(((struct lnet_hdr *)0)->msg.get.src_offset) != 4);
	BUILD_BUG_ON((int)offsetof(struct lnet_hdr, msg.get.sink_length) != 64);
	BUILD_BUG_ON((int)sizeof(((struct lnet_hdr *)0)->msg.get.sink_length) != 4);

	/* Reply */
	BUILD_BUG_ON((int)offsetof(struct lnet_hdr, msg.reply.dst_wmd) != 32);
	BUILD_BUG_ON((int)sizeof(((struct lnet_hdr *)0)->msg.reply.dst_wmd) != 16);

	/* Hello */
	BUILD_BUG_ON((int)offsetof(struct lnet_hdr, msg.hello.incarnation) != 32);
	BUILD_BUG_ON((int)sizeof(((struct lnet_hdr *)0)->msg.hello.incarnation) != 8);
	BUILD_BUG_ON((int)offsetof(struct lnet_hdr, msg.hello.type) != 40);
	BUILD_BUG_ON((int)sizeof(((struct lnet_hdr *)0)->msg.hello.type) != 4);
}

static struct lnet_lnd *
lnet_find_lnd_by_type(__u32 type)
{
	struct lnet_lnd *lnd;
	struct list_head *tmp;

	/* holding lnd mutex */
	list_for_each(tmp, &the_lnet.ln_lnds) {
		lnd = list_entry(tmp, struct lnet_lnd, lnd_list);

		if (lnd->lnd_type == type)
			return lnd;
	}

	return NULL;
}

void
lnet_register_lnd(struct lnet_lnd *lnd)
{
	mutex_lock(&the_lnet.ln_lnd_mutex);

	LASSERT(libcfs_isknown_lnd(lnd->lnd_type));
	LASSERT(!lnet_find_lnd_by_type(lnd->lnd_type));

	list_add_tail(&lnd->lnd_list, &the_lnet.ln_lnds);
	lnd->lnd_refcount = 0;

	CDEBUG(D_NET, "%s LND registered\n", libcfs_lnd2str(lnd->lnd_type));

	mutex_unlock(&the_lnet.ln_lnd_mutex);
}
EXPORT_SYMBOL(lnet_register_lnd);

void
lnet_unregister_lnd(struct lnet_lnd *lnd)
{
	mutex_lock(&the_lnet.ln_lnd_mutex);

	LASSERT(lnet_find_lnd_by_type(lnd->lnd_type) == lnd);
	LASSERT(!lnd->lnd_refcount);

	list_del(&lnd->lnd_list);
	CDEBUG(D_NET, "%s LND unregistered\n", libcfs_lnd2str(lnd->lnd_type));

	mutex_unlock(&the_lnet.ln_lnd_mutex);
}
EXPORT_SYMBOL(lnet_unregister_lnd);

void
lnet_counters_get(struct lnet_counters *counters)
{
	struct lnet_counters *ctr;
	int i;

	memset(counters, 0, sizeof(*counters));

	lnet_net_lock(LNET_LOCK_EX);

	cfs_percpt_for_each(ctr, i, the_lnet.ln_counters) {
		counters->msgs_max     += ctr->msgs_max;
		counters->msgs_alloc   += ctr->msgs_alloc;
		counters->errors       += ctr->errors;
		counters->send_count   += ctr->send_count;
		counters->recv_count   += ctr->recv_count;
		counters->route_count  += ctr->route_count;
		counters->drop_count   += ctr->drop_count;
		counters->send_length  += ctr->send_length;
		counters->recv_length  += ctr->recv_length;
		counters->route_length += ctr->route_length;
		counters->drop_length  += ctr->drop_length;
	}
	lnet_net_unlock(LNET_LOCK_EX);
}
EXPORT_SYMBOL(lnet_counters_get);

void
lnet_counters_reset(void)
{
	struct lnet_counters *counters;
	int i;

	lnet_net_lock(LNET_LOCK_EX);

	cfs_percpt_for_each(counters, i, the_lnet.ln_counters)
		memset(counters, 0, sizeof(struct lnet_counters));

	lnet_net_unlock(LNET_LOCK_EX);
}

static char *
lnet_res_type2str(int type)
{
	switch (type) {
	default:
		LBUG();
	case LNET_COOKIE_TYPE_MD:
		return "MD";
	case LNET_COOKIE_TYPE_ME:
		return "ME";
	case LNET_COOKIE_TYPE_EQ:
		return "EQ";
	}
}

static void
lnet_res_container_cleanup(struct lnet_res_container *rec)
{
	int count = 0;

	if (!rec->rec_type) /* not set yet, it's uninitialized */
		return;

	while (!list_empty(&rec->rec_active)) {
		struct list_head *e = rec->rec_active.next;

		list_del_init(e);
		if (rec->rec_type == LNET_COOKIE_TYPE_EQ) {
			lnet_eq_free(list_entry(e, struct lnet_eq, eq_list));

		} else if (rec->rec_type == LNET_COOKIE_TYPE_MD) {
			lnet_md_free(list_entry(e, struct lnet_libmd, md_list));

		} else { /* NB: Active MEs should be attached on portals */
			LBUG();
		}
		count++;
	}

	if (count > 0) {
		/*
		 * Found alive MD/ME/EQ, user really should unlink/free
		 * all of them before finalize LNet, but if someone didn't,
		 * we have to recycle garbage for him
		 */
		CERROR("%d active elements on exit of %s container\n",
		       count, lnet_res_type2str(rec->rec_type));
	}

	if (rec->rec_lh_hash) {
		LIBCFS_FREE(rec->rec_lh_hash,
			    LNET_LH_HASH_SIZE * sizeof(rec->rec_lh_hash[0]));
		rec->rec_lh_hash = NULL;
	}

	rec->rec_type = 0; /* mark it as finalized */
}

static int
lnet_res_container_setup(struct lnet_res_container *rec, int cpt, int type)
{
	int rc = 0;
	int i;

	LASSERT(!rec->rec_type);

	rec->rec_type = type;
	INIT_LIST_HEAD(&rec->rec_active);
	rec->rec_lh_cookie = (cpt << LNET_COOKIE_TYPE_BITS) | type;

	/* Arbitrary choice of hash table size */
	LIBCFS_CPT_ALLOC(rec->rec_lh_hash, lnet_cpt_table(), cpt,
			 LNET_LH_HASH_SIZE * sizeof(rec->rec_lh_hash[0]));
	if (!rec->rec_lh_hash) {
		rc = -ENOMEM;
		goto out;
	}

	for (i = 0; i < LNET_LH_HASH_SIZE; i++)
		INIT_LIST_HEAD(&rec->rec_lh_hash[i]);

	return 0;

out:
	CERROR("Failed to setup %s resource container\n",
	       lnet_res_type2str(type));
	lnet_res_container_cleanup(rec);
	return rc;
}

static void
lnet_res_containers_destroy(struct lnet_res_container **recs)
{
	struct lnet_res_container *rec;
	int i;

	cfs_percpt_for_each(rec, i, recs)
		lnet_res_container_cleanup(rec);

	cfs_percpt_free(recs);
}

static struct lnet_res_container **
lnet_res_containers_create(int type)
{
	struct lnet_res_container **recs;
	struct lnet_res_container *rec;
	int rc;
	int i;

	recs = cfs_percpt_alloc(lnet_cpt_table(), sizeof(*rec));
	if (!recs) {
		CERROR("Failed to allocate %s resource containers\n",
		       lnet_res_type2str(type));
		return NULL;
	}

	cfs_percpt_for_each(rec, i, recs) {
		rc = lnet_res_container_setup(rec, i, type);
		if (rc) {
			lnet_res_containers_destroy(recs);
			return NULL;
		}
	}

	return recs;
}

struct lnet_libhandle *
lnet_res_lh_lookup(struct lnet_res_container *rec, __u64 cookie)
{
	/* ALWAYS called with lnet_res_lock held */
	struct list_head *head;
	struct lnet_libhandle *lh;
	unsigned int hash;

	if ((cookie & LNET_COOKIE_MASK) != rec->rec_type)
		return NULL;

	hash = cookie >> (LNET_COOKIE_TYPE_BITS + LNET_CPT_BITS);
	head = &rec->rec_lh_hash[hash & LNET_LH_HASH_MASK];

	list_for_each_entry(lh, head, lh_hash_chain) {
		if (lh->lh_cookie == cookie)
			return lh;
	}

	return NULL;
}

void
lnet_res_lh_initialize(struct lnet_res_container *rec,
		       struct lnet_libhandle *lh)
{
	/* ALWAYS called with lnet_res_lock held */
	unsigned int ibits = LNET_COOKIE_TYPE_BITS + LNET_CPT_BITS;
	unsigned int hash;

	lh->lh_cookie = rec->rec_lh_cookie;
	rec->rec_lh_cookie += 1 << ibits;

	hash = (lh->lh_cookie >> ibits) & LNET_LH_HASH_MASK;

	list_add(&lh->lh_hash_chain, &rec->rec_lh_hash[hash]);
}

static int lnet_unprepare(void);

static int
lnet_prepare(lnet_pid_t requested_pid)
{
	/* Prepare to bring up the network */
	struct lnet_res_container **recs;
	int rc = 0;

	if (requested_pid == LNET_PID_ANY) {
		/* Don't instantiate LNET just for me */
		return -ENETDOWN;
	}

	LASSERT(!the_lnet.ln_refcount);

	the_lnet.ln_routing = 0;

	LASSERT(!(requested_pid & LNET_PID_USERFLAG));
	the_lnet.ln_pid = requested_pid;

	INIT_LIST_HEAD(&the_lnet.ln_test_peers);
	INIT_LIST_HEAD(&the_lnet.ln_nis);
	INIT_LIST_HEAD(&the_lnet.ln_nis_cpt);
	INIT_LIST_HEAD(&the_lnet.ln_nis_zombie);
	INIT_LIST_HEAD(&the_lnet.ln_routers);
	INIT_LIST_HEAD(&the_lnet.ln_drop_rules);
	INIT_LIST_HEAD(&the_lnet.ln_delay_rules);

	rc = lnet_create_remote_nets_table();
	if (rc)
		goto failed;
	/*
	 * NB the interface cookie in wire handles guards against delayed
	 * replies and ACKs appearing valid after reboot.
	 */
	the_lnet.ln_interface_cookie = ktime_get_ns();

	the_lnet.ln_counters = cfs_percpt_alloc(lnet_cpt_table(),
						sizeof(struct lnet_counters));
	if (!the_lnet.ln_counters) {
		CERROR("Failed to allocate counters for LNet\n");
		rc = -ENOMEM;
		goto failed;
	}

	rc = lnet_peer_tables_create();
	if (rc)
		goto failed;

	rc = lnet_msg_containers_create();
	if (rc)
		goto failed;

	rc = lnet_res_container_setup(&the_lnet.ln_eq_container, 0,
				      LNET_COOKIE_TYPE_EQ);
	if (rc)
		goto failed;

	recs = lnet_res_containers_create(LNET_COOKIE_TYPE_ME);
	if (!recs) {
		rc = -ENOMEM;
		goto failed;
	}

	the_lnet.ln_me_containers = recs;

	recs = lnet_res_containers_create(LNET_COOKIE_TYPE_MD);
	if (!recs) {
		rc = -ENOMEM;
		goto failed;
	}

	the_lnet.ln_md_containers = recs;

	rc = lnet_portals_create();
	if (rc) {
		CERROR("Failed to create portals for LNet: %d\n", rc);
		goto failed;
	}

	return 0;

 failed:
	lnet_unprepare();
	return rc;
}

static int
lnet_unprepare(void)
{
	/*
	 * NB no LNET_LOCK since this is the last reference.  All LND instances
	 * have shut down already, so it is safe to unlink and free all
	 * descriptors, even those that appear committed to a network op (eg MD
	 * with non-zero pending count)
	 */
	lnet_fail_nid(LNET_NID_ANY, 0);

	LASSERT(!the_lnet.ln_refcount);
	LASSERT(list_empty(&the_lnet.ln_test_peers));
	LASSERT(list_empty(&the_lnet.ln_nis));
	LASSERT(list_empty(&the_lnet.ln_nis_cpt));
	LASSERT(list_empty(&the_lnet.ln_nis_zombie));

	lnet_portals_destroy();

	if (the_lnet.ln_md_containers) {
		lnet_res_containers_destroy(the_lnet.ln_md_containers);
		the_lnet.ln_md_containers = NULL;
	}

	if (the_lnet.ln_me_containers) {
		lnet_res_containers_destroy(the_lnet.ln_me_containers);
		the_lnet.ln_me_containers = NULL;
	}

	lnet_res_container_cleanup(&the_lnet.ln_eq_container);

	lnet_msg_containers_destroy();
	lnet_peer_tables_destroy();
	lnet_rtrpools_free(0);

	if (the_lnet.ln_counters) {
		cfs_percpt_free(the_lnet.ln_counters);
		the_lnet.ln_counters = NULL;
	}
	lnet_destroy_remote_nets_table();

	return 0;
}

struct lnet_ni  *
lnet_net2ni_locked(__u32 net, int cpt)
{
	struct list_head *tmp;
	struct lnet_ni *ni;

	LASSERT(cpt != LNET_LOCK_EX);

	list_for_each(tmp, &the_lnet.ln_nis) {
		ni = list_entry(tmp, struct lnet_ni, ni_list);

		if (LNET_NIDNET(ni->ni_nid) == net) {
			lnet_ni_addref_locked(ni, cpt);
			return ni;
		}
	}

	return NULL;
}

struct lnet_ni *
lnet_net2ni(__u32 net)
{
	struct lnet_ni *ni;

	lnet_net_lock(0);
	ni = lnet_net2ni_locked(net, 0);
	lnet_net_unlock(0);

	return ni;
}
EXPORT_SYMBOL(lnet_net2ni);

static unsigned int
lnet_nid_cpt_hash(lnet_nid_t nid, unsigned int number)
{
	__u64 key = nid;
	unsigned int val;

	LASSERT(number >= 1 && number <= LNET_CPT_NUMBER);

	if (number == 1)
		return 0;

	val = hash_long(key, LNET_CPT_BITS);
	/* NB: LNET_CP_NUMBER doesn't have to be PO2 */
	if (val < number)
		return val;

	return (unsigned int)(key + val + (val >> 1)) % number;
}

int
lnet_cpt_of_nid_locked(lnet_nid_t nid)
{
	struct lnet_ni *ni;

	/* must called with hold of lnet_net_lock */
	if (LNET_CPT_NUMBER == 1)
		return 0; /* the only one */

	/* take lnet_net_lock(any) would be OK */
	if (!list_empty(&the_lnet.ln_nis_cpt)) {
		list_for_each_entry(ni, &the_lnet.ln_nis_cpt, ni_cptlist) {
			if (LNET_NIDNET(ni->ni_nid) != LNET_NIDNET(nid))
				continue;

			LASSERT(ni->ni_cpts);
			return ni->ni_cpts[lnet_nid_cpt_hash
					   (nid, ni->ni_ncpts)];
		}
	}

	return lnet_nid_cpt_hash(nid, LNET_CPT_NUMBER);
}

int
lnet_cpt_of_nid(lnet_nid_t nid)
{
	int cpt;
	int cpt2;

	if (LNET_CPT_NUMBER == 1)
		return 0; /* the only one */

	if (list_empty(&the_lnet.ln_nis_cpt))
		return lnet_nid_cpt_hash(nid, LNET_CPT_NUMBER);

	cpt = lnet_net_lock_current();
	cpt2 = lnet_cpt_of_nid_locked(nid);
	lnet_net_unlock(cpt);

	return cpt2;
}
EXPORT_SYMBOL(lnet_cpt_of_nid);

int
lnet_islocalnet(__u32 net)
{
	struct lnet_ni *ni;
	int cpt;

	cpt = lnet_net_lock_current();

	ni = lnet_net2ni_locked(net, cpt);
	if (ni)
		lnet_ni_decref_locked(ni, cpt);

	lnet_net_unlock(cpt);

	return !!ni;
}

struct lnet_ni  *
lnet_nid2ni_locked(lnet_nid_t nid, int cpt)
{
	struct lnet_ni *ni;
	struct list_head *tmp;

	LASSERT(cpt != LNET_LOCK_EX);

	list_for_each(tmp, &the_lnet.ln_nis) {
		ni = list_entry(tmp, struct lnet_ni, ni_list);

		if (ni->ni_nid == nid) {
			lnet_ni_addref_locked(ni, cpt);
			return ni;
		}
	}

	return NULL;
}

int
lnet_islocalnid(lnet_nid_t nid)
{
	struct lnet_ni *ni;
	int cpt;

	cpt = lnet_net_lock_current();
	ni = lnet_nid2ni_locked(nid, cpt);
	if (ni)
		lnet_ni_decref_locked(ni, cpt);
	lnet_net_unlock(cpt);

	return !!ni;
}

int
lnet_count_acceptor_nis(void)
{
	/* Return the # of NIs that need the acceptor. */
	int count = 0;
	struct list_head *tmp;
	struct lnet_ni *ni;
	int cpt;

	cpt = lnet_net_lock_current();
	list_for_each(tmp, &the_lnet.ln_nis) {
		ni = list_entry(tmp, struct lnet_ni, ni_list);

		if (ni->ni_lnd->lnd_accept)
			count++;
	}

	lnet_net_unlock(cpt);

	return count;
}

static struct lnet_ping_info *
lnet_ping_info_create(int num_ni)
{
	struct lnet_ping_info *ping_info;
	unsigned int infosz;

	infosz = offsetof(struct lnet_ping_info, pi_ni[num_ni]);
	LIBCFS_ALLOC(ping_info, infosz);
	if (!ping_info) {
		CERROR("Can't allocate ping info[%d]\n", num_ni);
		return NULL;
	}

	ping_info->pi_nnis = num_ni;
	ping_info->pi_pid = the_lnet.ln_pid;
	ping_info->pi_magic = LNET_PROTO_PING_MAGIC;
	ping_info->pi_features = LNET_PING_FEAT_NI_STATUS;

	return ping_info;
}

static inline int
lnet_get_ni_count(void)
{
	struct lnet_ni *ni;
	int count = 0;

	lnet_net_lock(0);

	list_for_each_entry(ni, &the_lnet.ln_nis, ni_list)
		count++;

	lnet_net_unlock(0);

	return count;
}

static inline void
lnet_ping_info_free(struct lnet_ping_info *pinfo)
{
	LIBCFS_FREE(pinfo,
		    offsetof(struct lnet_ping_info,
			     pi_ni[pinfo->pi_nnis]));
}

static void
lnet_ping_info_destroy(void)
{
	struct lnet_ni *ni;

	lnet_net_lock(LNET_LOCK_EX);

	list_for_each_entry(ni, &the_lnet.ln_nis, ni_list) {
		lnet_ni_lock(ni);
		ni->ni_status = NULL;
		lnet_ni_unlock(ni);
	}

	lnet_ping_info_free(the_lnet.ln_ping_info);
	the_lnet.ln_ping_info = NULL;

	lnet_net_unlock(LNET_LOCK_EX);
}

static void
lnet_ping_event_handler(struct lnet_event *event)
{
	struct lnet_ping_info *pinfo = event->md.user_ptr;

	if (event->unlinked)
		pinfo->pi_features = LNET_PING_FEAT_INVAL;
}

static int
lnet_ping_info_setup(struct lnet_ping_info **ppinfo,
		     struct lnet_handle_md *md_handle,
		     int ni_count, bool set_eq)
{
	struct lnet_process_id id = {LNET_NID_ANY, LNET_PID_ANY};
	struct lnet_handle_me me_handle;
	struct lnet_md md = { NULL };
	int rc, rc2;

	if (set_eq) {
		rc = LNetEQAlloc(0, lnet_ping_event_handler,
				 &the_lnet.ln_ping_target_eq);
		if (rc) {
			CERROR("Can't allocate ping EQ: %d\n", rc);
			return rc;
		}
	}

	*ppinfo = lnet_ping_info_create(ni_count);
	if (!*ppinfo) {
		rc = -ENOMEM;
		goto failed_0;
	}

	rc = LNetMEAttach(LNET_RESERVED_PORTAL, id,
			  LNET_PROTO_PING_MATCHBITS, 0,
			  LNET_UNLINK, LNET_INS_AFTER,
			  &me_handle);
	if (rc) {
		CERROR("Can't create ping ME: %d\n", rc);
		goto failed_1;
	}

	/* initialize md content */
	md.start = *ppinfo;
	md.length = offsetof(struct lnet_ping_info,
			     pi_ni[(*ppinfo)->pi_nnis]);
	md.threshold = LNET_MD_THRESH_INF;
	md.max_size = 0;
	md.options = LNET_MD_OP_GET | LNET_MD_TRUNCATE |
		     LNET_MD_MANAGE_REMOTE;
	md.user_ptr  = NULL;
	md.eq_handle = the_lnet.ln_ping_target_eq;
	md.user_ptr = *ppinfo;

	rc = LNetMDAttach(me_handle, md, LNET_RETAIN, md_handle);
	if (rc) {
		CERROR("Can't attach ping MD: %d\n", rc);
		goto failed_2;
	}

	return 0;

failed_2:
	rc2 = LNetMEUnlink(me_handle);
	LASSERT(!rc2);
failed_1:
	lnet_ping_info_free(*ppinfo);
	*ppinfo = NULL;
failed_0:
	if (set_eq)
		LNetEQFree(the_lnet.ln_ping_target_eq);
	return rc;
}

static void
lnet_ping_md_unlink(struct lnet_ping_info *pinfo,
		    struct lnet_handle_md *md_handle)
{
	sigset_t blocked = cfs_block_allsigs();

	LNetMDUnlink(*md_handle);
	LNetInvalidateMDHandle(md_handle);

	/* NB md could be busy; this just starts the unlink */
	while (pinfo->pi_features != LNET_PING_FEAT_INVAL) {
		CDEBUG(D_NET, "Still waiting for ping MD to unlink\n");
		set_current_state(TASK_UNINTERRUPTIBLE);
		schedule_timeout(cfs_time_seconds(1));
	}

	cfs_restore_sigs(blocked);
}

static void
lnet_ping_info_install_locked(struct lnet_ping_info *ping_info)
{
	struct lnet_ni_status *ns;
	struct lnet_ni *ni;
	int i = 0;

	list_for_each_entry(ni, &the_lnet.ln_nis, ni_list) {
		LASSERT(i < ping_info->pi_nnis);

		ns = &ping_info->pi_ni[i];

		ns->ns_nid = ni->ni_nid;

		lnet_ni_lock(ni);
		ns->ns_status = (ni->ni_status) ?
				 ni->ni_status->ns_status : LNET_NI_STATUS_UP;
		ni->ni_status = ns;
		lnet_ni_unlock(ni);

		i++;
	}
}

static void
lnet_ping_target_update(struct lnet_ping_info *pinfo,
			struct lnet_handle_md md_handle)
{
	struct lnet_ping_info *old_pinfo = NULL;
	struct lnet_handle_md old_md;

	/* switch the NIs to point to the new ping info created */
	lnet_net_lock(LNET_LOCK_EX);

	if (!the_lnet.ln_routing)
		pinfo->pi_features |= LNET_PING_FEAT_RTE_DISABLED;
	lnet_ping_info_install_locked(pinfo);

	if (the_lnet.ln_ping_info) {
		old_pinfo = the_lnet.ln_ping_info;
		old_md = the_lnet.ln_ping_target_md;
	}
	the_lnet.ln_ping_target_md = md_handle;
	the_lnet.ln_ping_info = pinfo;

	lnet_net_unlock(LNET_LOCK_EX);

	if (old_pinfo) {
		/* unlink the old ping info */
		lnet_ping_md_unlink(old_pinfo, &old_md);
		lnet_ping_info_free(old_pinfo);
	}
}

static void
lnet_ping_target_fini(void)
{
	int rc;

	lnet_ping_md_unlink(the_lnet.ln_ping_info,
			    &the_lnet.ln_ping_target_md);

	rc = LNetEQFree(the_lnet.ln_ping_target_eq);
	LASSERT(!rc);

	lnet_ping_info_destroy();
}

static int
lnet_ni_tq_credits(struct lnet_ni *ni)
{
	int credits;

	LASSERT(ni->ni_ncpts >= 1);

	if (ni->ni_ncpts == 1)
		return ni->ni_maxtxcredits;

	credits = ni->ni_maxtxcredits / ni->ni_ncpts;
	credits = max(credits, 8 * ni->ni_peertxcredits);
	credits = min(credits, ni->ni_maxtxcredits);

	return credits;
}

static void
lnet_ni_unlink_locked(struct lnet_ni *ni)
{
	if (!list_empty(&ni->ni_cptlist)) {
		list_del_init(&ni->ni_cptlist);
		lnet_ni_decref_locked(ni, 0);
	}

	/* move it to zombie list and nobody can find it anymore */
	LASSERT(!list_empty(&ni->ni_list));
	list_move(&ni->ni_list, &the_lnet.ln_nis_zombie);
	lnet_ni_decref_locked(ni, 0);	/* drop ln_nis' ref */
}

static void
lnet_clear_zombies_nis_locked(void)
{
	int i;
	int islo;
	struct lnet_ni *ni;
	struct lnet_ni *temp;

	/*
	 * Now wait for the NI's I just nuked to show up on ln_zombie_nis
	 * and shut them down in guaranteed thread context
	 */
	i = 2;
	list_for_each_entry_safe(ni, temp, &the_lnet.ln_nis_zombie, ni_list) {
		int *ref;
		int j;

		list_del_init(&ni->ni_list);
		cfs_percpt_for_each(ref, j, ni->ni_refs) {
			if (!*ref)
				continue;
			/* still busy, add it back to zombie list */
			list_add(&ni->ni_list, &the_lnet.ln_nis_zombie);
			break;
		}

		if (!list_empty(&ni->ni_list)) {
			lnet_net_unlock(LNET_LOCK_EX);
			++i;
			if ((i & (-i)) == i) {
				CDEBUG(D_WARNING, "Waiting for zombie LNI %s\n",
				       libcfs_nid2str(ni->ni_nid));
			}
			set_current_state(TASK_UNINTERRUPTIBLE);
			schedule_timeout(cfs_time_seconds(1));
			lnet_net_lock(LNET_LOCK_EX);
			continue;
		}

		ni->ni_lnd->lnd_refcount--;
		lnet_net_unlock(LNET_LOCK_EX);

		islo = ni->ni_lnd->lnd_type == LOLND;

		LASSERT(!in_interrupt());
		ni->ni_lnd->lnd_shutdown(ni);

		/*
		 * can't deref lnd anymore now; it might have unregistered
		 * itself...
		 */
		if (!islo)
			CDEBUG(D_LNI, "Removed LNI %s\n",
			       libcfs_nid2str(ni->ni_nid));

		lnet_ni_free(ni);
		i = 2;

		lnet_net_lock(LNET_LOCK_EX);
	}
}

static void
lnet_shutdown_lndnis(void)
{
	struct lnet_ni *ni;
	struct lnet_ni *temp;
	int i;

	/* NB called holding the global mutex */

	/* All quiet on the API front */
	LASSERT(!the_lnet.ln_shutdown);
	LASSERT(!the_lnet.ln_refcount);
	LASSERT(list_empty(&the_lnet.ln_nis_zombie));

	lnet_net_lock(LNET_LOCK_EX);
	the_lnet.ln_shutdown = 1;	/* flag shutdown */

	/* Unlink NIs from the global table */
	list_for_each_entry_safe(ni, temp, &the_lnet.ln_nis, ni_list) {
		lnet_ni_unlink_locked(ni);
	}

	/* Drop the cached loopback NI. */
	if (the_lnet.ln_loni) {
		lnet_ni_decref_locked(the_lnet.ln_loni, 0);
		the_lnet.ln_loni = NULL;
	}

	lnet_net_unlock(LNET_LOCK_EX);

	/*
	 * Clear lazy portals and drop delayed messages which hold refs
	 * on their lnet_msg::msg_rxpeer
	 */
	for (i = 0; i < the_lnet.ln_nportals; i++)
		LNetClearLazyPortal(i);

	/*
	 * Clear the peer table and wait for all peers to go (they hold refs on
	 * their NIs)
	 */
	lnet_peer_tables_cleanup(NULL);

	lnet_net_lock(LNET_LOCK_EX);

	lnet_clear_zombies_nis_locked();
	the_lnet.ln_shutdown = 0;
	lnet_net_unlock(LNET_LOCK_EX);
}

/* shutdown down the NI and release refcount */
static void
lnet_shutdown_lndni(struct lnet_ni *ni)
{
	int i;

	lnet_net_lock(LNET_LOCK_EX);
	lnet_ni_unlink_locked(ni);
	lnet_net_unlock(LNET_LOCK_EX);

	/* clear messages for this NI on the lazy portal */
	for (i = 0; i < the_lnet.ln_nportals; i++)
		lnet_clear_lazy_portal(ni, i, "Shutting down NI");

	/* Do peer table cleanup for this ni */
	lnet_peer_tables_cleanup(ni);

	lnet_net_lock(LNET_LOCK_EX);
	lnet_clear_zombies_nis_locked();
	lnet_net_unlock(LNET_LOCK_EX);
}

static int
lnet_startup_lndni(struct lnet_ni *ni, struct lnet_ioctl_config_data *conf)
{
	struct lnet_ioctl_config_lnd_tunables *lnd_tunables = NULL;
	int rc = -EINVAL;
	int lnd_type;
	struct lnet_lnd *lnd;
	struct lnet_tx_queue *tq;
	int i;

	lnd_type = LNET_NETTYP(LNET_NIDNET(ni->ni_nid));

	LASSERT(libcfs_isknown_lnd(lnd_type));

	if (lnd_type == CIBLND || lnd_type == OPENIBLND ||
	    lnd_type == IIBLND || lnd_type == VIBLND) {
		CERROR("LND %s obsoleted\n", libcfs_lnd2str(lnd_type));
		goto failed0;
	}

	/* Make sure this new NI is unique. */
	lnet_net_lock(LNET_LOCK_EX);
	rc = lnet_net_unique(LNET_NIDNET(ni->ni_nid), &the_lnet.ln_nis);
	lnet_net_unlock(LNET_LOCK_EX);
	if (!rc) {
		if (lnd_type == LOLND) {
			lnet_ni_free(ni);
			return 0;
		}

		CERROR("Net %s is not unique\n",
		       libcfs_net2str(LNET_NIDNET(ni->ni_nid)));
		rc = -EEXIST;
		goto failed0;
	}

	mutex_lock(&the_lnet.ln_lnd_mutex);
	lnd = lnet_find_lnd_by_type(lnd_type);

	if (!lnd) {
		mutex_unlock(&the_lnet.ln_lnd_mutex);
		rc = request_module("%s", libcfs_lnd2modname(lnd_type));
		mutex_lock(&the_lnet.ln_lnd_mutex);

		lnd = lnet_find_lnd_by_type(lnd_type);
		if (!lnd) {
			mutex_unlock(&the_lnet.ln_lnd_mutex);
			CERROR("Can't load LND %s, module %s, rc=%d\n",
			       libcfs_lnd2str(lnd_type),
			       libcfs_lnd2modname(lnd_type), rc);
			rc = -EINVAL;
			goto failed0;
		}
	}

	lnet_net_lock(LNET_LOCK_EX);
	lnd->lnd_refcount++;
	lnet_net_unlock(LNET_LOCK_EX);

	ni->ni_lnd = lnd;

	if (conf && conf->cfg_hdr.ioc_len > sizeof(*conf))
		lnd_tunables = (struct lnet_ioctl_config_lnd_tunables *)conf->cfg_bulk;

	if (lnd_tunables) {
		LIBCFS_ALLOC(ni->ni_lnd_tunables,
			     sizeof(*ni->ni_lnd_tunables));
		if (!ni->ni_lnd_tunables) {
			mutex_unlock(&the_lnet.ln_lnd_mutex);
			rc = -ENOMEM;
			goto failed0;
		}
		memcpy(ni->ni_lnd_tunables, lnd_tunables,
		       sizeof(*ni->ni_lnd_tunables));
	}

	/*
	 * If given some LND tunable parameters, parse those now to
	 * override the values in the NI structure.
	 */
	if (conf) {
		if (conf->cfg_config_u.cfg_net.net_peer_rtr_credits >= 0)
			ni->ni_peerrtrcredits =
				conf->cfg_config_u.cfg_net.net_peer_rtr_credits;
		if (conf->cfg_config_u.cfg_net.net_peer_timeout >= 0)
			ni->ni_peertimeout =
				conf->cfg_config_u.cfg_net.net_peer_timeout;
		if (conf->cfg_config_u.cfg_net.net_peer_tx_credits != -1)
			ni->ni_peertxcredits =
				conf->cfg_config_u.cfg_net.net_peer_tx_credits;
		if (conf->cfg_config_u.cfg_net.net_max_tx_credits >= 0)
			ni->ni_maxtxcredits =
				conf->cfg_config_u.cfg_net.net_max_tx_credits;
	}

	rc = lnd->lnd_startup(ni);

	mutex_unlock(&the_lnet.ln_lnd_mutex);

	if (rc) {
		LCONSOLE_ERROR_MSG(0x105, "Error %d starting up LNI %s\n",
				   rc, libcfs_lnd2str(lnd->lnd_type));
		lnet_net_lock(LNET_LOCK_EX);
		lnd->lnd_refcount--;
		lnet_net_unlock(LNET_LOCK_EX);
		goto failed0;
	}

	LASSERT(ni->ni_peertimeout <= 0 || lnd->lnd_query);

	lnet_net_lock(LNET_LOCK_EX);
	/* refcount for ln_nis */
	lnet_ni_addref_locked(ni, 0);
	list_add_tail(&ni->ni_list, &the_lnet.ln_nis);
	if (ni->ni_cpts) {
		lnet_ni_addref_locked(ni, 0);
		list_add_tail(&ni->ni_cptlist, &the_lnet.ln_nis_cpt);
	}

	lnet_net_unlock(LNET_LOCK_EX);

	if (lnd->lnd_type == LOLND) {
		lnet_ni_addref(ni);
		LASSERT(!the_lnet.ln_loni);
		the_lnet.ln_loni = ni;
		return 0;
	}

	if (!ni->ni_peertxcredits || !ni->ni_maxtxcredits) {
		LCONSOLE_ERROR_MSG(0x107, "LNI %s has no %scredits\n",
				   libcfs_lnd2str(lnd->lnd_type),
				   !ni->ni_peertxcredits ?
				   "" : "per-peer ");
		/*
		 * shutdown the NI since if we get here then it must've already
		 * been started
		 */
		lnet_shutdown_lndni(ni);
		return -EINVAL;
	}

	cfs_percpt_for_each(tq, i, ni->ni_tx_queues) {
		tq->tq_credits_min =
		tq->tq_credits_max =
		tq->tq_credits = lnet_ni_tq_credits(ni);
	}

	CDEBUG(D_LNI, "Added LNI %s [%d/%d/%d/%d]\n",
	       libcfs_nid2str(ni->ni_nid), ni->ni_peertxcredits,
	       lnet_ni_tq_credits(ni) * LNET_CPT_NUMBER,
	       ni->ni_peerrtrcredits, ni->ni_peertimeout);

	return 0;
failed0:
	lnet_ni_free(ni);
	return rc;
}

static int
lnet_startup_lndnis(struct list_head *nilist)
{
	struct lnet_ni *ni;
	int rc;
	int ni_count = 0;

	while (!list_empty(nilist)) {
		ni = list_entry(nilist->next, struct lnet_ni, ni_list);
		list_del(&ni->ni_list);
		rc = lnet_startup_lndni(ni, NULL);

		if (rc < 0)
			goto failed;

		ni_count++;
	}

	return ni_count;
failed:
	lnet_shutdown_lndnis();

	return rc;
}

/**
 * Initialize LNet library.
 *
 * Automatically called at module loading time. Caller has to call
 * lnet_lib_exit() after a call to lnet_lib_init(), if and only if the
 * latter returned 0. It must be called exactly once.
 *
 * \retval 0 on success
 * \retval -ve on failures.
 */
int lnet_lib_init(void)
{
	int rc;

	lnet_assert_wire_constants();

	memset(&the_lnet, 0, sizeof(the_lnet));

	/* refer to global cfs_cpt_table for now */
	the_lnet.ln_cpt_table	= cfs_cpt_table;
	the_lnet.ln_cpt_number	= cfs_cpt_number(cfs_cpt_table);

	LASSERT(the_lnet.ln_cpt_number > 0);
	if (the_lnet.ln_cpt_number > LNET_CPT_MAX) {
		/* we are under risk of consuming all lh_cookie */
		CERROR("Can't have %d CPTs for LNet (max allowed is %d), please change setting of CPT-table and retry\n",
		       the_lnet.ln_cpt_number, LNET_CPT_MAX);
		return -E2BIG;
	}

	while ((1 << the_lnet.ln_cpt_bits) < the_lnet.ln_cpt_number)
		the_lnet.ln_cpt_bits++;

	rc = lnet_create_locks();
	if (rc) {
		CERROR("Can't create LNet global locks: %d\n", rc);
		return rc;
	}

	the_lnet.ln_refcount = 0;
	LNetInvalidateEQHandle(&the_lnet.ln_rc_eqh);
	INIT_LIST_HEAD(&the_lnet.ln_lnds);
	INIT_LIST_HEAD(&the_lnet.ln_rcd_zombie);
	INIT_LIST_HEAD(&the_lnet.ln_rcd_deathrow);

	/*
	 * The hash table size is the number of bits it takes to express the set
	 * ln_num_routes, minus 1 (better to under estimate than over so we
	 * don't waste memory).
	 */
	if (rnet_htable_size <= 0)
		rnet_htable_size = LNET_REMOTE_NETS_HASH_DEFAULT;
	else if (rnet_htable_size > LNET_REMOTE_NETS_HASH_MAX)
		rnet_htable_size = LNET_REMOTE_NETS_HASH_MAX;
	the_lnet.ln_remote_nets_hbits = max_t(int, 1,
					   order_base_2(rnet_htable_size) - 1);

	/*
	 * All LNDs apart from the LOLND are in separate modules.  They
	 * register themselves when their module loads, and unregister
	 * themselves when their module is unloaded.
	 */
	lnet_register_lnd(&the_lolnd);
	return 0;
}

/**
 * Finalize LNet library.
 *
 * \pre lnet_lib_init() called with success.
 * \pre All LNet users called LNetNIFini() for matching LNetNIInit() calls.
 */
void lnet_lib_exit(void)
{
	LASSERT(!the_lnet.ln_refcount);

	while (!list_empty(&the_lnet.ln_lnds))
		lnet_unregister_lnd(list_entry(the_lnet.ln_lnds.next,
					       struct lnet_lnd, lnd_list));
	lnet_destroy_locks();
}

/**
 * Set LNet PID and start LNet interfaces, routing, and forwarding.
 *
 * Users must call this function at least once before any other functions.
 * For each successful call there must be a corresponding call to
 * LNetNIFini(). For subsequent calls to LNetNIInit(), \a requested_pid is
 * ignored.
 *
 * The PID used by LNet may be different from the one requested.
 * See LNetGetId().
 *
 * \param requested_pid PID requested by the caller.
 *
 * \return >= 0 on success, and < 0 error code on failures.
 */
int
LNetNIInit(lnet_pid_t requested_pid)
{
	int im_a_router = 0;
	int rc;
	int ni_count;
	struct lnet_ping_info *pinfo;
	struct lnet_handle_md md_handle;
	struct list_head net_head;

	INIT_LIST_HEAD(&net_head);

	mutex_lock(&the_lnet.ln_api_mutex);

	CDEBUG(D_OTHER, "refs %d\n", the_lnet.ln_refcount);

	if (the_lnet.ln_refcount > 0) {
		rc = the_lnet.ln_refcount++;
		mutex_unlock(&the_lnet.ln_api_mutex);
		return rc;
	}

	rc = lnet_prepare(requested_pid);
	if (rc) {
		mutex_unlock(&the_lnet.ln_api_mutex);
		return rc;
	}

	/* Add in the loopback network */
	if (!lnet_ni_alloc(LNET_MKNET(LOLND, 0), NULL, &net_head)) {
		rc = -ENOMEM;
		goto err_empty_list;
	}

	/*
	 * If LNet is being initialized via DLC it is possible
	 * that the user requests not to load module parameters (ones which
	 * are supported by DLC) on initialization.  Therefore, make sure not
	 * to load networks, routes and forwarding from module parameters
	 * in this case. On cleanup in case of failure only clean up
	 * routes if it has been loaded
	 */
	if (!the_lnet.ln_nis_from_mod_params) {
		rc = lnet_parse_networks(&net_head, lnet_get_networks());
		if (rc < 0)
			goto err_empty_list;
	}

	ni_count = lnet_startup_lndnis(&net_head);
	if (ni_count < 0) {
		rc = ni_count;
		goto err_empty_list;
	}

	if (!the_lnet.ln_nis_from_mod_params) {
		rc = lnet_parse_routes(lnet_get_routes(), &im_a_router);
		if (rc)
			goto err_shutdown_lndnis;

		rc = lnet_check_routes();
		if (rc)
			goto err_destroy_routes;

		rc = lnet_rtrpools_alloc(im_a_router);
		if (rc)
			goto err_destroy_routes;
	}

	rc = lnet_acceptor_start();
	if (rc)
		goto err_destroy_routes;

	the_lnet.ln_refcount = 1;
	/* Now I may use my own API functions... */

	rc = lnet_ping_info_setup(&pinfo, &md_handle, ni_count, true);
	if (rc)
		goto err_acceptor_stop;

	lnet_ping_target_update(pinfo, md_handle);

	rc = lnet_router_checker_start();
	if (rc)
		goto err_stop_ping;

	lnet_fault_init();
	lnet_router_debugfs_init();

	mutex_unlock(&the_lnet.ln_api_mutex);

	return 0;

err_stop_ping:
	lnet_ping_target_fini();
err_acceptor_stop:
	the_lnet.ln_refcount = 0;
	lnet_acceptor_stop();
err_destroy_routes:
	if (!the_lnet.ln_nis_from_mod_params)
		lnet_destroy_routes();
err_shutdown_lndnis:
	lnet_shutdown_lndnis();
err_empty_list:
	lnet_unprepare();
	LASSERT(rc < 0);
	mutex_unlock(&the_lnet.ln_api_mutex);
	while (!list_empty(&net_head)) {
		struct lnet_ni *ni;

		ni = list_entry(net_head.next, struct lnet_ni, ni_list);
		list_del_init(&ni->ni_list);
		lnet_ni_free(ni);
	}
	return rc;
}
EXPORT_SYMBOL(LNetNIInit);

/**
 * Stop LNet interfaces, routing, and forwarding.
 *
 * Users must call this function once for each successful call to LNetNIInit().
 * Once the LNetNIFini() operation has been started, the results of pending
 * API operations are undefined.
 *
 * \return always 0 for current implementation.
 */
int
LNetNIFini(void)
{
	mutex_lock(&the_lnet.ln_api_mutex);

	LASSERT(the_lnet.ln_refcount > 0);

	if (the_lnet.ln_refcount != 1) {
		the_lnet.ln_refcount--;
	} else {
		LASSERT(!the_lnet.ln_niinit_self);

		lnet_fault_fini();
		lnet_router_debugfs_fini();
		lnet_router_checker_stop();
		lnet_ping_target_fini();

		/* Teardown fns that use my own API functions BEFORE here */
		the_lnet.ln_refcount = 0;

		lnet_acceptor_stop();
		lnet_destroy_routes();
		lnet_shutdown_lndnis();
		lnet_unprepare();
	}

	mutex_unlock(&the_lnet.ln_api_mutex);
	return 0;
}
EXPORT_SYMBOL(LNetNIFini);

/**
 * Grabs the ni data from the ni structure and fills the out
 * parameters
 *
 * \param[in] ni network       interface structure
 * \param[out] config	       NI configuration
 */
static void
lnet_fill_ni_info(struct lnet_ni *ni, struct lnet_ioctl_config_data *config)
{
	struct lnet_ioctl_config_lnd_tunables *lnd_cfg = NULL;
	struct lnet_ioctl_net_config *net_config;
	size_t min_size, tunable_size = 0;
	int i;

	if (!ni || !config)
		return;

	net_config = (struct lnet_ioctl_net_config *)config->cfg_bulk;
	if (!net_config)
		return;

	BUILD_BUG_ON(ARRAY_SIZE(ni->ni_interfaces) !=
		     ARRAY_SIZE(net_config->ni_interfaces));

	for (i = 0; i < ARRAY_SIZE(ni->ni_interfaces); i++) {
		if (!ni->ni_interfaces[i])
			break;

		strncpy(net_config->ni_interfaces[i],
			ni->ni_interfaces[i],
			sizeof(net_config->ni_interfaces[i]));
	}

	config->cfg_nid = ni->ni_nid;
	config->cfg_config_u.cfg_net.net_peer_timeout = ni->ni_peertimeout;
	config->cfg_config_u.cfg_net.net_max_tx_credits = ni->ni_maxtxcredits;
	config->cfg_config_u.cfg_net.net_peer_tx_credits = ni->ni_peertxcredits;
	config->cfg_config_u.cfg_net.net_peer_rtr_credits = ni->ni_peerrtrcredits;

	net_config->ni_status = ni->ni_status->ns_status;

	if (ni->ni_cpts) {
		int num_cpts = min(ni->ni_ncpts, LNET_MAX_SHOW_NUM_CPT);

		for (i = 0; i < num_cpts; i++)
			net_config->ni_cpts[i] = ni->ni_cpts[i];

		config->cfg_ncpts = num_cpts;
	}

	/*
	 * See if user land tools sent in a newer and larger version
	 * of struct lnet_tunables than what the kernel uses.
	 */
	min_size = sizeof(*config) + sizeof(*net_config);

	if (config->cfg_hdr.ioc_len > min_size)
		tunable_size = config->cfg_hdr.ioc_len - min_size;

	/* Don't copy to much data to user space */
	min_size = min(tunable_size, sizeof(*ni->ni_lnd_tunables));
	lnd_cfg = (struct lnet_ioctl_config_lnd_tunables *)net_config->cfg_bulk;

	if (ni->ni_lnd_tunables && lnd_cfg && min_size) {
		memcpy(lnd_cfg, ni->ni_lnd_tunables, min_size);
		config->cfg_config_u.cfg_net.net_interface_count = 1;

		/* Tell user land that kernel side has less data */
		if (tunable_size > sizeof(*ni->ni_lnd_tunables)) {
			min_size = tunable_size - sizeof(ni->ni_lnd_tunables);
			config->cfg_hdr.ioc_len -= min_size;
		}
	}
}

static int
lnet_get_net_config(struct lnet_ioctl_config_data *config)
{
	struct lnet_ni *ni;
	struct list_head *tmp;
	int idx = config->cfg_count;
	int cpt, i = 0;
	int rc = -ENOENT;

	cpt = lnet_net_lock_current();

	list_for_each(tmp, &the_lnet.ln_nis) {
		if (i++ != idx)
			continue;

		ni = list_entry(tmp, struct lnet_ni, ni_list);
		lnet_ni_lock(ni);
		lnet_fill_ni_info(ni, config);
		lnet_ni_unlock(ni);
		rc = 0;
		break;
	}

	lnet_net_unlock(cpt);
	return rc;
}

int
lnet_dyn_add_ni(lnet_pid_t requested_pid, struct lnet_ioctl_config_data *conf)
{
	char *nets = conf->cfg_config_u.cfg_net.net_intf;
	struct lnet_ping_info *pinfo;
	struct lnet_handle_md md_handle;
	struct lnet_ni *ni;
	struct list_head net_head;
	struct lnet_remotenet *rnet;
	int rc;

	INIT_LIST_HEAD(&net_head);

	/* Create a ni structure for the network string */
	rc = lnet_parse_networks(&net_head, nets);
	if (rc <= 0)
		return !rc ? -EINVAL : rc;

	mutex_lock(&the_lnet.ln_api_mutex);

	if (rc > 1) {
		rc = -EINVAL; /* only add one interface per call */
		goto failed0;
	}

	ni = list_entry(net_head.next, struct lnet_ni, ni_list);

	lnet_net_lock(LNET_LOCK_EX);
	rnet = lnet_find_net_locked(LNET_NIDNET(ni->ni_nid));
	lnet_net_unlock(LNET_LOCK_EX);
	/*
	 * make sure that the net added doesn't invalidate the current
	 * configuration LNet is keeping
	 */
	if (rnet) {
		CERROR("Adding net %s will invalidate routing configuration\n",
		       nets);
		rc = -EUSERS;
		goto failed0;
	}

	rc = lnet_ping_info_setup(&pinfo, &md_handle, 1 + lnet_get_ni_count(),
				  false);
	if (rc)
		goto failed0;

	list_del_init(&ni->ni_list);

	rc = lnet_startup_lndni(ni, conf);
	if (rc)
		goto failed1;

	if (ni->ni_lnd->lnd_accept) {
		rc = lnet_acceptor_start();
		if (rc < 0) {
			/* shutdown the ni that we just started */
			CERROR("Failed to start up acceptor thread\n");
			lnet_shutdown_lndni(ni);
			goto failed1;
		}
	}

	lnet_ping_target_update(pinfo, md_handle);
	mutex_unlock(&the_lnet.ln_api_mutex);

	return 0;

failed1:
	lnet_ping_md_unlink(pinfo, &md_handle);
	lnet_ping_info_free(pinfo);
failed0:
	mutex_unlock(&the_lnet.ln_api_mutex);
	while (!list_empty(&net_head)) {
		ni = list_entry(net_head.next, struct lnet_ni, ni_list);
		list_del_init(&ni->ni_list);
		lnet_ni_free(ni);
	}
	return rc;
}

int
lnet_dyn_del_ni(__u32 net)
{
	struct lnet_ni *ni;
	struct lnet_ping_info *pinfo;
	struct lnet_handle_md md_handle;
	int rc;

	/* don't allow userspace to shutdown the LOLND */
	if (LNET_NETTYP(net) == LOLND)
		return -EINVAL;

	mutex_lock(&the_lnet.ln_api_mutex);
	/* create and link a new ping info, before removing the old one */
	rc = lnet_ping_info_setup(&pinfo, &md_handle,
				  lnet_get_ni_count() - 1, false);
	if (rc)
		goto out;

	ni = lnet_net2ni(net);
	if (!ni) {
		rc = -EINVAL;
		goto failed;
	}

	/* decrement the reference counter taken by lnet_net2ni() */
	lnet_ni_decref_locked(ni, 0);

	lnet_shutdown_lndni(ni);

	if (!lnet_count_acceptor_nis())
		lnet_acceptor_stop();

	lnet_ping_target_update(pinfo, md_handle);
	goto out;
failed:
	lnet_ping_md_unlink(pinfo, &md_handle);
	lnet_ping_info_free(pinfo);
out:
	mutex_unlock(&the_lnet.ln_api_mutex);

	return rc;
}

/**
 * LNet ioctl handler.
 *
 */
int
LNetCtl(unsigned int cmd, void *arg)
{
	struct libcfs_ioctl_data *data = arg;
	struct lnet_ioctl_config_data *config;
	struct lnet_process_id id = {0};
	struct lnet_ni *ni;
	int rc;
	unsigned long secs_passed;

	BUILD_BUG_ON(LIBCFS_IOC_DATA_MAX <
		     sizeof(struct lnet_ioctl_net_config) +
		     sizeof(struct lnet_ioctl_config_data));

	switch (cmd) {
	case IOC_LIBCFS_GET_NI:
		rc = LNetGetId(data->ioc_count, &id);
		data->ioc_nid = id.nid;
		return rc;

	case IOC_LIBCFS_FAIL_NID:
		return lnet_fail_nid(data->ioc_nid, data->ioc_count);

	case IOC_LIBCFS_ADD_ROUTE:
		config = arg;

		if (config->cfg_hdr.ioc_len < sizeof(*config))
			return -EINVAL;

		mutex_lock(&the_lnet.ln_api_mutex);
		rc = lnet_add_route(config->cfg_net,
				    config->cfg_config_u.cfg_route.rtr_hop,
				    config->cfg_nid,
				    config->cfg_config_u.cfg_route.rtr_priority);
		if (!rc) {
			rc = lnet_check_routes();
			if (rc)
				lnet_del_route(config->cfg_net,
					       config->cfg_nid);
		}
		mutex_unlock(&the_lnet.ln_api_mutex);
		return rc;

	case IOC_LIBCFS_DEL_ROUTE:
		config = arg;

		if (config->cfg_hdr.ioc_len < sizeof(*config))
			return -EINVAL;

		mutex_lock(&the_lnet.ln_api_mutex);
		rc = lnet_del_route(config->cfg_net, config->cfg_nid);
		mutex_unlock(&the_lnet.ln_api_mutex);
		return rc;

	case IOC_LIBCFS_GET_ROUTE:
		config = arg;

		if (config->cfg_hdr.ioc_len < sizeof(*config))
			return -EINVAL;

		return lnet_get_route(config->cfg_count,
				      &config->cfg_net,
				      &config->cfg_config_u.cfg_route.rtr_hop,
				      &config->cfg_nid,
				      &config->cfg_config_u.cfg_route.rtr_flags,
				      &config->cfg_config_u.cfg_route.rtr_priority);

	case IOC_LIBCFS_GET_NET: {
		size_t total = sizeof(*config) +
			       sizeof(struct lnet_ioctl_net_config);
		config = arg;

		if (config->cfg_hdr.ioc_len < total)
			return -EINVAL;

		return lnet_get_net_config(config);
	}

	case IOC_LIBCFS_GET_LNET_STATS: {
		struct lnet_ioctl_lnet_stats *lnet_stats = arg;

		if (lnet_stats->st_hdr.ioc_len < sizeof(*lnet_stats))
			return -EINVAL;

		lnet_counters_get(&lnet_stats->st_cntrs);
		return 0;
	}

	case IOC_LIBCFS_CONFIG_RTR:
		config = arg;

		if (config->cfg_hdr.ioc_len < sizeof(*config))
			return -EINVAL;

		mutex_lock(&the_lnet.ln_api_mutex);
		if (config->cfg_config_u.cfg_buffers.buf_enable) {
			rc = lnet_rtrpools_enable();
			mutex_unlock(&the_lnet.ln_api_mutex);
			return rc;
		}
		lnet_rtrpools_disable();
		mutex_unlock(&the_lnet.ln_api_mutex);
		return 0;

	case IOC_LIBCFS_ADD_BUF:
		config = arg;

		if (config->cfg_hdr.ioc_len < sizeof(*config))
			return -EINVAL;

		mutex_lock(&the_lnet.ln_api_mutex);
		rc = lnet_rtrpools_adjust(config->cfg_config_u.cfg_buffers.buf_tiny,
					  config->cfg_config_u.cfg_buffers.buf_small,
					  config->cfg_config_u.cfg_buffers.buf_large);
		mutex_unlock(&the_lnet.ln_api_mutex);
		return rc;

	case IOC_LIBCFS_GET_BUF: {
		struct lnet_ioctl_pool_cfg *pool_cfg;
		size_t total = sizeof(*config) + sizeof(*pool_cfg);

		config = arg;

		if (config->cfg_hdr.ioc_len < total)
			return -EINVAL;

		pool_cfg = (struct lnet_ioctl_pool_cfg *)config->cfg_bulk;
		return lnet_get_rtr_pool_cfg(config->cfg_count, pool_cfg);
	}

	case IOC_LIBCFS_GET_PEER_INFO: {
		struct lnet_ioctl_peer *peer_info = arg;

		if (peer_info->pr_hdr.ioc_len < sizeof(*peer_info))
			return -EINVAL;

		return lnet_get_peer_info(peer_info->pr_count,
			&peer_info->pr_nid,
			peer_info->pr_lnd_u.pr_peer_credits.cr_aliveness,
			&peer_info->pr_lnd_u.pr_peer_credits.cr_ncpt,
			&peer_info->pr_lnd_u.pr_peer_credits.cr_refcount,
			&peer_info->pr_lnd_u.pr_peer_credits.cr_ni_peer_tx_credits,
			&peer_info->pr_lnd_u.pr_peer_credits.cr_peer_tx_credits,
			&peer_info->pr_lnd_u.pr_peer_credits.cr_peer_rtr_credits,
			&peer_info->pr_lnd_u.pr_peer_credits.cr_peer_min_rtr_credits,
			&peer_info->pr_lnd_u.pr_peer_credits.cr_peer_tx_qnob);
	}

	case IOC_LIBCFS_NOTIFY_ROUTER:
		secs_passed = (ktime_get_real_seconds() - data->ioc_u64[0]);
		secs_passed *= msecs_to_jiffies(MSEC_PER_SEC);

		return lnet_notify(NULL, data->ioc_nid, data->ioc_flags,
				   jiffies - secs_passed);

	case IOC_LIBCFS_LNET_DIST:
		rc = LNetDist(data->ioc_nid, &data->ioc_nid, &data->ioc_u32[1]);
		if (rc < 0 && rc != -EHOSTUNREACH)
			return rc;

		data->ioc_u32[0] = rc;
		return 0;

	case IOC_LIBCFS_TESTPROTOCOMPAT:
		lnet_net_lock(LNET_LOCK_EX);
		the_lnet.ln_testprotocompat = data->ioc_flags;
		lnet_net_unlock(LNET_LOCK_EX);
		return 0;

	case IOC_LIBCFS_LNET_FAULT:
		return lnet_fault_ctl(data->ioc_flags, data);

	case IOC_LIBCFS_PING:
		id.nid = data->ioc_nid;
		id.pid = data->ioc_u32[0];
		rc = lnet_ping(id, data->ioc_u32[1], /* timeout */
			       data->ioc_pbuf1,
			       data->ioc_plen1 / sizeof(struct lnet_process_id));
		if (rc < 0)
			return rc;
		data->ioc_count = rc;
		return 0;

	default:
		ni = lnet_net2ni(data->ioc_net);
		if (!ni)
			return -EINVAL;

		if (!ni->ni_lnd->lnd_ctl)
			rc = -EINVAL;
		else
			rc = ni->ni_lnd->lnd_ctl(ni, cmd, arg);

		lnet_ni_decref(ni);
		return rc;
	}
	/* not reached */
}
EXPORT_SYMBOL(LNetCtl);

void LNetDebugPeer(struct lnet_process_id id)
{
	lnet_debug_peer(id.nid);
}
EXPORT_SYMBOL(LNetDebugPeer);

/**
 * Retrieve the lnet_process_id ID of LNet interface at \a index. Note that
 * all interfaces share a same PID, as requested by LNetNIInit().
 *
 * \param index Index of the interface to look up.
 * \param id On successful return, this location will hold the
 * lnet_process_id ID of the interface.
 *
 * \retval 0 If an interface exists at \a index.
 * \retval -ENOENT If no interface has been found.
 */
int
LNetGetId(unsigned int index, struct lnet_process_id *id)
{
	struct lnet_ni *ni;
	struct list_head *tmp;
	int cpt;
	int rc = -ENOENT;

	LASSERT(the_lnet.ln_refcount > 0);

	cpt = lnet_net_lock_current();

	list_for_each(tmp, &the_lnet.ln_nis) {
		if (index--)
			continue;

		ni = list_entry(tmp, struct lnet_ni, ni_list);

		id->nid = ni->ni_nid;
		id->pid = the_lnet.ln_pid;
		rc = 0;
		break;
	}

	lnet_net_unlock(cpt);
	return rc;
}
EXPORT_SYMBOL(LNetGetId);

static int lnet_ping(struct lnet_process_id id, int timeout_ms,
		     struct lnet_process_id __user *ids, int n_ids)
{
	struct lnet_handle_eq eqh;
	struct lnet_handle_md mdh;
	struct lnet_event event;
	struct lnet_md md = { NULL };
	int which;
	int unlinked = 0;
	int replied = 0;
	const int a_long_time = 60000; /* mS */
	int infosz;
	struct lnet_ping_info *info;
	struct lnet_process_id tmpid;
	int i;
	int nob;
	int rc;
	int rc2;
	sigset_t blocked;

	infosz = offsetof(struct lnet_ping_info, pi_ni[n_ids]);

	if (n_ids <= 0 ||
	    id.nid == LNET_NID_ANY ||
	    timeout_ms > 500000 ||	      /* arbitrary limit! */
	    n_ids > 20)			 /* arbitrary limit! */
		return -EINVAL;

	if (id.pid == LNET_PID_ANY)
		id.pid = LNET_PID_LUSTRE;

	LIBCFS_ALLOC(info, infosz);
	if (!info)
		return -ENOMEM;

	/* NB 2 events max (including any unlink event) */
	rc = LNetEQAlloc(2, LNET_EQ_HANDLER_NONE, &eqh);
	if (rc) {
		CERROR("Can't allocate EQ: %d\n", rc);
		goto out_0;
	}

	/* initialize md content */
	md.start     = info;
	md.length    = infosz;
	md.threshold = 2; /*GET/REPLY*/
	md.max_size  = 0;
	md.options   = LNET_MD_TRUNCATE;
	md.user_ptr  = NULL;
	md.eq_handle = eqh;

	rc = LNetMDBind(md, LNET_UNLINK, &mdh);
	if (rc) {
		CERROR("Can't bind MD: %d\n", rc);
		goto out_1;
	}

	rc = LNetGet(LNET_NID_ANY, mdh, id,
		     LNET_RESERVED_PORTAL,
		     LNET_PROTO_PING_MATCHBITS, 0);

	if (rc) {
		/* Don't CERROR; this could be deliberate! */

		rc2 = LNetMDUnlink(mdh);
		LASSERT(!rc2);

		/* NB must wait for the UNLINK event below... */
		unlinked = 1;
		timeout_ms = a_long_time;
	}

	do {
		/* MUST block for unlink to complete */
		if (unlinked)
			blocked = cfs_block_allsigs();

		rc2 = LNetEQPoll(&eqh, 1, timeout_ms, &event, &which);

		if (unlinked)
			cfs_restore_sigs(blocked);

		CDEBUG(D_NET, "poll %d(%d %d)%s\n", rc2,
		       (rc2 <= 0) ? -1 : event.type,
		       (rc2 <= 0) ? -1 : event.status,
		       (rc2 > 0 && event.unlinked) ? " unlinked" : "");

		LASSERT(rc2 != -EOVERFLOW);     /* can't miss anything */

		if (rc2 <= 0 || event.status) {
			/* timeout or error */
			if (!replied && !rc)
				rc = (rc2 < 0) ? rc2 :
				     !rc2 ? -ETIMEDOUT :
				     event.status;

			if (!unlinked) {
				/* Ensure completion in finite time... */
				LNetMDUnlink(mdh);
				/* No assertion (racing with network) */
				unlinked = 1;
				timeout_ms = a_long_time;
			} else if (!rc2) {
				/* timed out waiting for unlink */
				CWARN("ping %s: late network completion\n",
				      libcfs_id2str(id));
			}
		} else if (event.type == LNET_EVENT_REPLY) {
			replied = 1;
			rc = event.mlength;
		}

	} while (rc2 <= 0 || !event.unlinked);

	if (!replied) {
		if (rc >= 0)
			CWARN("%s: Unexpected rc >= 0 but no reply!\n",
			      libcfs_id2str(id));
		rc = -EIO;
		goto out_1;
	}

	nob = rc;
	LASSERT(nob >= 0 && nob <= infosz);

	rc = -EPROTO;			   /* if I can't parse... */

	if (nob < 8) {
		/* can't check magic/version */
		CERROR("%s: ping info too short %d\n",
		       libcfs_id2str(id), nob);
		goto out_1;
	}

	if (info->pi_magic == __swab32(LNET_PROTO_PING_MAGIC)) {
		lnet_swap_pinginfo(info);
	} else if (info->pi_magic != LNET_PROTO_PING_MAGIC) {
		CERROR("%s: Unexpected magic %08x\n",
		       libcfs_id2str(id), info->pi_magic);
		goto out_1;
	}

	if (!(info->pi_features & LNET_PING_FEAT_NI_STATUS)) {
		CERROR("%s: ping w/o NI status: 0x%x\n",
		       libcfs_id2str(id), info->pi_features);
		goto out_1;
	}

	if (nob < offsetof(struct lnet_ping_info, pi_ni[0])) {
		CERROR("%s: Short reply %d(%d min)\n", libcfs_id2str(id),
		       nob, (int)offsetof(struct lnet_ping_info, pi_ni[0]));
		goto out_1;
	}

	if (info->pi_nnis < n_ids)
		n_ids = info->pi_nnis;

	if (nob < offsetof(struct lnet_ping_info, pi_ni[n_ids])) {
		CERROR("%s: Short reply %d(%d expected)\n", libcfs_id2str(id),
		       nob, (int)offsetof(struct lnet_ping_info, pi_ni[n_ids]));
		goto out_1;
	}

	rc = -EFAULT;			   /* If I SEGV... */

	memset(&tmpid, 0, sizeof(tmpid));
	for (i = 0; i < n_ids; i++) {
		tmpid.pid = info->pi_pid;
		tmpid.nid = info->pi_ni[i].ns_nid;
		if (copy_to_user(&ids[i], &tmpid, sizeof(tmpid)))
			goto out_1;
	}
	rc = info->pi_nnis;

 out_1:
	rc2 = LNetEQFree(eqh);
	if (rc2)
		CERROR("rc2 %d\n", rc2);
	LASSERT(!rc2);

 out_0:
	LIBCFS_FREE(info, infosz);
	return rc;
}
