mirror of
https://github.com/SCST-project/scst.git
synced 2026-05-20 12:11:26 +00:00
Avoid that removing the scst_local kernel module triggers a deadlock
when one of its LUNs is a CD-ROM device. sr_block_release() invokes scst_local_release_adapter() indirectly with sr_mutex held. So if scst_local_release_adapter() blocks until the scst_local session has been freed a deadlock may be triggered if another CD-ROM device has to be closed in order to free that session. Fix this by changing scst_local_release_adapter() such that it does not wait until the session unregistration has finished. Call stacks obtained with echo w > /proc/sysrq-trigger: SysRq : Show Blocked State task PC stack pid father scst_mgmtd D ffffffff812f979d 0 5552 2 0x00000000 ffff88003c335b30 0000000000000046 ffffffff812f979d 0000000000000002 ffff8800171d47a0 ffff88003c335fd8 ffff88003c335fd8 ffff88003c335fd8 ffff88003d1b0000 ffff8800171d47a0 ffff88003c335b60 ffff88003c334000 Call Trace: [<ffffffff812f979d>] ? sr_block_release+0x2d/0x60 [<ffffffff812f979d>] ? sr_block_release+0x2d/0x60 [<ffffffff814a9b19>] schedule+0x29/0x70 [<ffffffff814a9e57>] schedule_preempt_disabled+0x27/0x40 [<ffffffff814a79b7>] mutex_lock_nested+0x187/0x390 [<ffffffff812f979d>] ? sr_block_release+0x2d/0x60 [<ffffffff812f979d>] sr_block_release+0x2d/0x60 [<ffffffff8118a1ec>] __blkdev_put+0x19c/0x1d0 [<ffffffff8118a27d>] blkdev_put+0x5d/0x180 [<ffffffff8118a3c8>] blkdev_close+0x28/0x30 [<ffffffff81153633>] fput+0x103/0x280 [<ffffffff8114fad9>] filp_close+0x69/0x90 [<ffffffffa022ec24>] vdisk_detach_tgt+0x134/0x150 [scst_vdisk] [<ffffffffa02d8f2f>] scst_free_tgt_dev+0xdf/0x220 [scst] [<ffffffffa02d949f>] ? scst_free_session_callback+0x7f/0x170 [scst] [<ffffffffa02d90eb>] scst_sess_free_tgt_devs+0x7b/0x110 [scst] [<ffffffffa02d91de>] scst_free_session+0x5e/0x2a0 [scst] [<ffffffffa02d94be>] scst_free_session_callback+0x9e/0x170 [scst] [<ffffffffa02c6a05>] scst_global_mgmt_thread+0x2e5/0x580 [scst] [<ffffffff8105e850>] ? __init_waitqueue_head+0x60/0x60 [<ffffffffa02c6720>] ? scst_register_session_non_gpl+0x20/0x20 [scst] [<ffffffff8105dd77>] kthread+0xb7/0xc0 [<ffffffff814b50b4>] kernel_thread_helper+0x4/0x10 [<ffffffff814abb30>] ? retint_restore_args+0x13/0x13 [<ffffffff8105dcc0>] ? __init_kthread_worker+0x70/0x70 [<ffffffff814b50b0>] ? gs_change+0x13/0x13 iscsi-scstd D ffffffffa02b1b1f 0 5567 1 0x00000004 ffff88003c2f59a8 0000000000000046 ffffffffa02b1b1f 0000000000000002 ffff8800173b23d0 ffff88003c2f5fd8 ffff88003c2f5fd8 ffff88003c2f5fd8 ffff88003d198000 ffff8800173b23d0 ffff88003c2f59d8 ffff88003c2f4000 Call Trace: [<ffffffffa02b1b1f>] ? scst_unregister_target+0x8f/0x450 [scst] [<ffffffffa02b1b1f>] ? scst_unregister_target+0x8f/0x450 [scst] [<ffffffff814a9b19>] schedule+0x29/0x70 [<ffffffff814a9e57>] schedule_preempt_disabled+0x27/0x40 [<ffffffff814a79b7>] mutex_lock_nested+0x187/0x390 [<ffffffffa02b1b1f>] ? scst_unregister_target+0x8f/0x450 [scst] [<ffffffffa025c7ba>] ? __iscsi_del_attr+0xea/0x190 [iscsi_scst] [<ffffffffa02b1b1f>] scst_unregister_target+0x8f/0x450 [scst] [<ffffffffa025c7ba>] ? __iscsi_del_attr+0xea/0x190 [iscsi_scst] [<ffffffffa026249f>] target_destroy+0x5f/0xc0 [iscsi_scst] [<ffffffffa02631f2>] target_del_all+0xf2/0x2d0 [iscsi_scst] [<ffffffffa025c8aa>] release+0x4a/0xe0 [iscsi_scst] [<ffffffff81153633>] fput+0x103/0x280 [<ffffffff8114fad9>] filp_close+0x69/0x90 [<ffffffff8103e533>] put_files_struct+0x103/0x1c0 [<ffffffff8103e478>] ? put_files_struct+0x48/0x1c0 [<ffffffff8103e6b2>] exit_files+0x52/0x60 [<ffffffff8103eb80>] do_exit+0x180/0x8e0 [<ffffffff8104ef87>] ? get_signal_to_deliver+0xe7/0x6e0 [<ffffffff8103f631>] do_group_exit+0x51/0xc0 [<ffffffff8104f0bf>] get_signal_to_deliver+0x21f/0x6e0 [<ffffffff8100223c>] do_signal+0x3c/0x580 [<ffffffff81002805>] do_notify_resume+0x65/0xa0 [<ffffffff812149de>] ? trace_hardirqs_on_thunk+0x3a/0x3f [<ffffffff814b4122>] int_signal+0x12/0x17 rmmod D ffffffffa02b1b70 0 5714 5681 0x00000000 ffff88000b497d48 0000000000000046 ffffffffa02b1b70 0000000000000002 ffff88003920a3d0 ffff88000b497fd8 ffff88000b497fd8 ffff88000b497fd8 ffff88003d17a3d0 ffff88003920a3d0 ffff88000b497d78 ffff88000b496000 Call Trace: [<ffffffffa02b1b70>] ? scst_unregister_target+0xe0/0x450 [scst] [<ffffffffa02b1b70>] ? scst_unregister_target+0xe0/0x450 [scst] [<ffffffff814a9b19>] schedule+0x29/0x70 [<ffffffff814a9e57>] schedule_preempt_disabled+0x27/0x40 [<ffffffff814a79b7>] mutex_lock_nested+0x187/0x390 [<ffffffffa02b1b70>] ? scst_unregister_target+0xe0/0x450 [scst] [<ffffffffa02b1b70>] scst_unregister_target+0xe0/0x450 [scst] [<ffffffffa0287e51>] ? scst_local_exit+0x6b/0x21a [scst_local] [<ffffffff812c2d37>] ? put_device+0x17/0x20 [<ffffffff812c3efa>] ? device_unregister+0x2a/0x60 [<ffffffffa0285108>] __scst_local_remove_target+0xa8/0x130 [scst_local] [<ffffffffa0287e6a>] scst_local_exit+0x84/0x21a [scst_local] [<ffffffff810a40c6>] sys_delete_module+0x1a6/0x2b0 [<ffffffff812149de>] ? trace_hardirqs_on_thunk+0x3a/0x3f [<ffffffff814b3de9>] system_call_fastpath+0x16/0x1b ata_id D ffff88003920c7a0 0 5715 5195 0x00000000 ffff880015e97818 0000000000000046 0000000000000000 0000000000000046 ffff88003920c7a0 ffff880015e97fd8 ffff880015e97fd8 ffff880015e97fd8 ffff880021788000 ffff88003920c7a0 ffff880015e977f8 7fffffffffffffff Call Trace: [<ffffffff814a9b19>] schedule+0x29/0x70 [<ffffffff814a7355>] schedule_timeout+0x315/0x390 [<ffffffff814a98e3>] ? wait_for_common+0x43/0x170 [<ffffffff814a98e3>] ? wait_for_common+0x43/0x170 [<ffffffff814a99c2>] wait_for_common+0x122/0x170 [<ffffffff810705b0>] ? try_to_wake_up+0x2f0/0x2f0 [<ffffffff814a9aed>] wait_for_completion+0x1d/0x20 [<ffffffffa02bfad3>] scst_unregister_session+0x1a3/0x320 [scst] [<ffffffffa0284990>] scst_local_release_adapter+0xa0/0x140 [scst_local] [<ffffffff812c2f87>] device_release+0x27/0xa0 [<ffffffff81209abb>] kobject_release+0x8b/0x1d0 [<ffffffff8120993c>] kobject_put+0x2c/0x60 [<ffffffff812c2d37>] put_device+0x17/0x20 [<ffffffff812e1850>] scsi_host_dev_release+0xc0/0xe0 [<ffffffff812c2f87>] device_release+0x27/0xa0 [<ffffffff81209abb>] kobject_release+0x8b/0x1d0 [<ffffffff8120993c>] kobject_put+0x2c/0x60 [<ffffffff812c2d37>] put_device+0x17/0x20 [<ffffffff812ea0c2>] scsi_target_dev_release+0x22/0x30 [<ffffffff812c2f87>] device_release+0x27/0xa0 [<ffffffff81209abb>] kobject_release+0x8b/0x1d0 [<ffffffff8120993c>] kobject_put+0x2c/0x60 [<ffffffff812c2d37>] put_device+0x17/0x20 [<ffffffff812ed818>] scsi_device_dev_release_usercontext+0x118/0x130 [<ffffffff812ed700>] ? scsi_device_cls_release+0x20/0x20 [<ffffffff81056576>] execute_in_process_context+0x86/0xa0 [<ffffffff812ed6dc>] scsi_device_dev_release+0x1c/0x20 [<ffffffff812c2f87>] device_release+0x27/0xa0 [<ffffffff81209abb>] kobject_release+0x8b/0x1d0 [<ffffffff8120993c>] kobject_put+0x2c/0x60 [<ffffffff812c2d37>] put_device+0x17/0x20 [<ffffffff812df594>] scsi_device_put+0x44/0x60 [<ffffffff812f974d>] scsi_cd_put+0x4d/0x70 [<ffffffff812f97b1>] sr_block_release+0x41/0x60 [<ffffffff8118a1ec>] __blkdev_put+0x19c/0x1d0 [<ffffffff8118a27d>] blkdev_put+0x5d/0x180 [<ffffffff8118a3c8>] blkdev_close+0x28/0x30 [<ffffffff81153633>] fput+0x103/0x280 [<ffffffff814a93b3>] ? __schedule+0x3c3/0x820 [<ffffffff8114fad9>] filp_close+0x69/0x90 [<ffffffff8114fba0>] sys_close+0xa0/0x100 [<ffffffff814b3de9>] system_call_fastpath+0x16/0x1b Signed-off-by: Bart Van Assche <bvanassche@acm.org> Cc: Richard Sharpe <realrichardsharpe@gmail.com> git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@4425 d57e44dd-8a1f-0410-8b47-8ef2f437770f
This commit is contained in:
@@ -1572,6 +1572,14 @@ static struct device scst_local_root = {
|
||||
static struct device *scst_local_root;
|
||||
#endif
|
||||
|
||||
static void scst_local_free_sess(struct scst_session *scst_sess)
|
||||
{
|
||||
struct scst_local_sess *sess = scst_sess_get_tgt_priv(scst_sess);
|
||||
|
||||
kfree(sess);
|
||||
return;
|
||||
}
|
||||
|
||||
static void scst_local_release_adapter(struct device *dev)
|
||||
{
|
||||
struct scst_local_sess *sess;
|
||||
@@ -1597,9 +1605,7 @@ static void scst_local_release_adapter(struct device *dev)
|
||||
cancel_work_sync(&sess->aen_work);
|
||||
#endif
|
||||
|
||||
scst_unregister_session(sess->scst_sess, true, NULL);
|
||||
|
||||
kfree(sess);
|
||||
scst_unregister_session(sess->scst_sess, false, scst_local_free_sess);
|
||||
|
||||
out:
|
||||
TRACE_EXIT();
|
||||
|
||||
Reference in New Issue
Block a user