From: Kirill A. Shutemov <hidden> Date: 2012-08-09 15:03:20
From: "Kirill A. Shutemov" <redacted>
Clearing a 2MB huge page will typically blow away several levels of CPU
caches. To avoid this only cache clear the 4K area around the fault
address and use a cache avoiding clears for the rest of the 2MB area.
This patchset implements cache avoiding version of clear_page only for
x86. If an architecture wants to provide cache avoiding version of
clear_page it should to define ARCH_HAS_USER_NOCACHE to 1 and implement
clear_page_nocache() and clear_user_highpage_nocache().
v2:
- No code change. Only commit messages are updated.
- RFC mark is dropped.
Andi Kleen (6):
THP: Use real address for NUMA policy
mm: make clear_huge_page tolerate non aligned address
THP: Pass real, not rounded, address to clear_huge_page
x86: Add clear_page_nocache
mm: make clear_huge_page cache clear only around the fault address
x86: switch the 64bit uncached page clear to SSE/AVX v2
arch/x86/include/asm/page.h | 2 +
arch/x86/include/asm/string_32.h | 5 ++
arch/x86/include/asm/string_64.h | 5 ++
arch/x86/lib/Makefile | 1 +
arch/x86/lib/clear_page_nocache_32.S | 30 +++++++++++
arch/x86/lib/clear_page_nocache_64.S | 92 ++++++++++++++++++++++++++++++++++
arch/x86/mm/fault.c | 7 +++
mm/huge_memory.c | 17 +++---
mm/memory.c | 29 ++++++++++-
9 files changed, 178 insertions(+), 10 deletions(-)
create mode 100644 arch/x86/lib/clear_page_nocache_32.S
create mode 100644 arch/x86/lib/clear_page_nocache_64.S
--
1.7.7.6
From: Kirill A. Shutemov <hidden> Date: 2012-08-09 15:03:28
From: Andi Kleen <redacted>
Clearing a 2MB huge page will typically blow away several levels
of CPU caches. To avoid this only cache clear the 4K area
around the fault address and use a cache avoiding clears
for the rest of the 2MB area.
Signed-off-by: Andi Kleen <redacted>
Signed-off-by: Kirill A. Shutemov <redacted>
---
mm/memory.c | 30 +++++++++++++++++++++++++++---
1 files changed, 27 insertions(+), 3 deletions(-)
From: Kirill A. Shutemov <hidden> Date: 2012-08-09 15:03:39
From: Andi Kleen <redacted>
Add a cache avoiding version of clear_page. Straight forward integer variant
of the existing 64bit clear_page, for both 32bit and 64bit.
Also add the necessary glue for highmem including a layer that non cache
coherent architectures that use the virtual address for flushing can
hook in. This is not needed on x86 of course.
If an architecture wants to provide cache avoiding version of clear_page
it should to define ARCH_HAS_USER_NOCACHE to 1 and implement
clear_page_nocache() and clear_user_highpage_nocache().
Signed-off-by: Andi Kleen <redacted>
Signed-off-by: Kirill A. Shutemov <redacted>
---
arch/x86/include/asm/page.h | 2 ++
arch/x86/include/asm/string_32.h | 5 +++++
arch/x86/include/asm/string_64.h | 5 +++++
arch/x86/lib/Makefile | 1 +
arch/x86/lib/clear_page_nocache_32.S | 30 ++++++++++++++++++++++++++++++
arch/x86/lib/clear_page_nocache_64.S | 29 +++++++++++++++++++++++++++++
arch/x86/mm/fault.c | 7 +++++++
7 files changed, 79 insertions(+), 0 deletions(-)
create mode 100644 arch/x86/lib/clear_page_nocache_32.S
create mode 100644 arch/x86/lib/clear_page_nocache_64.S
@@ -3,6 +3,8 @@#ifdef __KERNEL__+#include<linux/linkage.h>+/* Let gcc decide whether to inline or use the out of line functions */#define __HAVE_ARCH_STRCPY
@@ -3,6 +3,8 @@#ifdef __KERNEL__+#include<linux/linkage.h>+/* Written 2002 by Andi Kleen *//* Only used for special circumstances. Stolen from i386/string.h */
From: Kirill A. Shutemov <hidden> Date: 2012-08-09 15:03:43
From: Andi Kleen <redacted>
hugetlb does not necessarily pass in an aligned address, so the
low level address computation is wrong.
This will fix architectures that actually use the address for flushing
the cleared address (very few, like xtensa/sparc/...?)
Signed-off-by: Andi Kleen <redacted>
Signed-off-by: Kirill A. Shutemov <redacted>
---
mm/memory.c | 5 +++--
1 files changed, 3 insertions(+), 2 deletions(-)
From: Kirill A. Shutemov <hidden> Date: 2012-08-09 15:04:05
From: Andi Kleen <redacted>
Use the fault address, not the rounded down hpage address for NUMA
policy purposes. In some circumstances this can give more exact
NUMA policy.
Signed-off-by: Andi Kleen <redacted>
Signed-off-by: Kirill A. Shutemov <redacted>
---
mm/huge_memory.c | 8 ++++----
1 files changed, 4 insertions(+), 4 deletions(-)
From: Kirill A. Shutemov <hidden> Date: 2012-08-09 15:05:01
From: Andi Kleen <redacted>
With multiple threads vector stores are more efficient, so use them.
This will cause the page clear to run non preemptable and add some
overhead. However on 32bit it was already non preempable (due to
kmap_atomic) and there is an preemption opportunity every 4K unit.
On a NPB (Nasa Parallel Benchmark) 128GB run on a Westmere this improves
the performance regression of enabling transparent huge pages
by ~2% (2.81% to 0.81%), near the runtime variability now.
On a system with AVX support more is expected.
Signed-off-by: Andi Kleen <redacted>
[kirill.shutemov@linux.intel.com: Properly save/restore arguments]
Signed-off-by: Kirill A. Shutemov <redacted>
---
arch/x86/lib/clear_page_nocache_64.S | 91 ++++++++++++++++++++++++++++-----
1 files changed, 77 insertions(+), 14 deletions(-)
From: Jan Beulich <hidden> Date: 2012-08-09 15:22:14
quoted
quoted
On 09.08.12 at 17:03, "Kirill A. Shutemov" <kirill.shutemov@linux.intel=
.com> wrote:
From: Andi Kleen <redacted>
=20
Add a cache avoiding version of clear_page. Straight forward integer =
variant
of the existing 64bit clear_page, for both 32bit and 64bit.
While on 64-bit this is fine, I fail to see how you avoid using the
SSE2 instruction on non-SSE2 systems.
Also add the necessary glue for highmem including a layer that non cache
coherent architectures that use the virtual address for flushing can
hook in. This is not needed on x86 of course.
=20
If an architecture wants to provide cache avoiding version of clear_page
it should to define ARCH_HAS_USER_NOCACHE to 1 and implement
clear_page_nocache() and clear_user_highpage_nocache().
=20
Signed-off-by: Andi Kleen <redacted>
Signed-off-by: Kirill A. Shutemov <redacted>
---
arch/x86/include/asm/page.h | 2 ++
arch/x86/include/asm/string_32.h | 5 +++++
arch/x86/include/asm/string_64.h | 5 +++++
arch/x86/lib/Makefile | 1 +
arch/x86/lib/clear_page_nocache_32.S | 30 ++++++++++++++++++++++++++++=
From: "H. Peter Anvin" <hpa@zytor.com> Date: 2012-08-09 15:24:38
On 08/09/2012 08:03 AM, Kirill A. Shutemov wrote:
From: Andi Kleen <redacted>
Add a cache avoiding version of clear_page. Straight forward integer variant
of the existing 64bit clear_page, for both 32bit and 64bit.
Also add the necessary glue for highmem including a layer that non cache
coherent architectures that use the virtual address for flushing can
hook in. This is not needed on x86 of course.
If an architecture wants to provide cache avoiding version of clear_page
it should to define ARCH_HAS_USER_NOCACHE to 1 and implement
clear_page_nocache() and clear_user_highpage_nocache().
Compile failure:
/home/hpa/kernel/tip.x86-mm/arch/x86/mm/fault.c: In function
‘clear_user_highpage_nocache’:
/home/hpa/kernel/tip.x86-mm/arch/x86/mm/fault.c:1215:30: error:
‘KM_USER0’ undeclared (first use in this function)
/home/hpa/kernel/tip.x86-mm/arch/x86/mm/fault.c:1215:30: note: each
undeclared identifier is reported only once for each function it appears in
/home/hpa/kernel/tip.x86-mm/arch/x86/mm/fault.c:1215:2: error: too many
arguments to function ‘kmap_atomic’
In file included from
/home/hpa/kernel/tip.x86-mm/include/linux/pagemap.h:10:0,
from
/home/hpa/kernel/tip.x86-mm/include/linux/mempolicy.h:70,
from
/home/hpa/kernel/tip.x86-mm/include/linux/hugetlb.h:15,
from /home/hpa/kernel/tip.x86-mm/arch/x86/mm/fault.c:14:
/home/hpa/kernel/tip.x86-mm/include/linux/highmem.h:66:21: note:
declared here
make[4]: *** [arch/x86/mm/fault.o] Error 1
make[3]: *** [arch/x86/mm] Error 2
make[2]: *** [arch/x86] Error 2
make[1]: *** [sub-make] Error 2
make[1]: Leaving directory `/home/hpa/kernel/tip.x86-mm'
This happens on *all* my test configurations, including both x86-64 and
i386 allyesconfig. I suspect your patchset base is stale.
-hpa
--
H. Peter Anvin, Intel Open Source Technology Center
I work for Intel. I don't speak on their behalf.
Moving 64 bytes per cycle is faster on Sandy Bridge, but slower on
Westmere. Any preference? ;)
You have to be careful with these benchmarks.
- You need to make sure the data is cache cold, cache hot is misleading.
- The numbers can change if you have multiple CPUs doing this in parallel.
-Andi
This must still be the 32-bit version becaue it segfaults here. Here's
why:
mmap above gives a ptr which, on 64-bit, is larger than 32-bit, i.e. it
looks like 0x7fffxxxxx000, i.e. starting from top of userspace.
Now, the mov above truncates that ptr and the thing segfaults.
Doing s/edx/rdx/g fixes it though.
Thanks.
--
Regards/Gruss,
Boris.