From f1a2e6107c124d010d89973cfd716fbd17b689f0 Mon Sep 17 00:00:00 2001 From: Amir Shehata Date: Wed, 17 Dec 2014 09:35:15 -0800 Subject: [PATCH] LU-6010 lnet: prevent assert on LNet module unload There is a use case where lnet can be unloaded while there are no NIs configured. Removing lnet in this case will cause LNetFini() to be called without a prior call to LNetNIFini(). This will cause the LASSERT(the_lnet.ln_refcount == 0) to be triggered. To deal with this use case when LNet is configured a reference count on the module is taken using try_module_get(). This way LNet must be unconfigured before it could be removed; therefore avoiding the above case. When LNet is unconfigured module_put() is called to return the reference count. Signed-off-by: Amir Shehata Change-Id: I0f283eeb395fa9a076a4d65ab3edd5e7807fc169 Reviewed-on: http://review.whamcloud.com/13110 Tested-by: Jenkins Reviewed-by: James Simmons Reviewed-by: Doug Oucharek Tested-by: Maloo Reviewed-by: Oleg Drokin --- lnet/lnet/module.c | 32 +++++++++++++++++++++----------- 1 file changed, 21 insertions(+), 11 deletions(-) diff --git a/lnet/lnet/module.c b/lnet/lnet/module.c index 197ff25..a8f39b3 100644 --- a/lnet/lnet/module.c +++ b/lnet/lnet/module.c @@ -53,13 +53,21 @@ lnet_configure(void *arg) LNET_MUTEX_LOCK(&lnet_config_mutex); if (!the_lnet.ln_niinit_self) { + rc = try_module_get(THIS_MODULE); + + if (rc != 1) + goto out; + rc = LNetNIInit(LNET_PID_LUSTRE); if (rc >= 0) { the_lnet.ln_niinit_self = 1; rc = 0; + } else { + module_put(THIS_MODULE); } } +out: LNET_MUTEX_UNLOCK(&lnet_config_mutex); return rc; } @@ -67,21 +75,23 @@ lnet_configure(void *arg) static int lnet_unconfigure (void) { - int refcount; + int refcount; + + LNET_MUTEX_LOCK(&lnet_config_mutex); - LNET_MUTEX_LOCK(&lnet_config_mutex); + if (the_lnet.ln_niinit_self) { + the_lnet.ln_niinit_self = 0; + LNetNIFini(); + module_put(THIS_MODULE); + } - if (the_lnet.ln_niinit_self) { - the_lnet.ln_niinit_self = 0; - LNetNIFini(); - } + LNET_MUTEX_LOCK(&the_lnet.ln_api_mutex); + refcount = the_lnet.ln_refcount; + LNET_MUTEX_UNLOCK(&the_lnet.ln_api_mutex); - LNET_MUTEX_LOCK(&the_lnet.ln_api_mutex); - refcount = the_lnet.ln_refcount; - LNET_MUTEX_UNLOCK(&the_lnet.ln_api_mutex); + LNET_MUTEX_UNLOCK(&lnet_config_mutex); - LNET_MUTEX_UNLOCK(&lnet_config_mutex); - return (refcount == 0) ? 0 : -EBUSY; + return (refcount == 0) ? 0 : -EBUSY; } static int -- 1.8.3.1