• Jan Kara's avatar
    bfq: Do not let waker requests skip proper accounting · c65e6fd4
    Jan Kara authored
    Commit 7cc4ffc5 ("block, bfq: put reqs of waker and woken in
    dispatch list") added a condition to bfq_insert_request() which added
    waker's requests directly to dispatch list. The rationale was that
    completing waker's IO is needed to get more IO for the current queue.
    Although this rationale is valid, there is a hole in it. The waker does
    not necessarily serve the IO only for the current queue and maybe it's
    current IO is not needed for current queue to make progress. Furthermore
    injecting IO like this completely bypasses any service accounting within
    bfq and thus we do not properly track how much service is waker's queue
    getting or that the waker is actually doing any IO. Depending on the
    conditions this can result in the waker getting too much or too few
    service.
    
    Consider for example the following job file:
    
    [global]
    directory=/mnt/repro/
    rw=write
    size=8g
    time_based
    runtime=30
    ramp_time=10
    blocksize=1m
    direct=0
    ioengine=sync
    
    [slowwriter]
    numjobs=1
    prioclass=2
    prio=7
    fsync=200
    
    [fastwriter]
    numjobs=1
    prioclass=2
    prio=0
    fsync=200
    
    Despite processes have very different IO priorities, they get the same
    about of service. The reason is that bfq identifies these processes as
    having waker-wakee relationship and once that happens, IO from
    fastwriter gets injected during slowwriter's time slice. As a result bfq
    is not aware that fastwriter has any IO to do and constantly schedules
    only slowwriter's queue. Thus fastwriter is forced to compete with
    slowwriter's IO all the time instead of getting its share of time based
    on IO priority.
    
    Drop the special injection condition from bfq_insert_request(). As a
    result, requests will be tracked and queued in a normal way and on next
    dispatch bfq_select_queue() can decide whether the waker's inserted
    requests should be injected during the current queue's timeslice or not.
    
    Fixes: 7cc4ffc5 ("block, bfq: put reqs of waker and woken in dispatch list")
    Acked-by: default avatarPaolo Valente <paolo.valente@linaro.org>
    Signed-off-by: default avatarJan Kara <jack@suse.cz>
    Link: https://lore.kernel.org/r/20211125133645.27483-8-jack@suse.czSigned-off-by: default avatarJens Axboe <axboe@kernel.dk>
    c65e6fd4
bfq-iosched.c 257 KB