/*
* lnet_health_sensitivity determines by how much we decrement the health
- * value on sending error. The value defaults to 0, which means health
- * checking is turned off by default.
+ * value on sending error. The value defaults to 100, which means health
+ * interface health is decremented by 100 points every failure.
*/
-unsigned int lnet_health_sensitivity = 0;
+unsigned int lnet_health_sensitivity = 100;
static int sensitivity_set(const char *val, cfs_kernel_param_arg_t *kp);
+#ifdef HAVE_KERNEL_PARAM_OPS
static struct kernel_param_ops param_ops_health_sensitivity = {
.set = sensitivity_set,
.get = param_get_int,
};
#define param_check_health_sensitivity(name, p) \
__param_check(name, p, int)
-#ifdef HAVE_KERNEL_PARAM_OPS
module_param(lnet_health_sensitivity, health_sensitivity, S_IRUGO|S_IWUSR);
#else
module_param_call(lnet_health_sensitivity, sensitivity_set, param_get_int,
*/
unsigned int lnet_recovery_interval = 1;
static int recovery_interval_set(const char *val, cfs_kernel_param_arg_t *kp);
+#ifdef HAVE_KERNEL_PARAM_OPS
static struct kernel_param_ops param_ops_recovery_interval = {
.set = recovery_interval_set,
.get = param_get_int,
};
#define param_check_recovery_interval(name, p) \
__param_check(name, p, int)
-#ifdef HAVE_KERNEL_PARAM_OPS
module_param(lnet_recovery_interval, recovery_interval, S_IRUGO|S_IWUSR);
#else
module_param_call(lnet_recovery_interval, recovery_interval_set, param_get_int,
MODULE_PARM_DESC(lnet_peer_discovery_disabled,
"Set to 1 to disable peer discovery on this node.");
-unsigned lnet_transaction_timeout = 50;
+unsigned int lnet_drop_asym_route;
+static int drop_asym_route_set(const char *val, cfs_kernel_param_arg_t *kp);
+
+static struct kernel_param_ops param_ops_drop_asym_route = {
+ .set = drop_asym_route_set,
+ .get = param_get_int,
+};
+
+#define param_check_drop_asym_route(name, p) \
+ __param_check(name, p, int)
+#ifdef HAVE_KERNEL_PARAM_OPS
+module_param(lnet_drop_asym_route, drop_asym_route, 0644);
+#else
+module_param_call(lnet_drop_asym_route, drop_asym_route_set, param_get_int,
+ ¶m_ops_drop_asym_route, 0644);
+#endif
+MODULE_PARM_DESC(lnet_drop_asym_route,
+ "Set to 1 to drop asymmetrical route messages.");
+
+#define LNET_TRANSACTION_TIMEOUT_NO_HEALTH_DEFAULT 50
+#define LNET_TRANSACTION_TIMEOUT_HEALTH_DEFAULT 10
+
+unsigned lnet_transaction_timeout = LNET_TRANSACTION_TIMEOUT_HEALTH_DEFAULT;
static int transaction_to_set(const char *val, cfs_kernel_param_arg_t *kp);
+#ifdef HAVE_KERNEL_PARAM_OPS
static struct kernel_param_ops param_ops_transaction_timeout = {
.set = transaction_to_set,
.get = param_get_int,
#define param_check_transaction_timeout(name, p) \
__param_check(name, p, int)
-#ifdef HAVE_KERNEL_PARAM_OPS
module_param(lnet_transaction_timeout, transaction_timeout, S_IRUGO|S_IWUSR);
#else
module_param_call(lnet_transaction_timeout, transaction_to_set, param_get_int,
MODULE_PARM_DESC(lnet_transaction_timeout,
"Maximum number of seconds to wait for a peer response.");
-unsigned lnet_retry_count = 0;
+#define LNET_RETRY_COUNT_HEALTH_DEFAULT 3
+unsigned lnet_retry_count = LNET_RETRY_COUNT_HEALTH_DEFAULT;
static int retry_count_set(const char *val, cfs_kernel_param_arg_t *kp);
+#ifdef HAVE_KERNEL_PARAM_OPS
static struct kernel_param_ops param_ops_retry_count = {
.set = retry_count_set,
.get = param_get_int,
#define param_check_retry_count(name, p) \
__param_check(name, p, int)
-#ifdef HAVE_KERNEL_PARAM_OPS
module_param(lnet_retry_count, retry_count, S_IRUGO|S_IWUSR);
#else
module_param_call(lnet_retry_count, retry_count_set, param_get_int,
unsigned lnet_lnd_timeout = LNET_LND_DEFAULT_TIMEOUT;
+unsigned int lnet_current_net_count;
/*
* This sequence number keeps track of how many times DLC was used to
*/
mutex_lock(&the_lnet.ln_api_mutex);
- if (the_lnet.ln_state != LNET_STATE_RUNNING) {
- mutex_unlock(&the_lnet.ln_api_mutex);
- return 0;
- }
-
if (value > LNET_MAX_HEALTH_VALUE) {
mutex_unlock(&the_lnet.ln_api_mutex);
CERROR("Invalid health value. Maximum: %d value = %lu\n",
return -EINVAL;
}
+ /*
+ * if we're turning on health then use the health timeout
+ * defaults.
+ */
+ if (*sensitivity == 0 && value != 0) {
+ lnet_transaction_timeout = LNET_TRANSACTION_TIMEOUT_HEALTH_DEFAULT;
+ lnet_retry_count = LNET_RETRY_COUNT_HEALTH_DEFAULT;
+ /*
+ * if we're turning off health then use the no health timeout
+ * default.
+ */
+ } else if (*sensitivity != 0 && value == 0) {
+ lnet_transaction_timeout =
+ LNET_TRANSACTION_TIMEOUT_NO_HEALTH_DEFAULT;
+ lnet_retry_count = 0;
+ }
+
*sensitivity = value;
mutex_unlock(&the_lnet.ln_api_mutex);
*/
mutex_lock(&the_lnet.ln_api_mutex);
- if (the_lnet.ln_state != LNET_STATE_RUNNING) {
- mutex_unlock(&the_lnet.ln_api_mutex);
- return 0;
- }
-
*interval = value;
mutex_unlock(&the_lnet.ln_api_mutex);
}
static int
-transaction_to_set(const char *val, cfs_kernel_param_arg_t *kp)
+drop_asym_route_set(const char *val, cfs_kernel_param_arg_t *kp)
{
int rc;
- unsigned *transaction_to = (unsigned *)kp->arg;
+ unsigned int *drop_asym_route = (unsigned int *)kp->arg;
unsigned long value;
rc = kstrtoul(val, 0, &value);
if (rc) {
- CERROR("Invalid module parameter value for 'lnet_transaction_timeout'\n");
+ CERROR("Invalid module parameter value for "
+ "'lnet_drop_asym_route'\n");
return rc;
}
*/
mutex_lock(&the_lnet.ln_api_mutex);
- if (the_lnet.ln_state != LNET_STATE_RUNNING) {
+ if (value == *drop_asym_route) {
mutex_unlock(&the_lnet.ln_api_mutex);
return 0;
}
+ *drop_asym_route = value;
+
+ mutex_unlock(&the_lnet.ln_api_mutex);
+
+ return 0;
+}
+
+static int
+transaction_to_set(const char *val, cfs_kernel_param_arg_t *kp)
+{
+ int rc;
+ unsigned *transaction_to = (unsigned *)kp->arg;
+ unsigned long value;
+
+ rc = kstrtoul(val, 0, &value);
+ if (rc) {
+ CERROR("Invalid module parameter value for 'lnet_transaction_timeout'\n");
+ return rc;
+ }
+
+ /*
+ * The purpose of locking the api_mutex here is to ensure that
+ * the correct value ends up stored properly.
+ */
+ mutex_lock(&the_lnet.ln_api_mutex);
+
if (value < lnet_retry_count || value == 0) {
mutex_unlock(&the_lnet.ln_api_mutex);
CERROR("Invalid value for lnet_transaction_timeout (%lu). "
*/
mutex_lock(&the_lnet.ln_api_mutex);
- if (the_lnet.ln_state != LNET_STATE_RUNNING) {
+ if (lnet_health_sensitivity == 0) {
mutex_unlock(&the_lnet.ln_api_mutex);
- return 0;
+ CERROR("Can not set retry_count when health feature is turned off\n");
+ return -EINVAL;
}
if (value > lnet_transaction_timeout) {
return -EINVAL;
}
- if (value == *retry_count) {
- mutex_unlock(&the_lnet.ln_api_mutex);
- return 0;
- }
-
*retry_count = value;
if (value == 0)
spin_lock_init(&the_lnet.ln_eq_wait_lock);
spin_lock_init(&the_lnet.ln_msg_resend_lock);
init_waitqueue_head(&the_lnet.ln_eq_waitq);
- init_waitqueue_head(&the_lnet.ln_mt_waitq);
+ init_completion(&the_lnet.ln_mt_wait_complete);
mutex_init(&the_lnet.ln_lnd_mutex);
}
LASSERT(lnet_find_lnd_by_type(lnd->lnd_type) == NULL);
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_lock(&the_lnet.ln_lnd_mutex);
LASSERT(lnet_find_lnd_by_type(lnd->lnd_type) == lnd);
- LASSERT(lnd->lnd_refcount == 0);
list_del(&lnd->lnd_list);
CDEBUG(D_NET, "%s LND unregistered\n", libcfs_lnd2str(lnd->lnd_type));
list_add(&lh->lh_hash_chain, &rec->rec_lh_hash[hash]);
}
+struct list_head **
+lnet_create_array_of_queues(void)
+{
+ struct list_head **qs;
+ struct list_head *q;
+ int i;
+
+ qs = cfs_percpt_alloc(lnet_cpt_table(),
+ sizeof(struct list_head));
+ if (!qs) {
+ CERROR("Failed to allocate queues\n");
+ return NULL;
+ }
+
+ cfs_percpt_for_each(q, i, qs)
+ INIT_LIST_HEAD(q);
+
+ return qs;
+}
+
static int lnet_unprepare(void);
static int
INIT_LIST_HEAD(&the_lnet.ln_mt_localNIRecovq);
INIT_LIST_HEAD(&the_lnet.ln_mt_peerNIRecovq);
init_waitqueue_head(&the_lnet.ln_dc_waitq);
+ LNetInvalidateEQHandle(&the_lnet.ln_mt_eqh);
+ init_completion(&the_lnet.ln_started);
rc = lnet_descriptor_setup();
if (rc != 0)
goto failed;
}
+ the_lnet.ln_mt_zombie_rstqs = lnet_create_array_of_queues();
+ if (!the_lnet.ln_mt_zombie_rstqs) {
+ rc = -ENOMEM;
+ goto failed;
+ }
+
return 0;
failed:
static int
lnet_unprepare (void)
{
+ int rc;
+
/* 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
LASSERT(list_empty(&the_lnet.ln_test_peers));
LASSERT(list_empty(&the_lnet.ln_nets));
+ if (the_lnet.ln_mt_zombie_rstqs) {
+ lnet_clean_zombie_rstqs();
+ the_lnet.ln_mt_zombie_rstqs = NULL;
+ }
+
+ if (!LNetEQHandleIsInvalid(the_lnet.ln_mt_eqh)) {
+ rc = LNetEQFree(the_lnet.ln_mt_eqh);
+ LNetInvalidateEQHandle(&the_lnet.ln_mt_eqh);
+ LASSERT(rc == 0);
+ }
+
lnet_portals_destroy();
if (the_lnet.ln_md_containers != NULL) {
EXPORT_SYMBOL(lnet_cpt_of_nid);
int
-lnet_islocalnet(__u32 net_id)
+lnet_islocalnet_locked(__u32 net_id)
{
struct lnet_net *net;
- int cpt;
- bool local;
-
- cpt = lnet_net_lock_current();
+ bool local;
net = lnet_get_net_locked(net_id);
local = net != NULL;
+ return local;
+}
+
+int
+lnet_islocalnet(__u32 net_id)
+{
+ int cpt;
+ bool local;
+
+ cpt = lnet_net_lock_current();
+
+ local = lnet_islocalnet_locked(net_id);
+
lnet_net_unlock(cpt);
return local;
}
int
+lnet_get_net_count(void)
+{
+ struct lnet_net *net;
+ int count = 0;
+
+ lnet_net_lock(0);
+
+ list_for_each_entry(net, &the_lnet.ln_nets, net_list) {
+ count++;
+ }
+
+ lnet_net_unlock(0);
+
+ return count;
+}
+
+void
+lnet_swap_pinginfo(struct lnet_ping_buffer *pbuf)
+{
+ struct lnet_ni_status *stat;
+ int nnis;
+ int i;
+
+ __swab32s(&pbuf->pb_info.pi_magic);
+ __swab32s(&pbuf->pb_info.pi_features);
+ __swab32s(&pbuf->pb_info.pi_pid);
+ __swab32s(&pbuf->pb_info.pi_nnis);
+ nnis = pbuf->pb_info.pi_nnis;
+ if (nnis > pbuf->pb_nnis)
+ nnis = pbuf->pb_nnis;
+ for (i = 0; i < nnis; i++) {
+ stat = &pbuf->pb_info.pi_ni[i];
+ __swab64s(&stat->ns_nid);
+ __swab32s(&stat->ns_status);
+ }
+}
+
+int
lnet_ping_info_validate(struct lnet_ping_info *pinfo)
{
if (!pinfo)
lnet_net_lock(LNET_LOCK_EX);
- net->net_state = LNET_NET_STATE_DELETING;
-
list_del_init(&net->net_list);
while (!list_empty(&net->net_ni_list)) {
/* Do peer table cleanup for this net */
lnet_peer_tables_cleanup(net);
- lnet_net_lock(LNET_LOCK_EX);
- /*
- * decrement ref count on lnd only when the entire network goes
- * away
- */
- net->net_lnd->lnd_refcount--;
-
- lnet_net_unlock(LNET_LOCK_EX);
-
lnet_net_free(net);
}
if (rc != 0) {
LCONSOLE_ERROR_MSG(0x105, "Error %d starting up LNI %s\n",
rc, libcfs_lnd2str(net->net_lnd->lnd_type));
- lnet_net_lock(LNET_LOCK_EX);
- net->net_lnd->lnd_refcount--;
- lnet_net_unlock(LNET_LOCK_EX);
goto failed0;
}
}
}
- lnet_net_lock(LNET_LOCK_EX);
- lnd->lnd_refcount++;
- lnet_net_unlock(LNET_LOCK_EX);
-
net->net_lnd = lnd;
mutex_unlock(&the_lnet.ln_lnd_mutex);
* up is actually unique. if it's not fail. */
if (!lnet_ni_unique_net(&net_l->net_ni_list,
ni->ni_interfaces[0])) {
- rc = -EINVAL;
+ rc = -EEXIST;
goto failed1;
}
*/
lnet_net_free(net);
} else {
- net->net_state = LNET_NET_STATE_ACTIVE;
/*
* restore tunables after it has been overwitten by the
* lnd
lnet_net_unlock(LNET_LOCK_EX);
}
+ /* update net count */
+ lnet_current_net_count = lnet_get_net_count();
+
return ni_count;
failed1:
}
the_lnet.ln_refcount = 0;
- LNetInvalidateEQHandle(&the_lnet.ln_rc_eqh);
INIT_LIST_HEAD(&the_lnet.ln_lnds);
INIT_LIST_HEAD(&the_lnet.ln_net_zombie);
- INIT_LIST_HEAD(&the_lnet.ln_rcd_zombie);
INIT_LIST_HEAD(&the_lnet.ln_msg_resend);
- 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
if (rc != 0)
goto err_shutdown_lndnis;
- rc = lnet_check_routes();
- if (rc != 0)
- goto err_destroy_routes;
-
rc = lnet_rtrpools_alloc(im_a_router);
if (rc != 0)
goto err_destroy_routes;
lnet_ping_target_update(pbuf, ping_mdh);
- rc = lnet_monitor_thr_start();
- if (rc != 0)
+ rc = LNetEQAlloc(0, lnet_mt_event_handler, &the_lnet.ln_mt_eqh);
+ if (rc != 0) {
+ CERROR("Can't allocate monitor thread EQ: %d\n", rc);
goto err_stop_ping;
+ }
rc = lnet_push_target_init();
if (rc != 0)
- goto err_stop_monitor_thr;
+ goto err_stop_ping;
rc = lnet_peer_discovery_start();
if (rc != 0)
goto err_destroy_push_target;
+ rc = lnet_monitor_thr_start();
+ if (rc != 0)
+ goto err_stop_discovery_thr;
+
lnet_fault_init();
lnet_router_debugfs_init();
mutex_unlock(&the_lnet.ln_api_mutex);
+ complete_all(&the_lnet.ln_started);
+
+ /* wait for all routers to start */
+ lnet_wait_router_start();
+
return 0;
+err_stop_discovery_thr:
+ lnet_peer_discovery_stop();
err_destroy_push_target:
lnet_push_target_fini();
-err_stop_monitor_thr:
- lnet_monitor_thr_stop();
err_stop_ping:
lnet_ping_target_fini();
err_acceptor_stop:
* \return always 0 for current implementation.
*/
int
-LNetNIFini()
+LNetNIFini(void)
{
mutex_lock(&the_lnet.ln_api_mutex);
lnet_fault_fini();
- lnet_router_debugfs_init();
+ lnet_router_debugfs_fini();
+ lnet_monitor_thr_stop();
lnet_peer_discovery_stop();
lnet_push_target_fini();
- lnet_monitor_thr_stop();
lnet_ping_target_fini();
/* Teardown fns that use my own API functions BEFORE here */
case IOC_LIBCFS_FAIL_NID:
return lnet_fail_nid(data->ioc_nid, data->ioc_count);
- case IOC_LIBCFS_ADD_ROUTE:
+ case IOC_LIBCFS_ADD_ROUTE: {
+ /* default router sensitivity to 1 */
+ unsigned int sensitivity = 1;
config = arg;
if (config->cfg_hdr.ioc_len < sizeof(*config))
return -EINVAL;
+ if (config->cfg_config_u.cfg_route.rtr_sensitivity) {
+ sensitivity =
+ config->cfg_config_u.cfg_route.rtr_sensitivity;
+ }
+
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 == 0) {
- rc = lnet_check_routes();
- if (rc != 0)
- lnet_del_route(config->cfg_net,
- config->cfg_nid);
- }
+ rtr_priority, sensitivity);
mutex_unlock(&the_lnet.ln_api_mutex);
return rc;
+ }
case IOC_LIBCFS_DEL_ROUTE:
config = arg;
&config->cfg_nid,
&config->cfg_config_u.cfg_route.rtr_flags,
&config->cfg_config_u.cfg_route.
- rtr_priority);
+ rtr_priority,
+ &config->cfg_config_u.cfg_route.
+ rtr_sensitivity);
mutex_unlock(&the_lnet.ln_api_mutex);
return rc;
* that deadline to the wall clock.
*/
deadline += ktime_get_seconds();
- return lnet_notify(NULL, data->ioc_nid, data->ioc_flags,
+ return lnet_notify(NULL, data->ioc_nid, data->ioc_flags, false,
deadline);
}
/* If timeout is negative then set default of 3 minutes */
if (((s32)data->ioc_u32[1] <= 0) ||
data->ioc_u32[1] > (DEFAULT_PEER_TIMEOUT * MSEC_PER_SEC))
- timeout = msecs_to_jiffies(DEFAULT_PEER_TIMEOUT * MSEC_PER_SEC);
+ timeout = cfs_time_seconds(DEFAULT_PEER_TIMEOUT);
else
- timeout = msecs_to_jiffies(data->ioc_u32[1]);
+ timeout = nsecs_to_jiffies(data->ioc_u32[1] * NSEC_PER_MSEC);
rc = lnet_ping(id, timeout, data->ioc_pbuf1,
data->ioc_plen1 / sizeof(struct lnet_process_id));
/* If timeout is negative then set default of 3 minutes */
if (((s32)ping->op_param) <= 0 ||
ping->op_param > (DEFAULT_PEER_TIMEOUT * MSEC_PER_SEC))
- timeout = msecs_to_jiffies(DEFAULT_PEER_TIMEOUT * MSEC_PER_SEC);
+ timeout = cfs_time_seconds(DEFAULT_PEER_TIMEOUT);
else
- timeout = msecs_to_jiffies(ping->op_param);
+ timeout = nsecs_to_jiffies(ping->op_param * NSEC_PER_MSEC);
rc = lnet_ping(ping->ping_id, timeout,
ping->ping_buf,
int which;
int unlinked = 0;
int replied = 0;
- const signed long a_long_time = msecs_to_jiffies(60 * MSEC_PER_SEC);
+ const signed long a_long_time = cfs_time_seconds(60);
struct lnet_ping_buffer *pbuf;
struct lnet_process_id tmpid;
int i;