Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

Code Block
/*
 * 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)
{
...
	list_for_each_entry(peer_net, &peer->lp_peer_nets, lpn_peer_nets) {
	...
		struct lnet_net *net;


		net = lnet_get_net_locked(/* consider only highest priority peer_net */
		peer_net_prio = peer_net->lpn_net_id)priority;
		if (!netpeer_net_prio > best_peer_net_prio)
			continue;

		/*
		 * look only at the Nets with the highest priority and disregard
		 * nets 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 (!net)
			continue

		/*
		 * 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;
		if (net_prio > best_net_prio)
			continue;
		else if (net_prio < best_net_prio) {
			best_net_prio = net_prio;
			best_ni = NULL;
		}
		best_ni = lnet_find_best_ni_on_spec_net(best_ni, 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;
_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_lpni_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_prio;
	, sd->sd_rtr_nid);
			...
			/*
			 * selectif thegw NIis whichMR hasthen theselect best_ni's NID in its preferred list
	 */
	else if (!preferred && ni_is_pref)
		preferred = true;NI. Increment the sequence number of
			 * the gw NI for Round Robin selection.
		 	 */
			...
		}
	}
...
} 

User Space Design

UDSP Marshaling

After a UDSP is parsed in user space it needs to be marshaled marshalled and sent to the kernel. The kernel will de-marshal the data and store it in its own data structures. The UDSP is formed of the following pieces of information:

...

The address is expressed as a list of cfs_range_expr. These need to be marshalled. For IP address there are 4 of these structures. Other type of addresses can have a different number. As an example, gemini will only have one. The corresponding iou_[src|dst|rte]_dot_expr_count is set to the number of expressions describing the address. Each expression is then flattened in the structure. They have to be flattened in the order defined: SRC, DST, RTE.

The kernel will recieve receive the marshalled data and will form its internal structures. The functions to marshal and de-marshal should be straight forward. Note that user space and kernel space use the same structures. These structure will be defined in a common location. For this reason the functions to marshal and de-marshal will be shared.

...

Marshalling and de-

...

marshalling functions

Common functions that can be called from user space and kernel space will be created to marshal and de-marshal the UDSPs:

...

In a scenario where servers are being upgraded with new interfaces to be used in Multi-Rail, it's possible to add interfaces, for example MLX-EDR interfaces to the server. The user might want to continue making the existing QDR clients use the QDR interface, while new clients can use the EDR interface or even both interfaces. By specifying rules on the clients that prefer a specific interface interfaces this behavior behaviour can be achieved.

Gliffy Diagram
namePreferredNID
pagePin7

...