Skip to content
  • Tejun Heo's avatar
    block: exit_io_context() should call elevator_exit_icq_fn() · 621032ad
    Tejun Heo authored
    While updating locking, b2efa052 "block, cfq: unlink
    cfq_io_context's immediately" moved elevator_exit_icq_fn() invocation
    from exit_io_context() to the final ioc put.  While this doesn't cause
    catastrophic failure, it effectively removes task exit notification to
    elevator and cause noticeable IO performance degradation with CFQ.
    
    On task exit, CFQ used to immediately expire the slice if it was being
    used by the exiting task as no more IO would be issued by the task;
    however, after b2efa052
    
    , the notification is lost and disk could sit
    idle needlessly, leading to noticeable IO performance degradation for
    certain workloads.
    
    This patch renames ioc_exit_icq() to ioc_destroy_icq(), separates
    elevator_exit_icq_fn() invocation into ioc_exit_icq() and invokes it
    from exit_io_context().  ICQ_EXITED flag is added to avoid invoking
    the callback more than once for the same icq.
    
    Walking icq_list from ioc side and invoking elevator callback requires
    reverse double locking.  This may be better implemented using RCU;
    unfortunately, using RCU isn't trivial.  e.g. RCU protection would
    need to cover request_queue and queue_lock switch on cleanup makes
    grabbing queue_lock from RCU unsafe.  Reverse double locking should
    do, at least for now.
    
    Signed-off-by: default avatarTejun Heo <tj@kernel.org>
    Reported-and-bisected-by: default avatarShaohua Li <shli@kernel.org>
    LKML-Reference: <CANejiEVzs=pUhQSTvUppkDcc2TNZyfohBRLygW5zFmXyk5A-xQ@mail.gmail.com>
    Tested-by: default avatarShaohua Li <shaohua.li@intel.com>
    Signed-off-by: default avatarJens Axboe <axboe@kernel.dk>
    621032ad