Race between nlm_do_free_all() and nlm_suspend_zone() might lead to corruption
Both nlm_do_free_all() and nlm_suspend_zone() functions are adding hosts from nlm_hosts_tree into a private host list (named either host_list or all_hosts respectively). In both private host lists the nh_link member is used as a linking field. This could lead to a race when both functions might want one single host in their own private list, but that's obviously not possible and might cause corruption.
Updated by Gordon Ross almost 5 years ago
The function nlm_suspend_zone is also much more complex than it needs to be.
I really don't like what it's doing mucking with all the ref. counts and the private list.
A simpler way nlm_suspend_zone could prevent the GC thread from removing hosts would be to just stop the GC thread during suspend.
During resume, while the GC thread is still stopped, walk the hosts AVL and give every host a "new lease on life" by setting the expiration time to some point in the not too near future, then finally resume the GC thread.
Also, the nlm_nsm_stat calls in nlm_resume_zone would be much better handled in the (user-level) statd program, if these calls need to happen at all. It's a poor design to do these calls in nlm_resume_zone.