From: Michal Hocko <mhocko@suse.com>
To: Tetsuo Handa <penguin-kernel@i-love.sakura.ne.jp>
Cc: Johannes Weiner <hannes@cmpxchg.org>,
Andrew Morton <akpm@linux-foundation.org>,
linux-mm <linux-mm@kvack.org>
Subject: Re: [PATCH v2] mm: memcontrol: fix potential oom_lock recursion deadlock
Date: Fri, 22 Jul 2022 09:19:25 +0200 [thread overview]
Message-ID: <YtpPfXRPA/XDdPOe@dhcp22.suse.cz> (raw)
In-Reply-To: <834b896d-68fb-caeb-4316-2e0a2190e3eb@I-love.SAKURA.ne.jp>
On Fri 22-07-22 09:46:27, Tetsuo Handa wrote:
> syzbot is reporting GFP_KERNEL allocation with oom_lock held [1]. We
> must make sure that such allocation won't hit __alloc_pages_may_oom()
> path which will retry forever if oom_lock is already held. Use static
> buffer when oom_lock is already held.
The changelog is rather cryptic. Your previous one was more readable.
I would go with:
"
syzbot is reporting GFP_KERNEL allocation with oom_lock held [1]
when reporting memcg oom. This is problematic because this creates a
dependency between GFP_NOFS and GFP_KERNEL over oom_lock which could
dead lock the system.
Fix the problem by removing the allocation from memory_stat_format
completely. Use a statically preallocated buffer instead for this path.
OOM dumping is synchronized by the oom_lock so there is no exclusion
required here. memory_stat_show can use GFP_KERNEL allocation.
"
> Link: https://syzkaller.appspot.com/bug?extid=2d2aeadc6ce1e1f11d45 [1]
> Reported-by: syzbot <syzbot+2d2aeadc6ce1e1f11d45@syzkaller.appspotmail.com>
> Suggested-by: Michal Hocko <mhocko@suse.com>
> Fixes: c8713d0b23123759 ("mm: memcontrol: dump memory.stat during cgroup OOM")
> Signed-off-by: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
Acked-by: Michal Hocko <mhocko@suse.com>
Thanks!
> ---
> Changes in v2:
> Use static buffer for OOM reporting, suggested by Michal Hocko <mhocko@suse.com>.
>
> mm/memcontrol.c | 22 +++++++++-------------
> 1 file changed, 9 insertions(+), 13 deletions(-)
>
> diff --git a/mm/memcontrol.c b/mm/memcontrol.c
> index 618c366a2f07..8092be2fbb7c 100644
> --- a/mm/memcontrol.c
> +++ b/mm/memcontrol.c
> @@ -1460,14 +1460,12 @@ static inline unsigned long memcg_page_state_output(struct mem_cgroup *memcg,
> return memcg_page_state(memcg, item) * memcg_page_state_unit(item);
> }
>
> -static char *memory_stat_format(struct mem_cgroup *memcg)
> +static void memory_stat_format(struct mem_cgroup *memcg, char *buf, int bufsize)
> {
> struct seq_buf s;
> int i;
>
> - seq_buf_init(&s, kmalloc(PAGE_SIZE, GFP_KERNEL), PAGE_SIZE);
> - if (!s.buffer)
> - return NULL;
> + seq_buf_init(&s, buf, bufsize);
>
> /*
> * Provide statistics on the state of the memory subsystem as
> @@ -1533,8 +1531,6 @@ static char *memory_stat_format(struct mem_cgroup *memcg)
>
> /* The above should easily fit into one page */
> WARN_ON_ONCE(seq_buf_has_overflowed(&s));
> -
> - return s.buffer;
> }
>
> #define K(x) ((x) << (PAGE_SHIFT-10))
> @@ -1570,7 +1566,10 @@ void mem_cgroup_print_oom_context(struct mem_cgroup *memcg, struct task_struct *
> */
> void mem_cgroup_print_oom_meminfo(struct mem_cgroup *memcg)
> {
> - char *buf;
> + /* Use static buffer, for the caller is holding oom_lock. */
> + static char buf[PAGE_SIZE];
> +
> + lockdep_assert_held(&oom_lock);
>
> pr_info("memory: usage %llukB, limit %llukB, failcnt %lu\n",
> K((u64)page_counter_read(&memcg->memory)),
> @@ -1591,11 +1590,8 @@ void mem_cgroup_print_oom_meminfo(struct mem_cgroup *memcg)
> pr_info("Memory cgroup stats for ");
> pr_cont_cgroup_path(memcg->css.cgroup);
> pr_cont(":");
> - buf = memory_stat_format(memcg);
> - if (!buf)
> - return;
> + memory_stat_format(memcg, buf, sizeof(buf));
> pr_info("%s", buf);
> - kfree(buf);
> }
>
> /*
> @@ -6335,11 +6331,11 @@ static int memory_events_local_show(struct seq_file *m, void *v)
> static int memory_stat_show(struct seq_file *m, void *v)
> {
> struct mem_cgroup *memcg = mem_cgroup_from_seq(m);
> - char *buf;
> + char *buf = kmalloc(PAGE_SIZE, GFP_KERNEL);
>
> - buf = memory_stat_format(memcg);
> if (!buf)
> return -ENOMEM;
> + memory_stat_format(memcg, buf, PAGE_SIZE);
> seq_puts(m, buf);
> kfree(buf);
> return 0;
> --
> 2.18.4
>
--
Michal Hocko
SUSE Labs
next prev parent reply other threads:[~2022-07-22 7:19 UTC|newest]
Thread overview: 12+ messages / expand[flat|nested] mbox.gz Atom feed top
2022-07-14 12:08 [syzbot] possible deadlock in start_this_handle (3) syzbot
2022-07-14 14:18 ` Jan Kara
2022-07-14 22:24 ` Tetsuo Handa
2022-07-15 1:39 ` Shakeel Butt
2022-07-15 1:53 ` Tetsuo Handa
2022-07-20 23:49 ` [PATCH] mm: memcontrol: fix potential oom_lock recursion deadlock Tetsuo Handa
2022-07-21 8:01 ` Michal Hocko
2022-07-22 0:46 ` [PATCH v2] " Tetsuo Handa
2022-07-22 7:19 ` Michal Hocko [this message]
2022-07-22 10:45 ` [PATCH v3] " Tetsuo Handa
2022-07-22 11:04 ` Michal Hocko
2022-07-22 11:12 ` Tetsuo Handa
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=YtpPfXRPA/XDdPOe@dhcp22.suse.cz \
--to=mhocko@suse.com \
--cc=akpm@linux-foundation.org \
--cc=hannes@cmpxchg.org \
--cc=linux-mm@kvack.org \
--cc=penguin-kernel@i-love.sakura.ne.jp \
/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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.