struct lnet_peer_ni **gw_lpni,
struct lnet_peer **gw_peer)
{
- int rc;
+ int rc = 0;
struct lnet_peer *gw;
struct lnet_peer *lp;
struct lnet_peer_net *lpn;
struct lnet_peer_ni *lpni = NULL;
struct lnet_peer_ni *gwni = NULL;
bool route_found = false;
+ bool gwni_decref = false;
struct lnet_nid *src_nid =
!LNET_NID_IS_ANY(&sd->sd_src_nid) || !sd->sd_best_ni
? &sd->sd_src_nid
if (!LNET_NID_IS_ANY(&sd->sd_rtr_nid)) {
gwni = lnet_peer_ni_find_locked(&sd->sd_rtr_nid);
if (gwni) {
+ gwni_decref = true;
gw = gwni->lpni_peer_net->lpn_peer;
- lnet_peer_ni_decref_locked(gwni);
if (gw->lp_rtr_refcount)
route_found = true;
} else {
"any local NI" :
libcfs_nidstr(src_nid),
libcfs_nidstr(&sd->sd_dst_nid));
- return -EHOSTUNREACH;
+ rc = -EHOSTUNREACH;
+ goto out;
}
CDEBUG(D_NET, "best_rnet %s\n",
libcfs_net2str(best_rnet->lrn_net));
if (!best_lpn) {
CERROR("peer %s has no available nets\n",
libcfs_nidstr(&sd->sd_dst_nid));
- return -EHOSTUNREACH;
+ rc = -EHOSTUNREACH;
+ goto out;
}
CDEBUG(D_NET, "selected best_lpn %s\n",
if (!sd->sd_best_lpni) {
CERROR("peer %s is unreachable\n",
libcfs_nidstr(&sd->sd_dst_nid));
- return -EHOSTUNREACH;
+ rc = -EHOSTUNREACH;
+ goto out;
}
/* We're attempting to round robin over the remote peer
CERROR("no route to %s from %s\n",
libcfs_nidstr(dst_nid),
libcfs_nidstr(src_nid));
- return -EHOSTUNREACH;
+ rc = -EHOSTUNREACH;
+ goto out;
}
if (!gwni) {
CERROR("Internal Error. Route expected to %s from %s\n",
libcfs_nidstr(dst_nid),
libcfs_nidstr(src_nid));
- return -EFAULT;
+ rc = -EFAULT;
+ goto out;
}
gw = best_route->lr_gateway;
if (alive_router_check_interval <= 0) {
rc = lnet_initiate_peer_discovery(gwni, sd->sd_msg, sd->sd_cpt);
if (rc)
- return rc;
+ goto out;
}
if (!sd->sd_best_ni) {
CERROR("Internal Error. Expected local ni on %s but non found: %s\n",
libcfs_net2str(lpn->lpn_net_id),
libcfs_nidstr(&sd->sd_src_nid));
- return -EFAULT;
+ rc = -EFAULT;
+ goto out;
}
}
best_route->lr_seq = last_route->lr_seq + 1;
}
- return 0;
+out:
+ if (gwni_decref && gwni)
+ lnet_peer_ni_decref_locked(gwni);
+
+ return rc;
}
/*
lnet_net_unlock(cpt);
return rc;
}
- lnet_peer_ni_decref_locked(lpni);
peer = lpni->lpni_peer_net->lpn_peer;
* updated as a result of calling lnet_handle_send_case_locked().
*/
cpt = send_data.sd_cpt;
+ lnet_peer_ni_decref_locked(lpni);
if (rc == REPEAT_SEND)
goto again;
rc = -ENOENT;
goto out;
}
- lnet_peer_ni_decref_locked(lpni);
if (lp != lpni->lpni_peer_net->lpn_peer) {
rc = -ECHILD;
+ lnet_peer_ni_decref_locked(lpni);
goto out;
}
*/
if (nid_same(nid, &lp->lp_primary_nid) && lp->lp_nnis != 1 && !force) {
rc = -EBUSY;
+ lnet_peer_ni_decref_locked(lpni);
goto out;
}
lp->lp_primary_nid = lpni2->lpni_nid;
}
rc = lnet_peer_ni_del_locked(lpni, force);
+ lnet_peer_ni_decref_locked(lpni);
lnet_net_unlock(LNET_LOCK_EX);
lpni = lnet_peer_ni_find_locked(prim_nid);
if (!lpni)
return -ENOENT;
- lnet_peer_ni_decref_locked(lpni);
lp = lpni->lpni_peer_net->lpn_peer;
+ lnet_peer_ni_decref_locked(lpni);
/* Peer must have been configured. */
if ((flags & LNET_PEER_CONFIGURED) &&
lpni = lnet_peer_ni_find_locked(prim_nid);
if (!lpni)
return -ENOENT;
- lnet_peer_ni_decref_locked(lpni);
lp = lpni->lpni_peer_net->lpn_peer;
+ lnet_peer_ni_decref_locked(lpni);
if (!nid_same(prim_nid, &lp->lp_primary_nid)) {
CDEBUG(D_NET, "prim_nid %s is not primary for peer %s\n",
lnet_discover_peer_locked(struct lnet_peer_ni *lpni, int cpt, bool block)
{
DEFINE_WAIT(wait);
- struct lnet_peer *lp;
+ struct lnet_peer *lp = NULL;
int rc = 0;
int count = 0;
again:
+ if (lp)
+ lnet_peer_decref_locked(lp);
lnet_net_unlock(cpt);
lnet_net_lock(LNET_LOCK_EX);
lp = lpni->lpni_peer_net->lpn_peer;
lnet_net_unlock(LNET_LOCK_EX);
lnet_net_lock(cpt);
- lnet_peer_decref_locked(lp);
/*
* The peer may have changed, so re-check and rediscover if that turns
* out to have been the case. The reference count on lp ensured that
(lp ? libcfs_nidstr(&lp->lp_primary_nid) : "(none)"),
libcfs_nidstr(&lpni->lpni_nid), rc,
(!block) ? "pending discovery" : "discovery complete");
+ lnet_peer_decref_locked(lp);
return rc;
}
LBUG();
}
lnet_net_lock(LNET_LOCK_EX);
- if (event->unlinked) {
- pbuf = LNET_PING_INFO_TO_BUFFER(event->md_start);
- lnet_ping_buffer_decref(pbuf);
- lnet_peer_decref_locked(lp);
- }
/* put peer back at end of request queue, if discovery not already
* done */
list_move_tail(&lp->lp_dc_list, &the_lnet.ln_dc_request);
wake_up(&the_lnet.ln_dc_waitq);
}
+ if (event->unlinked) {
+ pbuf = LNET_PING_INFO_TO_BUFFER(event->md_start);
+ lnet_ping_buffer_decref(pbuf);
+ lnet_peer_decref_locked(lp);
+ }
lnet_net_unlock(LNET_LOCK_EX);
}
goto out;
}
- lnet_peer_ni_decref_locked(lpni);
-
lpn = lpni->lpni_peer_net;
if (lpn->lpn_peer_nets.prev != &lp->lp_peer_nets)
list_move(&lpn->lpn_peer_nets, &lp->lp_peer_nets);
list_move(&lpni->lpni_peer_nis,
&lpni->lpni_peer_net->lpn_peer_nis);
+ lnet_peer_ni_decref_locked(lpni);
/*
* Errors other than -ENOMEM are due to peers having been
* configured with DLC. Ignore these because DLC overrides