* Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
* Use is subject to license terms.
*
- * Copyright (c) 2011, Whamcloud, Inc.
+ * Copyright (c) 2011, 2013, Intel Corporation.
*/
/*
* This file is part of Lustre, http://www.lustre.org/
#define DEBUG_SUBSYSTEM S_LNET
#include <lnet/lib-lnet.h>
+#ifdef __KERNEL__
+#include <linux/log2.h>
+#endif
#ifdef __KERNEL__
#define D_LNI D_CONSOLE
#endif
lnet_t the_lnet; /* THE state of the network */
+EXPORT_SYMBOL(the_lnet);
#ifdef __KERNEL__
CFS_MODULE_PARM(routes, "s", charp, 0444,
"routes to non-local networks");
+static int rnet_htable_size = LNET_REMOTE_NETS_HASH_DEFAULT;
+CFS_MODULE_PARM(rnet_htable_size, "i", int, 0444,
+ "size of remote network hash table");
+
char *
lnet_get_routes(void)
{
void
lnet_init_locks(void)
{
- cfs_spin_lock_init(&the_lnet.ln_eq_wait_lock);
+ spin_lock_init(&the_lnet.ln_eq_wait_lock);
cfs_waitq_init(&the_lnet.ln_eq_waitq);
- cfs_mutex_init(&the_lnet.ln_lnd_mutex);
- cfs_mutex_init(&the_lnet.ln_api_mutex);
+ mutex_init(&the_lnet.ln_lnd_mutex);
+ mutex_init(&the_lnet.ln_api_mutex);
}
void
{
static char default_networks[256];
char *networks = getenv ("LNET_NETWORKS");
- char *ip2nets = getenv ("LNET_IP2NETS");
char *str;
char *sep;
int len;
int nob;
- int rc;
cfs_list_t *tmp;
-#ifdef NOT_YET
- if (networks != NULL && ip2nets != NULL) {
- LCONSOLE_ERROR_MSG(0x103, "Please set EITHER 'LNET_NETWORKS' or"
- " 'LNET_IP2NETS' but not both at once\n");
- return NULL;
- }
-
- if (ip2nets != NULL) {
- rc = lnet_parse_ip2nets(&networks, ip2nets);
- return (rc == 0) ? networks : NULL;
- }
-#else
- SET_BUT_UNUSED(ip2nets);
- SET_BUT_UNUSED(rc);
-#endif
if (networks != NULL)
return networks;
/* In userland, the default 'networks=' is the list of known net types */
-
len = sizeof(default_networks);
str = default_networks;
*str = 0;
nob = snprintf(str, len, "%s%s", sep,
libcfs_lnd2str(lnd->lnd_type));
+ if (nob >= len) {
+ /* overflowed the string; leave it where it was */
+ *str = 0;
+ break;
+ }
len -= nob;
- if (len < 0) {
- /* overflowed the string; leave it where it was */
- *str = 0;
- break;
- }
-
str += nob;
sep = ",";
}
#endif
static int
-lnet_create_locks(void)
+lnet_create_remote_nets_table(void)
{
- lnet_init_locks();
+ int i;
+ cfs_list_t *hash;
+
+ LASSERT(the_lnet.ln_remote_nets_hash == NULL);
+ LASSERT(the_lnet.ln_remote_nets_hbits > 0);
+ LIBCFS_ALLOC(hash, LNET_REMOTE_NETS_HASH_SIZE * sizeof(*hash));
+ if (hash == NULL) {
+ CERROR("Failed to create remote nets hash table\n");
+ return -ENOMEM;
+ }
- the_lnet.ln_res_lock = cfs_percpt_lock_alloc(lnet_cpt_table());
- if (the_lnet.ln_res_lock == NULL)
- goto failed;
+ for (i = 0; i < LNET_REMOTE_NETS_HASH_SIZE; i++)
+ CFS_INIT_LIST_HEAD(&hash[i]);
+ the_lnet.ln_remote_nets_hash = hash;
+ return 0;
+}
- the_lnet.ln_net_lock = cfs_percpt_lock_alloc(lnet_cpt_table());
- if (the_lnet.ln_net_lock == NULL)
- goto failed;
+static void
+lnet_destroy_remote_nets_table(void)
+{
+ int i;
+ cfs_list_t *hash;
- return 0;
+ if (the_lnet.ln_remote_nets_hash == NULL)
+ return;
- failed:
- lnet_fini_locks();
- return -ENOMEM;
+ for (i = 0; i < LNET_REMOTE_NETS_HASH_SIZE; i++)
+ LASSERT(cfs_list_empty(&the_lnet.ln_remote_nets_hash[i]));
+
+ LIBCFS_FREE(the_lnet.ln_remote_nets_hash,
+ LNET_REMOTE_NETS_HASH_SIZE * sizeof(*hash));
+ the_lnet.ln_remote_nets_hash = NULL;
}
static void
lnet_fini_locks();
}
+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 == NULL)
+ goto failed;
+
+ the_lnet.ln_net_lock = cfs_percpt_lock_alloc(lnet_cpt_table());
+ if (the_lnet.ln_net_lock == NULL)
+ goto failed;
+
+ return 0;
+
+ failed:
+ lnet_destroy_locks();
+ return -ENOMEM;
+}
+
void lnet_assert_wire_constants (void)
{
/* Wire protocol assertions generated by 'wirecheck'
LNET_MUTEX_UNLOCK(&the_lnet.ln_lnd_mutex);
}
+EXPORT_SYMBOL(lnet_register_lnd);
void
lnet_unregister_lnd (lnd_t *lnd)
LNET_MUTEX_UNLOCK(&the_lnet.ln_lnd_mutex);
}
+EXPORT_SYMBOL(lnet_unregister_lnd);
void
lnet_counters_get(lnet_counters_t *counters)
CFS_INIT_LIST_HEAD(&the_lnet.ln_nis);
CFS_INIT_LIST_HEAD(&the_lnet.ln_nis_cpt);
CFS_INIT_LIST_HEAD(&the_lnet.ln_nis_zombie);
- CFS_INIT_LIST_HEAD(&the_lnet.ln_remote_nets);
CFS_INIT_LIST_HEAD(&the_lnet.ln_routers);
+ rc = lnet_create_remote_nets_table();
+ if (rc != 0)
+ goto failed;
+
the_lnet.ln_interface_cookie = lnet_create_interface_cookie();
the_lnet.ln_counters = cfs_percpt_alloc(lnet_cpt_table(),
cfs_percpt_free(the_lnet.ln_counters);
the_lnet.ln_counters = NULL;
}
+ lnet_destroy_remote_nets_table();
return 0;
}
return NULL;
}
+lnet_ni_t *
+lnet_net2ni(__u32 net)
+{
+ lnet_ni_t *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)
{
LASSERT(!the_lnet.ln_shutdown);
LASSERT(the_lnet.ln_refcount == 0);
LASSERT(cfs_list_empty(&the_lnet.ln_nis_zombie));
- LASSERT(cfs_list_empty(&the_lnet.ln_remote_nets));
lnet_net_lock(LNET_LOCK_EX);
the_lnet.ln_shutdown = 1; /* flag shutdown */
CFS_INIT_LIST_HEAD(&the_lnet.ln_rcd_deathrow);
#ifdef __KERNEL__
+ /* 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. */
#else
+ the_lnet.ln_remote_nets_hbits = 8;
+
/* Register LNDs
* NB the order here determines default 'networks=' order */
-# ifdef CRAY_XT3
- LNET_REGISTER_ULND(the_ptllnd);
-# endif
# ifdef HAVE_LIBPTHREAD
LNET_REGISTER_ULND(the_tcplnd);
# endif
lnet_register_lnd(&the_lolnd);
return 0;
}
+EXPORT_SYMBOL(LNetInit);
/**
* Finalize LNet library.
the_lnet.ln_init = 0;
}
+EXPORT_SYMBOL(LNetFini);
/**
* Set LNet PID and start LNet interfaces, routing, and forwarding.
LNET_MUTEX_UNLOCK(&the_lnet.ln_api_mutex);
return rc;
}
+EXPORT_SYMBOL(LNetNIInit);
/**
* Stop LNet interfaces, routing, and forwarding.
LNET_MUTEX_UNLOCK(&the_lnet.ln_api_mutex);
return 0;
}
+EXPORT_SYMBOL(LNetNIFini);
/**
* This is an ugly hack to export IOC_LIBCFS_DEBUG_PEER and
return lnet_fail_nid(data->ioc_nid, data->ioc_count);
case IOC_LIBCFS_ADD_ROUTE:
- rc = lnet_add_route(data->ioc_net, data->ioc_count,
- data->ioc_nid);
+ rc = lnet_add_route(data->ioc_net, data->ioc_count,
+ data->ioc_nid, data->ioc_priority);
return (rc != 0) ? rc : lnet_check_routes();
case IOC_LIBCFS_DEL_ROUTE:
case IOC_LIBCFS_GET_ROUTE:
return lnet_get_route(data->ioc_count,
&data->ioc_net, &data->ioc_count,
- &data->ioc_nid, &data->ioc_flags);
+ &data->ioc_nid, &data->ioc_flags,
+ &data->ioc_priority);
case IOC_LIBCFS_NOTIFY_ROUTER:
return lnet_notify(NULL, data->ioc_nid, data->ioc_flags,
cfs_time_current() -
}
/* not reached */
}
+EXPORT_SYMBOL(LNetCtl);
/**
* Retrieve the lnet_process_id_t ID of LNet interface at \a index. Note that
lnet_net_unlock(cpt);
return rc;
}
+EXPORT_SYMBOL(LNetGetId);
/**
* Print a string representation of handle \a h into buffer \a str of
{
snprintf(str, len, LPX64, h.cookie);
}
+EXPORT_SYMBOL(LNetSnprintHandle);
static int
lnet_create_ping_info(void)
for (i = 0; i < n_ids; i++) {
tmpid.pid = info->pi_pid;
tmpid.nid = info->pi_ni[i].ns_nid;
-#ifdef __KERNEL__
- if (cfs_copy_to_user(&ids[i], &tmpid, sizeof(tmpid)))
+ if (copy_to_user(&ids[i], &tmpid, sizeof(tmpid)))
goto out_1;
-#else
- ids[i] = tmpid;
-#endif
}
rc = info->pi_nnis;