Whamcloud - gitweb
LU-14649 lnet: Correct distance calculation of local NIDs
[fs/lustre-release.git] / lnet / lnet / lib-move.c
index 9420d6a..e458bbf 100644 (file)
@@ -725,7 +725,7 @@ lnet_prep_send(struct lnet_msg *msg, int type, struct lnet_process_id target,
        msg->msg_hdr.payload_length = cpu_to_le32(len);
 }
 
-static void
+void
 lnet_ni_send(struct lnet_ni *ni, struct lnet_msg *msg)
 {
        void *priv = msg->msg_private;
@@ -927,6 +927,12 @@ lnet_post_send_locked(struct lnet_msg *msg, int do_send)
                }
        }
 
+       if (unlikely(!list_empty(&the_lnet.ln_delay_rules)) &&
+           lnet_delay_rule_match_locked(&msg->msg_hdr, msg)) {
+               msg->msg_tx_delayed = 1;
+               return LNET_CREDIT_WAIT;
+       }
+
        /* unset the tx_delay flag as we're going to send it now */
        msg->msg_tx_delayed = 0;
 
@@ -2098,7 +2104,6 @@ lnet_handle_find_routed_path(struct lnet_send_data *sd,
                             struct lnet_peer **gw_peer)
 {
        int rc;
-       __u32 local_lnet;
        struct lnet_peer *gw;
        struct lnet_peer *lp;
        struct lnet_peer_net *lpn;
@@ -2127,10 +2132,8 @@ lnet_handle_find_routed_path(struct lnet_send_data *sd,
                if (gwni) {
                        gw = gwni->lpni_peer_net->lpn_peer;
                        lnet_peer_ni_decref_locked(gwni);
-                       if (gw->lp_rtr_refcount) {
-                               local_lnet = LNET_NIDNET(sd->sd_rtr_nid);
+                       if (gw->lp_rtr_refcount)
                                route_found = true;
-                       }
                } else {
                        CWARN("No peer NI for gateway %s. Attempting to find an alternative route.\n",
                               libcfs_nid2str(sd->sd_rtr_nid));
@@ -2246,7 +2249,6 @@ use_lpn:
 
                gw = best_route->lr_gateway;
                LASSERT(gw == gwni->lpni_peer_net->lpn_peer);
-               local_lnet = best_route->lr_lnet;
        }
 
        /*
@@ -2254,22 +2256,20 @@ use_lpn:
         * This means we might delay the message until discovery has
         * completed
         */
-       sd->sd_msg->msg_src_nid_param = sd->sd_src_nid;
        rc = lnet_initiate_peer_discovery(gwni, sd->sd_msg, sd->sd_cpt);
        if (rc)
                return rc;
 
-       if (!sd->sd_best_ni)
-               sd->sd_best_ni = lnet_find_best_ni_on_spec_net(NULL, gw,
-                                       lnet_peer_get_net_locked(gw,
-                                                                local_lnet),
-                                       sd->sd_md_cpt);
-
        if (!sd->sd_best_ni) {
-               CERROR("Internal Error. Expected local ni on %s but non found :%s\n",
-                      libcfs_net2str(local_lnet),
-                      libcfs_nid2str(sd->sd_src_nid));
-               return -EFAULT;
+               lpn = gwni->lpni_peer_net;
+               sd->sd_best_ni = lnet_find_best_ni_on_spec_net(NULL, gw, lpn,
+                                                              sd->sd_md_cpt);
+               if (!sd->sd_best_ni) {
+                       CERROR("Internal Error. Expected local ni on %s but non found: %s\n",
+                              libcfs_net2str(lpn->lpn_net_id),
+                              libcfs_nid2str(sd->sd_src_nid));
+                       return -EFAULT;
+               }
        }
 
        *gw_lpni = gwni;
@@ -5242,6 +5242,7 @@ LNetDist(lnet_nid_t dstnid, lnet_nid_t *srcnidp, __u32 *orderp)
        int cpt;
        __u32 order = 2;
        struct list_head *rn_list;
+       bool matched_dstnet = false;
 
        /* if !local_nid_dist_zero, I don't return a distance of 0 ever
         * (when lustre sees a distance of 0, it substitutes 0@lo), so I
@@ -5267,25 +5268,40 @@ LNetDist(lnet_nid_t dstnid, lnet_nid_t *srcnidp, __u32 *orderp)
                        return local_nid_dist_zero ? 0 : 1;
                }
 
-               if (LNET_NIDNET(ni->ni_nid) == dstnet) {
-                       /* Check if ni was originally created in
-                        * current net namespace.
-                        * If not, assign order above 0xffff0000,
-                        * to make this ni not a priority. */
-                       if (current->nsproxy &&
-                           !net_eq(ni->ni_net_ns, current->nsproxy->net_ns))
-                                       order += 0xffff0000;
-                       if (srcnidp != NULL)
+               if (!matched_dstnet && LNET_NIDNET(ni->ni_nid) == dstnet) {
+                       matched_dstnet = true;
+                       /* We matched the destination net, but we may have
+                        * additional local NIs to inspect.
+                        *
+                        * We record the nid and order as appropriate, but
+                        * they may be overwritten if we match local NI above.
+                        */
+                       if (srcnidp)
                                *srcnidp = ni->ni_nid;
-                       if (orderp != NULL)
-                               *orderp = order;
-                       lnet_net_unlock(cpt);
-                       return 1;
+
+                       if (orderp) {
+                               /* Check if ni was originally created in
+                                * current net namespace.
+                                * If not, assign order above 0xffff0000,
+                                * to make this ni not a priority.
+                                */
+                               if (current->nsproxy &&
+                                   !net_eq(ni->ni_net_ns,
+                                           current->nsproxy->net_ns))
+                                       *orderp = order + 0xffff0000;
+                               else
+                                       *orderp = order;
+                       }
                }
 
                order++;
        }
 
+       if (matched_dstnet) {
+               lnet_net_unlock(cpt);
+               return 1;
+       }
+
        rn_list = lnet_net2rnethash(dstnet);
        list_for_each(e, rn_list) {
                rnet = list_entry(e, struct lnet_remotenet, lrn_list);