linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Linus Torvalds <torvalds@linux-foundation.org>
To: Steven Rostedt <rostedt@goodmis.org>,
	Willem de Bruijn <willemb@google.com>,
	Jakub Kicinski <kuba@kernel.org>,
	David Miller <davem@davemloft.net>,
	Jonathan Lemon <jonathan.lemon@gmail.com>
Cc: Thomas Gleixner <tglx@linutronix.de>,
	LKML <linux-kernel@vger.kernel.org>,
	"the arch/x86 maintainers" <x86@kernel.org>,
	Christoph Hellwig <hch@lst.de>,
	Matthew Wilcox <willy@infradead.org>,
	Daniel Vetter <daniel@ffwll.ch>,
	Andrew Morton <akpm@linux-foundation.org>,
	Linux-MM <linux-mm@kvack.org>,
	Peter Zijlstra <peterz@infradead.org>,
	Ingo Molnar <mingo@kernel.org>,
	Juri Lelli <juri.lelli@redhat.com>,
	Vincent Guittot <vincent.guittot@linaro.org>,
	Dietmar Eggemann <dietmar.eggemann@arm.com>,
	Ben Segall <bsegall@google.com>, Mel Gorman <mgorman@suse.de>,
	Daniel Bristot de Oliveira <bristot@redhat.com>,
	Netdev <netdev@vger.kernel.org>
Subject: Re: [BUG] from x86: Support kmap_local() forced debugging
Date: Wed, 6 Jan 2021 17:03:48 -0800	[thread overview]
Message-ID: <CAHk-=wh2895wXEXYtb70CTgW+UR7jfh6VFhJB_bOrF0L7UKoEg@mail.gmail.com> (raw)
In-Reply-To: <20210106180132.41dc249d@gandalf.local.home>

[-- Attachment #1: Type: text/plain, Size: 4491 bytes --]

On Wed, Jan 6, 2021 at 3:01 PM Steven Rostedt <rostedt@goodmis.org> wrote:
>
> I triggered the following crash on x86_32 by simply doing a:
>
> (ssh'ing into the box)
>
>   # head -100 /tmp/output-file
>
> Where the /tmp/output-file was the output of a trace-cmd report.
> Even after rebooting and not running the tracing code, simply doing the
> head command still crashed.

The code decodes to

   0:   3b 5d e8                cmp    -0x18(%ebp),%ebx
   3:   0f 47 5d e8             cmova  -0x18(%ebp),%ebx
   7:   c7 45 e0 00 00 00 00    movl   $0x0,-0x20(%ebp)
   e:   8b 7d e0                mov    -0x20(%ebp),%edi
  11:   39 7d e8                cmp    %edi,-0x18(%ebp)
  14:   76 3a                   jbe    0x50
  16:   8b 45 d4                mov    -0x2c(%ebp),%eax
  19:   e8 a4 e4 ff ff          call   0xffffe4c2
  1e:   8b 55 e4                mov    -0x1c(%ebp),%edx
  21:   03 55 e0                add    -0x20(%ebp),%edx
  24:   89 d9                   mov    %ebx,%ecx
  26:   01 c6                   add    %eax,%esi
  28:   89 d7                   mov    %edx,%edi
  2a:*  f3 a4                   rep movsb %ds:(%esi),%es:(%edi)
 <-- trapping instruction
  2c:   e8 c9 e4 ff ff          call   0xffffe4fa
  31:   01 5d e0                add    %ebx,-0x20(%ebp)
  34:   8b 5d e8                mov    -0x18(%ebp),%ebx
  37:   b8 00 10 00 00          mov    $0x1000,%eax
  3c:   2b 5d e0                sub    -0x20(%ebp),%ebx

and while it would be good to see the output of
scripts/decode_stacktrace.sh, I strongly suspect that the above is

                                vaddr = kmap_atomic(p);
                                memcpy(to + copied, vaddr + p_off, p_len);
                                kunmap_atomic(vaddr);

(although I wonder how/why the heck you've enabled
CC_OPTIMIZE_FOR_SIZE=y, which is what causes "memcpy()" to be done as
that "rep movsb". I thought we disabled it because it's so bad on most
cpus).

So that first "call" instruction is the kmap_atomic(), the "rep movs"
is the memcpy(), and the "call" instruction immediately after is the
kunmap_atomic().

Anyway, you can see vaddr in register state:

        EAX: fff57000

so we've kmapped that one page at fff57000, but we're accessing past
it into the next page:

> BUG: unable to handle page fault for address: fff58000

with the current source address being (ESI: fff58000) and we still
have 248 bytes to go (ECX: 000000f8) even though we've already
overflowed into the next page.

You can see the original count still (EBX: 000005a8), so it really
looks like that skb_frag_foreach_page() logic

                        skb_frag_foreach_page(f,
                                              skb_frag_off(f) + offset - start,
                                              copy, p, p_off, p_len, copied) {
                                vaddr = kmap_atomic(p);
                                memcpy(to + copied, vaddr + p_off, p_len);
                                kunmap_atomic(vaddr);
                        }

must be wrong, and doesn't handle the "each page" part properly. It
must have started in the middle of the page, and p_len (that 0x5a8)
was wrong.

IOW, it really looks like p_off + p_len had the value 0x10f8, which is
larger than one page. And looking at the code, in
skb_frag_foreach_page(), I see:

             p_off = (f_off) & (PAGE_SIZE - 1),                         \
             p_len = skb_frag_must_loop(p) ?                            \
             min_t(u32, f_len, PAGE_SIZE - p_off) : f_len,              \

where that "min_t(u32, f_len, PAGE_SIZE - p_off)" looks correct, but
then presumably skb_frag_must_loop() must be wrong.

Oh, and when I look at that, I see

    static inline bool skb_frag_must_loop(struct page *p)
    {
    #if defined(CONFIG_HIGHMEM)
            if (PageHighMem(p))
                    return true;
    #endif
            return false;
    }

and that is no longer true. With the kmap debugging, even non-highmem
pages need that "do one page at a time" code, because even non-highmem
pages get remapped by kmap().

IOW, I think the patch to fix this might be something like the attached.

I wonder whether there is other code that "knows" about kmap() only
affecting PageHighmem() pages thing that is no longer true.

Looking at some other code, skb_gro_reset_offset() looks suspiciously
like it also thinks highmem pages are special.

Adding the networking people involved in this area to the cc too.

               Linus

[-- Attachment #2: patch --]
[-- Type: application/octet-stream, Size: 544 bytes --]

 include/linux/skbuff.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h
index 333bcdc39635..c858adfb5a82 100644
--- a/include/linux/skbuff.h
+++ b/include/linux/skbuff.h
@@ -366,7 +366,7 @@ static inline void skb_frag_size_sub(skb_frag_t *frag, int delta)
 static inline bool skb_frag_must_loop(struct page *p)
 {
 #if defined(CONFIG_HIGHMEM)
-	if (PageHighMem(p))
+	if (IS_ENABLED(CONFIG_DEBUG_KMAP_LOCAL_FORCE_MAP) || PageHighMem(p))
 		return true;
 #endif
 	return false;

  reply	other threads:[~2021-01-07  1:06 UTC|newest]

Thread overview: 48+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-11-18 19:48 [patch V4 0/8] mm/highmem: Preemptible variant of kmap_atomic & friends Thomas Gleixner
2020-11-18 19:48 ` [patch V4 1/8] mm/highmem: Provide and use CONFIG_DEBUG_KMAP_LOCAL Thomas Gleixner
2020-11-24 14:20   ` [tip: core/mm] " tip-bot2 for Thomas Gleixner
2020-11-18 19:48 ` [patch V4 2/8] mm/highmem: Provide CONFIG_DEBUG_KMAP_LOCAL_FORCE_MAP Thomas Gleixner
2020-11-18 21:13   ` Linus Torvalds
2020-11-19  8:46     ` Mel Gorman
2020-11-19 17:19       ` Linus Torvalds
2020-11-24 14:20   ` [tip: core/mm] " tip-bot2 for Thomas Gleixner
2020-11-18 19:48 ` [patch V4 3/8] x86: Support kmap_local() forced debugging Thomas Gleixner
2020-11-24 14:20   ` [tip: core/mm] " tip-bot2 for Thomas Gleixner
2021-01-06 23:01   ` [BUG] from " Steven Rostedt
2021-01-07  1:03     ` Linus Torvalds [this message]
2021-01-07  1:16       ` Steven Rostedt
2021-01-07  1:49       ` Steven Rostedt
2021-01-07  1:49       ` Jakub Kicinski
2021-01-07  2:11         ` Willem de Bruijn
2021-01-07  4:44           ` Willem de Bruijn
2021-01-07 19:47             ` Linus Torvalds
2021-01-07 20:52               ` Steven Rostedt
2021-01-07 21:07                 ` Willem de Bruijn
2020-11-18 19:48 ` [patch V4 4/8] sched: Make migrate_disable/enable() independent of RT Thomas Gleixner
2020-11-19  9:38   ` Mel Gorman
2020-11-19 11:14     ` Peter Zijlstra
2020-11-19 12:14       ` Mel Gorman
2020-11-19 14:17         ` Steven Rostedt
2020-11-19 17:23       ` Linus Torvalds
2020-11-19 18:28         ` Peter Zijlstra
2020-11-20  1:33           ` Thomas Gleixner
2020-11-20  9:29             ` Peter Zijlstra
2020-11-22 23:16               ` Andy Lutomirski
2020-11-23 21:15                 ` Thomas Gleixner
2020-11-23 21:25                   ` Thomas Gleixner
2020-11-23 22:07                     ` Andy Lutomirski
2020-11-23 23:10                       ` Thomas Gleixner
2020-11-24 10:29   ` [tip: sched/core] " tip-bot2 for Thomas Gleixner
2020-11-18 19:48 ` [patch V4 5/8] sched: highmem: Store local kmaps in task struct Thomas Gleixner
2020-11-19 11:33   ` Peter Zijlstra
2020-11-19 11:51   ` Peter Zijlstra
2020-11-19 12:12     ` Peter Zijlstra
2020-11-19 14:11       ` Thomas Gleixner
2020-11-24 14:20   ` [tip: core/mm] " tip-bot2 for Thomas Gleixner
2020-11-18 19:48 ` [patch V4 6/8] mm/highmem: Provide kmap_local* Thomas Gleixner
2020-11-24 14:20   ` [tip: core/mm] " tip-bot2 for Thomas Gleixner
2020-11-18 19:48 ` [patch V4 7/8] io-mapping: Provide iomap_local variant Thomas Gleixner
2020-11-24 14:20   ` [tip: core/mm] " tip-bot2 for Thomas Gleixner
2020-11-18 19:48 ` [patch V4 8/8] x86/crashdump/32: Simplify copy_oldmem_page() Thomas Gleixner
2020-11-24 14:20   ` [tip: core/mm] " tip-bot2 for Thomas Gleixner
2020-11-24  8:03 ` [patch V4 0/8] mm/highmem: Preemptible variant of kmap_atomic & friends Peter Zijlstra

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='CAHk-=wh2895wXEXYtb70CTgW+UR7jfh6VFhJB_bOrF0L7UKoEg@mail.gmail.com' \
    --to=torvalds@linux-foundation.org \
    --cc=akpm@linux-foundation.org \
    --cc=bristot@redhat.com \
    --cc=bsegall@google.com \
    --cc=daniel@ffwll.ch \
    --cc=davem@davemloft.net \
    --cc=dietmar.eggemann@arm.com \
    --cc=hch@lst.de \
    --cc=jonathan.lemon@gmail.com \
    --cc=juri.lelli@redhat.com \
    --cc=kuba@kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-mm@kvack.org \
    --cc=mgorman@suse.de \
    --cc=mingo@kernel.org \
    --cc=netdev@vger.kernel.org \
    --cc=peterz@infradead.org \
    --cc=rostedt@goodmis.org \
    --cc=tglx@linutronix.de \
    --cc=vincent.guittot@linaro.org \
    --cc=willemb@google.com \
    --cc=willy@infradead.org \
    --cc=x86@kernel.org \
    /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).