From: Matthew Dillon Date: Tue, 23 Mar 2010 23:27:50 +0000 (-0700) Subject: HAMMER VFS - Fix another low memory deadlock issue X-Git-Tag: v2.7.0~28^2~4 X-Git-Url: https://gitweb.dragonflybsd.org/dragonfly.git/commitdiff_plain/1205225348c6b0af2fa0b8dea95c18d2dca61763 HAMMER VFS - Fix another low memory deadlock issue * Unlock the cursor around calls to vm_wait_nominal() to avoid deadlocking while holding shared node locks. * Add vm_test_nominal() which returns TRUE if vm_wait_nominal() would block. Reported-by: Francois Tigeot --- diff --git a/sys/vfs/hammer/hammer_rebalance.c b/sys/vfs/hammer/hammer_rebalance.c index 5390aa2935..e2326179bb 100644 --- a/sys/vfs/hammer/hammer_rebalance.c +++ b/sys/vfs/hammer/hammer_rebalance.c @@ -119,7 +119,11 @@ retry: * Rebalancing can be hard on the memory allocator, make * sure there is enough free memory before doing it. */ - vm_wait_nominal(); + if (vm_test_nominal()) { + hammer_unlock_cursor(&cursor); + vm_wait_nominal(); + hammer_lock_cursor(&cursor); + } /* * We only care about internal nodes visited for the last diff --git a/sys/vm/vm_extern.h b/sys/vm/vm_extern.h index 49fa4b9eb9..eb5e914264 100644 --- a/sys/vm/vm_extern.h +++ b/sys/vm/vm_extern.h @@ -96,6 +96,7 @@ int vm_fault_wire (vm_map_t, vm_map_entry_t, boolean_t); void vm_fork (struct proc *, struct proc *, int); void vm_fault_ratecheck(void); void vm_waitproc (struct proc *); +int vm_test_nominal (void); void vm_wait_nominal (void); void vm_init_limits(struct proc *); diff --git a/sys/vm/vm_page.c b/sys/vm/vm_page.c index 2a20a2377a..6b57cc3a4f 100644 --- a/sys/vm/vm_page.c +++ b/sys/vm/vm_page.c @@ -845,6 +845,17 @@ vm_wait_nominal(void) vm_wait(0); } +/* + * Test if vm_wait_nominal() would block. + */ +int +vm_test_nominal(void) +{ + if (vm_page_count_min(0)) + return(1); + return(0); +} + /* * Block until free pages are available for allocation, called in various * places before memory allocations.