*/
/*
* This file is part of Lustre, http://www.lustre.org/
- * Lustre is a trademark of Sun Microsystems, Inc.
*
* lnet/lnet/lib-msg.c
*
if (ev_type == LNET_EVENT_SEND) {
/* event for active message */
- ev->target.nid = le64_to_cpu(hdr->dest_nid);
- ev->target.pid = le32_to_cpu(hdr->dest_pid);
- ev->initiator.nid = LNET_NID_ANY;
+ ev->target.nid = hdr->dest_nid;
+ ev->target.pid = hdr->dest_pid;
+ ev->initiator.nid = LNET_ANY_NID;
ev->initiator.pid = the_lnet.ln_pid;
- ev->source.nid = LNET_NID_ANY;
+ ev->source.nid = LNET_ANY_NID;
ev->source.pid = the_lnet.ln_pid;
- ev->sender = LNET_NID_ANY;
+ ev->sender = LNET_ANY_NID;
} else {
/* event for passive message */
ev->target.pid = hdr->dest_pid;
/* Multi-Rail: track source NID. */
ev->source.pid = hdr->src_pid;
ev->source.nid = hdr->src_nid;
- ev->rlength = hdr->payload_length;
+ ev->rlength = hdr->payload_length;
ev->sender = msg->msg_from;
ev->mlength = msg->msg_wanted;
ev->offset = msg->msg_offset;
ack_wmd = msg->msg_hdr.msg.put.ack_wmd;
- lnet_prep_send(msg, LNET_MSG_ACK, msg->msg_ev.source, 0, 0);
+ lnet_prep_send(msg, LNET_MSG_ACK, &msg->msg_ev.source, 0, 0);
msg->msg_hdr.msg.ack.dst_wmd = ack_wmd;
msg->msg_hdr.msg.ack.match_bits = msg->msg_ev.match_bits;
msg->msg_hdr.msg.ack.mlength = cpu_to_le32(msg->msg_ev.mlength);
- rc = lnet_send(msg->msg_ev.target.nid, msg, msg->msg_from);
+ rc = lnet_send(&msg->msg_ev.target.nid, msg,
+ &msg->msg_from);
lnet_net_lock(cpt);
/*
LASSERT(!msg->msg_receiving); /* called back recv already */
lnet_net_unlock(cpt);
- rc = lnet_send(LNET_NID_ANY, msg, LNET_NID_ANY);
+ rc = lnet_send(NULL, msg, NULL);
lnet_net_lock(cpt);
/*
}
}
+/* must hold net_lock/0 */
+void
+lnet_ni_add_to_recoveryq_locked(struct lnet_ni *ni,
+ struct list_head *recovery_queue, time64_t now)
+{
+ if (!list_empty(&ni->ni_recovery))
+ return;
+
+ if (atomic_read(&ni->ni_healthv) == LNET_MAX_HEALTH_VALUE)
+ return;
+
+ /* This NI is going on the recovery queue, so take a ref on it */
+ lnet_ni_addref_locked(ni, 0);
+
+ lnet_ni_set_next_ping(ni, now);
+
+ CDEBUG(D_NET, "%s added to recovery queue. ping count: %u next ping: %lld health :%d\n",
+ libcfs_nidstr(&ni->ni_nid),
+ ni->ni_ping_count,
+ ni->ni_next_ping,
+ atomic_read(&ni->ni_healthv));
+
+ list_add_tail(&ni->ni_recovery, recovery_queue);
+}
+
static void
lnet_handle_local_failure(struct lnet_ni *local_ni)
{
}
lnet_dec_healthv_locked(&local_ni->ni_healthv, lnet_health_sensitivity);
- /*
- * add the NI to the recovery queue if it's not already there
- * and it's health value is actually below the maximum. It's
- * possible that the sensitivity might be set to 0, and the health
- * value will not be reduced. In this case, there is no reason to
- * invoke recovery
- */
- if (list_empty(&local_ni->ni_recovery) &&
- atomic_read(&local_ni->ni_healthv) < LNET_MAX_HEALTH_VALUE) {
- CDEBUG(D_NET, "ni %s added to recovery queue. Health = %d\n",
- libcfs_nid2str(local_ni->ni_nid),
- atomic_read(&local_ni->ni_healthv));
- list_add_tail(&local_ni->ni_recovery,
- &the_lnet.ln_mt_localNIRecovq);
- lnet_ni_addref_locked(local_ni, 0);
- }
+ lnet_ni_add_to_recoveryq_locked(local_ni, &the_lnet.ln_mt_localNIRecovq,
+ ktime_get_seconds());
lnet_net_unlock(0);
}
msg->msg_target_is_router = 0;
CDEBUG(D_NET, "%s->%s:%s:%s - queuing msg (%p) for resend\n",
- libcfs_nid2str(msg->msg_hdr.src_nid),
- libcfs_nid2str(msg->msg_hdr.dest_nid),
+ libcfs_nidstr(&msg->msg_hdr.src_nid),
+ libcfs_nidstr(&msg->msg_hdr.dest_nid),
lnet_msgtyp2str(msg->msg_type),
lnet_health_error2str(msg->msg_health_status), msg);
/* don't resend recovery messages */
if (msg->msg_recovery) {
CDEBUG(D_NET, "msg %s->%s is a recovery ping. retry# %d\n",
- libcfs_nid2str(msg->msg_from),
- libcfs_nid2str(msg->msg_target.nid),
+ libcfs_nidstr(&msg->msg_from),
+ libcfs_nidstr(&msg->msg_target.nid),
msg->msg_retry_count);
return -ENOTRECOVERABLE;
}
*/
if (msg->msg_no_resend) {
CDEBUG(D_NET, "msg %s->%s requested no resend. retry# %d\n",
- libcfs_nid2str(msg->msg_from),
- libcfs_nid2str(msg->msg_target.nid),
+ libcfs_nidstr(&msg->msg_from),
+ libcfs_nidstr(&msg->msg_target.nid),
msg->msg_retry_count);
return -ENOTRECOVERABLE;
}
/* check if the message has exceeded the number of retries */
if (msg->msg_retry_count >= lnet_retry_count) {
CNETERR("msg %s->%s exceeded retry count %d\n",
- libcfs_nid2str(msg->msg_from),
- libcfs_nid2str(msg->msg_target.nid),
+ libcfs_nidstr(&msg->msg_from),
+ libcfs_nidstr(&msg->msg_target.nid),
msg->msg_retry_count);
return -ENOTRECOVERABLE;
}
return 0;
}
- while (!list_empty(&container->msc_resending)) {
- msg = list_entry(container->msc_resending.next,
- struct lnet_msg, msg_list);
+ while ((msg = list_first_entry_or_null(&container->msc_resending,
+ struct lnet_msg,
+ msg_list)) != NULL) {
list_del(&msg->msg_list);
/*
* if we're sending to the LOLND then the msg_txpeer will not be
* set. So no need to sanity check it.
*/
- if (msg->msg_tx_committed && msg->msg_txni->ni_nid != LNET_NID_LO_0)
+ if (msg->msg_tx_committed &&
+ !nid_is_lo0(&msg->msg_txni->ni_nid))
LASSERT(msg->msg_txpeer);
else if (msg->msg_tx_committed &&
- msg->msg_txni->ni_nid == LNET_NID_LO_0)
+ nid_is_lo0(&msg->msg_txni->ni_nid))
lo = true;
if (hstatus != LNET_MSG_STATUS_OK &&
attempt_local_resend = attempt_remote_resend = false;
}
- /* Don't further decrement the health value if a recovery message
- * failed.
- */
- if (msg->msg_recovery)
- handle_local_health = handle_remote_health = false;
- else
- handle_local_health = handle_remote_health = true;
-
- /* For local failures, health/recovery/resends are not needed if I only
- * have a single (non-lolnd) interface. NB: pb_nnis includes the lolnd
- * interface, so a single-rail node would have pb_nnis == 2.
- */
- if (the_lnet.ln_ping_target->pb_nnis <= 2) {
- handle_local_health = false;
- attempt_local_resend = false;
- }
-
- /* For remote failures, health/recovery/resends are not needed if the
- * peer only has a single interface. Special case for routers where we
- * rely on health feature to manage route aliveness. NB: unlike pb_nnis
- * above, lp_nnis does _not_ include the lolnd, so a single-rail node
- * would have lp_nnis == 1.
- */
- if (lpni && lpni->lpni_peer_net->lpn_peer->lp_nnis <= 1) {
- attempt_remote_resend = false;
- if (!lnet_isrouter(lpni))
- handle_remote_health = false;
- }
-
if (!lo)
LASSERT(ni && lpni);
else
LASSERT(ni);
CDEBUG(D_NET, "health check: %s->%s: %s: %s\n",
- libcfs_nid2str(ni->ni_nid),
- (lo) ? "self" : libcfs_nid2str(lpni->lpni_nid),
+ libcfs_nidstr(&ni->ni_nid),
+ (lo) ? "self" : libcfs_nidstr(&lpni->lpni_nid),
lnet_msgtyp2str(msg->msg_type),
lnet_health_error2str(hstatus));
/*
* stats are only incremented for errors so avoid wasting time
- * incrementing statistics if there is no error.
+ * incrementing statistics if there is no error. Similarly, whether to
+ * update health values or perform resends is only applicable for
+ * messages with a health status != OK.
*/
if (hstatus != LNET_MSG_STATUS_OK) {
+ /* Don't further decrement the health value if a recovery
+ * message failed.
+ */
+ if (msg->msg_recovery)
+ handle_local_health = handle_remote_health = false;
+ else
+ handle_local_health = handle_remote_health = true;
+
+ /* For local failures, health/recovery/resends are not needed if
+ * I only have a single (non-lolnd) interface. NB: pb_nnis
+ * includes the lolnd interface, so a single-rail node would
+ * have pb_nnis == 2.
+ */
+ if (the_lnet.ln_ping_target->pb_nnis <= 2) {
+ handle_local_health = false;
+ attempt_local_resend = false;
+ }
+
lnet_net_lock(0);
lnet_incr_hstats(ni, lpni, hstatus);
+ /* For remote failures, health/recovery/resends are not needed
+ * if the peer only has a single interface. Special case for
+ * routers where we rely on health feature to manage route
+ * aliveness. NB: unlike pb_nnis above, lp_nnis does _not_
+ * include the lolnd, so a single-rail node would have
+ * lp_nnis == 1.
+ */
+ if (lpni && lpni->lpni_peer_net &&
+ lpni->lpni_peer_net->lpn_peer &&
+ lpni->lpni_peer_net->lpn_peer->lp_nnis <= 1) {
+ attempt_remote_resend = false;
+ if (!lnet_isrouter(lpni))
+ handle_remote_health = false;
+ }
+ /* Do not put my interfaces into peer NI recovery. They should
+ * be handled with local NI recovery.
+ */
+ if (handle_remote_health && lpni &&
+ lnet_nid_to_ni_locked(&lpni->lpni_nid, 0))
+ handle_remote_health = false;
lnet_net_unlock(0);
}
* as indication that the router is fully healthy.
*/
if (lpni && msg->msg_rx_committed) {
+ lnet_net_lock(0);
lpni->lpni_ping_count = 0;
+ ni->ni_ping_count = 0;
/*
* If we're receiving a message from the router or
* I'm a router, then set that lpni's health to
* maximum so we can commence communication
*/
- lnet_net_lock(0);
if (lnet_isrouter(lpni) || the_lnet.ln_routing) {
lnet_set_lpni_healthv_locked(lpni,
LNET_MAX_HEALTH_VALUE);
return false;
/* match only health rules */
- if (!lnet_drop_rule_match(&msg->msg_hdr, LNET_NID_ANY,
- hstatus))
+ if (!lnet_drop_rule_match(&msg->msg_hdr, NULL, hstatus))
return false;
CDEBUG(D_NET, "src %s(%s)->dst %s: %s simulate health error: %s\n",
- libcfs_nid2str(msg->msg_hdr.src_nid),
- libcfs_nid2str(msg->msg_txni->ni_nid),
- libcfs_nid2str(msg->msg_hdr.dest_nid),
+ libcfs_nidstr(&msg->msg_hdr.src_nid),
+ libcfs_nidstr(&msg->msg_txni->ni_nid),
+ libcfs_nidstr(&msg->msg_hdr.dest_nid),
lnet_msgtyp2str(msg->msg_type),
lnet_health_error2str(*hstatus));
}
rc = 0;
- while (!list_empty(&container->msc_finalizing)) {
- msg = list_entry(container->msc_finalizing.next,
- struct lnet_msg, msg_list);
-
+ while ((msg = list_first_entry_or_null(&container->msc_finalizing,
+ struct lnet_msg,
+ msg_list)) != NULL) {
list_del_init(&msg->msg_list);
/* NB drops and regains the lnet lock if it actually does
void
lnet_msg_container_cleanup(struct lnet_msg_container *container)
{
- int count = 0;
+ struct lnet_msg *msg;
+ int count = 0;
if (container->msc_init == 0)
return;
- while (!list_empty(&container->msc_active)) {
- struct lnet_msg *msg;
-
- msg = list_entry(container->msc_active.next,
- struct lnet_msg, msg_activelist);
+ while ((msg = list_first_entry_or_null(&container->msc_active,
+ struct lnet_msg,
+ msg_activelist)) != NULL) {
LASSERT(msg->msg_onactivelist);
msg->msg_onactivelist = 0;
list_del_init(&msg->msg_activelist);