* Re: [BUG] from x86: Support kmap_local() forced debugging
[not found] ` <20210106180132.41dc249d@gandalf.local.home>
@ 2021-01-07 1:03 ` Linus Torvalds
2021-01-07 1:16 ` Steven Rostedt
` (2 more replies)
0 siblings, 3 replies; 9+ messages in thread
From: Linus Torvalds @ 2021-01-07 1:03 UTC (permalink / raw)
To: Steven Rostedt, Willem de Bruijn, Jakub Kicinski, David Miller,
Jonathan Lemon
Cc: Thomas Gleixner, LKML, the arch/x86 maintainers,
Christoph Hellwig, Matthew Wilcox, Daniel Vetter, Andrew Morton,
Linux-MM, Peter Zijlstra, Ingo Molnar, Juri Lelli,
Vincent Guittot, Dietmar Eggemann, Ben Segall, Mel Gorman,
Daniel Bristot de Oliveira, Netdev
[-- 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;
^ permalink raw reply related [flat|nested] 9+ messages in thread
* Re: [BUG] from x86: Support kmap_local() forced debugging
2021-01-07 1:03 ` [BUG] from x86: Support kmap_local() forced debugging Linus Torvalds
@ 2021-01-07 1:16 ` Steven Rostedt
2021-01-07 1:49 ` Steven Rostedt
2021-01-07 1:49 ` Jakub Kicinski
2 siblings, 0 replies; 9+ messages in thread
From: Steven Rostedt @ 2021-01-07 1:16 UTC (permalink / raw)
To: Linus Torvalds
Cc: Willem de Bruijn, Jakub Kicinski, David Miller, Jonathan Lemon,
Thomas Gleixner, LKML, the arch/x86 maintainers,
Christoph Hellwig, Matthew Wilcox, Daniel Vetter, Andrew Morton,
Linux-MM, Peter Zijlstra, Ingo Molnar, Juri Lelli,
Vincent Guittot, Dietmar Eggemann, Ben Segall, Mel Gorman,
Daniel Bristot de Oliveira, Netdev
On Wed, 6 Jan 2021 17:03:48 -0800
Linus Torvalds <torvalds@linux-foundation.org> wrote:
> (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).
Why?
Because to test x86_32, I have a Fedora Core 13 (yes 13!) partition
(baremetal) that I use. And the .config I use for it hasn't changed
since that time ;-) (except to add new features that I want to test on
x86_32).
Anyway, I'll test out your patch. Thanks for investigating this.
-- Steve
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [BUG] from x86: Support kmap_local() forced debugging
2021-01-07 1:03 ` [BUG] from x86: Support kmap_local() forced debugging Linus Torvalds
2021-01-07 1:16 ` Steven Rostedt
@ 2021-01-07 1:49 ` Steven Rostedt
2021-01-07 1:49 ` Jakub Kicinski
2 siblings, 0 replies; 9+ messages in thread
From: Steven Rostedt @ 2021-01-07 1:49 UTC (permalink / raw)
To: Linus Torvalds
Cc: Willem de Bruijn, Jakub Kicinski, David Miller, Jonathan Lemon,
Thomas Gleixner, LKML, the arch/x86 maintainers,
Christoph Hellwig, Matthew Wilcox, Daniel Vetter, Andrew Morton,
Linux-MM, Peter Zijlstra, Ingo Molnar, Juri Lelli,
Vincent Guittot, Dietmar Eggemann, Ben Segall, Mel Gorman,
Daniel Bristot de Oliveira, Netdev
On Wed, 6 Jan 2021 17:03:48 -0800
Linus Torvalds <torvalds@linux-foundation.org> wrote:
> --- 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;
I applied this and I haven't been able to crash it again.
Thanks,
-- Steve
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [BUG] from x86: Support kmap_local() forced debugging
2021-01-07 1:03 ` [BUG] from x86: Support kmap_local() forced debugging Linus Torvalds
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
2 siblings, 1 reply; 9+ messages in thread
From: Jakub Kicinski @ 2021-01-07 1:49 UTC (permalink / raw)
To: Linus Torvalds
Cc: Steven Rostedt, Willem de Bruijn, David Miller, Jonathan Lemon,
Thomas Gleixner, LKML, the arch/x86 maintainers,
Christoph Hellwig, Matthew Wilcox, Daniel Vetter, Andrew Morton,
Linux-MM, Peter Zijlstra, Ingo Molnar, Juri Lelli,
Vincent Guittot, Dietmar Eggemann, Ben Segall, Mel Gorman,
Daniel Bristot de Oliveira, Netdev
On Wed, 6 Jan 2021 17:03:48 -0800 Linus Torvalds wrote:
> 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.
Thanks for the detailed analysis! skb_gro_reset_offset() checks if
kernel can read data in the fragments directly as an optimization,
in case the entire header is in a fragment.
IIUC DEBUG_KMAP_LOCAL_FORCE_MAP only affects the mappings from
explicit kmap calls, which GRO won't make - it will fall back to
pulling the header out of the fragment and end up in skb_copy_bits(),
i.e. the loop you fixed. So GRO should be good. I think..
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [BUG] from x86: Support kmap_local() forced debugging
2021-01-07 1:49 ` Jakub Kicinski
@ 2021-01-07 2:11 ` Willem de Bruijn
2021-01-07 4:44 ` Willem de Bruijn
0 siblings, 1 reply; 9+ messages in thread
From: Willem de Bruijn @ 2021-01-07 2:11 UTC (permalink / raw)
To: Jakub Kicinski
Cc: Linus Torvalds, Steven Rostedt, David Miller, Jonathan Lemon,
Thomas Gleixner, LKML, the arch/x86 maintainers,
Christoph Hellwig, Matthew Wilcox, Daniel Vetter, Andrew Morton,
Linux-MM, Peter Zijlstra, Ingo Molnar, Juri Lelli,
Vincent Guittot, Dietmar Eggemann, Ben Segall, Mel Gorman,
Daniel Bristot de Oliveira, Netdev
On Wed, Jan 6, 2021 at 8:49 PM Jakub Kicinski <kuba@kernel.org> wrote:
>
> On Wed, 6 Jan 2021 17:03:48 -0800 Linus Torvalds wrote:
> > 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.
>
> Thanks for the detailed analysis! skb_gro_reset_offset() checks if
> kernel can read data in the fragments directly as an optimization,
> in case the entire header is in a fragment.
>
> IIUC DEBUG_KMAP_LOCAL_FORCE_MAP only affects the mappings from
> explicit kmap calls, which GRO won't make - it will fall back to
> pulling the header out of the fragment and end up in skb_copy_bits(),
> i.e. the loop you fixed. So GRO should be good. I think..
Agreed. That code in skb_gro_reset_offset skips the GRO frag0
optimization in various cases, including if the first fragment is in
high mem.
That specific check goes back to the introduction of the frag0
optimization in commit 86911732d399 ("gro: Avoid copying headers of
unmerged packets"), at the time in helper skb_gro_header().
Very glad to hear that the fix addresses the crash in
skb_frag_foreach_page. Thanks!
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [BUG] from x86: Support kmap_local() forced debugging
2021-01-07 2:11 ` Willem de Bruijn
@ 2021-01-07 4:44 ` Willem de Bruijn
2021-01-07 19:47 ` Linus Torvalds
0 siblings, 1 reply; 9+ messages in thread
From: Willem de Bruijn @ 2021-01-07 4:44 UTC (permalink / raw)
To: Jakub Kicinski
Cc: Linus Torvalds, Steven Rostedt, David Miller, Jonathan Lemon,
Thomas Gleixner, LKML, the arch/x86 maintainers,
Christoph Hellwig, Matthew Wilcox, Daniel Vetter, Andrew Morton,
Linux-MM, Peter Zijlstra, Ingo Molnar, Juri Lelli,
Vincent Guittot, Dietmar Eggemann, Ben Segall, Mel Gorman,
Daniel Bristot de Oliveira, Netdev
On Wed, Jan 6, 2021 at 9:11 PM Willem de Bruijn <willemb@google.com> wrote:
>
> On Wed, Jan 6, 2021 at 8:49 PM Jakub Kicinski <kuba@kernel.org> wrote:
> >
> > On Wed, 6 Jan 2021 17:03:48 -0800 Linus Torvalds wrote:
> > > 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.
But there are three other kmap_atomic callers under net/ that do not
loop at all, so assume non-compound pages. In esp_output_head,
esp6_output_head and skb_seq_read. The first two directly use
skb_page_frag_refill, which can allocate compound (but not
__GFP_HIGHMEM) pages, and the third can be inserted with
netfilter xt_string in the path of tcp transmit skbs, which can also
have compound pages. I think that these could similarly access
data beyond the end of the kmap_atomic mapped page. I'll take
a closer look.
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [BUG] from x86: Support kmap_local() forced debugging
2021-01-07 4:44 ` Willem de Bruijn
@ 2021-01-07 19:47 ` Linus Torvalds
2021-01-07 20:52 ` Steven Rostedt
0 siblings, 1 reply; 9+ messages in thread
From: Linus Torvalds @ 2021-01-07 19:47 UTC (permalink / raw)
To: Willem de Bruijn
Cc: Jakub Kicinski, Steven Rostedt, David Miller, Jonathan Lemon,
Thomas Gleixner, LKML, the arch/x86 maintainers,
Christoph Hellwig, Matthew Wilcox, Daniel Vetter, Andrew Morton,
Linux-MM, Peter Zijlstra, Ingo Molnar, Juri Lelli,
Vincent Guittot, Dietmar Eggemann, Ben Segall, Mel Gorman,
Daniel Bristot de Oliveira, Netdev
On Wed, Jan 6, 2021 at 8:45 PM Willem de Bruijn <willemb@google.com> wrote:
>
> But there are three other kmap_atomic callers under net/ that do not
> loop at all, so assume non-compound pages. In esp_output_head,
> esp6_output_head and skb_seq_read. The first two directly use
> skb_page_frag_refill, which can allocate compound (but not
> __GFP_HIGHMEM) pages, and the third can be inserted with
> netfilter xt_string in the path of tcp transmit skbs, which can also
> have compound pages. I think that these could similarly access
> data beyond the end of the kmap_atomic mapped page. I'll take
> a closer look.
Thanks.
Note that I have flushed my random one-liner patch from my system, and
expect to get a proper fix through the normal networking pulls.
And _if_ the networking people feel that my one-liner was the proper
fix, you can use it and add my sign-off if you want to, but it really
was more of a "this is the quick ugly fix for testing" rather than
anything else.
Linus
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [BUG] from x86: Support kmap_local() forced debugging
2021-01-07 19:47 ` Linus Torvalds
@ 2021-01-07 20:52 ` Steven Rostedt
2021-01-07 21:07 ` Willem de Bruijn
0 siblings, 1 reply; 9+ messages in thread
From: Steven Rostedt @ 2021-01-07 20:52 UTC (permalink / raw)
To: Linus Torvalds
Cc: Willem de Bruijn, Jakub Kicinski, David Miller, Jonathan Lemon,
Thomas Gleixner, LKML, the arch/x86 maintainers,
Christoph Hellwig, Matthew Wilcox, Daniel Vetter, Andrew Morton,
Linux-MM, Peter Zijlstra, Ingo Molnar, Juri Lelli,
Vincent Guittot, Dietmar Eggemann, Ben Segall, Mel Gorman,
Daniel Bristot de Oliveira, Netdev
On Thu, 7 Jan 2021 11:47:02 -0800
Linus Torvalds <torvalds@linux-foundation.org> wrote:
> On Wed, Jan 6, 2021 at 8:45 PM Willem de Bruijn <willemb@google.com> wrote:
> >
> > But there are three other kmap_atomic callers under net/ that do not
> > loop at all, so assume non-compound pages. In esp_output_head,
> > esp6_output_head and skb_seq_read. The first two directly use
> > skb_page_frag_refill, which can allocate compound (but not
> > __GFP_HIGHMEM) pages, and the third can be inserted with
> > netfilter xt_string in the path of tcp transmit skbs, which can also
> > have compound pages. I think that these could similarly access
> > data beyond the end of the kmap_atomic mapped page. I'll take
> > a closer look.
>
> Thanks.
>
> Note that I have flushed my random one-liner patch from my system, and
> expect to get a proper fix through the normal networking pulls.
>
> And _if_ the networking people feel that my one-liner was the proper
> fix, you can use it and add my sign-off if you want to, but it really
> was more of a "this is the quick ugly fix for testing" rather than
> anything else.
>
Please add:
Link: https://lore.kernel.org/linux-mm/20210106180132.41dc249d@gandalf.local.home/
Reported-by: Steven Rostedt (VMware) <rostedt@goodmis.org>
And if you take Linus's patch, please add my:
Tested-by: Steven Rostedt (VMware) <rostedt@goodmis.org>
and if you come up with another patch, please send it to me for testing.
Thanks!
-- Steve
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [BUG] from x86: Support kmap_local() forced debugging
2021-01-07 20:52 ` Steven Rostedt
@ 2021-01-07 21:07 ` Willem de Bruijn
0 siblings, 0 replies; 9+ messages in thread
From: Willem de Bruijn @ 2021-01-07 21:07 UTC (permalink / raw)
To: Steven Rostedt
Cc: Linus Torvalds, Jakub Kicinski, David Miller, Jonathan Lemon,
Thomas Gleixner, LKML, the arch/x86 maintainers,
Christoph Hellwig, Matthew Wilcox, Daniel Vetter, Andrew Morton,
Linux-MM, Peter Zijlstra, Ingo Molnar, Juri Lelli,
Vincent Guittot, Dietmar Eggemann, Ben Segall, Mel Gorman,
Daniel Bristot de Oliveira, Netdev
On Thu, Jan 7, 2021 at 3:53 PM Steven Rostedt <rostedt@goodmis.org> wrote:
>
> On Thu, 7 Jan 2021 11:47:02 -0800
> Linus Torvalds <torvalds@linux-foundation.org> wrote:
>
> > On Wed, Jan 6, 2021 at 8:45 PM Willem de Bruijn <willemb@google.com> wrote:
> > >
> > > But there are three other kmap_atomic callers under net/ that do not
> > > loop at all, so assume non-compound pages. In esp_output_head,
> > > esp6_output_head and skb_seq_read. The first two directly use
> > > skb_page_frag_refill, which can allocate compound (but not
> > > __GFP_HIGHMEM) pages, and the third can be inserted with
> > > netfilter xt_string in the path of tcp transmit skbs, which can also
> > > have compound pages. I think that these could similarly access
> > > data beyond the end of the kmap_atomic mapped page. I'll take
> > > a closer look.
> >
> > Thanks.
> >
> > Note that I have flushed my random one-liner patch from my system, and
> > expect to get a proper fix through the normal networking pulls.
> >
> > And _if_ the networking people feel that my one-liner was the proper
> > fix, you can use it and add my sign-off if you want to, but it really
> > was more of a "this is the quick ugly fix for testing" rather than
> > anything else.
I do think it is the proper fix as is. If no one else has comments, I
can submit it through the net tree.
It won't address the other issues that became apparent only as a
result of this. I'm preparing separate patches for those.
> Please add:
>
> Link: https://lore.kernel.org/linux-mm/20210106180132.41dc249d@gandalf.local.home/
> Reported-by: Steven Rostedt (VMware) <rostedt@goodmis.org>
>
> And if you take Linus's patch, please add my:
>
> Tested-by: Steven Rostedt (VMware) <rostedt@goodmis.org>
>
> and if you come up with another patch, please send it to me for testing.
>
> Thanks!
Will do, thanks.
^ permalink raw reply [flat|nested] 9+ messages in thread
end of thread, other threads:[~2021-01-07 21:09 UTC | newest]
Thread overview: 9+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
[not found] <20201118194838.753436396@linutronix.de>
[not found] ` <20201118204007.169209557@linutronix.de>
[not found] ` <20210106180132.41dc249d@gandalf.local.home>
2021-01-07 1:03 ` [BUG] from x86: Support kmap_local() forced debugging Linus Torvalds
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
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox