path: root/mm/swap_cgroup.c
diff options
authorRoss Zwisler <>2017-04-07 16:04:57 -0700
committerLinus Torvalds <>2017-04-08 00:47:49 -0700
commite11f8b7b6c4ea13bf8af6b8f42b45e15b554a92b (patch)
treea19bf4df6a3475546fe5cf81c9ebe89e49ddf17d /mm/swap_cgroup.c
parent4fad7fb6b0279a85e16e6a63e0f1f7d98cedddf1 (diff)
dax: fix radix tree insertion race
While running generic/340 in my test setup I hit the following race. It can happen with kernels that support FS DAX PMDs, so v4.10 thru v4.11-rc5. Thread 1 Thread 2 -------- -------- dax_iomap_pmd_fault() grab_mapping_entry() spin_lock_irq() get_unlocked_mapping_entry() 'entry' is NULL, can't call lock_slot() spin_unlock_irq() radix_tree_preload() dax_iomap_pmd_fault() grab_mapping_entry() spin_lock_irq() get_unlocked_mapping_entry() ... lock_slot() spin_unlock_irq() dax_pmd_insert_mapping() <inserts a PMD mapping> spin_lock_irq() __radix_tree_insert() fails with -EEXIST <fall back to 4k fault, and die horribly when inserting a 4k entry where a PMD exists> The issue is that we have to drop mapping->tree_lock while calling radix_tree_preload(), but since we didn't have a radix tree entry to lock (unlike in the pmd_downgrade case) we have no protection against Thread 2 coming along and inserting a PMD at the same index. For 4k entries we handled this with a special-case response to -EEXIST coming from the __radix_tree_insert(), but this doesn't save us for PMDs because the -EEXIST case can also mean that we collided with a 4k entry in the radix tree at a different index, but one that is covered by our PMD range. So, correctly handle both the 4k and 2M collision cases by explicitly re-checking the radix tree for an entry at our index once we reacquire mapping->tree_lock. This patch has made it through a clean xfstests run with the current v4.11-rc5 based linux/master, and it also ran generic/340 500 times in a loop. It used to fail within the first 10 iterations. Link: Signed-off-by: Ross Zwisler <> Cc: "Darrick J. Wong" <> Cc: Alexander Viro <> Cc: Christoph Hellwig <> Cc: Dan Williams <> Cc: Jan Kara <> Cc: Matthew Wilcox <> Cc: <> [4.10+] Signed-off-by: Andrew Morton <> Signed-off-by: Linus Torvalds <>
Diffstat (limited to 'mm/swap_cgroup.c')
0 files changed, 0 insertions, 0 deletions