From b7278ecc699b5bd7c431222c93f1f209f02d4670 Mon Sep 17 00:00:00 2001 From: Mr NeilBrown Date: Wed, 25 Mar 2020 16:26:28 +1100 Subject: [PATCH] LU-13005 lnet: Support checking for MD leaks. Since we dropped the refcounting on LNetEQ we no longer get confirmation that all MDs for a given handler a gone by the time they should be. So add lnet_assert_handler_unused() which searches the per-cpt containers and ensures there are no MDs for a given handler, and call that are the same place that we used to call LNetEQFree(). Signed-off-by: Mr NeilBrown Change-Id: Ic04e5b4f67a79055c49994bd1d92e275fa71dd4b Reviewed-on: https://review.whamcloud.com/38059 Tested-by: jenkins Tested-by: Maloo Reviewed-by: Chris Horn Reviewed-by: James Simmons Reviewed-by: Oleg Drokin --- lnet/include/lnet/api.h | 2 ++ lnet/lnet/api-ni.c | 3 +++ lnet/lnet/lib-md.c | 18 ++++++++++++++++++ lnet/lnet/peer.c | 1 + lnet/selftest/rpc.c | 1 + lustre/ptlrpc/events.c | 1 + 6 files changed, 26 insertions(+) diff --git a/lnet/include/lnet/api.h b/lnet/include/lnet/api.h index 02b43ce..bc6e9d9 100644 --- a/lnet/include/lnet/api.h +++ b/lnet/include/lnet/api.h @@ -128,6 +128,8 @@ int LNetMDBind(struct lnet_md md_in, struct lnet_handle_md *md_handle_out); int LNetMDUnlink(struct lnet_handle_md md_in); + +void lnet_assert_handler_unused(lnet_handler_t handler); /** @} lnet_md */ /** \defgroup lnet_data Data movement operations diff --git a/lnet/lnet/api-ni.c b/lnet/lnet/api-ni.c index c5ffd6d..5922a6a 100644 --- a/lnet/lnet/api-ni.c +++ b/lnet/lnet/api-ni.c @@ -1270,6 +1270,7 @@ lnet_unprepare (void) the_lnet.ln_mt_zombie_rstqs = NULL; } + lnet_assert_handler_unused(the_lnet.ln_mt_handler); the_lnet.ln_mt_handler = NULL; lnet_portals_destroy(); @@ -1842,6 +1843,7 @@ lnet_ping_target_fini(void) lnet_ping_md_unlink(the_lnet.ln_ping_target, &the_lnet.ln_ping_target_md); + lnet_assert_handler_unused(the_lnet.ln_ping_target_handler); lnet_ping_target_destroy(); } @@ -2015,6 +2017,7 @@ static void lnet_push_target_fini(void) the_lnet.ln_push_target_nnis = 0; LNetClearLazyPortal(LNET_RESERVED_PORTAL); + lnet_assert_handler_unused(the_lnet.ln_push_target_handler); the_lnet.ln_push_target_handler = NULL; } diff --git a/lnet/lnet/lib-md.c b/lnet/lnet/lib-md.c index 0d1cc3e..de72e45 100644 --- a/lnet/lnet/lib-md.c +++ b/lnet/lnet/lib-md.c @@ -264,6 +264,24 @@ lnet_md_link(struct lnet_libmd *md, lnet_handler_t handler, int cpt) return 0; } +void lnet_assert_handler_unused(lnet_handler_t handler) +{ + struct lnet_res_container *container; + int cpt; + + if (!handler) + return; + cfs_percpt_for_each(container, cpt, the_lnet.ln_md_containers) { + struct lnet_libmd *md; + + lnet_res_lock(cpt); + list_for_each_entry(md, &container->rec_active, md_list) + LASSERT(md->md_handler != handler); + lnet_res_unlock(cpt); + } +} +EXPORT_SYMBOL(lnet_assert_handler_unused); + /* must be called with lnet_res_lock held */ void lnet_md_deconstruct(struct lnet_libmd *lmd, struct lnet_event *ev) diff --git a/lnet/lnet/peer.c b/lnet/lnet/peer.c index c77417a..f4c45ed 100644 --- a/lnet/lnet/peer.c +++ b/lnet/lnet/peer.c @@ -3475,6 +3475,7 @@ static int lnet_peer_discovery(void *arg) } lnet_net_unlock(LNET_LOCK_EX); + lnet_assert_handler_unused(the_lnet.ln_dc_handler); the_lnet.ln_dc_handler = NULL; the_lnet.ln_dc_state = LNET_DC_STATE_SHUTDOWN; diff --git a/lnet/selftest/rpc.c b/lnet/selftest/rpc.c index 5ebd0e5..99e3774 100644 --- a/lnet/selftest/rpc.c +++ b/lnet/selftest/rpc.c @@ -1674,6 +1674,7 @@ srpc_shutdown (void) rc = LNetClearLazyPortal(SRPC_FRAMEWORK_REQUEST_PORTAL); rc = LNetClearLazyPortal(SRPC_REQUEST_PORTAL); LASSERT(rc == 0); + lnet_assert_handler_unused(srpc_data.rpc_lnet_handler); /* fallthrough */ case SRPC_STATE_NI_INIT: diff --git a/lustre/ptlrpc/events.c b/lustre/ptlrpc/events.c index 0578529..52be97b 100644 --- a/lustre/ptlrpc/events.c +++ b/lustre/ptlrpc/events.c @@ -567,6 +567,7 @@ static void ptlrpc_ni_fini(void) percpu_ref_kill(&ptlrpc_pending); wait_for_completion(&ptlrpc_done); + lnet_assert_handler_unused(ptlrpc_handler); LNetNIFini(); } -- 1.8.3.1