lnet_destroy_peer_locked(lp);
}
-static inline void
-lnet_peer_ni_addref_locked(struct lnet_peer_ni *lp)
-{
- kref_get(&lp->lpni_kref);
-}
-
extern void lnet_destroy_peer_ni_locked(struct kref *ref);
static inline void
int lnet_ping_info_validate(struct lnet_ping_info *pinfo);
struct lnet_ping_buffer *lnet_ping_buffer_alloc(int bytes, gfp_t gfp);
-void lnet_ping_buffer_free(struct lnet_ping_buffer *pbuf);
+void lnet_ping_buffer_free(struct kref *kref);
int lnet_get_link_status(struct net_device *dev);
__u32 lnet_set_link_fatal_state(struct lnet_ni *ni, unsigned int link_state);
-static inline void lnet_ping_buffer_addref(struct lnet_ping_buffer *pbuf)
-{
- atomic_inc(&pbuf->pb_refcnt);
-}
-
-static inline void lnet_ping_buffer_decref(struct lnet_ping_buffer *pbuf)
-{
- if (atomic_dec_and_test(&pbuf->pb_refcnt)) {
- wake_up_var(&pbuf->pb_refcnt);
- lnet_ping_buffer_free(pbuf);
- }
-}
-
struct lnet_ping_iter {
struct lnet_ping_info *pinfo;
void *pos, *end;
*/
struct lnet_ping_buffer {
int pb_nbytes; /* sizeof pb_info */
- atomic_t pb_refcnt;
+ struct kref pb_refcnt;
bool pb_needs_post;
struct lnet_ping_info pb_info;
};
if (pbuf) {
pbuf->pb_nbytes = nbytes; /* sizeof of pb_info */
pbuf->pb_needs_post = false;
- atomic_set(&pbuf->pb_refcnt, 1);
+ kref_init(&pbuf->pb_refcnt);
}
return pbuf;
}
void
-lnet_ping_buffer_free(struct lnet_ping_buffer *pbuf)
+lnet_ping_buffer_free(struct kref *kerf)
{
- LASSERT(atomic_read(&pbuf->pb_refcnt) == 0);
+ struct lnet_ping_buffer *pbuf = container_of(kerf,
+ struct lnet_ping_buffer,
+ pb_refcnt);
+
+ wake_up_var(&pbuf->pb_refcnt);
LIBCFS_FREE(pbuf, LNET_PING_BUFFER_SIZE(pbuf->pb_nbytes));
}
}
}
- lnet_ping_buffer_decref(the_lnet.ln_ping_target);
+ kref_put(&(the_lnet.ln_ping_target)->pb_refcnt, lnet_ping_buffer_free);
the_lnet.ln_ping_target = NULL;
lnet_net_unlock(LNET_LOCK_EX);
struct lnet_ping_buffer *pbuf = event->md_user_ptr;
if (event->unlinked)
- lnet_ping_buffer_decref(pbuf);
+ kref_put(&pbuf->pb_refcnt, lnet_ping_buffer_free);
}
static int
CERROR("Can't attach ping target MD: %d\n", rc);
goto fail_decref_ping_buffer;
}
- lnet_ping_buffer_addref(*ppbuf);
+ kref_get(&(*ppbuf)->pb_refcnt);
return 0;
fail_decref_ping_buffer:
- LASSERT(atomic_read(&(*ppbuf)->pb_refcnt) == 1);
- lnet_ping_buffer_decref(*ppbuf);
+ kref_put(&(*ppbuf)->pb_refcnt, lnet_ping_buffer_free);
*ppbuf = NULL;
fail_free_eq:
return rc;
/* NB the MD could be busy; this just starts the unlink */
wait_var_event_warning(&pbuf->pb_refcnt,
- atomic_read(&pbuf->pb_refcnt) <= 1,
+ kref_read(&pbuf->pb_refcnt) == 1,
"Still waiting for ping data MD to unlink\n");
}
mutex_unlock(&the_lnet.ln_api_mutex);
lnet_ping_md_unlink(old_pbuf, &old_ping_md);
mutex_lock(&the_lnet.ln_api_mutex);
- lnet_ping_buffer_decref(old_pbuf);
+ kref_put(&old_pbuf->pb_refcnt, lnet_ping_buffer_free);
}
lnet_push_update_to_peers(0);
rc = lnet_push_target_post(pbuf, &mdh);
if (rc) {
CDEBUG(D_NET, "Failed to post push target: %d\n", rc);
- lnet_ping_buffer_decref(pbuf);
+ kref_put(&pbuf->pb_refcnt, lnet_ping_buffer_free);
return rc;
}
if (old_pbuf) {
LNetMDUnlink(old_mdh);
/* Drop ref set by lnet_ping_buffer_alloc() */
- lnet_ping_buffer_decref(old_pbuf);
+ kref_put(&old_pbuf->pb_refcnt, lnet_ping_buffer_free);
}
/* Received another push or reply that requires a larger buffer */
pbuf->pb_needs_post = false;
/* This reference is dropped by lnet_push_target_event_handler() */
- lnet_ping_buffer_addref(pbuf);
+ kref_get(&pbuf->pb_refcnt);
/* initialize md content */
md.start = &pbuf->pb_info;
rc = LNetMDAttach(me, &md, LNET_UNLINK, mdhp);
if (rc) {
CERROR("Can't attach push MD: %d\n", rc);
- lnet_ping_buffer_decref(pbuf);
+ kref_put(&pbuf->pb_refcnt, lnet_ping_buffer_free);
pbuf->pb_needs_post = true;
return rc;
}
if (ev->type == LNET_EVENT_UNLINK) {
/* Drop ref added by lnet_push_target_post() */
- lnet_ping_buffer_decref(pbuf);
+ kref_put(&pbuf->pb_refcnt, lnet_ping_buffer_free);
return;
}
lnet_peer_push_event(ev);
if (ev->unlinked)
/* Drop ref added by lnet_push_target_post */
- lnet_ping_buffer_decref(pbuf);
+ kref_put(&pbuf->pb_refcnt, lnet_ping_buffer_free);
}
/* Initialize the push target. */
/* Wait for the unlink to complete. */
wait_var_event_warning(&the_lnet.ln_push_target->pb_refcnt,
- atomic_read(&the_lnet.ln_push_target->pb_refcnt) <= 1,
+ kref_read(&the_lnet.ln_push_target->pb_refcnt) == 1,
"Still waiting for ping data MD to unlink\n");
/* Drop ref set by lnet_ping_buffer_alloc() */
- lnet_ping_buffer_decref(the_lnet.ln_push_target);
+ kref_put(&(the_lnet.ln_push_target)->pb_refcnt, lnet_ping_buffer_free);
the_lnet.ln_push_target = NULL;
the_lnet.ln_push_target_nbytes = 0;
failed:
lnet_ping_md_unlink(pbuf, &ping_mdh);
- lnet_ping_buffer_decref(pbuf);
+ kref_put(&pbuf->pb_refcnt, lnet_ping_buffer_free);
return rc;
}
}
rc = i;
fail_ping_buffer_decref:
- lnet_ping_buffer_decref(pbuf);
+ kref_put(&pbuf->pb_refcnt, lnet_ping_buffer_free);
return rc;
}
struct lnet_peer_ni *best_lpni = sd->sd_best_lpni;
struct lnet_peer_ni *final_dst_lpni = sd->sd_final_dst_lpni;
struct lnet_msg *msg = sd->sd_msg;
- int cpt2;
__u32 send_case = sd->sd_send_case;
- int rc;
__u32 routing = send_case & REMOTE_DST;
struct lnet_rsp_tracker *rspt;
+ int cpt2, rc;
/* Increment sequence number of the selected peer, peer net,
* local ni and local net so that we pick the next ones
best_lpni->lpni_txcredits,
best_lpni->lpni_sel_priority);
- /*
- * grab a reference on the peer_ni so it sticks around even if
+ /* grab a reference on the peer_ni so it sticks around even if
* we need to drop and relock the lnet_net_lock below.
*/
- lnet_peer_ni_addref_locked(best_lpni);
+ kref_get(&best_lpni->lpni_kref);
- /*
- * Use lnet_cpt_of_nid() to determine the CPT used to commit the
+ /* Use lnet_cpt_of_nid() to determine the CPT used to commit the
* message. This ensures that we get a CPT that is correct for
* the NI when the NI has been restricted to a subset of all CPTs.
* If the selected CPT differs from the one currently locked, we
lnet_initiate_peer_discovery(struct lnet_peer_ni *lpni, struct lnet_msg *msg,
int cpt)
{
- struct lnet_peer *peer;
struct lnet_peer_ni *new_lpni;
+ struct lnet_peer *peer;
int rc;
- lnet_peer_ni_addref_locked(lpni);
+ kref_get(&lpni->lpni_kref);
peer = lpni->lpni_peer_net->lpn_peer;
rc = LNetMDBind(&md, LNET_UNLINK, mdh);
if (rc) {
- lnet_ping_buffer_decref(pbuf);
+ kref_put(&pbuf->pb_refcnt, lnet_ping_buffer_free);
CERROR("Can't bind MD: %d\n", rc);
rc = -rc; /* change the rc to positive */
goto fail_error;
if (event->unlinked) {
LIBCFS_FREE(ev_info, sizeof(*ev_info));
pbuf = LNET_PING_INFO_TO_BUFFER(event->md_start);
- lnet_ping_buffer_decref(pbuf);
+ kref_put(&pbuf->pb_refcnt, lnet_ping_buffer_free);
}
}
* list so it can be easily found and revisited.
*/
/* FIXME: per-net implementation instead? */
- lnet_peer_ni_addref_locked(lpni);
+ kref_get(&lpni->lpni_kref);
list_add_tail(&lpni->lpni_on_remote_peer_ni_list,
&the_lnet.ln_remote_peer_ni_list);
}
LASSERT(list_empty(&lp->lp_dc_list));
if (lp->lp_data)
- lnet_ping_buffer_decref(lp->lp_data);
+ kref_put(&lp->lp_data->pb_refcnt, lnet_ping_buffer_free);
/*
* if there are messages still on the pending queue, then make
peers = &ptable->pt_hash[lnet_nid2peerhash(nid)];
list_for_each_entry(lp, peers, lpni_hashlist) {
if (nid_same(&lp->lpni_nid, nid)) {
- lnet_peer_ni_addref_locked(lp);
+ kref_get(&lp->lpni_kref);
return lp;
}
}
ptable = the_lnet.ln_peer_tables[lpni->lpni_cpt];
list_add_tail(&lpni->lpni_hashlist, &ptable->pt_hash[hash]);
ptable->pt_version++;
- lnet_peer_ni_addref_locked(lpni);
+ kref_get(&lpni->lpni_kref);
}
/* Detach the peer_ni from an existing peer, if necessary. */
/* lnet_peer_attach_peer_ni() always returns 0 */
rc = lnet_peer_attach_peer_ni(lp, lpn, lpni, flags);
- lnet_peer_ni_addref_locked(lpni);
+ kref_get(&lpni->lpni_kref);
out_err:
if (rc) {
libcfs_nidstr(&lp->lp_primary_nid), lp->lp_peer_seqno,
lp->lp_state);
if (lp->lp_state & LNET_PEER_DATA_PRESENT)
- lnet_ping_buffer_decref(lp->lp_data);
+ kref_put(&lp->lp_data->pb_refcnt, lnet_ping_buffer_free);
else
lp->lp_state |= LNET_PEER_DATA_PRESENT;
- lnet_ping_buffer_addref(pbuf);
+ kref_get(&pbuf->pb_refcnt);
lp->lp_data = pbuf;
out:
lp->lp_state &= ~LNET_PEER_PING_SENT;
}
if (event->unlinked) {
pbuf = LNET_PING_INFO_TO_BUFFER(event->md_start);
- lnet_ping_buffer_decref(pbuf);
+ kref_put(&pbuf->pb_refcnt, lnet_ping_buffer_free);
lnet_peer_decref_locked(lp);
}
lnet_net_unlock(LNET_LOCK_EX);
CFS_FREE_PTR_ARRAY(curnis, nnis);
CFS_FREE_PTR_ARRAY(addnis, nnis);
CFS_FREE_PTR_ARRAY(delnis, nnis);
- lnet_ping_buffer_decref(pbuf);
+ kref_put(&pbuf->pb_refcnt, lnet_ping_buffer_free);
CDEBUG(D_NET, "peer %s (%p): %d\n",
libcfs_nidstr(&lp->lp_primary_nid), lp, rc);
lp->lp_peer_seqno = LNET_PING_BUFFER_SEQNO(pbuf);
} else if (lp->lp_state & LNET_PEER_DATA_PRESENT) {
lp->lp_state &= ~LNET_PEER_DATA_PRESENT;
- lnet_ping_buffer_decref(pbuf);
+ kref_put(&pbuf->pb_refcnt, lnet_ping_buffer_free);
pbuf = lp->lp_data;
lp->lp_data = NULL;
}
}
if (lp->lp_state & LNET_PEER_DATA_PRESENT) {
- lnet_ping_buffer_decref(lp->lp_data);
+ kref_put(&lp->lp_data->pb_refcnt, lnet_ping_buffer_free);
lp->lp_data = NULL;
lp->lp_state &= ~LNET_PEER_DATA_PRESENT;
}
*/
mutex_lock(&the_lnet.ln_api_mutex);
if (the_lnet.ln_state != LNET_STATE_RUNNING) {
- lnet_ping_buffer_decref(pbuf);
+ kref_put(&pbuf->pb_refcnt, lnet_ping_buffer_free);
rc = -ESHUTDOWN;
goto out;
}
* alive. Don't do any work on it.
*/
if (list_empty(&lp->lp_peer_list)) {
- lnet_ping_buffer_decref(pbuf);
+ kref_put(&pbuf->pb_refcnt, lnet_ping_buffer_free);
goto out;
}
* can show up with only the loopback NID in the ping buffer.
*/
if (!find_primary(&nid, pbuf)) {
- lnet_ping_buffer_decref(pbuf);
+ kref_put(&pbuf->pb_refcnt, lnet_ping_buffer_free);
goto out;
}
/* If lp_merge_primary_nid is set, assign it as primary,
if (nid_is_lo0(&lp->lp_primary_nid)) {
rc = lnet_peer_set_primary_nid(lp, &nid, flags);
if (rc)
- lnet_ping_buffer_decref(pbuf);
+ kref_put(&pbuf->pb_refcnt, lnet_ping_buffer_free);
else
rc = lnet_peer_merge_data(lp, pbuf);
/*
CERROR("Primary NID error %s versus %s: %d\n",
libcfs_nidstr(&lp->lp_primary_nid),
libcfs_nidstr(&nid), rc);
- lnet_ping_buffer_decref(pbuf);
+ kref_put(&pbuf->pb_refcnt,
+ lnet_ping_buffer_free);
} else {
rc = lnet_peer_merge_data(lp, pbuf);
}
cpt = lnet_net_lock_current();
pbuf = the_lnet.ln_ping_target;
- lnet_ping_buffer_addref(pbuf);
+ kref_get(&pbuf->pb_refcnt);
lnet_net_unlock(cpt);
/* Push source MD */
rc = LNetMDBind(&md, LNET_UNLINK, &lp->lp_push_mdh);
if (rc) {
- lnet_ping_buffer_decref(pbuf);
+ kref_put(&pbuf->pb_refcnt, lnet_ping_buffer_free);
CERROR("Can't bind push source MD: %d\n", rc);
goto fail_error;
}
}
/* This peer NI is going on the recovery queue, so take a ref on it */
- lnet_peer_ni_addref_locked(lpni);
+ kref_get(&lpni->lpni_kref);
+
lnet_peer_ni_set_next_ping(lpni, now);
libcfs_nidstr(&rtr->lp_primary_nid));
continue;
}
- lnet_peer_ni_addref_locked(lpni);
+ kref_get(&lpni->lpni_kref);
/* specify the net to use */
rtr->lp_disc_net_id = lpn->lpn_net_id;