From: Michal Hocko <mhocko@kernel.org>
To: <linux-mm@kvack.org>, <linux-fsdevel@vger.kernel.org>
Cc: Andrew Morton <akpm@linux-foundation.org>,
Dave Chinner <david@fromorbit.com>,
djwong@kernel.org, "Theodore Ts'o" <tytso@mit.edu>,
Chris Mason <clm@fb.com>, David Sterba <dsterba@suse.cz>,
Jan Kara <jack@suse.cz>,
ceph-devel@vger.kernel.org, cluster-devel@redhat.com,
linux-nfs@vger.kernel.org, logfs@logfs.org,
linux-xfs@vger.kernel.org, linux-ext4@vger.kernel.org,
linux-btrfs@vger.kernel.org, linux-mtd@lists.infradead.org,
reiserfs-devel@vger.kernel.org,
linux-ntfs-dev@lists.sourceforge.net,
linux-f2fs-devel@lists.sourceforge.net,
linux-afs@lists.infradead.org,
LKML <linux-kernel@vger.kernel.org>,
Michal Hocko <mhocko@suse.com>
Subject: [DEBUG PATCH 1/2] mm, debug: report when GFP_NO{FS,IO} is used explicitly from memalloc_no{fs,io}_{save,restore} context
Date: Fri, 6 Jan 2017 15:18:44 +0100 [thread overview]
Message-ID: <20170106141845.24362-2-mhocko@kernel.org> (raw)
In-Reply-To: <20170106141845.24362-1-mhocko@kernel.org>
From: Michal Hocko <mhocko@suse.com>
THIS PATCH IS FOR TESTING ONLY AND NOT MEANT TO HIT LINUS TREE
It is desirable to reduce the direct GFP_NO{FS,IO} usage at minimum and
prefer scope usage defined by memalloc_no{fs,io}_{save,restore} API.
Let's help this process and add a debugging tool to catch when an
explicit allocation request for GFP_NO{FS,IO} is done from the scope
context. The printed stacktrace should help to identify the caller
and evaluate whether it can be changed to use a wider context or whether
it is called from another potentially dangerous context which needs
a scope protection as well.
The checks have to be enabled explicitly by debug_scope_gfp kernel
command line parameter.
Signed-off-by: Michal Hocko <mhocko@suse.com>
---
include/linux/sched.h | 14 +++++++++++--
include/linux/slab.h | 3 +++
mm/page_alloc.c | 58 +++++++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 73 insertions(+), 2 deletions(-)
diff --git a/include/linux/sched.h b/include/linux/sched.h
index 2032fc642a26..59428926e989 100644
--- a/include/linux/sched.h
+++ b/include/linux/sched.h
@@ -1988,6 +1988,8 @@ struct task_struct {
/* A live task holds one reference. */
atomic_t stack_refcount;
#endif
+ unsigned long nofs_caller;
+ unsigned long noio_caller;
/* CPU-specific state of this task */
struct thread_struct thread;
/*
@@ -2345,6 +2347,8 @@ extern void thread_group_cputime_adjusted(struct task_struct *p, cputime_t *ut,
#define tsk_used_math(p) ((p)->flags & PF_USED_MATH)
#define used_math() tsk_used_math(current)
+extern void debug_scope_gfp_context(gfp_t gfp_mask);
+
/*
* Applies per-task gfp context to the given allocation flags.
* PF_MEMALLOC_NOIO implies GFP_NOIO
@@ -2363,25 +2367,31 @@ static inline gfp_t current_gfp_context(gfp_t flags)
return flags;
}
-static inline unsigned int memalloc_noio_save(void)
+static inline unsigned int __memalloc_noio_save(unsigned long caller)
{
unsigned int flags = current->flags & PF_MEMALLOC_NOIO;
current->flags |= PF_MEMALLOC_NOIO;
+ current->noio_caller = caller;
return flags;
}
+#define memalloc_noio_save() __memalloc_noio_save(_RET_IP_)
+
static inline void memalloc_noio_restore(unsigned int flags)
{
current->flags = (current->flags & ~PF_MEMALLOC_NOIO) | flags;
}
-static inline unsigned int memalloc_nofs_save(void)
+static inline unsigned int __memalloc_nofs_save(unsigned long caller)
{
unsigned int flags = current->flags & PF_MEMALLOC_NOFS;
current->flags |= PF_MEMALLOC_NOFS;
+ current->nofs_caller = caller;
return flags;
}
+#define memalloc_nofs_save() __memalloc_nofs_save(_RET_IP_)
+
static inline void memalloc_nofs_restore(unsigned int flags)
{
current->flags = (current->flags & ~PF_MEMALLOC_NOFS) | flags;
diff --git a/include/linux/slab.h b/include/linux/slab.h
index 084b12bad198..6559668e29db 100644
--- a/include/linux/slab.h
+++ b/include/linux/slab.h
@@ -477,6 +477,7 @@ static __always_inline void *kmalloc_large(size_t size, gfp_t flags)
*/
static __always_inline void *kmalloc(size_t size, gfp_t flags)
{
+ debug_scope_gfp_context(flags);
if (__builtin_constant_p(size)) {
if (size > KMALLOC_MAX_CACHE_SIZE)
return kmalloc_large(size, flags);
@@ -517,6 +518,7 @@ static __always_inline int kmalloc_size(int n)
static __always_inline void *kmalloc_node(size_t size, gfp_t flags, int node)
{
+ debug_scope_gfp_context(flags);
#ifndef CONFIG_SLOB
if (__builtin_constant_p(size) &&
size <= KMALLOC_MAX_CACHE_SIZE && !(flags & GFP_DMA)) {
@@ -575,6 +577,7 @@ int memcg_update_all_caches(int num_memcgs);
*/
static inline void *kmalloc_array(size_t n, size_t size, gfp_t flags)
{
+ debug_scope_gfp_context(flags);
if (size != 0 && n > SIZE_MAX / size)
return NULL;
if (__builtin_constant_p(n) && __builtin_constant_p(size))
diff --git a/mm/page_alloc.c b/mm/page_alloc.c
index 5138b46a4295..87a2bb5262b2 100644
--- a/mm/page_alloc.c
+++ b/mm/page_alloc.c
@@ -3738,6 +3738,63 @@ __alloc_pages_slowpath(gfp_t gfp_mask, unsigned int order,
return page;
}
+static bool debug_scope_gfp;
+
+static int __init enable_debug_scope_gfp(char *unused)
+{
+ debug_scope_gfp = true;
+ return 0;
+}
+
+/*
+ * spit the stack trace if the given gfp_mask clears flags which are context
+ * wide cleared. Such a caller can remove special flags clearing and rely on
+ * the context wide mask.
+ */
+void debug_scope_gfp_context(gfp_t gfp_mask)
+{
+ gfp_t restrict_mask;
+
+ if (likely(!debug_scope_gfp))
+ return;
+
+ /* both NOFS, NOIO are irrelevant when direct reclaim is disabled */
+ if (!(gfp_mask & __GFP_DIRECT_RECLAIM))
+ return;
+
+ if (current->flags & PF_MEMALLOC_NOIO)
+ restrict_mask = __GFP_IO;
+ else if ((current->flags & PF_MEMALLOC_NOFS) && (gfp_mask & __GFP_IO))
+ restrict_mask = __GFP_FS;
+ else
+ return;
+
+ if ((gfp_mask & restrict_mask) != restrict_mask) {
+ /*
+ * If you see this this warning then the code does:
+ * memalloc_no{fs,io}_save()
+ * ...
+ * foo()
+ * alloc_page(GFP_NO{FS,IO})
+ * ...
+ * memalloc_no{fs,io}_restore()
+ *
+ * allocation which is unnecessary because the scope gfp
+ * context will do that for all allocation requests already.
+ * If foo() is called from multiple contexts then make sure other
+ * contexts are safe wrt. GFP_NO{FS,IO} semantic and either add
+ * scope protection into particular paths or change the gfp mask
+ * to GFP_KERNEL.
+ */
+ pr_info("Unnecesarily specific gfp mask:%#x(%pGg) for the %s task wide context from %ps\n", gfp_mask, &gfp_mask,
+ (current->flags & PF_MEMALLOC_NOIO)?"NOIO":"NOFS",
+ (void*)((current->flags & PF_MEMALLOC_NOIO)?current->noio_caller:current->nofs_caller));
+ dump_stack();
+ }
+}
+EXPORT_SYMBOL(debug_scope_gfp_context);
+early_param("debug_scope_gfp", enable_debug_scope_gfp);
+
/*
* This is the 'heart' of the zoned buddy allocator.
*/
@@ -3802,6 +3859,7 @@ __alloc_pages_nodemask(gfp_t gfp_mask, unsigned int order,
}
/* First allocation attempt */
+ debug_scope_gfp_context(gfp_mask);
page = get_page_from_freelist(alloc_mask, order, alloc_flags, &ac);
if (likely(page))
goto out;
--
2.11.0
next prev parent reply other threads:[~2017-01-06 14:19 UTC|newest]
Thread overview: 47+ messages / expand[flat|nested] mbox.gz Atom feed top
2017-01-06 14:10 [PATCH 0/8 v3] scope GFP_NOFS api Michal Hocko
2017-01-06 14:11 ` [PATCH 1/8] lockdep: allow to disable reclaim lockup detection Michal Hocko
2017-01-09 12:56 ` Vlastimil Babka
2017-01-06 14:11 ` [PATCH 2/8] xfs: abstract PF_FSTRANS to PF_MEMALLOC_NOFS Michal Hocko
2017-01-09 12:59 ` Vlastimil Babka
2017-01-09 14:29 ` Michal Hocko
2017-01-09 20:58 ` Darrick J. Wong
2017-01-06 14:11 ` [PATCH 3/8] mm: introduce memalloc_nofs_{save,restore} API Michal Hocko
2017-01-09 13:04 ` Vlastimil Babka
2017-01-09 13:42 ` Michal Hocko
2017-01-09 13:59 ` Michal Hocko
2017-01-09 14:04 ` Vlastimil Babka
2017-01-06 14:11 ` [PATCH 4/8] xfs: use memalloc_nofs_{save,restore} instead of memalloc_noio* Michal Hocko
2017-01-09 14:08 ` Vlastimil Babka
2017-01-09 14:25 ` Michal Hocko
2017-01-09 15:56 ` Brian Foster
2017-01-09 20:59 ` Darrick J. Wong
2017-01-06 14:11 ` [PATCH 5/8] jbd2: mark the transaction context with the scope GFP_NOFS context Michal Hocko
2017-01-06 14:11 ` [PATCH 6/8] jbd2: make the whole kjournald2 kthread NOFS safe Michal Hocko
2017-01-06 14:11 ` [PATCH 7/8] Revert "ext4: avoid deadlocks in the writeback path by using sb_getblk_gfp" Michal Hocko
2017-01-17 3:01 ` Theodore Ts'o
2017-01-17 7:54 ` Michal Hocko
2017-03-06 11:59 ` Michal Hocko
2017-01-06 14:11 ` [PATCH 8/8] Revert "ext4: fix wrong gfp type under transaction" Michal Hocko
2017-01-17 2:56 ` Theodore Ts'o
2017-01-17 8:24 ` Michal Hocko
2017-01-17 15:18 ` Michal Hocko
2017-01-17 15:59 ` Theodore Ts'o
2017-01-17 16:16 ` Michal Hocko
2017-01-17 17:29 ` Jan Kara
2017-01-19 8:39 ` Michal Hocko
2017-01-19 9:22 ` Jan Kara
2017-01-19 9:44 ` Michal Hocko
2017-01-26 7:44 ` Michal Hocko
2017-01-27 6:13 ` Theodore Ts'o
2017-01-27 9:37 ` Michal Hocko
2017-01-27 16:40 ` Theodore Ts'o
2017-01-28 7:32 ` [Cluster-devel] " Christoph Hellwig
2017-01-28 8:17 ` David Lang
2017-01-30 8:12 ` Michal Hocko
2017-02-03 15:32 ` Michal Hocko
2017-01-17 21:04 ` Andreas Dilger
2017-01-18 8:29 ` Michal Hocko
2017-01-06 14:18 ` [DEBUG PATCH 0/2] debug explicit GFP_NO{FS,IO} usage from the scope context Michal Hocko
2017-01-06 14:18 ` Michal Hocko [this message]
2017-01-06 14:18 ` [DEBUG PATCH 2/2] silent warnings which we cannot do anything about Michal Hocko
-- strict thread matches above, loose matches on Subject: below --
2016-12-15 14:07 [PATCH 0/9 v2] scope GFP_NOFS api Michal Hocko
2016-12-16 12:46 ` [DEBUG PATCH 0/2] debug explicit GFP_NO{FS,IO} usage from the scope context Michal Hocko
2016-12-16 12:46 ` [DEBUG PATCH 1/2] mm, debug: report when GFP_NO{FS,IO} is used explicitly from memalloc_no{fs,io}_{save,restore} context Michal Hocko
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20170106141845.24362-2-mhocko@kernel.org \
--to=mhocko@kernel.org \
--cc=akpm@linux-foundation.org \
--cc=ceph-devel@vger.kernel.org \
--cc=clm@fb.com \
--cc=cluster-devel@redhat.com \
--cc=david@fromorbit.com \
--cc=djwong@kernel.org \
--cc=dsterba@suse.cz \
--cc=jack@suse.cz \
--cc=linux-afs@lists.infradead.org \
--cc=linux-btrfs@vger.kernel.org \
--cc=linux-ext4@vger.kernel.org \
--cc=linux-f2fs-devel@lists.sourceforge.net \
--cc=linux-fsdevel@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-mm@kvack.org \
--cc=linux-mtd@lists.infradead.org \
--cc=linux-nfs@vger.kernel.org \
--cc=linux-ntfs-dev@lists.sourceforge.net \
--cc=linux-xfs@vger.kernel.org \
--cc=logfs@logfs.org \
--cc=mhocko@suse.com \
--cc=reiserfs-devel@vger.kernel.org \
--cc=tytso@mit.edu \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).