aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/locking/lockdep.c
diff options
context:
space:
mode:
authorMichal Hocko <mhocko@suse.com>2017-05-03 17:53:15 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2017-05-03 18:52:09 -0400
commit7dea19f9ee636cb244109a4dba426bbb3e5304b7 (patch)
treea6d5b2c3bc43f57a81d349c78c0114b28a1b63b2 /kernel/locking/lockdep.c
parent9070733b4efac4bf17f299a81b01c15e206f9ff5 (diff)
mm: introduce memalloc_nofs_{save,restore} API
GFP_NOFS context is used for the following 5 reasons currently: - to prevent from deadlocks when the lock held by the allocation context would be needed during the memory reclaim - to prevent from stack overflows during the reclaim because the allocation is performed from a deep context already - to prevent lockups when the allocation context depends on other reclaimers to make a forward progress indirectly - just in case because this would be safe from the fs POV - silence lockdep false positives Unfortunately overuse of this allocation context brings some problems to the MM. Memory reclaim is much weaker (especially during heavy FS metadata workloads), OOM killer cannot be invoked because the MM layer doesn't have enough information about how much memory is freeable by the FS layer. In many cases it is far from clear why the weaker context is even used and so it might be used unnecessarily. We would like to get rid of those as much as possible. One way to do that is to use the flag in scopes rather than isolated cases. Such a scope is declared when really necessary, tracked per task and all the allocation requests from within the context will simply inherit the GFP_NOFS semantic. Not only this is easier to understand and maintain because there are much less problematic contexts than specific allocation requests, this also helps code paths where FS layer interacts with other layers (e.g. crypto, security modules, MM etc...) and there is no easy way to convey the allocation context between the layers. Introduce memalloc_nofs_{save,restore} API to control the scope of GFP_NOFS allocation context. This is basically copying memalloc_noio_{save,restore} API we have for other restricted allocation context GFP_NOIO. The PF_MEMALLOC_NOFS flag already exists and it is just an alias for PF_FSTRANS which has been xfs specific until recently. There are no more PF_FSTRANS users anymore so let's just drop it. PF_MEMALLOC_NOFS is now checked in the MM layer and drops __GFP_FS implicitly same as PF_MEMALLOC_NOIO drops __GFP_IO. memalloc_noio_flags is renamed to current_gfp_context because it now cares about both PF_MEMALLOC_NOFS and PF_MEMALLOC_NOIO contexts. Xfs code paths preserve their semantic. kmem_flags_convert() doesn't need to evaluate the flag anymore. This patch shouldn't introduce any functional changes. Let's hope that filesystems will drop direct GFP_NOFS (resp. ~__GFP_FS) usage as much as possible and only use a properly documented memalloc_nofs_{save,restore} checkpoints where they are appropriate. [akpm@linux-foundation.org: fix comment typo, reflow comment] Link: http://lkml.kernel.org/r/20170306131408.9828-5-mhocko@kernel.org Signed-off-by: Michal Hocko <mhocko@suse.com> Acked-by: Vlastimil Babka <vbabka@suse.cz> Cc: Dave Chinner <david@fromorbit.com> Cc: Theodore Ts'o <tytso@mit.edu> Cc: Chris Mason <clm@fb.com> Cc: David Sterba <dsterba@suse.cz> Cc: Jan Kara <jack@suse.cz> Cc: Brian Foster <bfoster@redhat.com> Cc: Darrick J. Wong <darrick.wong@oracle.com> Cc: Nikolay Borisov <nborisov@suse.com> Cc: Peter Zijlstra <peterz@infradead.org> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'kernel/locking/lockdep.c')
-rw-r--r--kernel/locking/lockdep.c6
1 files changed, 3 insertions, 3 deletions
diff --git a/kernel/locking/lockdep.c b/kernel/locking/lockdep.c
index f84294c9a018..fd440b5a3c75 100644
--- a/kernel/locking/lockdep.c
+++ b/kernel/locking/lockdep.c
@@ -2877,7 +2877,7 @@ static void __lockdep_trace_alloc(gfp_t gfp_mask, unsigned long flags)
2877 if (unlikely(!debug_locks)) 2877 if (unlikely(!debug_locks))
2878 return; 2878 return;
2879 2879
2880 gfp_mask = memalloc_noio_flags(gfp_mask); 2880 gfp_mask = current_gfp_context(gfp_mask);
2881 2881
2882 /* no reclaim without waiting on it */ 2882 /* no reclaim without waiting on it */
2883 if (!(gfp_mask & __GFP_DIRECT_RECLAIM)) 2883 if (!(gfp_mask & __GFP_DIRECT_RECLAIM))
@@ -2888,7 +2888,7 @@ static void __lockdep_trace_alloc(gfp_t gfp_mask, unsigned long flags)
2888 return; 2888 return;
2889 2889
2890 /* We're only interested __GFP_FS allocations for now */ 2890 /* We're only interested __GFP_FS allocations for now */
2891 if (!(gfp_mask & __GFP_FS)) 2891 if (!(gfp_mask & __GFP_FS) || (curr->flags & PF_MEMALLOC_NOFS))
2892 return; 2892 return;
2893 2893
2894 /* 2894 /*
@@ -3954,7 +3954,7 @@ EXPORT_SYMBOL_GPL(lock_unpin_lock);
3954 3954
3955void lockdep_set_current_reclaim_state(gfp_t gfp_mask) 3955void lockdep_set_current_reclaim_state(gfp_t gfp_mask)
3956{ 3956{
3957 current->lockdep_reclaim_gfp = memalloc_noio_flags(gfp_mask); 3957 current->lockdep_reclaim_gfp = current_gfp_context(gfp_mask);
3958} 3958}
3959 3959
3960void lockdep_clear_current_reclaim_state(void) 3960void lockdep_clear_current_reclaim_state(void)