From 4c72e3df768a38139562e8c519cca2a8c3da940c Mon Sep 17 00:00:00 2001 From: Arshad Hussain Date: Sat, 24 Aug 2024 03:08:10 -0400 Subject: [PATCH] LU-16796 lnet: Change struct lnet_ping_buffer to use kref This patch changes struct lnet_ping_buffer to use kref instead of atomic_t Test-Parameters: trivial testlist=sanity-lnet Signed-off-by: Arshad Hussain Change-Id: Ic180e576c3b11afec687dcb3b55b857c730598f6 Reviewed-on: https://review.whamcloud.com/c/fs/lustre-release/+/56177 Tested-by: jenkins Tested-by: Maloo Reviewed-by: Timothy Day Reviewed-by: Chris Horn Reviewed-by: Neil Brown Reviewed-by: James Simmons Reviewed-by: Oleg Drokin --- lnet/include/lnet/lib-lnet.h | 21 +-------------------- lnet/include/lnet/lib-types.h | 2 +- lnet/lnet/api-ni.c | 43 +++++++++++++++++++++++-------------------- lnet/lnet/lib-move.c | 19 ++++++++----------- lnet/lnet/peer.c | 40 +++++++++++++++++++++------------------- lnet/lnet/router.c | 2 +- 6 files changed, 55 insertions(+), 72 deletions(-) diff --git a/lnet/include/lnet/lib-lnet.h b/lnet/include/lnet/lib-lnet.h index eba26b6..519870f 100644 --- a/lnet/include/lnet/lib-lnet.h +++ b/lnet/include/lnet/lib-lnet.h @@ -384,12 +384,6 @@ lnet_peer_decref_locked(struct lnet_peer *lp) 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 @@ -981,23 +975,10 @@ void lnet_swap_pinginfo(struct lnet_ping_buffer *pbuf); 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; diff --git a/lnet/include/lnet/lib-types.h b/lnet/include/lnet/lib-types.h index 8a13cc1..c3c8124 100644 --- a/lnet/include/lnet/lib-types.h +++ b/lnet/include/lnet/lib-types.h @@ -1263,7 +1263,7 @@ struct lnet_ni { */ 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; }; diff --git a/lnet/lnet/api-ni.c b/lnet/lnet/api-ni.c index aaff0d5..0335632 100644 --- a/lnet/lnet/api-ni.c +++ b/lnet/lnet/api-ni.c @@ -1786,16 +1786,20 @@ lnet_ping_buffer_alloc(int nbytes, gfp_t gfp) 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)); } @@ -1917,7 +1921,7 @@ lnet_ping_target_destroy(void) } } - 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); @@ -1929,7 +1933,7 @@ lnet_ping_target_event_handler(struct lnet_event *event) 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 @@ -1980,13 +1984,12 @@ lnet_ping_target_setup(struct lnet_ping_buffer **ppbuf, 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; @@ -2001,7 +2004,7 @@ lnet_ping_md_unlink(struct lnet_ping_buffer *pbuf, /* 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"); } @@ -2116,7 +2119,7 @@ __must_hold(&the_lnet.ln_api_mutex) 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); @@ -2162,7 +2165,7 @@ again: 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; } @@ -2176,7 +2179,7 @@ again: 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 */ @@ -2207,7 +2210,7 @@ int lnet_push_target_post(struct lnet_ping_buffer *pbuf, 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; @@ -2221,7 +2224,7 @@ int lnet_push_target_post(struct lnet_ping_buffer *pbuf, 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; } @@ -2243,14 +2246,14 @@ static void lnet_push_target_event_handler(struct lnet_event *ev) 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. */ @@ -2291,11 +2294,11 @@ static void lnet_push_target_fini(void) /* 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; @@ -3660,7 +3663,7 @@ static int lnet_add_net_common(struct lnet_net *net, failed: lnet_ping_md_unlink(pbuf, &ping_mdh); - lnet_ping_buffer_decref(pbuf); + kref_put(&pbuf->pb_refcnt, lnet_ping_buffer_free); return rc; } @@ -10141,7 +10144,7 @@ static int lnet_ping(struct lnet_processid *id, struct lnet_nid *src_nid, } rc = i; fail_ping_buffer_decref: - lnet_ping_buffer_decref(pbuf); + kref_put(&pbuf->pb_refcnt, lnet_ping_buffer_free); return rc; } diff --git a/lnet/lnet/lib-move.c b/lnet/lnet/lib-move.c index add5a27..2b33310 100644 --- a/lnet/lnet/lib-move.c +++ b/lnet/lnet/lib-move.c @@ -1842,11 +1842,10 @@ lnet_handle_send(struct lnet_send_data *sd) 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 @@ -1870,14 +1869,12 @@ lnet_handle_send(struct lnet_send_data *sd) 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 @@ -2097,11 +2094,11 @@ static int 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; @@ -4129,7 +4126,7 @@ lnet_send_ping(struct lnet_nid *dest_nid, 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; @@ -4253,7 +4250,7 @@ lnet_mt_event_handler(struct lnet_event *event) 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); } } diff --git a/lnet/lnet/peer.c b/lnet/lnet/peer.c index 05633d3..da51655 100644 --- a/lnet/lnet/peer.c +++ b/lnet/lnet/peer.c @@ -177,7 +177,7 @@ lnet_peer_ni_alloc(struct lnet_nid *nid) * 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); } @@ -285,7 +285,7 @@ lnet_destroy_peer_locked(struct lnet_peer *lp) 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 @@ -687,7 +687,7 @@ lnet_get_peer_ni_locked(struct lnet_peer_table *ptable, struct lnet_nid *nid) 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; } } @@ -1583,7 +1583,7 @@ lnet_peer_attach_peer_ni(struct lnet_peer *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. */ @@ -2006,7 +2006,7 @@ __must_hold(&the_lnet.ln_api_mutex) /* 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) { @@ -3011,10 +3011,10 @@ lnet_discovery_event_reply(struct lnet_peer *lp, struct lnet_event *ev) 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; @@ -3130,7 +3130,7 @@ static void lnet_discovery_event_handler(struct lnet_event *event) } 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); @@ -3430,7 +3430,7 @@ out: 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); @@ -3474,13 +3474,13 @@ lnet_peer_set_primary_data(struct lnet_peer *lp, struct lnet_ping_buffer *pbuf) 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; } @@ -3624,7 +3624,7 @@ __must_hold(&lp->lp_lock) */ 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; } @@ -3635,7 +3635,7 @@ __must_hold(&lp->lp_lock) * 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; } @@ -3657,7 +3657,7 @@ __must_hold(&lp->lp_lock) * 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, @@ -3673,7 +3673,7 @@ __must_hold(&lp->lp_lock) 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); /* @@ -3696,7 +3696,8 @@ __must_hold(&lp->lp_lock) 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); } @@ -3900,7 +3901,7 @@ __must_hold(&lp->lp_lock) 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 */ @@ -3914,7 +3915,7 @@ __must_hold(&lp->lp_lock) 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; } @@ -4541,7 +4542,8 @@ lnet_peer_ni_add_to_recoveryq_locked(struct lnet_peer_ni *lpni, } /* 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); diff --git a/lnet/lnet/router.c b/lnet/lnet/router.c index 7bcb1be..1db22a2 100644 --- a/lnet/lnet/router.c +++ b/lnet/lnet/router.c @@ -1168,7 +1168,7 @@ rescan: 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; -- 1.8.3.1