]> git.baikalelectronics.ru Git - kernel.git/commit
dax: fix deadlock with DAX 4k holes
authorRoss Zwisler <ross.zwisler@linux.intel.com>
Wed, 11 Jan 2017 00:57:15 +0000 (16:57 -0800)
committerLinus Torvalds <torvalds@linux-foundation.org>
Wed, 11 Jan 2017 02:31:54 +0000 (18:31 -0800)
commitf7a277cc799841d24e90b65ceb018f85eb6c45fa
treef5ab79fb6a830d035842e08c34512608607ad5b5
parent819e601333255d371010cf5c7d885521828fde3c
dax: fix deadlock with DAX 4k holes

Currently in DAX if we have three read faults on the same hole address we
can end up with the following:

Thread 0 Thread 1 Thread 2
-------- -------- --------
dax_iomap_fault
 grab_mapping_entry
  lock_slot
   <locks empty DAX entry>

   dax_iomap_fault
 grab_mapping_entry
  get_unlocked_mapping_entry
   <sleeps on empty DAX entry>

dax_iomap_fault
 grab_mapping_entry
  get_unlocked_mapping_entry
   <sleeps on empty DAX entry>
  dax_load_hole
   find_or_create_page
   ...
    page_cache_tree_insert
     dax_wake_mapping_entry_waiter
      <wakes one sleeper>
     __radix_tree_replace
      <swaps empty DAX entry with 4k zero page>

<wakes>
get_page
lock_page
...
put_locked_mapping_entry
unlock_page
put_page

<sleeps forever on the DAX
 wait queue>

The crux of the problem is that once we insert a 4k zero page, all
locking from then on is done in terms of that 4k zero page and any
additional threads sleeping on the empty DAX entry will never be woken.

Fix this by waking all sleepers when we replace the DAX radix tree entry
with a 4k zero page.  This will allow all sleeping threads to
successfully transition from locking based on the DAX empty entry to
locking on the 4k zero page.

With the test case reported by Xiong this happens very regularly in my
test setup, with some runs resulting in 9+ threads in this deadlocked
state.  With this fix I've been able to run that same test dozens of
times in a loop without issue.

Fixes: b0c9423ba5e1 ("dax: New fault locking")
Link: http://lkml.kernel.org/r/1483479365-13607-1-git-send-email-ross.zwisler@linux.intel.com
Signed-off-by: Ross Zwisler <ross.zwisler@linux.intel.com>
Reported-by: Xiong Zhou <xzhou@redhat.com>
Reviewed-by: Jan Kara <jack@suse.cz>
Cc: <stable@vger.kernel.org> [4.7+]
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
mm/filemap.c