Details
-
Bug
-
Resolution: Fixed
-
Major
-
Lustre 2.13.0, Lustre 2.12.1, Lustre 2.12.3
-
None
-
3
-
9223372036854775807
Description
I reproduced this issue with master and Cray's 2.12 branch. For completeness I'll note that my master was slightly modified so that I can configure LNet on Cray's hardware, and I also applied the fix from LU-11756.
Here's the relevant git log. Commit '8cb7ccf54e' is on master.
86ef522cac LU-11756 o2iblnd: kib_conn leak 888adb9340 MRP-342 lnet: add config file support d661c584c6 Revert "LU-11838 lnet: change lnet_ipaddr_enumerate() to use for_each_netdev()" 4c681cf4ee Revert "LU-11838 o2iblnd: get IP address more directly." f4fe014620 Revert "LU-6399 lnet: socket cleanup" 8cb7ccf54e LU-11986 lnet: properly cleanup lnet debugfs files
LNetNIFini() takes the ln_api_mutex and then shuts down LNet. It doesn't release the mutex until all teardown functions have returned.
The message receive path also takes the ln_api_mutex in lnet_nid2peerni_locked().
kgnilnd_check_fma_rx->lnet_parse->lnet_nid2peerni_locked
kiblnd_handle_rx->lnet_parse->lnet_nid2peerni_locked
ksocknal_process_receive->lnet_parse->lnet_nid2peerni_locked
/* * Get a peer_ni for the given nid, create it if necessary. Takes a * hold on the peer_ni. */ struct lnet_peer_ni * lnet_nid2peerni_locked(lnet_nid_t nid, lnet_nid_t pref, int cpt) { struct lnet_peer_ni *lpni = NULL; int rc; if (the_lnet.ln_state != LNET_STATE_RUNNING) return ERR_PTR(-ESHUTDOWN); /* * find if a peer_ni already exists. * If so then just return that. */ lpni = lnet_find_peer_ni_locked(nid); if (lpni) return lpni; /* * Slow path: * use the lnet_api_mutex to serialize the creation of the peer_ni * and the creation/deletion of the local ni/net. When a local ni is * created, if there exists a set of peer_nis on that network, * they need to be traversed and updated. When a local NI is * deleted, which could result in a network being deleted, then * all peer nis on that network need to be removed as well. * * Creation through traffic should also be serialized with * creation through DLC. */ lnet_net_unlock(cpt); mutex_lock(&the_lnet.ln_api_mutex);
int LNetNIFini() { mutex_lock(&the_lnet.ln_api_mutex); LASSERT(the_lnet.ln_refcount > 0); if (the_lnet.ln_refcount != 1) { the_lnet.ln_refcount--; } else { LASSERT(!the_lnet.ln_niinit_self); lnet_fault_fini(); lnet_router_debugfs_init(); lnet_peer_discovery_stop(); lnet_push_target_fini(); lnet_monitor_thr_stop(); lnet_ping_target_fini(); /* Teardown fns that use my own API functions BEFORE here */ the_lnet.ln_refcount = 0; lnet_acceptor_stop(); lnet_destroy_routes(); lnet_shutdown_lndnets(); <<< the_lnet.ln_state = LNET_STATE_STOPPING; happens here lnet_unprepare(); } mutex_unlock(&the_lnet.ln_api_mutex); return 0; } EXPORT_SYMBOL(LNetNIFini);
We can see there is a decent sized window where the deadlock can be hit.
It is easy to reproduce for me.
[root@snx11922n000 ~]# pdsh -g lustre modprobe lnet; lctl net up ; lctl list_nids ; lctl ping 10.12.0.50@o2ib40 ; lctl net down ; lustre_rmmod
Sometimes the command needs to be repeated a couple of times.
I believe this regression was introduced by:
commit fa8b4e6357c53ea457ef6624b0b19bece0b0fdde Author: Amir Shehata <amir.shehata@intel.com> Date: Thu May 26 15:42:39 2016 -0700 LU-7734 lnet: peer/peer_ni handling adjustments
Attachments
Issue Links
- is related to
-
LU-13807 LNet: Net delete dead lock deadlock
-
- Open
-