The global list has a marker with an invariant that free vnodes are placed somewhere past that. A caller which performs filtering (like ZFS) can move said marker all the way to the end, across free vnodes which don't match. Then a caller which does not perform filtering will fail to find them. This makes vn_alloc_hard sleep for 1 second instead of reclaiming, resulting in significant stalls.
Fix the problem by requiring an explicit marker by callers which do filtering.
As a temporary measure extend vnlru_free to restart if it fails to reclaim anything.