X-Git-Url: https://git.whamcloud.com/?p=fs%2Flustre-release.git;a=blobdiff_plain;f=lnet%2Flnet%2Flib-move.c;h=615d755593c58490c374a7e61cb96c2c805c1ae3;hp=c15143013eb12c619bbe07a652563a0e3c7fb4ed;hb=275016fcae729f8467dc09aa15aa2b4bb2690875;hpb=80edb2ad72baf9b096e03f2929b8b018b0a630d2 diff --git a/lnet/lnet/lib-move.c b/lnet/lnet/lib-move.c index c151430..615d755 100644 --- a/lnet/lnet/lib-move.c +++ b/lnet/lnet/lib-move.c @@ -1315,7 +1315,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,103 +1453,98 @@ 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_net *net, __u32 remote_net, +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_remotenet *rnet; - struct lnet_peer *lp_best; struct lnet_route *route; - struct lnet_peer *lp; int rc; + __u32 restrict_net; + __u32 any_net = LNET_NIDNET(LNET_NID_ANY); - rnet = lnet_find_rnet_locked(remote_net); - if (rnet == NULL) - return NULL; - - lp_best = NULL; best_route = last_route = NULL; list_for_each_entry(route, &rnet->lrn_routes, lr_list) { - lp = route->lr_gateway; - if (!lnet_is_route_alive(route)) continue; - if (lp_best == NULL) { - best_route = last_route = route; - lp_best = lp; + /* 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) { + 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; } /* no protection on below fields, but it's harmless */ 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; - lp_best = lp; + 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; @@ -2026,7 +2021,7 @@ lnet_handle_find_routed_path(struct lnet_send_data *sd, struct lnet_peer *lp; struct lnet_peer_net *lpn; struct lnet_peer_net *best_lpn = NULL; - struct lnet_remotenet *rnet; + struct lnet_remotenet *rnet, *best_rnet = NULL; struct lnet_route *best_route = NULL; struct lnet_route *last_route = NULL; struct lnet_peer_ni *lpni = NULL; @@ -2061,13 +2056,16 @@ lnet_handle_find_routed_path(struct lnet_send_data *sd, if (!rnet) continue; - if (!best_lpn) + if (!best_lpn) { best_lpn = lpn; + best_rnet = rnet; + } if (best_lpn->lpn_seq <= lpn->lpn_seq) continue; best_lpn = lpn; + best_rnet = rnet; } if (!best_lpn) { @@ -2086,7 +2084,8 @@ lnet_handle_find_routed_path(struct lnet_send_data *sd, return -EHOSTUNREACH; } - best_route = lnet_find_route_locked(NULL, best_lpn->lpn_net_id, + 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", @@ -2653,20 +2652,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; @@ -4657,7 +4649,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; /* @@ -4677,7 +4668,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; @@ -4693,9 +4683,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); }