aboutsummaryrefslogtreecommitdiffstats
path: root/mm/page_alloc.c
diff options
context:
space:
mode:
authorOmar Sandoval <osandov@fb.com>2018-06-07 20:07:02 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2018-06-07 20:34:35 -0400
commit93781325da6e07af57a21f111d1f2b9f128fa397 (patch)
tree35542710adcf686003dadb55d3e6ae20036a3d36 /mm/page_alloc.c
parent89fdcd262fd40712da65e922558872a12b203332 (diff)
lockdep: fix fs_reclaim annotation
While revisiting my Btrfs swapfile series [1], I introduced a situation in which reclaim would lock i_rwsem, and even though the swapon() path clearly made GFP_KERNEL allocations while holding i_rwsem, I got no complaints from lockdep. It turns out that the rework of the fs_reclaim annotation was broken: if the current task has PF_MEMALLOC set, we don't acquire the dummy fs_reclaim lock, but when reclaiming we always check this _after_ we've just set the PF_MEMALLOC flag. In most cases, we can fix this by moving the fs_reclaim_{acquire,release}() outside of the memalloc_noreclaim_{save,restore}(), althought kswapd is slightly different. After applying this, I got the expected lockdep splats. 1: https://lwn.net/Articles/625412/ Link: http://lkml.kernel.org/r/9f8aa70652a98e98d7c4de0fc96a4addcee13efe.1523778026.git.osandov@fb.com Fixes: d92a8cfcb37e ("locking/lockdep: Rework FS_RECLAIM annotation") Signed-off-by: Omar Sandoval <osandov@fb.com> Reviewed-by: Andrew Morton <akpm@linux-foundation.org> Cc: Peter Zijlstra <peterz@infradead.org> Cc: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp> Cc: Ingo Molnar <mingo@kernel.org> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'mm/page_alloc.c')
-rw-r--r--mm/page_alloc.c20
1 files changed, 15 insertions, 5 deletions
diff --git a/mm/page_alloc.c b/mm/page_alloc.c
index 4fbe211340e0..b93cc79a8db4 100644
--- a/mm/page_alloc.c
+++ b/mm/page_alloc.c
@@ -3701,7 +3701,7 @@ should_compact_retry(struct alloc_context *ac, unsigned int order, int alloc_fla
3701#endif /* CONFIG_COMPACTION */ 3701#endif /* CONFIG_COMPACTION */
3702 3702
3703#ifdef CONFIG_LOCKDEP 3703#ifdef CONFIG_LOCKDEP
3704struct lockdep_map __fs_reclaim_map = 3704static struct lockdep_map __fs_reclaim_map =
3705 STATIC_LOCKDEP_MAP_INIT("fs_reclaim", &__fs_reclaim_map); 3705 STATIC_LOCKDEP_MAP_INIT("fs_reclaim", &__fs_reclaim_map);
3706 3706
3707static bool __need_fs_reclaim(gfp_t gfp_mask) 3707static bool __need_fs_reclaim(gfp_t gfp_mask)
@@ -3726,17 +3726,27 @@ static bool __need_fs_reclaim(gfp_t gfp_mask)
3726 return true; 3726 return true;
3727} 3727}
3728 3728
3729void __fs_reclaim_acquire(void)
3730{
3731 lock_map_acquire(&__fs_reclaim_map);
3732}
3733
3734void __fs_reclaim_release(void)
3735{
3736 lock_map_release(&__fs_reclaim_map);
3737}
3738
3729void fs_reclaim_acquire(gfp_t gfp_mask) 3739void fs_reclaim_acquire(gfp_t gfp_mask)
3730{ 3740{
3731 if (__need_fs_reclaim(gfp_mask)) 3741 if (__need_fs_reclaim(gfp_mask))
3732 lock_map_acquire(&__fs_reclaim_map); 3742 __fs_reclaim_acquire();
3733} 3743}
3734EXPORT_SYMBOL_GPL(fs_reclaim_acquire); 3744EXPORT_SYMBOL_GPL(fs_reclaim_acquire);
3735 3745
3736void fs_reclaim_release(gfp_t gfp_mask) 3746void fs_reclaim_release(gfp_t gfp_mask)
3737{ 3747{
3738 if (__need_fs_reclaim(gfp_mask)) 3748 if (__need_fs_reclaim(gfp_mask))
3739 lock_map_release(&__fs_reclaim_map); 3749 __fs_reclaim_release();
3740} 3750}
3741EXPORT_SYMBOL_GPL(fs_reclaim_release); 3751EXPORT_SYMBOL_GPL(fs_reclaim_release);
3742#endif 3752#endif
@@ -3754,8 +3764,8 @@ __perform_reclaim(gfp_t gfp_mask, unsigned int order,
3754 3764
3755 /* We now go into synchronous reclaim */ 3765 /* We now go into synchronous reclaim */
3756 cpuset_memory_pressure_bump(); 3766 cpuset_memory_pressure_bump();
3757 noreclaim_flag = memalloc_noreclaim_save();
3758 fs_reclaim_acquire(gfp_mask); 3767 fs_reclaim_acquire(gfp_mask);
3768 noreclaim_flag = memalloc_noreclaim_save();
3759 reclaim_state.reclaimed_slab = 0; 3769 reclaim_state.reclaimed_slab = 0;
3760 current->reclaim_state = &reclaim_state; 3770 current->reclaim_state = &reclaim_state;
3761 3771
@@ -3763,8 +3773,8 @@ __perform_reclaim(gfp_t gfp_mask, unsigned int order,
3763 ac->nodemask); 3773 ac->nodemask);
3764 3774
3765 current->reclaim_state = NULL; 3775 current->reclaim_state = NULL;
3766 fs_reclaim_release(gfp_mask);
3767 memalloc_noreclaim_restore(noreclaim_flag); 3776 memalloc_noreclaim_restore(noreclaim_flag);
3777 fs_reclaim_release(gfp_mask);
3768 3778
3769 cond_resched(); 3779 cond_resched();
3770 3780