-
Notifications
You must be signed in to change notification settings - Fork 0
blk-mq: fix possible deadlocks #403
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
|
Upstream branch: fd95357 |
6f43942 to
ec9caac
Compare
To move implementation details inside blk-wbt.c, prepare to fix possible deadlock to call wbt_init() while queue is frozen in the next patch. Signed-off-by: Yu Kuai <[email protected]>
…_counter If wbt is disabled by default and user configures wbt by sysfs, queue will be frozen first and then pcpu_alloc_mutex will be held in blk_stat_alloc_callback(). Fix this problem by allocating memory first before queue frozen. Signed-off-by: Yu Kuai <[email protected]>
There is already a helper blk_mq_debugfs_register_rqos() to register one rqos, however this helper is called synchronously when the rqos is created with queue frozen. Prepare to fix possible deadlock to create blk-mq debugfs entries while queue is still frozen. Signed-off-by: Yu Kuai <[email protected]>
Currently rq-qos debugfs entries are created from rq_qos_add(), while rq_qos_add() can be called while queue is still frozen. This can deadlock because creating new entries can trigger fs reclaim. Fix this problem by delaying creating rq-qos debugfs entries after queue is unfrozen. - For wbt, 1) it can be initialized by default, fix it by calling new helper after wbt_init() from wbt_enable_default; 2) it can be initialized by sysfs, fix it by calling new helper after queue is unfrozen from queue_wb_lat_store(). - For iocost and iolatency, they can only be initialized by blkcg configuration, however, they don't have debugfs entries for now, hence they are not handled yet. Signed-off-by: Yu Kuai <[email protected]>
Because it's only used inside blk-mq-debugfs.c now. Signed-off-by: Yu Kuai <[email protected]>
Creating new debugfs entries can trigger fs reclaim, hence we can't do this with queue frozen, meanwhile, other locks that can be held while queue is frozen should not be held as well. Signed-off-by: Yu Kuai <[email protected]>
queue should not be frozen under rq_qos_mutex, see example from commit 9730763 ("block: correct locking order for protecting blk-wbt parameters"), which means current implementation of rq_qos_add() is problematic. Add a new helper and prepare to fix this problem in following patches. Signed-off-by: Yu Kuai <[email protected]>
wbt_init() can be called from sysfs attribute and wbt_enable_default(), however the lock order are inversely. - queue_wb_lat_store() freeze queue first, and then wbt_init() hold rq_qos_mutex. In this case queue will be frozen again inside rq_qos_add(), however, in this case freeze queue recursively is inoperative; - wbt_enable_default() from elevator switch will hold rq_qos_mutex first, and then rq_qos_add() will freeze queue; Fix this problem by converting to use new helper rq_qos_add_frozen() in wbt_init(), and for wbt_enable_default(), freeze queue before calling wbt_init(). Fixes: a13bd91 ("block/rq_qos: protect rq_qos apis with a new lock") Signed-off-by: Yu Kuai <[email protected]>
Like wbt, rq_qos_add() can be called from two path and the lock order are inversely: - From ioc_qos_write(), queue is already frozen before rq_qos_add(); - From ioc_cost_model_write(), rq_qos_add() is called directly; Fix this problem by converting to use blkg_conf_open_bdev_frozen() from ioc_cost_model_write(), then since all rq_qos_add() callers already freeze queue, convert to use rq_qos_add_frozen(). Signed-off-by: Yu Kuai <[email protected]>
…ueue Currently blk-iolatency will hold rq_qos_mutex first and then call rq_qos_add() to freeze queue. Fix this problem by converting to use blkg_conf_open_bdev_frozen() from iolatency_set_limit(), and convert to use rq_qos_add_frozen(). Signed-off-by: Yu Kuai <[email protected]>
blk-throttle is still holding rq_qos_mutex before freezing queue from blk_throtl_init(). However blk_throtl_bio() can be called before grabbing q_usage_counter hence freeze queue really doesn't stop new IO issuing to blk-throtl. Also use READ_ONCE and WRITE_ONCE for q->td because blk_throtl_init() can concurrent with issuing IO. Signed-off-by: Yu Kuai <[email protected]>
Now that there is no caller of rq_qos_add(), remove it, and also rename rq_qos_add_frozen() back to rq_qos_add(). Signed-off-by: Yu Kuai <[email protected]>
|
Upstream branch: c2f2b01 |
f0d7e3e to
41390fc
Compare
ec9caac to
4a5ddea
Compare
|
Upstream branch: d26143b |
|
Upstream branch: d26143b |
|
Github failed to update this PR after force push. Close it. |
Pull request for series with
subject: blk-mq: fix possible deadlocks
version: 2
url: https://patchwork.kernel.org/project/linux-block/list/?series=1026165