• Jens Axboe's avatar
    block: directly insert blk-mq request from blk_insert_cloned_request() · 157f377b
    Jens Axboe authored
    A NULL pointer crash was reported for the case of having the BFQ IO
    scheduler attached to the underlying blk-mq paths of a DM multipath
    device.  The crash occured in blk_mq_sched_insert_request()'s call to
    e->type->ops.mq.insert_requests().
    
    Paolo Valente correctly summarized why the crash occured with:
    "the call chain (dm_mq_queue_rq -> map_request -> setup_clone ->
    blk_rq_prep_clone) creates a cloned request without invoking
    e->type->ops.mq.prepare_request for the target elevator e.  The cloned
    request is therefore not initialized for the scheduler, but it is
    however inserted into the scheduler by blk_mq_sched_insert_request."
    
    All said, a request-based DM multipath device's IO scheduler should be
    the only one used -- when the original requests are issued to the
    underlying paths as cloned requests they are inserted directly in the
    underlying dispatch queue(s) rather than through an additional elevator.
    
    But commit bd166ef1 ("blk-mq-sched: add framework for MQ capable IO
    schedulers") switched blk_insert_cloned_request() from using
    blk_mq_insert_request() to blk_mq_sched_insert_request().  Which
    incorrectly added elevator machinery into a call chain that isn't
    supposed to have any.
    
    To fix this introduce a blk-mq private blk_mq_request_bypass_insert()
    that blk_insert_cloned_request() calls to insert the request without
    involving any elevator that may be attached to the cloned request's
    request_queue.
    
    Fixes: bd166ef1 ("blk-mq-sched: add framework for MQ capable IO schedulers")
    Cc: stable@vger.kernel.org
    Reported-by: 's avatarBart Van Assche <Bart.VanAssche@wdc.com>
    Tested-by: 's avatarMike Snitzer <snitzer@redhat.com>
    Signed-off-by: 's avatarJens Axboe <axboe@kernel.dk>
    157f377b