*/
/*
* This file is part of Lustre, http://www.lustre.org/
- * Lustre is a trademark of Sun Microsystems, Inc.
*/
#define DEBUG_SUBSYSTEM S_LNET
#ifdef HAVE_SCHED_HEADERS
#include <linux/sched/signal.h>
#endif
-
+#include <lnet/udsp.h>
#include <lnet/lib-lnet.h>
#define D_LNI D_CONSOLE
module_param(rnet_htable_size, int, 0444);
MODULE_PARM_DESC(rnet_htable_size, "size of remote network hash table");
-static int use_tcp_bonding = false;
+static int use_tcp_bonding;
module_param(use_tcp_bonding, int, 0444);
MODULE_PARM_DESC(use_tcp_bonding,
- "use_tcp_bonding parameter has been deprecated");
+ "use_tcp_bonding parameter has been removed");
unsigned int lnet_numa_range = 0;
module_param(lnet_numa_range, uint, 0444);
&lnet_recovery_interval, S_IRUGO|S_IWUSR);
#endif
MODULE_PARM_DESC(lnet_recovery_interval,
- "Interval to recover unhealthy interfaces in seconds");
+ "DEPRECATED - Interval to recover unhealthy interfaces in seconds");
unsigned int lnet_recovery_limit;
module_param(lnet_recovery_limit, uint, 0644);
MODULE_PARM_DESC(lnet_recovery_limit,
"How long to attempt recovery of unhealthy peer interfaces in seconds. Set to 0 to allow indefinite recovery");
+unsigned int lnet_max_recovery_ping_interval = 900;
+unsigned int lnet_max_recovery_ping_count = 9;
+static int max_recovery_ping_interval_set(const char *val,
+ cfs_kernel_param_arg_t *kp);
+
+#define param_check_max_recovery_ping_interval(name, p) \
+ __param_check(name, p, int)
+
+#ifdef HAVE_KERNEL_PARAM_OPS
+static struct kernel_param_ops param_ops_max_recovery_ping_interval = {
+ .set = max_recovery_ping_interval_set,
+ .get = param_get_int,
+};
+module_param(lnet_max_recovery_ping_interval, max_recovery_ping_interval, 0644);
+#else
+module_param_call(lnet_max_recovery_ping_interval, max_recovery_ping_interval,
+ param_get_int, &lnet_max_recovery_ping_interval, 0644);
+#endif
+MODULE_PARM_DESC(lnet_max_recovery_ping_interval,
+ "The max interval between LNet recovery pings, in seconds");
+
static int lnet_interfaces_max = LNET_INTERFACES_MAX_DEFAULT;
static int intf_max_set(const char *val, cfs_kernel_param_arg_t *kp);
(lnet_retry_count + 1);
}
-unsigned int lnet_current_net_count;
-
/*
* This sequence number keeps track of how many times DLC was used to
* update the local NIs. It is incremented when a NI is added or
*/
static atomic_t lnet_dlc_seq_no = ATOMIC_INIT(0);
-static int lnet_ping(struct lnet_process_id id, signed long timeout,
- struct lnet_process_id __user *ids, int n_ids);
+static int lnet_ping(struct lnet_process_id id4, struct lnet_nid *src_nid,
+ signed long timeout, struct lnet_process_id __user *ids,
+ int n_ids);
static int lnet_discover(struct lnet_process_id id, __u32 force,
struct lnet_process_id __user *ids, int n_ids);
static int
recovery_interval_set(const char *val, cfs_kernel_param_arg_t *kp)
{
+ CWARN("'lnet_recovery_interval' has been deprecated\n");
+
+ return 0;
+}
+
+static int
+max_recovery_ping_interval_set(const char *val, cfs_kernel_param_arg_t *kp)
+{
int rc;
- unsigned *interval = (unsigned *)kp->arg;
unsigned long value;
rc = kstrtoul(val, 0, &value);
if (rc) {
- CERROR("Invalid module parameter value for 'lnet_recovery_interval'\n");
+ CERROR("Invalid module parameter value for 'lnet_max_recovery_ping_interval'\n");
return rc;
}
- if (value < 1) {
- CERROR("lnet_recovery_interval must be at least 1 second\n");
+ if (!value) {
+ CERROR("Invalid max ping timeout. Must be strictly positive\n");
return -EINVAL;
}
- /*
- * The purpose of locking the api_mutex here is to ensure that
+ /* 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);
-
- *interval = value;
-
+ lnet_max_recovery_ping_interval = value;
+ lnet_max_recovery_ping_count = 0;
+ value >>= 1;
+ while (value) {
+ lnet_max_recovery_ping_count++;
+ value >>= 1;
+ }
mutex_unlock(&the_lnet.ln_api_mutex);
return 0;
struct kmem_cache *lnet_mes_cachep; /* MEs kmem_cache */
struct kmem_cache *lnet_small_mds_cachep; /* <= LNET_SMALL_MD_SIZE bytes
* MDs kmem_cache */
+struct kmem_cache *lnet_udsp_cachep; /* udsp cache */
struct kmem_cache *lnet_rspt_cachep; /* response tracker cache */
struct kmem_cache *lnet_msg_cachep;
if (!lnet_small_mds_cachep)
return -ENOMEM;
+ lnet_udsp_cachep = kmem_cache_create("lnet_udsp",
+ sizeof(struct lnet_udsp),
+ 0, 0, NULL);
+ if (!lnet_udsp_cachep)
+ return -ENOMEM;
+
lnet_rspt_cachep = kmem_cache_create("lnet_rspt", sizeof(struct lnet_rsp_tracker),
0, 0, NULL);
if (!lnet_rspt_cachep)
lnet_msg_cachep = NULL;
}
-
if (lnet_rspt_cachep) {
kmem_cache_destroy(lnet_rspt_cachep);
lnet_rspt_cachep = NULL;
}
+ if (lnet_udsp_cachep) {
+ kmem_cache_destroy(lnet_udsp_cachep);
+ lnet_udsp_cachep = NULL;
+ }
+
if (lnet_small_mds_cachep) {
kmem_cache_destroy(lnet_small_mds_cachep);
lnet_small_mds_cachep = NULL;
/* 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) */
+ * 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_MSG_REPLY != 3);
BUILD_BUG_ON(LNET_MSG_HELLO != 4);
+ BUILD_BUG_ON((int)sizeof(lnet_nid_t) != 8);
+ BUILD_BUG_ON((int)sizeof(lnet_pid_t) != 4);
+
+ /* Checks for struct lnet_nid */
+ BUILD_BUG_ON((int)sizeof(struct lnet_nid) != 20);
+ BUILD_BUG_ON((int)offsetof(struct lnet_nid, nid_size) != 0);
+ BUILD_BUG_ON((int)sizeof(((struct lnet_nid *)0)->nid_size) != 1);
+ BUILD_BUG_ON((int)offsetof(struct lnet_nid, nid_type) != 1);
+ BUILD_BUG_ON((int)sizeof(((struct lnet_nid *)0)->nid_type) != 1);
+ BUILD_BUG_ON((int)offsetof(struct lnet_nid, nid_num) != 2);
+ BUILD_BUG_ON((int)sizeof(((struct lnet_nid *)0)->nid_num) != 2);
+ BUILD_BUG_ON((int)offsetof(struct lnet_nid, nid_addr) != 4);
+ BUILD_BUG_ON((int)sizeof(((struct lnet_nid *)0)->nid_addr) != 16);
+
+ /* Checks for struct lnet_process_id_packed */
+ BUILD_BUG_ON((int)sizeof(struct lnet_process_id_packed) != 12);
+ BUILD_BUG_ON((int)offsetof(struct lnet_process_id_packed, nid) != 0);
+ BUILD_BUG_ON((int)sizeof(((struct lnet_process_id_packed *)0)->nid) != 8);
+ BUILD_BUG_ON((int)offsetof(struct lnet_process_id_packed, pid) != 8);
+ BUILD_BUG_ON((int)sizeof(((struct lnet_process_id_packed *)0)->pid) != 4);
+
/* Checks for struct lnet_handle_wire */
BUILD_BUG_ON((int)sizeof(struct lnet_handle_wire) != 16);
BUILD_BUG_ON((int)offsetof(struct lnet_handle_wire,
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);
+ /* Checks for struct _lnet_hdr_nid4 */
+ BUILD_BUG_ON((int)sizeof(struct _lnet_hdr_nid4) != 72);
+ BUILD_BUG_ON((int)offsetof(struct _lnet_hdr_nid4, dest_nid) != 0);
+ BUILD_BUG_ON((int)sizeof(((struct _lnet_hdr_nid4 *)0)->dest_nid) != 8);
+ BUILD_BUG_ON((int)offsetof(struct _lnet_hdr_nid4, src_nid) != 8);
+ BUILD_BUG_ON((int)sizeof(((struct _lnet_hdr_nid4 *)0)->src_nid) != 8);
+ BUILD_BUG_ON((int)offsetof(struct _lnet_hdr_nid4, dest_pid) != 16);
+ BUILD_BUG_ON((int)sizeof(((struct _lnet_hdr_nid4 *)0)->dest_pid) != 4);
+ BUILD_BUG_ON((int)offsetof(struct _lnet_hdr_nid4, src_pid) != 20);
+ BUILD_BUG_ON((int)sizeof(((struct _lnet_hdr_nid4 *)0)->src_pid) != 4);
+ BUILD_BUG_ON((int)offsetof(struct _lnet_hdr_nid4, type) != 24);
+ BUILD_BUG_ON((int)sizeof(((struct _lnet_hdr_nid4 *)0)->type) != 4);
+ BUILD_BUG_ON((int)offsetof(struct _lnet_hdr_nid4, payload_length) != 28);
+ BUILD_BUG_ON((int)sizeof(((struct _lnet_hdr_nid4 *)0)->payload_length) != 4);
+ BUILD_BUG_ON((int)offsetof(struct _lnet_hdr_nid4, msg) != 32);
+ BUILD_BUG_ON((int)sizeof(((struct _lnet_hdr_nid4 *)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);
+ BUILD_BUG_ON((int)offsetof(struct _lnet_hdr_nid4, msg.ack.dst_wmd) != 32);
+ BUILD_BUG_ON((int)sizeof(((struct _lnet_hdr_nid4 *)0)->msg.ack.dst_wmd) != 16);
+ BUILD_BUG_ON((int)offsetof(struct _lnet_hdr_nid4, msg.ack.match_bits) != 48);
+ BUILD_BUG_ON((int)sizeof(((struct _lnet_hdr_nid4 *)0)->msg.ack.match_bits) != 8);
+ BUILD_BUG_ON((int)offsetof(struct _lnet_hdr_nid4, msg.ack.mlength) != 56);
+ BUILD_BUG_ON((int)sizeof(((struct _lnet_hdr_nid4 *)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);
+ BUILD_BUG_ON((int)offsetof(struct _lnet_hdr_nid4, msg.put.ack_wmd) != 32);
+ BUILD_BUG_ON((int)sizeof(((struct _lnet_hdr_nid4 *)0)->msg.put.ack_wmd) != 16);
+ BUILD_BUG_ON((int)offsetof(struct _lnet_hdr_nid4, msg.put.match_bits) != 48);
+ BUILD_BUG_ON((int)sizeof(((struct _lnet_hdr_nid4 *)0)->msg.put.match_bits) != 8);
+ BUILD_BUG_ON((int)offsetof(struct _lnet_hdr_nid4, msg.put.hdr_data) != 56);
+ BUILD_BUG_ON((int)sizeof(((struct _lnet_hdr_nid4 *)0)->msg.put.hdr_data) != 8);
+ BUILD_BUG_ON((int)offsetof(struct _lnet_hdr_nid4, msg.put.ptl_index) != 64);
+ BUILD_BUG_ON((int)sizeof(((struct _lnet_hdr_nid4 *)0)->msg.put.ptl_index) != 4);
+ BUILD_BUG_ON((int)offsetof(struct _lnet_hdr_nid4, msg.put.offset) != 68);
+ BUILD_BUG_ON((int)sizeof(((struct _lnet_hdr_nid4 *)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);
+ BUILD_BUG_ON((int)offsetof(struct _lnet_hdr_nid4, msg.get.return_wmd) != 32);
+ BUILD_BUG_ON((int)sizeof(((struct _lnet_hdr_nid4 *)0)->msg.get.return_wmd) != 16);
+ BUILD_BUG_ON((int)offsetof(struct _lnet_hdr_nid4, msg.get.match_bits) != 48);
+ BUILD_BUG_ON((int)sizeof(((struct _lnet_hdr_nid4 *)0)->msg.get.match_bits) != 8);
+ BUILD_BUG_ON((int)offsetof(struct _lnet_hdr_nid4, msg.get.ptl_index) != 56);
+ BUILD_BUG_ON((int)sizeof(((struct _lnet_hdr_nid4 *)0)->msg.get.ptl_index) != 4);
+ BUILD_BUG_ON((int)offsetof(struct _lnet_hdr_nid4, msg.get.src_offset) != 60);
+ BUILD_BUG_ON((int)sizeof(((struct _lnet_hdr_nid4 *)0)->msg.get.src_offset) != 4);
+ BUILD_BUG_ON((int)offsetof(struct _lnet_hdr_nid4, msg.get.sink_length) != 64);
+ BUILD_BUG_ON((int)sizeof(((struct _lnet_hdr_nid4 *)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);
+ BUILD_BUG_ON((int)offsetof(struct _lnet_hdr_nid4, msg.reply.dst_wmd) != 32);
+ BUILD_BUG_ON((int)sizeof(((struct _lnet_hdr_nid4 *)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);
+ BUILD_BUG_ON((int)offsetof(struct _lnet_hdr_nid4, msg.hello.incarnation) != 32);
+ BUILD_BUG_ON((int)sizeof(((struct _lnet_hdr_nid4 *)0)->msg.hello.incarnation) != 8);
+ BUILD_BUG_ON((int)offsetof(struct _lnet_hdr_nid4, msg.hello.type) != 40);
+ BUILD_BUG_ON((int)sizeof(((struct _lnet_hdr_nid4 *)0)->msg.hello.type) != 4);
/* Checks for struct lnet_ni_status and related constants */
BUILD_BUG_ON(LNET_NI_STATUS_INVALID != 0x00000000);
BUILD_BUG_ON((int)sizeof(((struct lnet_ping_info *)0)->pi_nnis) != 4);
BUILD_BUG_ON((int)offsetof(struct lnet_ping_info, pi_ni) != 16);
BUILD_BUG_ON((int)sizeof(((struct lnet_ping_info *)0)->pi_ni) != 0);
+
+ /* Acceptor connection request */
+ BUILD_BUG_ON(LNET_PROTO_ACCEPTOR_VERSION != 1);
+
+ /* Checks for struct lnet_acceptor_connreq */
+ BUILD_BUG_ON((int)sizeof(struct lnet_acceptor_connreq) != 16);
+ BUILD_BUG_ON((int)offsetof(struct lnet_acceptor_connreq, acr_magic) != 0);
+ BUILD_BUG_ON((int)sizeof(((struct lnet_acceptor_connreq *)0)->acr_magic) != 4);
+ BUILD_BUG_ON((int)offsetof(struct lnet_acceptor_connreq, acr_version) != 4);
+ BUILD_BUG_ON((int)sizeof(((struct lnet_acceptor_connreq *)0)->acr_version) != 4);
+ BUILD_BUG_ON((int)offsetof(struct lnet_acceptor_connreq, acr_nid) != 8);
+ BUILD_BUG_ON((int)sizeof(((struct lnet_acceptor_connreq *)0)->acr_nid) != 8);
+
+ /* Checks for struct lnet_acceptor_connreq_v2 */
+ BUILD_BUG_ON((int)sizeof(struct lnet_acceptor_connreq_v2) != 28);
+ BUILD_BUG_ON((int)offsetof(struct lnet_acceptor_connreq_v2, acr_magic) != 0);
+ BUILD_BUG_ON((int)sizeof(((struct lnet_acceptor_connreq_v2 *)0)->acr_magic) != 4);
+ BUILD_BUG_ON((int)offsetof(struct lnet_acceptor_connreq_v2, acr_version) != 4);
+ BUILD_BUG_ON((int)sizeof(((struct lnet_acceptor_connreq_v2 *)0)->acr_version) != 4);
+ BUILD_BUG_ON((int)offsetof(struct lnet_acceptor_connreq_v2, acr_nid) != 8);
+ BUILD_BUG_ON((int)sizeof(((struct lnet_acceptor_connreq_v2 *)0)->acr_nid) != 20);
+
+ /* Checks for struct lnet_counters_common */
+ BUILD_BUG_ON((int)sizeof(struct lnet_counters_common) != 60);
+ BUILD_BUG_ON((int)offsetof(struct lnet_counters_common, lcc_msgs_alloc) != 0);
+ BUILD_BUG_ON((int)sizeof(((struct lnet_counters_common *)0)->lcc_msgs_alloc) != 4);
+ BUILD_BUG_ON((int)offsetof(struct lnet_counters_common, lcc_msgs_max) != 4);
+ BUILD_BUG_ON((int)sizeof(((struct lnet_counters_common *)0)->lcc_msgs_max) != 4);
+ BUILD_BUG_ON((int)offsetof(struct lnet_counters_common, lcc_errors) != 8);
+ BUILD_BUG_ON((int)sizeof(((struct lnet_counters_common *)0)->lcc_errors) != 4);
+ BUILD_BUG_ON((int)offsetof(struct lnet_counters_common, lcc_send_count) != 12);
+ BUILD_BUG_ON((int)sizeof(((struct lnet_counters_common *)0)->lcc_send_count) != 4);
+ BUILD_BUG_ON((int)offsetof(struct lnet_counters_common, lcc_recv_count) != 16);
+ BUILD_BUG_ON((int)sizeof(((struct lnet_counters_common *)0)->lcc_recv_count) != 4);
+ BUILD_BUG_ON((int)offsetof(struct lnet_counters_common, lcc_route_count) != 20);
+ BUILD_BUG_ON((int)sizeof(((struct lnet_counters_common *)0)->lcc_route_count) != 4);
+ BUILD_BUG_ON((int)offsetof(struct lnet_counters_common, lcc_drop_count) != 24);
+ BUILD_BUG_ON((int)sizeof(((struct lnet_counters_common *)0)->lcc_drop_count) != 4);
+ BUILD_BUG_ON((int)offsetof(struct lnet_counters_common, lcc_send_length) != 28);
+ BUILD_BUG_ON((int)sizeof(((struct lnet_counters_common *)0)->lcc_send_length) != 8);
+ BUILD_BUG_ON((int)offsetof(struct lnet_counters_common, lcc_recv_length) != 36);
+ BUILD_BUG_ON((int)sizeof(((struct lnet_counters_common *)0)->lcc_recv_length) != 8);
+ BUILD_BUG_ON((int)offsetof(struct lnet_counters_common, lcc_route_length) != 44);
+ BUILD_BUG_ON((int)sizeof(((struct lnet_counters_common *)0)->lcc_route_length) != 8);
+ BUILD_BUG_ON((int)offsetof(struct lnet_counters_common, lcc_drop_length) != 52);
+ BUILD_BUG_ON((int)sizeof(((struct lnet_counters_common *)0)->lcc_drop_length) != 8);
}
static const struct lnet_lnd *lnet_find_lnd_by_type(__u32 type)
}
static int
-lnet_unprepare (void)
+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
the_lnet.ln_counters = NULL;
}
lnet_destroy_remote_nets_table();
+ lnet_udsp_destroy(true);
lnet_slab_cleanup();
return 0;
return NULL;
}
+void
+lnet_net_clr_pref_rtrs(struct lnet_net *net)
+{
+ struct list_head zombies;
+ struct lnet_nid_list *ne;
+ struct lnet_nid_list *tmp;
+
+ INIT_LIST_HEAD(&zombies);
+
+ lnet_net_lock(LNET_LOCK_EX);
+ list_splice_init(&net->net_rtr_pref_nids, &zombies);
+ lnet_net_unlock(LNET_LOCK_EX);
+
+ list_for_each_entry_safe(ne, tmp, &zombies, nl_list) {
+ list_del_init(&ne->nl_list);
+ LIBCFS_FREE(ne, sizeof(*ne));
+ }
+}
+
+int
+lnet_net_add_pref_rtr(struct lnet_net *net,
+ struct lnet_nid *gw_nid)
+__must_hold(&the_lnet.ln_api_mutex)
+{
+ struct lnet_nid_list *ne;
+
+ /* This function is called with api_mutex held. When the api_mutex
+ * is held the list can not be modified, as it is only modified as
+ * a result of applying a UDSP and that happens under api_mutex
+ * lock.
+ */
+ list_for_each_entry(ne, &net->net_rtr_pref_nids, nl_list) {
+ if (nid_same(&ne->nl_nid, gw_nid))
+ return -EEXIST;
+ }
+
+ LIBCFS_ALLOC(ne, sizeof(*ne));
+ if (!ne)
+ return -ENOMEM;
+
+ ne->nl_nid = *gw_nid;
+
+ /* Lock the cpt to protect against addition and checks in the
+ * selection algorithm
+ */
+ lnet_net_lock(LNET_LOCK_EX);
+ list_add(&ne->nl_list, &net->net_rtr_pref_nids);
+ lnet_net_unlock(LNET_LOCK_EX);
+
+ return 0;
+}
+
+bool
+lnet_net_is_pref_rtr_locked(struct lnet_net *net, struct lnet_nid *rtr_nid)
+{
+ struct lnet_nid_list *ne;
+
+ CDEBUG(D_NET, "%s: rtr pref empty: %d\n",
+ libcfs_net2str(net->net_id),
+ list_empty(&net->net_rtr_pref_nids));
+
+ if (list_empty(&net->net_rtr_pref_nids))
+ return false;
+
+ list_for_each_entry(ne, &net->net_rtr_pref_nids, nl_list) {
+ CDEBUG(D_NET, "Comparing pref %s with gw %s\n",
+ libcfs_nidstr(&ne->nl_nid),
+ libcfs_nidstr(rtr_nid));
+ if (nid_same(rtr_nid, &ne->nl_nid))
+ return true;
+ }
+
+ return false;
+}
+
+static unsigned int
+lnet_nid4_cpt_hash(lnet_nid_t nid, unsigned int number)
+{
+ __u64 key = nid;
+ __u64 pair_bits = 0x0001000100010001LLU;
+ __u64 mask = pair_bits * 0xFF;
+ __u64 pair_sum;
+
+ /* Use (sum-by-multiplication of nid bytes) mod (number of CPTs)
+ * to match nid to a CPT.
+ */
+ pair_sum = (key & mask) + ((key >> 8) & mask);
+ pair_sum = (pair_sum * pair_bits) >> 48;
+
+ CDEBUG(D_NET, "Match nid %s to cpt %u\n",
+ libcfs_nid2str(nid), (unsigned int)(pair_sum) % number);
+
+ return (unsigned int)(pair_sum) % number;
+}
+
unsigned int
-lnet_nid_cpt_hash(lnet_nid_t nid, unsigned int number)
+lnet_nid_cpt_hash(struct lnet_nid *nid, unsigned int number)
{
- __u64 key = nid;
- unsigned int val;
+ unsigned int val;
+ u32 h = 0;
+ int i;
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 (nid_is_nid4(nid))
+ return lnet_nid4_cpt_hash(lnet_nid_to_nid4(nid), number);
+
+ for (i = 0; i < 4; i++)
+ h = hash_32(nid->nid_addr[i]^h, 32);
+ val = hash_32(LNET_NID_NET(nid) ^ h, LNET_CPT_BITS);
if (val < number)
return val;
-
- return (unsigned int)(key + val + (val >> 1)) % number;
+ return (unsigned int)(h + val + (val >> 1)) % number;
}
int
-lnet_cpt_of_nid_locked(lnet_nid_t nid, struct lnet_ni *ni)
+lnet_cpt_of_nid_locked(struct lnet_nid *nid, struct lnet_ni *ni)
{
struct lnet_net *net;
}
/* no NI provided so look at the net */
- net = lnet_get_net_locked(LNET_NIDNET(nid));
+ net = lnet_get_net_locked(LNET_NID_NET(nid));
if (net != NULL && net->net_cpts != NULL) {
return net->net_cpts[lnet_nid_cpt_hash(nid, net->net_ncpts)];
}
int
-lnet_cpt_of_nid(lnet_nid_t nid, struct lnet_ni *ni)
+lnet_nid2cpt(struct lnet_nid *nid, struct lnet_ni *ni)
{
int cpt;
int cpt2;
return cpt2;
}
+EXPORT_SYMBOL(lnet_nid2cpt);
+
+int
+lnet_cpt_of_nid(lnet_nid_t nid4, struct lnet_ni *ni)
+{
+ struct lnet_nid nid;
+
+ if (LNET_CPT_NUMBER == 1)
+ return 0; /* the only one */
+
+ lnet_nid4_to_nid(nid4, &nid);
+ return lnet_nid2cpt(&nid, ni);
+}
EXPORT_SYMBOL(lnet_cpt_of_nid);
int
}
struct lnet_ni *
-lnet_nid2ni_locked(lnet_nid_t nid, int cpt)
+lnet_nid_to_ni_locked(struct lnet_nid *nid, int cpt)
{
struct lnet_net *net;
- struct lnet_ni *ni;
+ struct lnet_ni *ni;
LASSERT(cpt != LNET_LOCK_EX);
list_for_each_entry(net, &the_lnet.ln_nets, net_list) {
list_for_each_entry(ni, &net->net_ni_list, ni_netlist) {
- if (ni->ni_nid == nid)
+ if (nid_same(&ni->ni_nid, nid))
return ni;
}
}
return NULL;
}
+struct lnet_ni *
+lnet_nid2ni_locked(lnet_nid_t nid4, int cpt)
+{
+ struct lnet_nid nid;
+
+ lnet_nid4_to_nid(nid4, &nid);
+ return lnet_nid_to_ni_locked(&nid, cpt);
+}
+
struct lnet_ni *
-lnet_nid2ni_addref(lnet_nid_t nid)
+lnet_nid2ni_addref(lnet_nid_t nid4)
{
struct lnet_ni *ni;
+ struct lnet_nid nid;
+
+ lnet_nid4_to_nid(nid4, &nid);
lnet_net_lock(0);
- ni = lnet_nid2ni_locked(nid, 0);
+ ni = lnet_nid_to_ni_locked(&nid, 0);
if (ni)
lnet_ni_addref_locked(ni, 0);
lnet_net_unlock(0);
}
EXPORT_SYMBOL(lnet_nid2ni_addref);
+struct lnet_ni *
+lnet_nid_to_ni_addref(struct lnet_nid *nid)
+{
+ struct lnet_ni *ni;
+
+ lnet_net_lock(0);
+ ni = lnet_nid_to_ni_locked(nid, 0);
+ if (ni)
+ lnet_ni_addref_locked(ni, 0);
+ lnet_net_unlock(0);
+
+ return ni;
+}
+EXPORT_SYMBOL(lnet_nid_to_ni_addref);
+
int
-lnet_islocalnid(lnet_nid_t nid)
+lnet_islocalnid(struct lnet_nid *nid)
{
struct lnet_ni *ni;
int cpt;
cpt = lnet_net_lock_current();
- ni = lnet_nid2ni_locked(nid, cpt);
+ ni = lnet_nid_to_ni_locked(nid, cpt);
lnet_net_unlock(cpt);
return ni != NULL;
return count;
}
-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_handle_md *ping_mdh,
int ni_count, bool set_eq)
{
- struct lnet_process_id id = {
- .nid = LNET_NID_ANY,
+ struct lnet_processid id = {
+ .nid = LNET_ANY_NID,
.pid = LNET_PID_ANY
};
struct lnet_me *me;
}
/* Ping target ME/MD */
- me = LNetMEAttach(LNET_RESERVED_PORTAL, id,
+ me = LNetMEAttach(LNET_RESERVED_PORTAL, &id,
LNET_PROTO_PING_MATCHBITS, 0,
LNET_UNLINK, LNET_INS_AFTER);
if (IS_ERR(me)) {
ns = &pbuf->pb_info.pi_ni[i];
- ns->ns_nid = ni->ni_nid;
+ if (!nid_is_nid4(&ni->ni_nid))
+ continue;
+ ns->ns_nid = lnet_nid_to_nid4(&ni->ni_nid);
lnet_ni_lock(ni);
- ns->ns_status = (ni->ni_status != NULL) ?
- ni->ni_status->ns_status :
- LNET_NI_STATUS_UP;
+ ns->ns_status = lnet_ni_get_status_locked(ni);
ni->ni_status = ns;
lnet_ni_unlock(ni);
int lnet_push_target_post(struct lnet_ping_buffer *pbuf,
struct lnet_handle_md *mdhp)
{
- struct lnet_process_id id = { LNET_NID_ANY, LNET_PID_ANY };
+ struct lnet_processid id = { LNET_ANY_NID, LNET_PID_ANY };
struct lnet_md md = { NULL };
struct lnet_me *me;
int rc;
- me = LNetMEAttach(LNET_RESERVED_PORTAL, id,
+ me = LNetMEAttach(LNET_RESERVED_PORTAL, &id,
LNET_PROTO_PING_MATCHBITS, 0,
LNET_UNLINK, LNET_INS_AFTER);
if (IS_ERR(me)) {
if ((i & (-i)) == i) {
CDEBUG(D_WARNING,
"Waiting for zombie LNI %s\n",
- libcfs_nid2str(ni->ni_nid));
+ libcfs_nidstr(&ni->ni_nid));
}
schedule_timeout_uninterruptible(cfs_time_seconds(1));
islo = ni->ni_net->net_lnd->lnd_type == LOLND;
LASSERT(!in_interrupt());
- /* Holding the mutex makes it safe for lnd_shutdown
+ /* Holding the LND mutex makes it safe for lnd_shutdown
* to call module_put(). Module unload cannot finish
* until lnet_unregister_lnd() completes, and that
- * requires the mutex.
+ * requires the LND mutex.
*/
+ mutex_unlock(&the_lnet.ln_api_mutex);
mutex_lock(&the_lnet.ln_lnd_mutex);
(net->net_lnd->lnd_shutdown)(ni);
mutex_unlock(&the_lnet.ln_lnd_mutex);
+ mutex_lock(&the_lnet.ln_api_mutex);
if (!islo)
CDEBUG(D_LNI, "Removed LNI %s\n",
- libcfs_nid2str(ni->ni_nid));
+ libcfs_nidstr(&ni->ni_nid));
lnet_ni_free(ni);
i = 2;
/* NB called holding the global mutex */
/* All quiet on the API front */
- LASSERT(the_lnet.ln_state == LNET_STATE_RUNNING);
+ LASSERT(the_lnet.ln_state == LNET_STATE_RUNNING ||
+ the_lnet.ln_state == LNET_STATE_STOPPING);
LASSERT(the_lnet.ln_refcount == 0);
lnet_net_lock(LNET_LOCK_EX);
lnet_ni_tq_credits(ni) * ni->ni_ncpts);
atomic_set(&ni->ni_healthv, LNET_MAX_HEALTH_VALUE);
+ /* Nodes with small feet have little entropy. The NID for this
+ * node gives the most entropy in the low bits.
+ */
+ add_device_randomness(&ni->ni_nid, sizeof(ni->ni_nid));
+
CDEBUG(D_LNI, "Added LNI %s [%d/%d/%d/%d]\n",
- libcfs_nid2str(ni->ni_nid),
+ libcfs_nidstr(&ni->ni_nid),
ni->ni_net->net_tunables.lct_peer_tx_credits,
lnet_ni_tq_credits(ni) * LNET_CPT_NUMBER,
ni->ni_net->net_tunables.lct_peer_rtr_credits,
* After than we want to delete the network being added,
* to avoid a memory leak.
*/
-
- /*
- * When a network uses TCP bonding then all its interfaces
- * must be specified when the network is first defined: the
- * TCP bonding code doesn't allow for interfaces to be added
- * or removed.
- */
- if (net_l != net && net_l != NULL && use_tcp_bonding &&
- LNET_NETTYP(net_l->net_id) == SOCKLND) {
- rc = -EINVAL;
- goto failed0;
- }
-
while (!list_empty(&net->net_ni_added)) {
ni = list_entry(net->net_ni_added.next, struct lnet_ni,
ni_netlist);
/* make sure that the the NI we're about to start
* up is actually unique. if it's not fail. */
if (!lnet_ni_unique_net(&net_l->net_ni_list,
- ni->ni_interfaces[0])) {
+ ni->ni_interface)) {
rc = -EEXIST;
goto failed1;
}
lnet_net_unlock(LNET_LOCK_EX);
}
- /* update net count */
- lnet_current_net_count = lnet_get_net_count();
-
return ni_count;
failed1:
return rc;
}
+static int lnet_genl_parse_list(struct sk_buff *msg,
+ const struct ln_key_list *data[], u16 idx)
+{
+ const struct ln_key_list *list = data[idx];
+ const struct ln_key_props *props;
+ struct nlattr *node;
+ u16 count;
+
+ if (!list)
+ return 0;
+
+ if (!list->lkl_maxattr)
+ return -ERANGE;
+
+ props = list->lkl_list;
+ if (!props)
+ return -EINVAL;
+
+ node = nla_nest_start(msg, LN_SCALAR_ATTR_LIST);
+ if (!node)
+ return -ENOBUFS;
+
+ for (count = 1; count <= list->lkl_maxattr; count++) {
+ struct nlattr *key = nla_nest_start(msg, count);
+
+ if (count == 1)
+ nla_put_u16(msg, LN_SCALAR_ATTR_LIST_SIZE,
+ list->lkl_maxattr);
+
+ nla_put_u16(msg, LN_SCALAR_ATTR_INDEX, count);
+ if (props[count].lkp_value)
+ nla_put_string(msg, LN_SCALAR_ATTR_VALUE,
+ props[count].lkp_value);
+ if (props[count].lkp_key_format)
+ nla_put_u16(msg, LN_SCALAR_ATTR_KEY_FORMAT,
+ props[count].lkp_key_format);
+ nla_put_u16(msg, LN_SCALAR_ATTR_NLA_TYPE,
+ props[count].lkp_data_type);
+ if (props[count].lkp_data_type == NLA_NESTED) {
+ int rc;
+
+ rc = lnet_genl_parse_list(msg, data, ++idx);
+ if (rc < 0)
+ return rc;
+ idx = rc;
+ }
+
+ nla_nest_end(msg, key);
+ }
+
+ nla_nest_end(msg, node);
+ return idx;
+}
+
+int lnet_genl_send_scalar_list(struct sk_buff *msg, u32 portid, u32 seq,
+ const struct genl_family *family, int flags,
+ u8 cmd, const struct ln_key_list *data[])
+{
+ int rc = 0;
+ void *hdr;
+
+ if (!data[0])
+ return -EINVAL;
+
+ hdr = genlmsg_put(msg, portid, seq, family, flags, cmd);
+ if (!hdr)
+ GOTO(canceled, rc = -EMSGSIZE);
+
+ rc = lnet_genl_parse_list(msg, data, 0);
+ if (rc < 0)
+ GOTO(canceled, rc);
+
+ genlmsg_end(msg, hdr);
+canceled:
+ if (rc < 0)
+ genlmsg_cancel(msg, hdr);
+ return rc > 0 ? 0 : rc;
+}
+EXPORT_SYMBOL(lnet_genl_send_scalar_list);
+
/**
* Initialize LNet library.
*
CDEBUG(D_OTHER, "refs %d\n", the_lnet.ln_refcount);
+ if (the_lnet.ln_state == LNET_STATE_STOPPING) {
+ mutex_unlock(&the_lnet.ln_api_mutex);
+ return -ESHUTDOWN;
+ }
+
if (the_lnet.ln_refcount > 0) {
rc = the_lnet.ln_refcount++;
mutex_unlock(&the_lnet.ln_api_mutex);
}
if (use_tcp_bonding)
- CWARN("'use_tcp_bonding' option has been deprecated. See LU-13641\n");
+ CWARN("use_tcp_bonding has been removed. Use Multi-Rail and Dynamic Discovery instead, see LU-13641\n");
/* If LNet is being initialized via DLC it is possible
* that the user requests not to load module parameters (ones which
* 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(),
- use_tcp_bonding);
+ rc = lnet_parse_networks(&net_head, lnet_get_networks());
if (rc < 0)
goto err_empty_list;
}
} else {
LASSERT(!the_lnet.ln_niinit_self);
+ lnet_net_lock(LNET_LOCK_EX);
+ the_lnet.ln_state = LNET_STATE_STOPPING;
+ lnet_net_unlock(LNET_LOCK_EX);
+
lnet_fault_fini();
lnet_router_debugfs_fini();
size_t min_size = 0;
int i;
- if (!ni || !cfg_ni || !tun)
+ if (!ni || !cfg_ni || !tun || !nid_is_nid4(&ni->ni_nid))
return;
- if (ni->ni_interfaces[0] != NULL) {
- for (i = 0; i < ARRAY_SIZE(ni->ni_interfaces); i++) {
- if (ni->ni_interfaces[i] != NULL) {
- strncpy(cfg_ni->lic_ni_intf[i],
- ni->ni_interfaces[i],
- sizeof(cfg_ni->lic_ni_intf[i]));
- }
- }
+ if (ni->ni_interface != NULL) {
+ strncpy(cfg_ni->lic_ni_intf,
+ ni->ni_interface,
+ sizeof(cfg_ni->lic_ni_intf));
}
- cfg_ni->lic_nid = ni->ni_nid;
- if (ni->ni_nid == LNET_NID_LO_0)
- cfg_ni->lic_status = LNET_NI_STATUS_UP;
- else
- cfg_ni->lic_status = ni->ni_status->ns_status;
- cfg_ni->lic_tcp_bonding = use_tcp_bonding;
+ cfg_ni->lic_nid = lnet_nid_to_nid4(&ni->ni_nid);
+ cfg_ni->lic_status = lnet_ni_get_status_locked(ni);
cfg_ni->lic_dev_cpt = ni->ni_dev_cpt;
memcpy(&tun->lt_cmn, &ni->ni_net->net_tunables, sizeof(tun->lt_cmn));
size_t min_size, tunable_size = 0;
int i;
- if (!ni || !config)
+ if (!ni || !config || !nid_is_nid4(&ni->ni_nid))
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;
+ if (!ni->ni_interface)
+ return;
- strncpy(net_config->ni_interfaces[i],
- ni->ni_interfaces[i],
- sizeof(net_config->ni_interfaces[i]));
- }
+ strncpy(net_config->ni_interface,
+ ni->ni_interface,
+ sizeof(net_config->ni_interface));
- config->cfg_nid = ni->ni_nid;
+ config->cfg_nid = lnet_nid_to_nid4(&ni->ni_nid);
config->cfg_config_u.cfg_net.net_peer_timeout =
ni->ni_net->net_tunables.lct_peer_timeout;
config->cfg_config_u.cfg_net.net_max_tx_credits =
config->cfg_config_u.cfg_net.net_peer_rtr_credits =
ni->ni_net->net_tunables.lct_peer_rtr_credits;
- if (ni->ni_nid == LNET_NID_LO_0)
- net_config->ni_status = LNET_NI_STATUS_UP;
- else
- net_config->ni_status = ni->ni_status->ns_status;
+ net_config->ni_status = lnet_ni_get_status_locked(ni);
if (ni->ni_cpts) {
int num_cpts = min(ni->ni_ncpts, LNET_MAX_SHOW_NUM_CPT);
{
struct lnet_ni *ni;
int best_healthv = 0;
- int healthv;
+ int healthv, ni_fatal;
list_for_each_entry(ni, &net->net_ni_list, ni_netlist) {
healthv = atomic_read(&ni->ni_healthv);
- if (healthv > best_healthv)
+ ni_fatal = atomic_read(&ni->ni_fatal_error_on);
+ if (!ni_fatal && healthv > best_healthv)
best_healthv = healthv;
}
static int lnet_add_net_common(struct lnet_net *net,
struct lnet_ioctl_config_lnd_tunables *tun)
{
- __u32 net_id;
+ struct lnet_handle_md ping_mdh;
struct lnet_ping_buffer *pbuf;
- struct lnet_handle_md ping_mdh;
- int rc;
struct lnet_remotenet *rnet;
- int net_ni_count;
+ struct lnet_ni *ni;
+ int net_ni_count;
+ __u32 net_id;
+ int rc;
lnet_net_lock(LNET_LOCK_EX);
rnet = lnet_find_rnet_locked(net->net_id);
lnet_net_lock(LNET_LOCK_EX);
net = lnet_get_net_locked(net_id);
- lnet_net_unlock(LNET_LOCK_EX);
-
LASSERT(net);
+ /* apply the UDSPs */
+ rc = lnet_udsp_apply_policies_on_net(net);
+ if (rc)
+ CERROR("Failed to apply UDSPs on local net %s\n",
+ libcfs_net2str(net->net_id));
+
+ /* At this point we lost track of which NI was just added, so we
+ * just re-apply the policies on all of the NIs on this net
+ */
+ list_for_each_entry(ni, &net->net_ni_list, ni_netlist) {
+ rc = lnet_udsp_apply_policies_on_ni(ni);
+ if (rc)
+ CERROR("Failed to apply UDSPs on ni %s\n",
+ libcfs_nidstr(&ni->ni_nid));
+ }
+ lnet_net_unlock(LNET_LOCK_EX);
+
/*
* Start the acceptor thread if this is the first network
* being added that requires the thread.
if (rc < 0)
return rc;
- rc = lnet_parse_networks(&net_head, nets, use_tcp_bonding);
+ rc = lnet_parse_networks(&net_head, nets);
if (rc < 0)
return rc;
lnet_set_tune_defaults(tun);
mutex_lock(&the_lnet.ln_api_mutex);
+ if (the_lnet.ln_state != LNET_STATE_RUNNING) {
+ rc = -ESHUTDOWN;
+ goto out;
+ }
while (!list_empty(&net_head)) {
net = list_entry(net_head.next, struct lnet_net, net_list);
list_del_init(&net->net_list);
}
ni = lnet_ni_alloc_w_cpt_array(net, conf->lic_cpts, conf->lic_ncpts,
- conf->lic_ni_intf[0]);
+ conf->lic_ni_intf);
if (!ni)
return -ENOMEM;
lnet_set_tune_defaults(tun);
mutex_lock(&the_lnet.ln_api_mutex);
-
- rc = lnet_add_net_common(net, tun);
+ if (the_lnet.ln_state != LNET_STATE_RUNNING)
+ rc = -ESHUTDOWN;
+ else
+ rc = lnet_add_net_common(net, tun);
mutex_unlock(&the_lnet.ln_api_mutex);
return -EINVAL;
mutex_lock(&the_lnet.ln_api_mutex);
+ if (the_lnet.ln_state != LNET_STATE_RUNNING) {
+ rc = -ESHUTDOWN;
+ goto unlock_api_mutex;
+ }
lnet_net_lock(0);
const char *nets = conf->cfg_config_u.cfg_net.net_intf;
/* Create a net/ni structures for the network string */
- rc = lnet_parse_networks(&net_head, nets, use_tcp_bonding);
+ rc = lnet_parse_networks(&net_head, nets);
if (rc <= 0)
return rc == 0 ? -EINVAL : rc;
mutex_lock(&the_lnet.ln_api_mutex);
+ if (the_lnet.ln_state != LNET_STATE_RUNNING) {
+ rc = -ESHUTDOWN;
+ goto out_unlock_clean;
+ }
if (rc > 1) {
rc = -EINVAL; /* only add one network per call */
return -EINVAL;
mutex_lock(&the_lnet.ln_api_mutex);
+ if (the_lnet.ln_state != LNET_STATE_RUNNING) {
+ rc = -ESHUTDOWN;
+ goto out;
+ }
lnet_net_lock(0);
lnet_net_lock(LNET_LOCK_EX);
list_for_each_entry(net, &the_lnet.ln_nets, net_list) {
list_for_each_entry(ni, &net->net_ni_list, ni_netlist) {
- if (ni->ni_nid == nid || all) {
+ if (all || (nid_is_nid4(&ni->ni_nid) &&
+ lnet_nid_to_nid4(&ni->ni_nid) == nid)) {
atomic_set(&ni->ni_healthv, value);
if (list_empty(&ni->ni_recovery) &&
value < LNET_MAX_HEALTH_VALUE) {
CERROR("manually adding local NI %s to recovery\n",
- libcfs_nid2str(ni->ni_nid));
+ libcfs_nidstr(&ni->ni_nid));
list_add_tail(&ni->ni_recovery,
&the_lnet.ln_mt_localNIRecovq);
lnet_ni_addref_locked(ni, 0);
lnet_net_unlock(LNET_LOCK_EX);
}
+static void
+lnet_ni_set_conns_per_peer(lnet_nid_t nid, int value, bool all)
+{
+ struct lnet_net *net;
+ struct lnet_ni *ni;
+
+ lnet_net_lock(LNET_LOCK_EX);
+ list_for_each_entry(net, &the_lnet.ln_nets, net_list) {
+ list_for_each_entry(ni, &net->net_ni_list, ni_netlist) {
+ if (lnet_nid_to_nid4(&ni->ni_nid) != nid && !all)
+ continue;
+ if (LNET_NETTYP(net->net_id) == SOCKLND)
+ ni->ni_lnd_tunables.lnd_tun_u.lnd_sock.lnd_conns_per_peer = value;
+ else if (LNET_NETTYP(net->net_id) == O2IBLND)
+ ni->ni_lnd_tunables.lnd_tun_u.lnd_o2ib.lnd_conns_per_peer = value;
+ if (!all) {
+ lnet_net_unlock(LNET_LOCK_EX);
+ return;
+ }
+ }
+ }
+ lnet_net_unlock(LNET_LOCK_EX);
+}
+
static int
lnet_get_local_ni_hstats(struct lnet_ioctl_local_ni_hstats *stats)
{
stats->hlni_local_no_route = atomic_read(&ni->ni_hstats.hlt_local_no_route);
stats->hlni_local_timeout = atomic_read(&ni->ni_hstats.hlt_local_timeout);
stats->hlni_local_error = atomic_read(&ni->ni_hstats.hlt_local_error);
+ stats->hlni_fatal_error = atomic_read(&ni->ni_fatal_error_on);
stats->hlni_health_value = atomic_read(&ni->ni_healthv);
+ stats->hlni_ping_count = ni->ni_ping_count;
+ stats->hlni_next_ping = ni->ni_next_ping;
unlock:
lnet_net_unlock(cpt);
lnet_net_lock(LNET_LOCK_EX);
list_for_each_entry(ni, &the_lnet.ln_mt_localNIRecovq, ni_recovery) {
- list->rlst_nid_array[i] = ni->ni_nid;
+ if (!nid_is_nid4(&ni->ni_nid))
+ continue;
+ list->rlst_nid_array[i] = lnet_nid_to_nid4(&ni->ni_nid);
i++;
if (i >= LNET_MAX_SHOW_NUM_NID)
break;
lnet_net_lock(LNET_LOCK_EX);
list_for_each_entry(lpni, &the_lnet.ln_mt_peerNIRecovq, lpni_recovery) {
- list->rlst_nid_array[i] = lpni->lpni_nid;
+ list->rlst_nid_array[i] = lnet_nid_to_nid4(&lpni->lpni_nid);
i++;
if (i >= LNET_MAX_SHOW_NUM_NID)
break;
{
struct libcfs_ioctl_data *data = arg;
struct lnet_ioctl_config_data *config;
- struct lnet_process_id id = {0};
+ struct lnet_process_id id4 = {};
+ struct lnet_processid id = {};
struct lnet_ni *ni;
+ struct lnet_nid nid;
int rc;
BUILD_BUG_ON(sizeof(struct lnet_ioctl_net_config) +
switch (cmd) {
case IOC_LIBCFS_GET_NI:
rc = LNetGetId(data->ioc_count, &id);
- data->ioc_nid = id.nid;
+ data->ioc_nid = lnet_nid_to_nid4(&id.nid);
return rc;
case IOC_LIBCFS_FAIL_NID:
config->cfg_config_u.cfg_route.rtr_sensitivity;
}
+ lnet_nid4_to_nid(config->cfg_nid, &nid);
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,
+ &nid,
config->cfg_config_u.cfg_route.
rtr_priority, sensitivity);
mutex_unlock(&the_lnet.ln_api_mutex);
if (config->cfg_hdr.ioc_len < sizeof(*config))
return -EINVAL;
+ lnet_nid4_to_nid(config->cfg_nid, &nid);
mutex_lock(&the_lnet.ln_api_mutex);
- rc = lnet_del_route(config->cfg_net, config->cfg_nid);
+ rc = lnet_del_route(config->cfg_net, &nid);
mutex_unlock(&the_lnet.ln_api_mutex);
return rc;
return rc;
}
+ case IOC_LIBCFS_RESET_LNET_STATS:
+ {
+ mutex_lock(&the_lnet.ln_api_mutex);
+ lnet_counters_reset();
+ mutex_unlock(&the_lnet.ln_api_mutex);
+ return 0;
+ }
+
case IOC_LIBCFS_CONFIG_RTR:
config = arg;
case IOC_LIBCFS_ADD_PEER_NI: {
struct lnet_ioctl_peer_cfg *cfg = arg;
+ struct lnet_nid prim_nid;
if (cfg->prcfg_hdr.ioc_len < sizeof(*cfg))
return -EINVAL;
mutex_lock(&the_lnet.ln_api_mutex);
- rc = lnet_add_peer_ni(cfg->prcfg_prim_nid,
- cfg->prcfg_cfg_nid,
- cfg->prcfg_mr);
+ lnet_nid4_to_nid(cfg->prcfg_prim_nid, &prim_nid);
+ lnet_nid4_to_nid(cfg->prcfg_cfg_nid, &nid);
+ rc = lnet_add_peer_ni(&prim_nid, &nid, cfg->prcfg_mr, false);
mutex_unlock(&the_lnet.ln_api_mutex);
return rc;
}
case IOC_LIBCFS_DEL_PEER_NI: {
struct lnet_ioctl_peer_cfg *cfg = arg;
+ struct lnet_nid prim_nid;
if (cfg->prcfg_hdr.ioc_len < sizeof(*cfg))
return -EINVAL;
mutex_lock(&the_lnet.ln_api_mutex);
- rc = lnet_del_peer_ni(cfg->prcfg_prim_nid,
- cfg->prcfg_cfg_nid);
+ lnet_nid4_to_nid(cfg->prcfg_prim_nid, &prim_nid);
+ lnet_nid4_to_nid(cfg->prcfg_cfg_nid, &nid);
+ rc = lnet_del_peer_ni(&prim_nid,
+ &nid);
mutex_unlock(&the_lnet.ln_api_mutex);
return rc;
}
return 0;
}
+ case IOC_LIBCFS_SET_CONNS_PER_PEER: {
+ struct lnet_ioctl_reset_conns_per_peer_cfg *cfg = arg;
+ int value;
+
+ if (cfg->rcpp_hdr.ioc_len < sizeof(*cfg))
+ return -EINVAL;
+ if (cfg->rcpp_value < 0)
+ value = 1;
+ else
+ value = cfg->rcpp_value;
+ CDEBUG(D_NET,
+ "Setting conns_per_peer to %d for %s. all = %d\n",
+ value, libcfs_nid2str(cfg->rcpp_nid), cfg->rcpp_all);
+ mutex_lock(&the_lnet.ln_api_mutex);
+ lnet_ni_set_conns_per_peer(cfg->rcpp_nid, value, cfg->rcpp_all);
+ mutex_unlock(&the_lnet.ln_api_mutex);
+ return 0;
+ }
+
case IOC_LIBCFS_NOTIFY_ROUTER: {
time64_t deadline = ktime_get_real_seconds() - data->ioc_u64[0];
}
case IOC_LIBCFS_LNET_DIST:
- rc = LNetDist(data->ioc_nid, &data->ioc_nid, &data->ioc_u32[1]);
+ lnet_nid4_to_nid(data->ioc_nid, &nid);
+ rc = LNetDist(&nid, &nid, &data->ioc_u32[1]);
if (rc < 0 && rc != -EHOSTUNREACH)
return rc;
+ data->ioc_nid = lnet_nid_to_nid4(&nid);
data->ioc_u32[0] = rc;
return 0;
case IOC_LIBCFS_PING: {
signed long timeout;
- id.nid = data->ioc_nid;
- id.pid = data->ioc_u32[0];
+ id4.nid = data->ioc_nid;
+ id4.pid = data->ioc_u32[0];
/* If timeout is negative then set default of 3 minutes */
if (((s32)data->ioc_u32[1] <= 0) ||
else
timeout = nsecs_to_jiffies(data->ioc_u32[1] * NSEC_PER_MSEC);
- rc = lnet_ping(id, timeout, data->ioc_pbuf1,
+ rc = lnet_ping(id4, &LNET_ANY_NID, timeout, data->ioc_pbuf1,
data->ioc_plen1 / sizeof(struct lnet_process_id));
if (rc < 0)
case IOC_LIBCFS_PING_PEER: {
struct lnet_ioctl_ping_data *ping = arg;
+ struct lnet_nid src_nid = LNET_ANY_NID;
struct lnet_peer *lp;
signed long timeout;
+ /* Check if the supplied ping data supports source nid
+ * NB: This check is sufficient if lnet_ioctl_ping_data has
+ * additional fields added, but if they are re-ordered or
+ * fields removed then this will break. It is expected that
+ * these ioctls will be replaced with netlink implementation, so
+ * it is probably not worth coming up with a more robust version
+ * compatibility scheme.
+ */
+ if (ping->ping_hdr.ioc_len >= sizeof(struct lnet_ioctl_ping_data))
+ lnet_nid4_to_nid(ping->ping_src, &src_nid);
+
/* 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))
else
timeout = nsecs_to_jiffies(ping->op_param * NSEC_PER_MSEC);
- rc = lnet_ping(ping->ping_id, timeout,
+ rc = lnet_ping(ping->ping_id, &src_nid, timeout,
ping->ping_buf,
ping->ping_count);
if (rc < 0)
return rc;
mutex_lock(&the_lnet.ln_api_mutex);
- lp = lnet_find_peer(ping->ping_id.nid);
+ lnet_nid4_to_nid(ping->ping_id.nid, &nid);
+ lp = lnet_find_peer(&nid);
if (lp) {
- ping->ping_id.nid = lp->lp_primary_nid;
+ ping->ping_id.nid =
+ lnet_nid_to_nid4(&lp->lp_primary_nid);
ping->mr_info = lnet_peer_is_multi_rail(lp);
lnet_peer_decref_locked(lp);
}
return rc;
mutex_lock(&the_lnet.ln_api_mutex);
- lp = lnet_find_peer(discover->ping_id.nid);
+ lnet_nid4_to_nid(discover->ping_id.nid, &nid);
+ lp = lnet_find_peer(&nid);
if (lp) {
- discover->ping_id.nid = lp->lp_primary_nid;
+ discover->ping_id.nid =
+ lnet_nid_to_nid4(&lp->lp_primary_nid);
discover->mr_info = lnet_peer_is_multi_rail(lp);
lnet_peer_decref_locked(lp);
}
return 0;
}
+ case IOC_LIBCFS_ADD_UDSP: {
+ struct lnet_ioctl_udsp *ioc_udsp = arg;
+ __u32 bulk_size = ioc_udsp->iou_hdr.ioc_len;
+
+ mutex_lock(&the_lnet.ln_api_mutex);
+ rc = lnet_udsp_demarshal_add(arg, bulk_size);
+ if (!rc) {
+ rc = lnet_udsp_apply_policies(NULL, false);
+ CDEBUG(D_NET, "policy application returned %d\n", rc);
+ rc = 0;
+ }
+ mutex_unlock(&the_lnet.ln_api_mutex);
+
+ return rc;
+ }
+
+ case IOC_LIBCFS_DEL_UDSP: {
+ struct lnet_ioctl_udsp *ioc_udsp = arg;
+ int idx = ioc_udsp->iou_idx;
+
+ if (ioc_udsp->iou_hdr.ioc_len < sizeof(*ioc_udsp))
+ return -EINVAL;
+
+ mutex_lock(&the_lnet.ln_api_mutex);
+ rc = lnet_udsp_del_policy(idx);
+ if (!rc) {
+ rc = lnet_udsp_apply_policies(NULL, false);
+ CDEBUG(D_NET, "policy re-application returned %d\n",
+ rc);
+ rc = 0;
+ }
+ mutex_unlock(&the_lnet.ln_api_mutex);
+
+ return rc;
+ }
+
+ case IOC_LIBCFS_GET_UDSP_SIZE: {
+ struct lnet_ioctl_udsp *ioc_udsp = arg;
+ struct lnet_udsp *udsp;
+
+ if (ioc_udsp->iou_hdr.ioc_len < sizeof(*ioc_udsp))
+ return -EINVAL;
+
+ rc = 0;
+
+ mutex_lock(&the_lnet.ln_api_mutex);
+ udsp = lnet_udsp_get_policy(ioc_udsp->iou_idx);
+ if (!udsp) {
+ rc = -ENOENT;
+ } else {
+ /* coming in iou_idx will hold the idx of the udsp
+ * to get the size of. going out the iou_idx will
+ * hold the size of the UDSP found at the passed
+ * in index.
+ */
+ ioc_udsp->iou_idx = lnet_get_udsp_size(udsp);
+ if (ioc_udsp->iou_idx < 0)
+ rc = -EINVAL;
+ }
+ mutex_unlock(&the_lnet.ln_api_mutex);
+
+ return rc;
+ }
+
+ case IOC_LIBCFS_GET_UDSP: {
+ struct lnet_ioctl_udsp *ioc_udsp = arg;
+ struct lnet_udsp *udsp;
+
+ if (ioc_udsp->iou_hdr.ioc_len < sizeof(*ioc_udsp))
+ return -EINVAL;
+
+ rc = 0;
+
+ mutex_lock(&the_lnet.ln_api_mutex);
+ udsp = lnet_udsp_get_policy(ioc_udsp->iou_idx);
+ if (!udsp)
+ rc = -ENOENT;
+ else
+ rc = lnet_udsp_marshal(udsp, ioc_udsp);
+ mutex_unlock(&the_lnet.ln_api_mutex);
+
+ return rc;
+ }
+
+ case IOC_LIBCFS_GET_CONST_UDSP_INFO: {
+ struct lnet_ioctl_construct_udsp_info *info = arg;
+
+ if (info->cud_hdr.ioc_len < sizeof(*info))
+ return -EINVAL;
+
+ CDEBUG(D_NET, "GET_UDSP_INFO for %s\n",
+ libcfs_nid2str(info->cud_nid));
+
+ mutex_lock(&the_lnet.ln_api_mutex);
+ lnet_udsp_get_construct_info(info);
+ mutex_unlock(&the_lnet.ln_api_mutex);
+
+ return 0;
+ }
+
default:
ni = lnet_net2ni_addref(data->ioc_net);
if (ni == NULL)
}
EXPORT_SYMBOL(LNetCtl);
-void LNetDebugPeer(struct lnet_process_id id)
+void LNetDebugPeer(struct lnet_processid *id)
{
- lnet_debug_peer(id.nid);
+ lnet_debug_peer(lnet_nid_to_nid4(&id->nid));
}
EXPORT_SYMBOL(LNetDebugPeer);
* \retval true If peer NID is on the local node.
* \retval false If peer NID is not on the local node.
*/
-bool LNetIsPeerLocal(lnet_nid_t nid)
+bool LNetIsPeerLocal(struct lnet_nid *nid)
{
struct lnet_net *net;
struct lnet_ni *ni;
cpt = lnet_net_lock_current();
list_for_each_entry(net, &the_lnet.ln_nets, net_list) {
list_for_each_entry(ni, &net->net_ni_list, ni_netlist) {
- if (ni->ni_nid == nid) {
+ if (nid_same(&ni->ni_nid, nid)) {
lnet_net_unlock(cpt);
return true;
}
* \retval -ENOENT If no interface has been found.
*/
int
-LNetGetId(unsigned int index, struct lnet_process_id *id)
+LNetGetId(unsigned int index, struct lnet_processid *id)
{
struct lnet_ni *ni;
struct lnet_net *net;
list_for_each_entry(net, &the_lnet.ln_nets, net_list) {
list_for_each_entry(ni, &net->net_ni_list, ni_netlist) {
+ if (!nid_is_nid4(&ni->ni_nid))
+ /* FIXME this needs to be handled */
+ continue;
if (index-- != 0)
continue;
complete(&pd->completion);
}
-static int lnet_ping(struct lnet_process_id id, signed long timeout,
- struct lnet_process_id __user *ids, int n_ids)
+static int lnet_ping(struct lnet_process_id id4, struct lnet_nid *src_nid,
+ signed long timeout, struct lnet_process_id __user *ids,
+ int n_ids)
{
struct lnet_md md = { NULL };
struct ping_data pd = { 0 };
struct lnet_ping_buffer *pbuf;
struct lnet_process_id tmpid;
+ struct lnet_processid id;
int i;
int nob;
int rc;
int rc2;
/* n_ids limit is arbitrary */
- if (n_ids <= 0 || id.nid == LNET_NID_ANY)
+ if (n_ids <= 0 || id4.nid == LNET_NID_ANY)
return -EINVAL;
/*
if (n_ids > lnet_interfaces_max)
n_ids = lnet_interfaces_max;
- if (id.pid == LNET_PID_ANY)
- id.pid = LNET_PID_LUSTRE;
+ if (id4.pid == LNET_PID_ANY)
+ id4.pid = LNET_PID_LUSTRE;
pbuf = lnet_ping_buffer_alloc(n_ids, GFP_NOFS);
if (!pbuf)
goto fail_ping_buffer_decref;
}
- rc = LNetGet(LNET_NID_ANY, pd.mdh, id,
- LNET_RESERVED_PORTAL,
+ lnet_pid4_to_pid(id4, &id);
+ rc = LNetGet(src_nid, pd.mdh, &id, LNET_RESERVED_PORTAL,
LNET_PROTO_PING_MATCHBITS, 0, false);
if (rc != 0) {
if (nob < 8) {
CERROR("%s: ping info too short %d\n",
- libcfs_id2str(id), nob);
+ libcfs_idstr(&id), nob);
goto fail_ping_buffer_decref;
}
lnet_swap_pinginfo(pbuf);
} else if (pbuf->pb_info.pi_magic != LNET_PROTO_PING_MAGIC) {
CERROR("%s: Unexpected magic %08x\n",
- libcfs_id2str(id), pbuf->pb_info.pi_magic);
+ libcfs_idstr(&id), pbuf->pb_info.pi_magic);
goto fail_ping_buffer_decref;
}
if ((pbuf->pb_info.pi_features & LNET_PING_FEAT_NI_STATUS) == 0) {
CERROR("%s: ping w/o NI status: 0x%x\n",
- libcfs_id2str(id), pbuf->pb_info.pi_features);
+ libcfs_idstr(&id), pbuf->pb_info.pi_features);
goto fail_ping_buffer_decref;
}
if (nob < LNET_PING_INFO_SIZE(0)) {
CERROR("%s: Short reply %d(%d min)\n",
- libcfs_id2str(id),
+ libcfs_idstr(&id),
nob, (int)LNET_PING_INFO_SIZE(0));
goto fail_ping_buffer_decref;
}
if (nob < LNET_PING_INFO_SIZE(n_ids)) {
CERROR("%s: Short reply %d(%d expected)\n",
- libcfs_id2str(id),
+ libcfs_idstr(&id),
nob, (int)LNET_PING_INFO_SIZE(n_ids));
goto fail_ping_buffer_decref;
}
}
static int
-lnet_discover(struct lnet_process_id id, __u32 force,
+lnet_discover(struct lnet_process_id id4, __u32 force,
struct lnet_process_id __user *ids, int n_ids)
{
struct lnet_peer_ni *lpni;
struct lnet_peer_ni *p;
struct lnet_peer *lp;
struct lnet_process_id *buf;
+ struct lnet_processid id;
int cpt;
int i;
int rc;
if (n_ids <= 0 ||
- id.nid == LNET_NID_ANY)
+ id4.nid == LNET_NID_ANY)
return -EINVAL;
+ lnet_pid4_to_pid(id4, &id);
if (id.pid == LNET_PID_ANY)
id.pid = LNET_PID_LUSTRE;
return -ENOMEM;
cpt = lnet_net_lock_current();
- lpni = lnet_nid2peerni_locked(id.nid, LNET_NID_ANY, cpt);
+ lpni = lnet_peerni_by_nid_locked(&id.nid, NULL, cpt);
if (IS_ERR(lpni)) {
rc = PTR_ERR(lpni);
goto out;
if (rc)
goto out_decref;
+ /* The lpni (or lp) for this NID may have changed and our ref is
+ * the only thing keeping the old one around. Release the ref
+ * and lookup the lpni again
+ */
+ lnet_peer_ni_decref_locked(lpni);
+ lpni = lnet_peer_ni_find_locked(&id.nid);
+ if (!lpni) {
+ rc = -ENOENT;
+ goto out;
+ }
+ lp = lpni->lpni_peer_net->lpn_peer;
+
i = 0;
p = NULL;
while ((p = lnet_get_next_peer_ni_locked(lp, NULL, p)) != NULL) {
buf[i].pid = id.pid;
- buf[i].nid = p->lpni_nid;
+ buf[i].nid = lnet_nid_to_nid4(&p->lpni_nid);
if (++i >= n_ids)
break;
}