zfsonlinux/zfs — pull request #726 by ryao (2012-05-07 20:54:22+00:00)
Title: Fix deadlocks in DMU

DMU operations perform allocations using KM_SLEEP, which is mapped to GFP_KERNEL in the SPL. GFP_KERNEL permits paging to occur in low memory situations. When swap operations are done in zvols, memory allocations in the DMU will often trigger additional swap operations, which deadlocks.

I observed a nonsensical behavior where swap worked with the loop device, but not zvols. Commit zfsonlinux/zfs@e3822ceb31dc0b5bdecd5a1b355c14860a3bca9e appears to have disabled the direct reclaim path on the filesystem operations that the loop device exercises, which explains the cause of that behavior. This lead me to replace all instances of KM_SLEEP with KM_PUSHPAGE in files containing functions listed in the backtrace in the commit message. That enabled swap on zvols to work. I tested swap on a zvol with KM_SLEEP redefined to be GFP_NOIO in the SPL code, but swap operations failed to function. As such, it seems that the use of KM_PUSHPAGE is necessary to address this issue.

In theory, this change should also prevent the original deadlock, but I have not yet tested it to verify that this prevents it. I have also not verified that all allocations that swap can trigger have been converted to KM_PUSHPAGE.

I am opening this pull request so that others can provide their thoughts while I continue to work on this. This will close #342 when it is merged.