ev->status = 0;
ev->unlinked = 1;
ev->type = LNET_EVENT_UNLINK;
- lnet_md_deconstruct(md, &ev->md);
+ lnet_md_deconstruct(md, ev);
lnet_md2handle(&ev->md_handle, md);
EXIT;
}
/* build umd in event */
lnet_md2handle(&msg->msg_ev.md_handle, md);
- lnet_md_deconstruct(md, &msg->msg_ev.md);
+ lnet_md_deconstruct(md, &msg->msg_ev);
}
static int
__u32 sensitivity = lnet_health_sensitivity;
__u32 lp_sensitivity;
- /* lpni could be NULL if we're in the LOLND case */
+ /*
+ * NO-OP if:
+ * 1. lpni could be NULL if we're in the LOLND case
+ * 2. this is a recovery message
+ */
if (!lpni)
return;
}
static void
-lnet_incr_hstats(struct lnet_msg *msg, enum lnet_msg_hstatus hstatus)
+lnet_incr_hstats(struct lnet_ni *ni, struct lnet_peer_ni *lpni,
+ enum lnet_msg_hstatus hstatus)
{
- struct lnet_ni *ni = msg->msg_txni;
- struct lnet_peer_ni *lpni = msg->msg_txpeer;
struct lnet_counters_health *health;
health = &the_lnet.ln_counters[0]->lct_health;
struct lnet_peer_ni *lpni;
struct lnet_ni *ni;
bool lo = false;
+ bool attempt_local_resend;
+ bool attempt_remote_resend;
+ bool handle_local_health;
+ bool handle_remote_health;
/* if we're shutting down no point in handling health. */
if (the_lnet.ln_mt_state != LNET_MT_STATE_RUNNING)
* 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 &&
- LNET_NETTYP(LNET_NIDNET(msg->msg_txni->ni_nid)) != LOLND)
+ if (msg->msg_tx_committed && msg->msg_txni->ni_nid != LNET_NID_LO_0)
LASSERT(msg->msg_txpeer);
else if (msg->msg_tx_committed &&
- LNET_NETTYP(LNET_NIDNET(msg->msg_txni->ni_nid)) == LOLND)
+ msg->msg_txni->ni_nid == LNET_NID_LO_0)
lo = true;
if (hstatus != LNET_MSG_STATUS_OK &&
return -1;
/*
- * stats are only incremented for errors so avoid wasting time
- * incrementing statistics if there is no error.
- */
- if (hstatus != LNET_MSG_STATUS_OK) {
- lnet_net_lock(0);
- lnet_incr_hstats(msg, hstatus);
- lnet_net_unlock(0);
- }
-
- /*
* always prefer txni/txpeer if they message is committed for both
* directions.
*/
if (msg->msg_tx_committed) {
ni = msg->msg_txni;
lpni = msg->msg_txpeer;
+ attempt_local_resend = attempt_remote_resend = true;
} else {
ni = msg->msg_rxni;
lpni = msg->msg_rxpeer;
+ 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)
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.
+ */
+ if (hstatus != LNET_MSG_STATUS_OK) {
+ lnet_net_lock(0);
+ lnet_incr_hstats(ni, lpni, hstatus);
+ lnet_net_unlock(0);
+ }
+
switch (hstatus) {
case LNET_MSG_STATUS_OK:
/*
case LNET_MSG_STATUS_LOCAL_ABORTED:
case LNET_MSG_STATUS_LOCAL_NO_ROUTE:
case LNET_MSG_STATUS_LOCAL_TIMEOUT:
- lnet_handle_local_failure(ni);
- if (msg->msg_tx_committed)
- /* add to the re-send queue */
+ if (handle_local_health)
+ lnet_handle_local_failure(ni);
+ if (attempt_local_resend)
return lnet_attempt_msg_resend(msg);
break;
-
- /*
- * These errors will not trigger a resend so simply
- * finalize the message
- */
case LNET_MSG_STATUS_LOCAL_ERROR:
- lnet_handle_local_failure(ni);
+ if (handle_local_health)
+ lnet_handle_local_failure(ni);
return -1;
-
- /*
- * TODO: since the remote dropped the message we can
- * attempt a resend safely.
- */
case LNET_MSG_STATUS_REMOTE_DROPPED:
- lnet_handle_remote_failure(lpni);
- if (msg->msg_tx_committed)
+ if (handle_remote_health)
+ lnet_handle_remote_failure(lpni);
+ if (attempt_remote_resend)
return lnet_attempt_msg_resend(msg);
break;
-
case LNET_MSG_STATUS_REMOTE_ERROR:
case LNET_MSG_STATUS_REMOTE_TIMEOUT:
case LNET_MSG_STATUS_NETWORK_TIMEOUT:
- lnet_handle_remote_failure(lpni);
+ if (handle_remote_health)
+ lnet_handle_remote_failure(lpni);
return -1;
default:
LBUG();
LASSERT(md->md_refcount >= 0);
unlink = lnet_md_unlinkable(md);
- if (md->md_eq != NULL) {
+ if (md->md_handler) {
if ((md->md_flags & LNET_MD_FLAG_ABORTED) && !status) {
msg->msg_ev.status = -ETIMEDOUT;
CDEBUG(D_NET, "md 0x%p already unlinked\n", md);
msg->msg_ev.status = status;
}
msg->msg_ev.unlinked = unlink;
- lnet_eq_enqueue_event(md->md_eq, &msg->msg_ev);
+ md->md_handler(&msg->msg_ev);
}
if (unlink || (md->md_refcount == 0 &&