lkml.org 
[lkml]   [2023]   [Mar]   [14]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH v18 11/15] block: Fix bio_flagged() so that gcc can better optimise it
    Date
    Fix bio_flagged() so that multiple instances of it, such as:

    if (bio_flagged(bio, BIO_PAGE_REFFED) ||
    bio_flagged(bio, BIO_PAGE_PINNED))

    can be combined by the gcc optimiser into a single test in assembly
    (arguably, this is a compiler optimisation issue[1]).

    The missed optimisation stems from bio_flagged() comparing the result of
    the bitwise-AND to zero. This results in an out-of-line bio_release_page()
    being compiled to something like:

    <+0>: mov 0x14(%rdi),%eax
    <+3>: test $0x1,%al
    <+5>: jne 0xffffffff816dac53 <bio_release_pages+11>
    <+7>: test $0x2,%al
    <+9>: je 0xffffffff816dac5c <bio_release_pages+20>
    <+11>: movzbl %sil,%esi
    <+15>: jmp 0xffffffff816daba1 <__bio_release_pages>
    <+20>: jmp 0xffffffff81d0b800 <__x86_return_thunk>

    However, the test is superfluous as the return type is bool. Removing it
    results in:

    <+0>: testb $0x3,0x14(%rdi)
    <+4>: je 0xffffffff816e4af4 <bio_release_pages+15>
    <+6>: movzbl %sil,%esi
    <+10>: jmp 0xffffffff816dab7c <__bio_release_pages>
    <+15>: jmp 0xffffffff81d0b7c0 <__x86_return_thunk>

    instead.

    Also, the MOVZBL instruction looks unnecessary[2] - I think it's just
    're-booling' the mark_dirty parameter.

    Signed-off-by: David Howells <dhowells@redhat.com>
    Reviewed-by: Christoph Hellwig <hch@lst.de>
    Reviewed-by: John Hubbard <jhubbard@nvidia.com>
    cc: Jens Axboe <axboe@kernel.dk>
    cc: linux-block@vger.kernel.org
    Link: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=108370 [1]
    Link: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=108371 [2]
    Link: https://lore.kernel.org/r/167391056756.2311931.356007731815807265.stgit@warthog.procyon.org.uk/ # v6
    ---
    include/linux/bio.h | 2 +-
    1 file changed, 1 insertion(+), 1 deletion(-)

    diff --git a/include/linux/bio.h b/include/linux/bio.h
    index d766be7152e1..d9d6df62ea57 100644
    --- a/include/linux/bio.h
    +++ b/include/linux/bio.h
    @@ -229,7 +229,7 @@ static inline void bio_cnt_set(struct bio *bio, unsigned int count)

    static inline bool bio_flagged(struct bio *bio, unsigned int bit)
    {
    - return (bio->bi_flags & (1U << bit)) != 0;
    + return bio->bi_flags & (1U << bit);
    }

    static inline void bio_set_flag(struct bio *bio, unsigned int bit)
    \
     
     \ /
      Last update: 2023-03-27 01:00    [W:4.118 / U:0.024 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site