...
Kernel Selection Algorithm Modifications
| Code Block |
|---|
static inline int lnet_get_peer_net_health(struct lnet_peer_net *lpn) { /* * The peer net is highest health value of all lpnis in the peer * This is a value which will be maintained when the lpni health * value is updated. */ return lpn->lpn_health; } /* * select an NI from the Nets with highest priority */ struct lnet_ni * lnet_find_best_ni_on_local_net(struct lnet_peer *peer, int md_cpt) { ... /* * All criteria are defaulted at the beginning of the loop such that * the first peer_net is selected and then overwritten if there is a * better peer_net found */ list_for_each_entry(peer_net, &peer->lp_peer_nets, lpn_peer_nets) { ... struct lnet_net *net; _peer_nets) { ... struct lnet_net *net; best_peer_net = peer_net; /* get the the health of a peer net */ peer_net_health = lnet_get_peer_net_health(peer_net); if (peer_net_health < best_peer_net_health) continue; else if (peer_net_health > best_peer_net_health) best_peer_net_health = peer_net_health; /* consider only highest priority peer_net */ peer_net_prio = peer_net->lpn_priority; else if (peer_net_prio > best_peer_net_prio) continue; else if (peer_net_prio < best_peer_net_prio) peer_net_prio = best_peer_net_prio; net = lnet_get_net_locked(peer_net->lpn_net_id); if (!best_net) continue net_prio = net->net_priority; /* * look only at the Nets with the highest priority and disregard * nets which have lower priority. Nets with equal priority are * examined and the best_ni is selected from amongst them. */ net_prio = net->net_priority; equal priority are * examined and the best_ni is selected from amongst them. */ net_health = lnet_get_local_net_health(net) if (net_health < best_net_health) continue; else if (net_health > best_net_health) best_net_health = net_health; else if (net_prio > best_net_prio) continue; else if (net_prio < best_net_prio) { best_net_prio = net_prio; best_ninet = NULL;net ... } if (!best_net || !best_peer_net) goto fail; best_ni = lnet_find_best_ni_on_spec_net(best_niNULL, peer, best_peer_net, md_cpt, false); ... } ... } /* * select the NI with the highest priority */ static struct lnet_ni * lnet_get_best_ni(struct lnet_net *local_net, struct lnet_ni *best_ni, struct lnet_peer *peer, struct lnet_peer_net *peer_net, int md_cpt) { ... ni_prio = ni->ni_priority; if (ni_fatal) { continue; } else if (ni_healthv < best_healthv) { continue; } else if (ni_healthv > best_healthv) { best_healthv = ni_healthv; if (distance < shortest_distance) shortest_distance = distance; /* * if this NI is lower in priority than the one already set then discard it * otherwise use it and set the best priority so far to this NI's. */ } else if ni_prio > best_ni_prio) { continue; } else if (ni_prio < best_ni_prio) best_ni_prio = ni_prio; } ... } /* * When a UDSP rule associates local NIs with remote NIs, the list of local NIs NIDs * is flattened to a list in the associated peer_NI. When selecting a peer NI, the * peer NI with the corresponding preferred local NI is selected. */ bool lnet_peer_is_pref_nid_locked(struct lnet_peer_ni *lpni, lnet_nid_t nid) { ... } /* * select the peer NI with the highest priority first and then check * if it's preferred. */ static struct lnet_peer_ni * lnet_select_peer_ni(struct lnet_send_data *sd, struct lnet_peer *peer, struct lnet_peer_net *peer_net) { ... ni_is_pref = lnet_peer_is_pref_nid_locked(lpni, best_ni->ni_nid); lpni_prio = lpni->lpni_priority; if (lpni_healthv < best_lpni_healthv) continue; /* * select the NI with the highest priority. */ else if lpni_prio > best_lpni_prio) continue; else if (lpni_prio < best_lpni_prio) best_lpni_prio = lpni_prio; /* * select the NI which has the best_ni's NID in its preferred list */ else if (!preferred && ni_is_pref) preferred = true; ... } static int lnet_handle_find_routed_path(struct lnet_send_data *sd, lnet_nid_t dst_nid, struct lnet_peer_ni **gw_lpni, struct lnet_peer **gw_peer) { ... lpni = lnet_find_peer_ni_locked(dst_nid); peer = lpni->lpni_net->lpn_peer; list_for_each_entry(peer_net, &peer->lp_peer_nets, lpn_peer_nets) { peer_net_priority = peer_net->lpn_priority; if (peer_net_priority > peer_net_best_priority) continue; else if (peer_net_priority < peer_net_best_priority) peer_net_best_priority = peer_net_priority; lpni = NULL; while ((lpni = lnet_get_next_peer_ni_locked(peer, peer_net, lpni)) { /* find best gw for this lpni */ lpni_prio = lpni->lpni_priority; if (lpni_prio > lpni_best_prio) continue; else if (lpni_prio < lpni_best_prio) lpni_best_prio = lpni_prio; /* * lnet_find_route_locked will be changed to consider the list of * gw NIDs on the lpni */ gw = lnet_find_route_locked(NULL, lpni, sd->sd_rtr_nid); ... /* * if gw is MR then select best_NI. Increment the sequence number of * the gw NI for Round Robin selection. */ ... } } ... } |
...