Whamcloud - gitweb
LU-12036 ofd: add "no_precreate" mount option
[fs/lustre-release.git] / lnet / lnet / lib-move.c
index 4050395..9f1a580 100644 (file)
@@ -42,8 +42,6 @@
 #include <linux/nsproxy.h>
 #include <net/net_namespace.h>
 
-extern unsigned int lnet_current_net_count;
-
 static int local_nid_dist_zero = 1;
 module_param(local_nid_dist_zero, int, 0444);
 MODULE_PARM_DESC(local_nid_dist_zero, "Reserved");
@@ -196,8 +194,7 @@ lnet_fail_nid(lnet_nid_t nid, unsigned int threshold)
                if (tp->tp_threshold == 0 ||    /* needs culling anyway */
                    nid == LNET_NID_ANY ||      /* removing all entries */
                    tp->tp_nid == nid) {        /* matched this one */
-                       list_del(&tp->tp_list);
-                       list_add(&tp->tp_list, &cull);
+                       list_move(&tp->tp_list, &cull);
                }
        }
 
@@ -235,8 +232,7 @@ fail_peer (lnet_nid_t nid, int outgoing)
                                /* only cull zombies on outgoing tests,
                                 * since we may be at interrupt priority on
                                 * incoming messages. */
-                               list_del(&tp->tp_list);
-                               list_add(&tp->tp_list, &cull);
+                               list_move(&tp->tp_list, &cull);
                        }
                        continue;
                }
@@ -250,8 +246,7 @@ fail_peer (lnet_nid_t nid, int outgoing)
                                if (outgoing &&
                                    tp->tp_threshold == 0) {
                                        /* see above */
-                                       list_del(&tp->tp_list);
-                                       list_add(&tp->tp_list, &cull);
+                                       list_move(&tp->tp_list, &cull);
                                }
                        }
                        break;
@@ -1518,7 +1513,7 @@ lnet_compare_routes(struct lnet_route *r1, struct lnet_route *r2,
 
 static struct lnet_route *
 lnet_find_route_locked(struct lnet_net *net, __u32 remote_net,
-                      lnet_nid_t rtr_nid, struct lnet_route **prev_route,
+                      struct lnet_route **prev_route,
                       struct lnet_peer_ni **gwni)
 {
        struct lnet_peer_ni *best_gw_ni = NULL;
@@ -1530,9 +1525,6 @@ lnet_find_route_locked(struct lnet_net *net, __u32 remote_net,
        struct lnet_peer *lp;
        int rc;
 
-       /* If @rtr_nid is not LNET_NID_ANY, return the gateway with
-        * rtr_nid nid, otherwise find the best gateway I can use */
-
        rnet = lnet_find_rnet_locked(remote_net);
        if (rnet == NULL)
                return NULL;
@@ -1849,13 +1841,14 @@ lnet_handle_send(struct lnet_send_data *sd)
        rc = lnet_post_send_locked(msg, 0);
 
        if (!rc)
-               CDEBUG(D_NET, "TRACE: %s(%s:%s) -> %s(%s:%s) : %s try# %d\n",
+               CDEBUG(D_NET, "TRACE: %s(%s:%s) -> %s(%s:%s) %s : %s try# %d\n",
                       libcfs_nid2str(msg->msg_hdr.src_nid),
                       libcfs_nid2str(msg->msg_txni->ni_nid),
                       libcfs_nid2str(sd->sd_src_nid),
                       libcfs_nid2str(msg->msg_hdr.dest_nid),
                       libcfs_nid2str(sd->sd_dst_nid),
                       libcfs_nid2str(msg->msg_txpeer->lpni_nid),
+                      libcfs_nid2str(sd->sd_rtr_nid),
                       lnet_msgtyp2str(msg->msg_type), msg->msg_retry_count);
 
        return rc;
@@ -2030,69 +2023,90 @@ 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;
        struct lnet_peer_net *best_lpn = NULL;
        struct lnet_remotenet *rnet;
-       struct lnet_route *best_route;
-       struct lnet_route *last_route;
+       struct lnet_route *best_route = NULL;
+       struct lnet_route *last_route = NULL;
        struct lnet_peer_ni *lpni = NULL;
        struct lnet_peer_ni *gwni = NULL;
        lnet_nid_t src_nid = sd->sd_src_nid;
 
-       /* we've already looked up the initial lpni using dst_nid */
-       lpni = sd->sd_best_lpni;
-       /* the peer tree must be in existence */
-       LASSERT(lpni && lpni->lpni_peer_net && lpni->lpni_peer_net->lpn_peer);
-       lp = lpni->lpni_peer_net->lpn_peer;
+       /* If a router nid was specified then we are replying to a GET or
+        * sending an ACK. In this case we use the gateway associated with the
+        * specified router nid.
+        */
+       if (sd->sd_rtr_nid != LNET_NID_ANY) {
+               gwni = lnet_find_peer_ni_locked(sd->sd_rtr_nid);
+               if (!gwni) {
+                       CERROR("No peer NI for gateway %s\n",
+                              libcfs_nid2str(sd->sd_rtr_nid));
+                       return -EHOSTUNREACH;
+               }
+               gw = gwni->lpni_peer_net->lpn_peer;
+               lnet_peer_ni_decref_locked(gwni);
+               local_lnet = LNET_NIDNET(sd->sd_rtr_nid);
+       } else {
+               /* we've already looked up the initial lpni using dst_nid */
+               lpni = sd->sd_best_lpni;
+               /* the peer tree must be in existence */
+               LASSERT(lpni && lpni->lpni_peer_net &&
+                       lpni->lpni_peer_net->lpn_peer);
+               lp = lpni->lpni_peer_net->lpn_peer;
+
+               list_for_each_entry(lpn, &lp->lp_peer_nets, lpn_peer_nets) {
+                       /* is this remote network reachable?  */
+                       rnet = lnet_find_rnet_locked(lpn->lpn_net_id);
+                       if (!rnet)
+                               continue;
 
-       list_for_each_entry(lpn, &lp->lp_peer_nets, lpn_peer_nets) {
-               /* is this remote network reachable?  */
-               rnet = lnet_find_rnet_locked(lpn->lpn_net_id);
-               if (!rnet)
-                       continue;
+                       if (!best_lpn)
+                               best_lpn = lpn;
+
+                       if (best_lpn->lpn_seq <= lpn->lpn_seq)
+                               continue;
 
-               if (!best_lpn)
                        best_lpn = lpn;
+               }
 
-               if (best_lpn->lpn_seq <= lpn->lpn_seq)
-                       continue;
+               if (!best_lpn) {
+                       CERROR("peer %s has no available nets\n",
+                              libcfs_nid2str(sd->sd_dst_nid));
+                       return -EHOSTUNREACH;
+               }
 
-               best_lpn = lpn;
-       }
+               sd->sd_best_lpni = lnet_find_best_lpni_on_net(sd, lp, best_lpn->lpn_net_id);
+               if (!sd->sd_best_lpni) {
+                       CERROR("peer %s down\n",
+                              libcfs_nid2str(sd->sd_dst_nid));
+                       return -EHOSTUNREACH;
+               }
 
-       if (!best_lpn) {
-               CERROR("peer %s has no available nets \n",
-                      libcfs_nid2str(sd->sd_dst_nid));
-               return -EHOSTUNREACH;
-       }
+               best_route = lnet_find_route_locked(NULL, best_lpn->lpn_net_id,
+                                                   &last_route, &gwni);
+               if (!best_route) {
+                       CERROR("no route to %s from %s\n",
+                              libcfs_nid2str(dst_nid),
+                              libcfs_nid2str(src_nid));
+                       return -EHOSTUNREACH;
+               }
 
-       sd->sd_best_lpni = lnet_find_best_lpni_on_net(sd, lp, best_lpn->lpn_net_id);
-       if (!sd->sd_best_lpni) {
-               CERROR("peer %s down\n", libcfs_nid2str(sd->sd_dst_nid));
-               return -EHOSTUNREACH;
-       }
+               if (!gwni) {
+                       CERROR("Internal Error. Route expected to %s from %s\n",
+                              libcfs_nid2str(dst_nid),
+                              libcfs_nid2str(src_nid));
+                       return -EFAULT;
+               }
 
-       best_route = lnet_find_route_locked(NULL, best_lpn->lpn_net_id,
-                                           sd->sd_rtr_nid, &last_route,
-                                           &gwni);
-       if (!best_route) {
-               CERROR("no route to %s from %s\n",
-                      libcfs_nid2str(dst_nid), libcfs_nid2str(src_nid));
-               return -EHOSTUNREACH;
-       }
+               gw = best_route->lr_gateway;
+               LASSERT(gw == gwni->lpni_peer_net->lpn_peer);
+               local_lnet = best_route->lr_lnet;
 
-       if (!gwni) {
-               CERROR("Internal Error. Route expected to %s from %s\n",
-                       libcfs_nid2str(dst_nid),
-                       libcfs_nid2str(src_nid));
-               return -EFAULT;
        }
 
-       gw = best_route->lr_gateway;
-       LASSERT(gw == gwni->lpni_peer_net->lpn_peer);
-
        /*
         * Discover this gateway if it hasn't already been discovered.
         * This means we might delay the message until discovery has
@@ -2107,14 +2121,13 @@ lnet_handle_find_routed_path(struct lnet_send_data *sd,
        if (!sd->sd_best_ni)
                sd->sd_best_ni = lnet_find_best_ni_on_spec_net(NULL, gw,
                                        lnet_peer_get_net_locked(gw,
-                                               best_route->lr_lnet),
+                                                                local_lnet),
                                        sd->sd_md_cpt,
                                        true);
 
        if (!sd->sd_best_ni) {
-               CERROR("Internal Error. Expected local ni on %s "
-                      "but non found :%s\n",
-                      libcfs_net2str(best_route->lr_lnet),
+               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;
        }
@@ -2126,9 +2139,11 @@ lnet_handle_find_routed_path(struct lnet_send_data *sd,
         * increment the sequence numbers since now we're sure we're
         * going to use this path
         */
-       LASSERT(best_route && last_route);
-       best_route->lr_seq = last_route->lr_seq + 1;
-       best_lpn->lpn_seq++;
+       if (sd->sd_rtr_nid == LNET_NID_ANY) {
+               LASSERT(best_route && last_route);
+               best_route->lr_seq = last_route->lr_seq + 1;
+               best_lpn->lpn_seq++;
+       }
 
        return 0;
 }
@@ -2636,13 +2651,20 @@ lnet_select_pathway(lnet_nid_t src_nid, lnet_nid_t dst_nid,
 again:
 
        /*
-        * If we're being asked to send to the loopback interface, there
-        * is no need to go through any selection. We can just shortcut
-        * the entire process and send over lolnd
+        * If we're sending to ourselves then there is no need to go through
+        * any selection. We can shortcut the entire process and send over
+        * lolnd.
+        *
+        * However, we make two exceptions to this rule:
+        * 1. If the src_nid is specified then our API defines that we must send
+        *    via that interface.
+        * 2. Recovery messages must be sent to the lnet_ni that is being
+        *    recovered.
         */
        send_data.sd_msg = msg;
        send_data.sd_cpt = cpt;
-       if (LNET_NETTYP(LNET_NIDNET(dst_nid)) == LOLND) {
+       if (src_nid == LNET_NID_ANY && !msg->msg_recovery &&
+           lnet_nid2ni_locked(dst_nid, cpt)) {
                rc = lnet_handle_lo_send(&send_data);
                lnet_net_unlock(cpt);
                return rc;
@@ -4652,7 +4674,7 @@ lnet_attach_rsp_tracker(struct lnet_rsp_tracker *rspt, int cpt,
                 * we already have an rspt attached to the md, so we'll
                 * update the deadline on that one.
                 */
-               LIBCFS_FREE(rspt, sizeof(*rspt));
+               lnet_rspt_free(rspt, cpt);
                new_entry = false;
        } else {
                /* new md */
@@ -4773,7 +4795,7 @@ LNetPut(lnet_nid_t self, struct lnet_handle_md mdh, enum lnet_ack_req ack,
                               md->md_me->me_portal);
                lnet_res_unlock(cpt);
 
-               LIBCFS_FREE(rspt, sizeof(*rspt));
+               lnet_rspt_free(rspt, cpt);
                lnet_msg_free(msg);
                return -ENOENT;
        }
@@ -5000,7 +5022,7 @@ LNetGet(lnet_nid_t self, struct lnet_handle_md mdh,
                lnet_res_unlock(cpt);
 
                lnet_msg_free(msg);
-               LIBCFS_FREE(rspt, sizeof(*rspt));
+               lnet_rspt_free(rspt, cpt);
                return -ENOENT;
        }