diff options
author | Matthew Wilcox <mawilcox@microsoft.com> | 2017-05-03 14:53:29 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2017-05-03 15:52:09 -0700 |
commit | 9ab2594febb468964a4c00f8023ec22073ca8716 (patch) | |
tree | cc9ab63967d6a6d339ea3359c5161df252fc5ccc /mm/rodata_test.c | |
parent | eb52da3f48f5b1ddceb7e8d4725b6c88204aa2c4 (diff) | |
download | linux-stable-9ab2594febb468964a4c00f8023ec22073ca8716.tar.gz linux-stable-9ab2594febb468964a4c00f8023ec22073ca8716.tar.bz2 linux-stable-9ab2594febb468964a4c00f8023ec22073ca8716.zip |
mm: tighten up the fault path a little
The round_up() macro generates a couple of unnecessary instructions
in this usage:
48cd: 49 8b 47 50 mov 0x50(%r15),%rax
48d1: 48 83 e8 01 sub $0x1,%rax
48d5: 48 0d ff 0f 00 00 or $0xfff,%rax
48db: 48 83 c0 01 add $0x1,%rax
48df: 48 c1 f8 0c sar $0xc,%rax
48e3: 48 39 c3 cmp %rax,%rbx
48e6: 72 2e jb 4916 <filemap_fault+0x96>
If we change round_up() to ((x) + __round_mask(x, y)) & ~__round_mask(x, y)
then GCC can see through it and remove the mask (because that would be
dead code given the subsequent shift):
48cd: 49 8b 47 50 mov 0x50(%r15),%rax
48d1: 48 05 ff 0f 00 00 add $0xfff,%rax
48d7: 48 c1 e8 0c shr $0xc,%rax
48db: 48 39 c3 cmp %rax,%rbx
48de: 72 2e jb 490e <filemap_fault+0x8e>
But that's problematic because we'd evaluate 'y' twice. Converting
round_up into an inline function prevents it from being used in other
definitions. The easiest thing to do is just change these three usages
of round_up to use DIV_ROUND_UP. Also add an unlikely() because GCC's
heuristic is wrong in this case.
Link: http://lkml.kernel.org/r/20170207192812.5281-1-willy@infradead.org
Signed-off-by: Matthew Wilcox <mawilcox@microsoft.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'mm/rodata_test.c')
0 files changed, 0 insertions, 0 deletions