Whamcloud - gitweb
LU-10391 lnet: change lnet_*_peer_ni to take struct lnet_nid
[fs/lustre-release.git] / lnet / lnet / api-ni.c
index c4d6e6c..35e8ab3 100644 (file)
@@ -128,6 +128,27 @@ 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);
 
@@ -261,8 +282,9 @@ static void lnet_set_lnd_timeout(void)
  */
 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);
@@ -314,6 +336,39 @@ recovery_interval_set(const char *val, cfs_kernel_param_arg_t *kp)
 }
 
 static int
+max_recovery_ping_interval_set(const char *val, cfs_kernel_param_arg_t *kp)
+{
+       int rc;
+       unsigned long value;
+
+       rc = kstrtoul(val, 0, &value);
+       if (rc) {
+               CERROR("Invalid module parameter value for 'lnet_max_recovery_ping_interval'\n");
+               return rc;
+       }
+
+       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 correct value ends up stored properly.
+        */
+       mutex_lock(&the_lnet.ln_api_mutex);
+       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;
+}
+
+static int
 discovery_set(const char *val, cfs_kernel_param_arg_t *kp)
 {
        int rc;
@@ -775,64 +830,64 @@ static void lnet_assert_wire_constants(void)
                                   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);
@@ -1349,7 +1404,7 @@ lnet_prepare(lnet_pid_t requested_pid)
 }
 
 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
@@ -1519,20 +1574,21 @@ lnet_net_is_pref_rtr_locked(struct lnet_net *net, struct lnet_nid *rtr_nid)
 static unsigned int
 lnet_nid4_cpt_hash(lnet_nid_t nid, unsigned int number)
 {
-       __u64           key = nid;
-       unsigned int    val;
+       __u64 key = nid;
+       __u64 pair_bits = 0x0001000100010001LLU;
+       __u64 mask = pair_bits * 0xFF;
+       __u64 pair_sum;
 
-       LASSERT(number >= 1 && number <= LNET_CPT_NUMBER);
-
-       if (number == 1)
-               return 0;
+       /* 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;
 
-       val = hash_long(key, LNET_CPT_BITS);
-       /* NB: LNET_CP_NUMBER doesn't have to be PO2 */
-       if (val < number)
-               return val;
+       CDEBUG(D_NET, "Match nid %s to cpt %u\n",
+              libcfs_nid2str(nid), (unsigned int)(pair_sum) % number);
 
-       return (unsigned int)(key + val + (val >> 1)) % number;
+       return (unsigned int)(pair_sum) % number;
 }
 
 unsigned int
@@ -1713,19 +1769,6 @@ lnet_nid_to_ni_addref(struct lnet_nid *nid)
 EXPORT_SYMBOL(lnet_nid_to_ni_addref);
 
 int
-lnet_islocalnid4(lnet_nid_t nid)
-{
-       struct lnet_ni  *ni;
-       int             cpt;
-
-       cpt = lnet_net_lock_current();
-       ni = lnet_nid2ni_locked(nid, cpt);
-       lnet_net_unlock(cpt);
-
-       return ni != NULL;
-}
-
-int
 lnet_islocalnid(struct lnet_nid *nid)
 {
        struct lnet_ni  *ni;
@@ -2333,14 +2376,16 @@ lnet_clear_zombies_nis_locked(struct lnet_net *net)
                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",
@@ -2411,7 +2456,8 @@ lnet_shutdown_lndnets(void)
        /* 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);
@@ -2517,6 +2563,11 @@ lnet_startup_lndni(struct lnet_ni *ni, struct lnet_lnd_tunables *tun)
                   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_nidstr(&ni->ni_nid),
                ni->ni_net->net_tunables.lct_peer_tx_credits,
@@ -2753,9 +2804,9 @@ static int lnet_genl_parse_list(struct sk_buff *msg,
                                    list->lkl_maxattr);
 
                nla_put_u16(msg, LN_SCALAR_ATTR_INDEX, count);
-               if (props[count].lkp_values)
+               if (props[count].lkp_value)
                        nla_put_string(msg, LN_SCALAR_ATTR_VALUE,
-                                      props[count].lkp_values);
+                                      props[count].lkp_value);
                if (props[count].lkp_key_format)
                        nla_put_u16(msg, LN_SCALAR_ATTR_KEY_FORMAT,
                                    props[count].lkp_key_format);
@@ -2767,13 +2818,14 @@ static int lnet_genl_parse_list(struct sk_buff *msg,
                        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 0;
+       return idx;
 }
 
 int lnet_genl_send_scalar_list(struct sk_buff *msg, u32 portid, u32 seq,
@@ -2798,7 +2850,7 @@ int lnet_genl_send_scalar_list(struct sk_buff *msg, u32 portid, u32 seq,
 canceled:
        if (rc < 0)
                genlmsg_cancel(msg, hdr);
-       return rc;
+       return rc > 0 ? 0 : rc;
 }
 EXPORT_SYMBOL(lnet_genl_send_scalar_list);
 
@@ -2911,6 +2963,11 @@ LNetNIInit(lnet_pid_t requested_pid)
 
        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);
@@ -3056,6 +3113,10 @@ LNetNIFini(void)
        } 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();
@@ -3524,6 +3585,10 @@ static int lnet_handle_legacy_ip2nets(char *ip2nets,
        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);
@@ -3587,8 +3652,10 @@ int lnet_dyn_add_ni(struct lnet_ioctl_config_ni *conf)
        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);
 
@@ -3611,6 +3678,10 @@ int lnet_dyn_del_ni(struct lnet_ioctl_config_ni *conf)
                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);
 
@@ -3704,6 +3775,10 @@ lnet_dyn_add_net(struct lnet_ioctl_config_data *conf)
                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 */
@@ -3756,6 +3831,10 @@ lnet_dyn_del_net(__u32 net_id)
                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);
 
@@ -3933,7 +4012,8 @@ 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_process_id    id4 = {};
+       struct lnet_processid     id = {};
        struct lnet_ni           *ni;
        struct lnet_nid           nid;
        int                       rc;
@@ -3944,7 +4024,7 @@ LNetCtl(unsigned int cmd, void *arg)
        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:
@@ -3980,8 +4060,9 @@ LNetCtl(unsigned int cmd, void *arg)
                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;
 
@@ -4177,27 +4258,31 @@ LNetCtl(unsigned int cmd, void *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, false);
+               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;
        }
@@ -4306,10 +4391,12 @@ LNetCtl(unsigned int cmd, void *arg)
        }
 
        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;
 
@@ -4323,8 +4410,8 @@ LNetCtl(unsigned int cmd, void *arg)
        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) ||
@@ -4333,7 +4420,7 @@ LNetCtl(unsigned int cmd, void *arg)
                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)
@@ -4345,9 +4432,21 @@ LNetCtl(unsigned int cmd, void *arg)
 
        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))
@@ -4355,14 +4454,15 @@ LNetCtl(unsigned int cmd, void *arg)
                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 =
                                lnet_nid_to_nid4(&lp->lp_primary_nid);
@@ -4386,7 +4486,8 @@ LNetCtl(unsigned int cmd, void *arg)
                        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 =
                                lnet_nid_to_nid4(&lp->lp_primary_nid);
@@ -4516,9 +4617,9 @@ LNetCtl(unsigned int cmd, void *arg)
 }
 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);
 
@@ -4530,7 +4631,7 @@ 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;
@@ -4539,7 +4640,7 @@ bool LNetIsPeerLocal(lnet_nid_t nid)
        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 (lnet_nid_to_nid4(&ni->ni_nid) == nid) {
+                       if (nid_same(&ni->ni_nid, nid)) {
                                lnet_net_unlock(cpt);
                                return true;
                        }
@@ -4563,7 +4664,7 @@ EXPORT_SYMBOL(LNetIsPeerLocal);
  * \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;
@@ -4582,7 +4683,7 @@ LNetGetId(unsigned int index, struct lnet_process_id *id)
                        if (index-- != 0)
                                continue;
 
-                       id->nid = lnet_nid_to_nid4(&ni->ni_nid);
+                       id->nid = ni->ni_nid;
                        id->pid = the_lnet.ln_pid;
                        rc = 0;
                        break;
@@ -4621,20 +4722,22 @@ lnet_ping_event_handler(struct lnet_event *event)
                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;
 
        /*
@@ -4644,8 +4747,8 @@ static int lnet_ping(struct lnet_process_id id, signed long timeout,
        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)
@@ -4668,8 +4771,8 @@ static int lnet_ping(struct lnet_process_id id, signed long timeout,
                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) {
@@ -4697,7 +4800,7 @@ static int lnet_ping(struct lnet_process_id id, signed long timeout,
 
        if (nob < 8) {
                CERROR("%s: ping info too short %d\n",
-                      libcfs_id2str(id), nob);
+                      libcfs_idstr(&id), nob);
                goto fail_ping_buffer_decref;
        }
 
@@ -4705,19 +4808,19 @@ static int lnet_ping(struct lnet_process_id id, signed long timeout,
                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;
        }
@@ -4727,7 +4830,7 @@ static int lnet_ping(struct lnet_process_id id, signed long timeout,
 
        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;
        }
@@ -4749,21 +4852,23 @@ static int lnet_ping(struct lnet_process_id id, signed long timeout,
 }
 
 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;
 
@@ -4779,7 +4884,7 @@ lnet_discover(struct lnet_process_id id, __u32 force,
                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;
@@ -4805,7 +4910,7 @@ lnet_discover(struct lnet_process_id id, __u32 force,
         * and lookup the lpni again
         */
        lnet_peer_ni_decref_locked(lpni);
-       lpni = lnet_find_peer_ni_locked(id.nid);
+       lpni = lnet_peer_ni_find_locked(&id.nid);
        if (!lpni) {
                rc = -ENOENT;
                goto out;