mirror of
https://github.com/torvalds/linux.git
synced 2026-11-10 08:53:02 +01:00
ublk: drop the device reference outside ublk_ctl_mutex in DEL_DEV
ublk_ctrl_del_dev() drops its reference to the device while holding the
global ublk_ctl_mutex. When this is the last reference, ublk_cdev_rel()
frees the tag set, and blk_mq_free_tag_set() waits for the pending SRCU
callbacks of the tag set with srcu_barrier(). Every DEL_DEV thus waits
for an SRCU grace period with the mutex held, and deleting devices from
several threads serializes on it.
The release path doesn't need ublk_ctl_mutex. The device number is freed
under ublk_idr_lock, and the last reference is already dropped without
the mutex when the ublk server still has the char device open at
DEL_DEV time, from ublk_ch_release_work_fn().
Drop the reference after unlocking ublk_ctl_mutex.
ublk null target, 4000 single-queue devices, STOP_DEV + DEL_DEV issued
from N threads, 16 vCPU KVM guest:
threads before after
1 77.6 s 77.6 s
4 20.1 s 19.4 s
8 19.3 s 9.0 s
16 19.2 s 4.1 s
Signed-off-by: Qiliang Yuan <odys.yuan@gmail.com>
Reviewed-by: Ming Lei <tom.leiming@gmail.com>
Link: https://patch.msgid.link/20261001-bug-ublk-del-dev-put-unlocked-v1-1-18e9bb9be727@gmail.com
Signed-off-by: Jens Axboe <axboe@kernel.dk>
This commit is contained in:
parent
2b8ee88f18
commit
812485c8ff
|
|
@ -4901,10 +4901,15 @@ static int ublk_ctrl_del_dev(struct ublk_device **p_ub, bool wait)
|
|||
set_bit(UB_STATE_DELETED, &ub->state);
|
||||
}
|
||||
|
||||
/* Mark the reference as consumed */
|
||||
mutex_unlock(&ublk_ctl_mutex);
|
||||
|
||||
/*
|
||||
* Drop the reference outside ublk_ctl_mutex: if it is the last one,
|
||||
* the release frees the tag set, which waits for an SRCU grace period,
|
||||
* and holding the mutex would serialize concurrent deletions on it.
|
||||
*/
|
||||
*p_ub = NULL;
|
||||
ublk_put_device(ub);
|
||||
mutex_unlock(&ublk_ctl_mutex);
|
||||
|
||||
/*
|
||||
* Wait until the idr is removed, then it can be reused after
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user