• Matthew Wilcox's avatar
    mm: tighten up the fault path a little · 9ab2594f
    Matthew Wilcox authored
    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.orgSigned-off-by: default avatarMatthew Wilcox <mawilcox@microsoft.com>
    Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
    Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
    9ab2594f
filemap.c 80 KB