diff options
author | Paul Dagnelie <paul.dagnelie@delphix.com> | 2015-01-19 09:58:35 -0800 |
---|---|---|
committer | Christopher Siden <chris@delphix.com> | 2015-01-19 09:58:35 -0800 |
commit | 096e63b2c66f47e2a2d213edc199cdb082d8b2d6 (patch) | |
tree | 9823222fa51b33d82805e861a3e962f3f5443088 | |
parent | 18059eae28246ed2eef942a16364131202558094 (diff) | |
download | illumos-joyent-096e63b2c66f47e2a2d213edc199cdb082d8b2d6.tar.gz |
4872 system crash after nlm_gc hits bogus mutex
Reviewed by: Adam Leventhal <ahl@delphix.com>
Reviewed by: Christopher Siden <christopher.siden@delphix.com>
Reviewed by: Eric Schrock <eric.schrock@delphix.com>
Reviewed by: Jeremy Jones <jeremy@delphix.com>
Approved by: Garrett D'Amore <garrett@damore.org>
-rw-r--r-- | usr/src/uts/common/klm/nlm_impl.c | 25 |
1 files changed, 13 insertions, 12 deletions
diff --git a/usr/src/uts/common/klm/nlm_impl.c b/usr/src/uts/common/klm/nlm_impl.c index 7daa30dcb3..a10ba86a6e 100644 --- a/usr/src/uts/common/klm/nlm_impl.c +++ b/usr/src/uts/common/klm/nlm_impl.c @@ -398,23 +398,23 @@ nlm_gc(struct nlm_globals *g) mutex_enter(&g->lock); /* - * While we were doing expensive operations outside of - * nlm_globals critical section, somebody could - * take the host, add lock/share to one of its vnodes - * and release the host back. If so, host's idle timeout - * is renewed and our information about locks on the - * given host is outdated. + * While we were doing expensive operations + * outside of nlm_globals critical section, + * somebody could take the host and remove it + * from the idle list. Whether its been + * reinserted or not, our information about + * the host is outdated, and we should take no + * further action. */ - if (hostp->nh_idle_timeout > now) + if (hostp->nh_idle_timeout > now || hostp->nh_refs > 0) continue; /* - * If either host has locks or somebody has began to - * use it while we were outside the nlm_globals critical - * section. In both cases we have to renew host's - * timeout and put it to the end of LRU list. + * If the host has locks we have to renew the + * host's timeout and put it at the end of LRU + * list. */ - if (has_locks || hostp->nh_refs > 0) { + if (has_locks) { TAILQ_REMOVE(&g->nlm_idle_hosts, hostp, nh_link); hostp->nh_idle_timeout = now + idle_period; @@ -1139,6 +1139,7 @@ static void nlm_host_unregister(struct nlm_globals *g, struct nlm_host *hostp) { ASSERT(hostp->nh_refs == 0); + ASSERT(hostp->nh_flags & NLM_NH_INIDLE); avl_remove(&g->nlm_hosts_tree, hostp); VERIFY(mod_hash_remove(g->nlm_hosts_hash, |