Whamcloud - gitweb
LU-9679 lnet: use LIST_HEAD() for local lists.
[fs/lustre-release.git] / lnet / lnet / lib-move.c
index b1b2252..0bebc01 100644 (file)
@@ -165,7 +165,7 @@ lnet_fail_nid(lnet_nid_t nid, unsigned int threshold)
        struct lnet_test_peer *tp;
        struct list_head *el;
        struct list_head *next;
-       struct list_head  cull;
+       LIST_HEAD(cull);
 
        /* NB: use lnet_net_lock(0) to serialize operations on test peers */
        if (threshold != 0) {
@@ -183,9 +183,6 @@ lnet_fail_nid(lnet_nid_t nid, unsigned int threshold)
                return 0;
        }
 
-       /* removing entries */
-       INIT_LIST_HEAD(&cull);
-
        lnet_net_lock(0);
 
        list_for_each_safe(el, next, &the_lnet.ln_test_peers) {
@@ -215,10 +212,8 @@ fail_peer (lnet_nid_t nid, int outgoing)
        struct lnet_test_peer *tp;
        struct list_head *el;
        struct list_head *next;
-       struct list_head  cull;
-       int               fail = 0;
-
-       INIT_LIST_HEAD(&cull);
+       LIST_HEAD(cull);
+       int fail = 0;
 
        /* NB: use lnet_net_lock(0) to serialize operations on test peers */
        lnet_net_lock(0);
@@ -1269,8 +1264,7 @@ routing_off:
                /* drop all messages which are queued to be routed on that
                 * peer. */
                if (!the_lnet.ln_routing) {
-                       struct list_head drop;
-                       INIT_LIST_HEAD(&drop);
+                       LIST_HEAD(drop);
                        list_splice_init(&lp->lp_rtrq, &drop);
                        spin_unlock(&lp->lp_lock);
                        spin_unlock(&rxpeerni->lpni_lock);
@@ -1315,7 +1309,7 @@ routing_off:
 }
 
 static int
-lnet_compare_peers(struct lnet_peer_ni *p1, struct lnet_peer_ni *p2)
+lnet_compare_gw_lpnis(struct lnet_peer_ni *p1, struct lnet_peer_ni *p2)
 {
        if (p1->lpni_txqnob < p2->lpni_txqnob)
                return 1;
@@ -1453,85 +1447,62 @@ lnet_find_best_lpni_on_net(struct lnet_ni *lni, lnet_nid_t dst_nid,
        return lnet_select_peer_ni(lni, dst_nid, peer, peer_net);
 }
 
+/* Compare route priorities and hop counts */
 static int
-lnet_compare_routes(struct lnet_route *r1, struct lnet_route *r2,
-                   struct lnet_peer_ni **best_lpni)
+lnet_compare_routes(struct lnet_route *r1, struct lnet_route *r2)
 {
        int r1_hops = (r1->lr_hops == LNET_UNDEFINED_HOPS) ? 1 : r1->lr_hops;
        int r2_hops = (r2->lr_hops == LNET_UNDEFINED_HOPS) ? 1 : r2->lr_hops;
-       struct lnet_peer *lp1 = r1->lr_gateway;
-       struct lnet_peer *lp2 = r2->lr_gateway;
-       struct lnet_peer_ni *lpni1;
-       struct lnet_peer_ni *lpni2;
-       int rc;
 
-       lpni1 = lnet_find_best_lpni_on_net(NULL, LNET_NID_ANY, lp1,
-                                          r1->lr_lnet);
-       lpni2 = lnet_find_best_lpni_on_net(NULL, LNET_NID_ANY, lp2,
-                                          r2->lr_lnet);
-       LASSERT(lpni1 && lpni2);
-
-       if (r1->lr_priority < r2->lr_priority) {
-               *best_lpni = lpni1;
+       if (r1->lr_priority < r2->lr_priority)
                return 1;
-       }
 
-       if (r1->lr_priority > r2->lr_priority) {
-               *best_lpni = lpni2;
+       if (r1->lr_priority > r2->lr_priority)
                return -1;
-       }
 
-       if (r1_hops < r2_hops) {
-               *best_lpni = lpni1;
+       if (r1_hops < r2_hops)
                return 1;
-       }
 
-       if (r1_hops > r2_hops) {
-               *best_lpni = lpni2;
+       if (r1_hops > r2_hops)
                return -1;
-       }
-
-       rc = lnet_compare_peers(lpni1, lpni2);
-       if (rc == 1) {
-               *best_lpni = lpni1;
-               return rc;
-       } else if (rc == -1) {
-               *best_lpni = lpni2;
-               return rc;
-       }
 
-       if (r1->lr_seq - r2->lr_seq <= 0) {
-               *best_lpni = lpni1;
-               return 1;
-       }
-
-       *best_lpni = lpni2;
-       return -1;
+       return 0;
 }
 
 static struct lnet_route *
-lnet_find_route_locked(struct lnet_remotenet *rnet,
+lnet_find_route_locked(struct lnet_remotenet *rnet, __u32 src_net,
                       struct lnet_route **prev_route,
                       struct lnet_peer_ni **gwni)
 {
-       struct lnet_peer_ni *best_gw_ni = NULL;
+       struct lnet_peer_ni *lpni, *best_gw_ni = NULL;
        struct lnet_route *best_route;
        struct lnet_route *last_route;
        struct lnet_route *route;
        int rc;
+       __u32 restrict_net;
+       __u32 any_net = LNET_NIDNET(LNET_NID_ANY);
 
        best_route = last_route = NULL;
        list_for_each_entry(route, &rnet->lrn_routes, lr_list) {
                if (!lnet_is_route_alive(route))
                        continue;
 
+               /* If the src_net is specified then we need to find an lpni
+                * on that network
+                */
+               restrict_net = src_net == any_net ? route->lr_lnet : src_net;
                if (!best_route) {
-                       best_route = last_route = route;
-                       best_gw_ni = lnet_find_best_lpni_on_net(NULL,
-                                                               LNET_NID_ANY,
-                                                               route->lr_gateway,
-                                                               route->lr_lnet);
-                       LASSERT(best_gw_ni);
+                       lpni = lnet_find_best_lpni_on_net(NULL, LNET_NID_ANY,
+                                                         route->lr_gateway,
+                                                         restrict_net);
+                       if (lpni) {
+                               best_route = last_route = route;
+                               best_gw_ni = lpni;
+                       } else
+                               CERROR("Gateway %s does not have a peer NI on net %s\n",
+                                      libcfs_nid2str(route->lr_gateway->lp_primary_nid),
+                                      libcfs_net2str(restrict_net));
+
                        continue;
                }
 
@@ -1539,11 +1510,35 @@ lnet_find_route_locked(struct lnet_remotenet *rnet,
                if (last_route->lr_seq - route->lr_seq < 0)
                        last_route = route;
 
-               rc = lnet_compare_routes(route, best_route, &best_gw_ni);
-               if (rc < 0)
+               rc = lnet_compare_routes(route, best_route);
+               if (rc == -1)
                        continue;
 
-               best_route = route;
+               lpni = lnet_find_best_lpni_on_net(NULL, LNET_NID_ANY,
+                                                 route->lr_gateway,
+                                                 restrict_net);
+               if (!lpni) {
+                       CERROR("Gateway %s does not have a peer NI on net %s\n",
+                              libcfs_nid2str(route->lr_gateway->lp_primary_nid),
+                              libcfs_net2str(restrict_net));
+                       continue;
+               }
+
+               if (rc == 1) {
+                       best_route = route;
+                       best_gw_ni = lpni;
+                       continue;
+               }
+
+               rc = lnet_compare_gw_lpnis(lpni, best_gw_ni);
+               if (rc == -1)
+                       continue;
+
+               if (rc == 1 || route->lr_seq <= best_route->lr_seq) {
+                       best_route = route;
+                       best_gw_ni = lpni;
+                       continue;
+               }
        }
 
        *prev_route = last_route;
@@ -2083,8 +2078,9 @@ lnet_handle_find_routed_path(struct lnet_send_data *sd,
                        return -EHOSTUNREACH;
                }
 
-               best_route = lnet_find_route_locked(best_rnet, &last_route,
-                                                   &gwni);
+               best_route = lnet_find_route_locked(best_rnet,
+                                                   LNET_NIDNET(src_nid),
+                                                   &last_route, &gwni);
                if (!best_route) {
                        CERROR("no route to %s from %s\n",
                               libcfs_nid2str(dst_nid),
@@ -2650,20 +2646,13 @@ lnet_select_pathway(lnet_nid_t src_nid, lnet_nid_t dst_nid,
 again:
 
        /*
-        * 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.
+        * 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
         */
        send_data.sd_msg = msg;
        send_data.sd_cpt = cpt;
-       if (src_nid == LNET_NID_ANY && !msg->msg_recovery &&
-           lnet_nid2ni_locked(dst_nid, cpt)) {
+       if (LNET_NETTYP(LNET_NIDNET(dst_nid)) == LOLND) {
                rc = lnet_handle_lo_send(&send_data);
                lnet_net_unlock(cpt);
                return rc;
@@ -2872,7 +2861,6 @@ static void
 lnet_finalize_expired_responses(void)
 {
        struct lnet_libmd *md;
-       struct list_head local_queue;
        struct lnet_rsp_tracker *rspt, *tmp;
        ktime_t now;
        int i;
@@ -2881,7 +2869,7 @@ lnet_finalize_expired_responses(void)
                return;
 
        cfs_cpt_for_each(i, lnet_cpt_table()) {
-               INIT_LIST_HEAD(&local_queue);
+               LIST_HEAD(local_queue);
 
                lnet_net_lock(i);
                if (!the_lnet.ln_mt_rstq[i]) {
@@ -3109,8 +3097,8 @@ static void
 lnet_recover_local_nis(void)
 {
        struct lnet_mt_event_info *ev_info;
-       struct list_head processed_list;
-       struct list_head local_queue;
+       LIST_HEAD(processed_list);
+       LIST_HEAD(local_queue);
        struct lnet_handle_md mdh;
        struct lnet_ni *tmp;
        struct lnet_ni *ni;
@@ -3118,9 +3106,6 @@ lnet_recover_local_nis(void)
        int healthv;
        int rc;
 
-       INIT_LIST_HEAD(&local_queue);
-       INIT_LIST_HEAD(&processed_list);
-
        /*
         * splice the recovery queue on a local queue. We will iterate
         * through the local queue and update it as needed. Once we're
@@ -3351,11 +3336,9 @@ static void
 lnet_clean_resendqs(void)
 {
        struct lnet_msg *msg, *tmp;
-       struct list_head msgs;
+       LIST_HEAD(msgs);
        int i;
 
-       INIT_LIST_HEAD(&msgs);
-
        cfs_cpt_for_each(i, lnet_cpt_table()) {
                lnet_net_lock(i);
                list_splice_init(the_lnet.ln_mt_resendqs[i], &msgs);
@@ -3374,8 +3357,8 @@ static void
 lnet_recover_peer_nis(void)
 {
        struct lnet_mt_event_info *ev_info;
-       struct list_head processed_list;
-       struct list_head local_queue;
+       LIST_HEAD(processed_list);
+       LIST_HEAD(local_queue);
        struct lnet_handle_md mdh;
        struct lnet_peer_ni *lpni;
        struct lnet_peer_ni *tmp;
@@ -3383,9 +3366,6 @@ lnet_recover_peer_nis(void)
        int healthv;
        int rc;
 
-       INIT_LIST_HEAD(&local_queue);
-       INIT_LIST_HEAD(&processed_list);
-
        /*
         * Always use cpt 0 for locking across all interactions with
         * ln_mt_peerNIRecovq
@@ -4404,8 +4384,8 @@ lnet_parse(struct lnet_ni *ni, struct lnet_hdr *hdr, lnet_nid_t from_nid,
 
        if (!list_empty(&the_lnet.ln_drop_rules) &&
            lnet_drop_rule_match(hdr, ni->ni_nid, NULL)) {
-               CDEBUG(D_NET, "%s, src %s, dst %s: Dropping %s to simulate"
-                             "silent message loss\n",
+               CDEBUG(D_NET,
+                      "%s, src %s, dst %s: Dropping %s to simulate silent message loss\n",
                       libcfs_nid2str(from_nid), libcfs_nid2str(src_nid),
                       libcfs_nid2str(dest_nid), lnet_msgtyp2str(type));
                goto drop;
@@ -4654,7 +4634,6 @@ lnet_attach_rsp_tracker(struct lnet_rsp_tracker *rspt, int cpt,
                        struct lnet_libmd *md, struct lnet_handle_md mdh)
 {
        s64 timeout_ns;
-       bool new_entry = true;
        struct lnet_rsp_tracker *local_rspt;
 
        /*
@@ -4674,7 +4653,6 @@ lnet_attach_rsp_tracker(struct lnet_rsp_tracker *rspt, int cpt,
                 * update the deadline on that one.
                 */
                lnet_rspt_free(rspt, cpt);
-               new_entry = false;
        } else {
                /* new md */
                rspt->rspt_mdh = mdh;
@@ -4690,9 +4668,7 @@ lnet_attach_rsp_tracker(struct lnet_rsp_tracker *rspt, int cpt,
         * list in order to expire all the older entries first.
         */
        lnet_net_lock(cpt);
-       if (!new_entry && !list_empty(&local_rspt->rspt_on_list))
-               list_del_init(&local_rspt->rspt_on_list);
-       list_add_tail(&local_rspt->rspt_on_list, the_lnet.ln_mt_rstq[cpt]);
+       list_move_tail(&local_rspt->rspt_on_list, the_lnet.ln_mt_rstq[cpt]);
        lnet_net_unlock(cpt);
        lnet_res_unlock(cpt);
 }