[lkml]   [2008]   [Nov]   [14]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
Messages in this thread
    Patch in this message
    I'm wondering whether we need this patch: though perhaps it doesn't
    matter, since OPTIMIZE_INLINING is already under kernel hacking and
    defaulted off and there expressly for gathering feedback...

    --- 2.6.28-rc4/arch/x86/Kconfig.debug 2008-10-24 09:27:47.000000000 +0100
    +++ linux/arch/x86/Kconfig.debug 2008-11-14 16:26:15.000000000 +0000
    @@ -302,6 +302,7 @@ config CPA_DEBUG

    bool "Allow gcc to uninline functions marked 'inline'"
    + depends on !CC_OPTIMIZE_FOR_SIZE
    This option determines if the kernel forces gcc to inline the functions
    developers have marked 'inline'. Doing so takes away freedom from gcc to
    I've been building with CC_OPTIMIZE_FOR_SIZE=y and OPTIMIZE_INLINING=y
    for a while, but I've now taken OPTIMIZE_INLINING off, after noticing
    the 83 " Page" and 202 constant_test_bit functions in my
    it appears that the functions in include/linux/page-flags.h (perhaps
    others I've not noticed) make OPTIMIZE_INLINING behave very stupidly
    when CC_OPTIMIZE_FOR_SIZE is on (and somewhat even when off).

    Those constant_test_bit()s show up noticeably in the profile of my
    swapping load on an oldish P4 Xeon 2*HT: the average system time for an
    iteration is 63.3 seconds when running a kernel built with both options
    on, but 49.2 seconds when kernel is built with only CC_OPTIMIZE_FOR_SIZE.
    Not put much effort into timing my newer machines: I think there's a
    visible but lesser effect.

    That was with the gcc 4.2.1 from openSUSE 10.3. I've since tried the
    gcc 4.3.2 from Ubuntu 8.10: which is much better on the " Page"s, only
    6 of them - PageUptodate() reasonable though PagePrivate() mysterious;
    but still 130 constant_test_bits, which I'd guess are the worst of it,
    containing an idiv. Hmm, with the 4.3.2, I get 77 constant_test_bits
    with OPTIMIZE_INLINING on but CC_OPTIMIZE_FOR_SIZE off: that's worse
    than 4.2.1, which only gave me 5 of them. So, the patch above won't
    help much then.

    You'll be amused to see the asm for this example from mm/swap_state.c
    (I was intending to downgrade these BUG_ONs to VM_BUG_ONs anyway, but
    this example makes that seem highly desirable):

    void __delete_from_swap_cache(struct page *page)
    radix_tree_delete(&swapper_space.page_tree, page_private(page));
    and let's break it off there.

    Here's the nice asm 4.2.1 gives with just CONFIG_CC_OPTIMIZE_FOR_SIZE=y
    (different machine, this one a laptop with CONFIG_VMSPLIT_2G_OPT=y):

    78173430 <__delete_from_swap_cache>:
    78173430: 55 push %ebp
    78173431: 89 e5 mov %esp,%ebp
    78173433: 53 push %ebx
    78173434: 89 c3 mov %eax,%ebx
    78173436: 8b 00 mov (%eax),%eax
    78173438: a8 01 test $0x1,%al
    7817343a: 74 45 je 78173481 <__delete_from_swap_cache+0x51>
    7817343c: 66 85 c0 test %ax,%ax
    7817343f: 79 53 jns 78173494 <__delete_from_swap_cache+0x64>
    78173441: f6 c4 10 test $0x10,%ah
    78173444: 75 4a jne 78173490 <__delete_from_swap_cache+0x60>
    78173446: f6 c4 08 test $0x8,%ah
    78173449: 75 3a jne 78173485 <__delete_from_swap_cache+0x55>
    7817344b: 8b 53 0c mov 0xc(%ebx),%edx
    7817344e: b8 a4 9b 51 78 mov $0x78519ba4,%eax
    78173453: e8 f8 83 0d 00 call 7824b850 <radix_tree_delete>

    And here is what you get when you add in CONFIG_OPTIMIZE_INLINING=y:

    7815eda4 <constant_test_bit>:
    7815eda4: 55 push %ebp
    7815eda5: b9 20 00 00 00 mov $0x20,%ecx
    7815edaa: 89 e5 mov %esp,%ebp
    7815edac: 53 push %ebx
    7815edad: 89 d3 mov %edx,%ebx
    7815edaf: 99 cltd
    7815edb0: f7 f9 idiv %ecx
    7815edb2: 8b 04 83 mov (%ebx,%eax,4),%eax
    7815edb5: 89 d1 mov %edx,%ecx
    7815edb7: 5b pop %ebx
    7815edb8: 5d pop %ebp
    7815edb9: d3 e8 shr %cl,%eax
    7815edbb: 83 e0 01 and $0x1,%eax
    7815edbe: c3 ret

    7815edbf <PageLocked>:
    7815edbf: 55 push %ebp
    7815edc0: 89 c2 mov %eax,%edx
    7815edc2: 89 e5 mov %esp,%ebp
    7815edc4: 31 c0 xor %eax,%eax
    7815edc6: e8 d9 ff ff ff call 7815eda4 <constant_test_bit>
    7815edcb: 5d pop %ebp
    7815edcc: c3 ret

    7815edcd <PagePrivate>:
    7815edcd: 55 push %ebp
    7815edce: 89 c2 mov %eax,%edx
    7815edd0: 89 e5 mov %esp,%ebp
    7815edd2: b8 0b 00 00 00 mov $0xb,%eax
    7815edd7: e8 c8 ff ff ff call 7815eda4 <constant_test_bit>
    7815eddc: 5d pop %ebp
    7815eddd: c3 ret

    7815edde <PageSwapCache>:
    7815edde: 55 push %ebp
    7815eddf: 89 c2 mov %eax,%edx
    7815ede1: 89 e5 mov %esp,%ebp
    7815ede3: b8 0f 00 00 00 mov $0xf,%eax
    7815ede8: e8 b7 ff ff ff call 7815eda4 <constant_test_bit>
    7815eded: 5d pop %ebp
    7815edee: c3 ret

    [ unrelated functions ]

    7815eecf <__delete_from_swap_cache>:
    7815eecf: 55 push %ebp
    7815eed0: 89 e5 mov %esp,%ebp
    7815eed2: 53 push %ebx
    7815eed3: 89 c3 mov %eax,%ebx
    7815eed5: e8 e5 fe ff ff call 7815edbf <PageLocked>
    7815eeda: 85 c0 test %eax,%eax
    7815eedc: 75 04 jne 7815eee2 <__delete_from_swap_cache+0x13>
    7815eede: 0f 0b ud2a
    7815eee0: eb fe jmp 7815eee0 <__delete_from_swap_cache+0x11>
    7815eee2: 89 d8 mov %ebx,%eax
    7815eee4: e8 f5 fe ff ff call 7815edde <PageSwapCache>
    7815eee9: 85 c0 test %eax,%eax
    7815eeeb: 75 04 jne 7815eef1 <__delete_from_swap_cache+0x22>
    7815eeed: 0f 0b ud2a
    7815eeef: eb fe jmp 7815eeef <__delete_from_swap_cache+0x20>
    7815eef1: 89 da mov %ebx,%edx
    7815eef3: b8 0c 00 00 00 mov $0xc,%eax
    7815eef8: e8 a7 fe ff ff call 7815eda4 <constant_test_bit>
    7815eefd: 85 c0 test %eax,%eax
    7815eeff: 74 04 je 7815ef05 <__delete_from_swap_cache+0x36>
    7815ef01: 0f 0b ud2a
    7815ef03: eb fe jmp 7815ef03 <__delete_from_swap_cache+0x34>
    7815ef05: 89 d8 mov %ebx,%eax
    7815ef07: e8 c1 fe ff ff call 7815edcd <PagePrivate>
    7815ef0c: 85 c0 test %eax,%eax
    7815ef0e: 74 04 je 7815ef14 <__delete_from_swap_cache+0x45>
    7815ef10: 0f 0b ud2a
    7815ef12: eb fe jmp 7815ef12 <__delete_from_swap_cache+0x43>
    7815ef14: 8b 53 0c mov 0xc(%ebx),%edx
    7815ef17: b8 04 16 49 78 mov $0x78491604,%eax
    7815ef1c: e8 6a 09 0b 00 call 7820f88b <radix_tree_delete>

    Fun, isn't it? I particularly admire the way it's somehow managed
    not to create a function for PageWriteback - aah, that'll be because
    there are no other references to PageWriteback in that unit. The
    4.3.2 asm is much less amusing, but calling constant_test_bit()
    each time from __delete_from_swap_cache().

    The numbers I've given are all for x86_32: similar story on x86_64,
    though I've not spent as much time on that, just noticed all the
    " Page"s there and hurried to switch off its OPTIMIZE_INLINING too.

    I do wonder whether there's some tweak we could make to page-flags.h
    which would stop this nonsense. Change the inline functions back to
    macros? I suspect that by itself wouldn't work, and my quick attempt
    to try it failed abysmally to compile, I've not the cpp foo needed.

    A part of the problem may be that test_bit() etc. are designed for
    arrays of unsigned longs, but page->flags is only the one unsigned long:
    maybe gcc loses track of the optimizations available for that case when

    Hah, I've just noticed the defaults in arch/x86/configs -
    you might want to change those...


     \ /
      Last update: 2008-11-14 19:15    [W:4.052 / U:0.964 seconds]
    ©2003-2017 Jasper Spaans. hosted at Digital OceanAdvertise on this site