• Luis Chamberlain's avatar
    block: revert back to synchronous request_queue removal · e8c7d14a
    Luis Chamberlain authored
    Commit dc9edc44 ("block: Fix a blk_exit_rl() regression") merged on
    v4.12 moved the work behind blk_release_queue() into a workqueue after a
    splat floated around which indicated some work on blk_release_queue()
    could sleep in blk_exit_rl(). This splat would be possible when a driver
    called blk_put_queue() or blk_cleanup_queue() (which calls blk_put_queue()
    as its final call) from an atomic context.
    
    blk_put_queue() decrements the refcount for the request_queue kobject, and
    upon reaching 0 blk_release_queue() is called. Although blk_exit_rl() is
    now removed through commit db6d9952 ("block: remove request_list code")
    on v5.0, we reserve the right to be able to sleep within
    blk_release_queue() context.
    
    The last reference for the request_queue must not be called from atomic
    context. *When* the last reference to the request_queue reaches 0 varies,
    and so let's take the opportunity to document when that is expected to
    happen and also document the context of the related calls as best as
    possible so we can avoid future issues, and with the hopes that the
    synchronous request_queue removal sticks.
    
    We revert back to synchronous request_queue removal because asynchronous
    removal creates a regression with expected userspace interaction with
    several drivers. An example is when removing the loopback driver, one
    uses ioctls from userspace to do so, but upon return and if successful,
    one expects the device to be removed. Likewise if one races to add another
    device the new one may not be added as it is still being removed. This was
    expected behavior before and it now fails as the device is still present
    and busy still. Moving to asynchronous request_queue removal could have
    broken many scripts which relied on the removal to have been completed if
    there was no error. Document this expectation as well so that this
    doesn't regress userspace again.
    
    Using asynchronous request_queue removal however has helped us find
    other bugs. In the future we can test what could break with this
    arrangement by enabling CONFIG_DEBUG_KOBJECT_RELEASE.
    
    While at it, update the docs with the context expectations for the
    request_queue / gendisk refcount decrement, and make these
    expectations explicit by using might_sleep().
    
    Fixes: dc9edc44 ("block: Fix a blk_exit_rl() regression")
    Suggested-by: default avatarNicolai Stange <nstange@suse.de>
    Signed-off-by: default avatarLuis Chamberlain <mcgrof@kernel.org>
    Reviewed-by: default avatarChristoph Hellwig <hch@lst.de>
    Reviewed-by: default avatarBart Van Assche <bvanassche@acm.org>
    Cc: Bart Van Assche <bvanassche@acm.org>
    Cc: Omar Sandoval <osandov@fb.com>
    Cc: Hannes Reinecke <hare@suse.com>
    Cc: Nicolai Stange <nstange@suse.de>
    Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
    Cc: Michal Hocko <mhocko@kernel.org>
    Cc: yu kuai <yukuai3@huawei.com>
    Signed-off-by: default avatarJens Axboe <axboe@kernel.dk>
    e8c7d14a
blk-sysfs.c 26.7 KB