sparc64: Fix tsb_grow() in atomic context.
authorDavid S. Miller <davem@davemloft.net>
Wed, 20 Feb 2013 06:34:10 +0000 (22:34 -0800)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 27 Feb 2013 17:21:12 +0000 (09:21 -0800)
commitd13cdf91b4ccc961b496a72d80b549dc158f970e
treec87d305ecd2248ea304e196291d83773ea8dcc1d
parentf39d6de4af78fb70abbf7f43a2ecbff2a1e8d795
sparc64: Fix tsb_grow() in atomic context.

[ Upstream commit 0fbebed682ff2788dee58e8d7f7dda46e33aa10b ]

If our first THP installation for an MM is via the set_pmd_at() done
during khugepaged's collapsing we'll end up in tsb_grow() trying to do
a GFP_KERNEL allocation with several locks held.

Simply using GFP_ATOMIC in this situation is not the best option
because we really can't have this fail, so we'd really like to keep
this an order 0 GFP_KERNEL allocation if possible.

Also, doing the TSB allocation from khugepaged is a really bad idea
because we'll allocate it potentially from the wrong NUMA node in that
context.

So what we do is defer the hugepage TSB allocation until the first TLB
miss we take on a hugepage.  This is slightly tricky because we have
to handle two unusual cases:

1) Taking the first hugepage TLB miss in the window trap handler.
   We'll call the winfix_trampoline when that is detected.

2) An initial TSB allocation via TLB miss races with a hugetlb
   fault on another cpu running the same MM.  We handle this by
   unconditionally loading the TSB we see into the current cpu
   even if it's non-NULL at hugetlb_setup time.

Reported-by: Meelis Roos <mroos@ut.ee>
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
arch/sparc/include/asm/hugetlb.h
arch/sparc/include/asm/page_64.h
arch/sparc/kernel/tsb.S
arch/sparc/mm/fault_64.c
arch/sparc/mm/init_64.c
arch/sparc/mm/tlb.c