• Tejun Heo's avatar
    blk-iocost: Fix an UBSAN shift-out-of-bounds warning · 2a427b49
    Tejun Heo authored
    When iocg_kick_delay() is called from a CPU different than the one which set
    the delay, @now may be in the past of @iocg->delay_at leading to the
    following warning:
    
      UBSAN: shift-out-of-bounds in block/blk-iocost.c:1359:23
      shift exponent 18446744073709 is too large for 64-bit type 'u64' (aka 'unsigned long long')
      ...
      Call Trace:
       <TASK>
       dump_stack_lvl+0x79/0xc0
       __ubsan_handle_shift_out_of_bounds+0x2ab/0x300
       iocg_kick_delay+0x222/0x230
       ioc_rqos_merge+0x1d7/0x2c0
       __rq_qos_merge+0x2c/0x80
       bio_attempt_back_merge+0x83/0x190
       blk_attempt_plug_merge+0x101/0x150
       blk_mq_submit_bio+0x2b1/0x720
       submit_bio_noacct_nocheck+0x320/0x3e0
       __swap_writepage+0x2ab/0x9d0
    
    The underflow itself doesn't really affect the behavior in any meaningful
    way; however, the past timestamp may exaggerate the delay amount calculated
    later in the code, which shouldn't be a material problem given the nature of
    the delay mechanism.
    
    If @now is in the past, this CPU is racing another CPU which recently set up
    the delay and there's nothing this CPU can contribute w.r.t. the delay.
    Let's bail early from iocg_kick_delay() in such cases.
    Reported-by: default avatarBreno Leitão <leitao@debian.org>
    Signed-off-by: default avatarTejun Heo <tj@kernel.org>
    Fixes: 5160a5a5 ("blk-iocost: implement delay adjustment hysteresis")
    Link: https://lore.kernel.org/r/ZVvc9L_CYk5LO1fT@slm.duckdns.orgSigned-off-by: default avatarJens Axboe <axboe@kernel.dk>
    2a427b49
blk-iocost.c 98.3 KB