#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");
* Local Destination
* MR Peer
*
- * Run the selection algorithm on the peer NIs unless we're sending
- * a response, in this case just send to the destination
+ * Don't run the selection algorithm on the peer NIs. By specifying the
+ * local NID, we're also saying that we should always use the destination NID
+ * provided. This handles the case where we should be using the same
+ * destination NID for the all the messages which belong to the same RPC
+ * request.
*/
static int
lnet_handle_spec_local_mr_dst(struct lnet_send_data *sd)
return -EINVAL;
}
- /*
- * only run the selection algorithm to pick the peer_ni if we're
- * sending a GET or a PUT. Responses are sent to the same
- * destination NID provided.
- */
- if (!(sd->sd_send_case & SND_RESP)) {
- sd->sd_best_lpni =
- lnet_find_best_lpni_on_net(sd, sd->sd_peer,
- sd->sd_best_ni->ni_net->net_id);
- }
-
if (sd->sd_best_lpni &&
sd->sd_best_lpni->lpni_nid == the_lnet.ln_loni->ni_nid)
return lnet_handle_lo_send(sd);
}
/* The peer may have changed. */
peer = lpni->lpni_peer_net->lpn_peer;
+ spin_lock(&peer->lp_lock);
+ if (lnet_peer_is_uptodate_locked(peer)) {
+ spin_unlock(&peer->lp_lock);
+ lnet_peer_ni_decref_locked(lpni);
+ return 0;
+ }
/* queue message and return */
msg->msg_rtr_nid_param = rtr_nid;
msg->msg_sending = 0;
msg->msg_txpeer = NULL;
- spin_lock(&peer->lp_lock);
list_add_tail(&msg->msg_list, &peer->lp_dc_pendq);
+ primary_nid = peer->lp_primary_nid;
spin_unlock(&peer->lp_lock);
+
lnet_peer_ni_decref_locked(lpni);
- primary_nid = peer->lp_primary_nid;
CDEBUG(D_NET, "msg %p delayed. %s pending discovery\n",
msg, libcfs_nid2str(primary_nid));
msg->msg_src_nid_param = src_nid;
/*
- * Now that we have a peer_ni, check if we want to discover
- * the peer. Traffic to the LNET_RESERVED_PORTAL should not
- * trigger discovery.
+ * If necessary, perform discovery on the peer that owns this peer_ni.
+ * Note, this can result in the ownership of this peer_ni changing
+ * to another peer object.
*/
- peer = lpni->lpni_peer_net->lpn_peer;
rc = lnet_initiate_peer_discovery(lpni, msg, rtr_nid, cpt);
if (rc) {
lnet_peer_ni_decref_locked(lpni);
}
lnet_peer_ni_decref_locked(lpni);
+ peer = lpni->lpni_peer_net->lpn_peer;
+
/*
* Identify the different send cases
*/
min((unsigned int) alive_router_check_interval /
lnet_current_net_count,
lnet_transaction_timeout / 2));
- wait_event_interruptible_timeout(the_lnet.ln_mt_waitq,
- false,
- cfs_time_seconds(interval));
+ wait_for_completion_interruptible_timeout(
+ &the_lnet.ln_mt_wait_complete,
+ cfs_time_seconds(interval));
+ /* Must re-init the completion before testing anything,
+ * including ln_mt_state.
+ */
+ reinit_completion(&the_lnet.ln_mt_wait_complete);
}
/* Shutting down */
lnet_net_unlock(LNET_LOCK_EX);
/* tell the monitor thread that we're shutting down */
- wake_up(&the_lnet.ln_mt_waitq);
+ complete(&the_lnet.ln_mt_wait_complete);
/* block until monitor thread signals that it's done */
down(&the_lnet.ln_mt_signal);
lnet_clean_local_ni_recoveryq();
lnet_clean_peer_ni_recoveryq();
lnet_clean_resendqs();
-
- return;
}
void
* current net namespace.
* If not, assign order above 0xffff0000,
* to make this ni not a priority. */
- if (!net_eq(ni->ni_net_ns, current->nsproxy->net_ns))
- order += 0xffff0000;
-
+ if (current->nsproxy &&
+ !net_eq(ni->ni_net_ns, current->nsproxy->net_ns))
+ order += 0xffff0000;
if (srcnidp != NULL)
*srcnidp = ni->ni_nid;
if (orderp != NULL)