]>
Commit | Line | Data |
---|---|---|
2705b78f GKH |
1 | From 32e36bfbcf31452a854263e7c7f32fbefc4b44d8 Mon Sep 17 00:00:00 2001 |
2 | From: Bart Van Assche <bvanassche@acm.org> | |
3 | Date: Fri, 25 Jan 2019 10:34:56 -0800 | |
4 | Subject: scsi: target/iscsi: Avoid iscsit_release_commands_from_conn() deadlock | |
5 | ||
6 | From: Bart Van Assche <bvanassche@acm.org> | |
7 | ||
8 | commit 32e36bfbcf31452a854263e7c7f32fbefc4b44d8 upstream. | |
9 | ||
10 | When using SCSI passthrough in combination with the iSCSI target driver | |
11 | then cmd->t_state_lock may be obtained from interrupt context. Hence, all | |
12 | code that obtains cmd->t_state_lock from thread context must disable | |
13 | interrupts first. This patch avoids that lockdep reports the following: | |
14 | ||
15 | WARNING: inconsistent lock state | |
16 | 4.18.0-dbg+ #1 Not tainted | |
17 | -------------------------------- | |
18 | inconsistent {HARDIRQ-ON-W} -> {IN-HARDIRQ-W} usage. | |
19 | iscsi_ttx/1800 [HC1[1]:SC0[2]:HE0:SE0] takes: | |
20 | 000000006e7b0ceb (&(&cmd->t_state_lock)->rlock){?...}, at: target_complete_cmd+0x47/0x2c0 [target_core_mod] | |
21 | {HARDIRQ-ON-W} state was registered at: | |
22 | lock_acquire+0xd2/0x260 | |
23 | _raw_spin_lock+0x32/0x50 | |
24 | iscsit_close_connection+0x97e/0x1020 [iscsi_target_mod] | |
25 | iscsit_take_action_for_connection_exit+0x108/0x200 [iscsi_target_mod] | |
26 | iscsi_target_rx_thread+0x180/0x190 [iscsi_target_mod] | |
27 | kthread+0x1cf/0x1f0 | |
28 | ret_from_fork+0x24/0x30 | |
29 | irq event stamp: 1281 | |
30 | hardirqs last enabled at (1279): [<ffffffff970ade79>] __local_bh_enable_ip+0xa9/0x160 | |
31 | hardirqs last disabled at (1281): [<ffffffff97a008a5>] interrupt_entry+0xb5/0xd0 | |
32 | softirqs last enabled at (1278): [<ffffffff977cd9a1>] lock_sock_nested+0x51/0xc0 | |
33 | softirqs last disabled at (1280): [<ffffffffc07a6e04>] ip6_finish_output2+0x124/0xe40 [ipv6] | |
34 | ||
35 | other info that might help us debug this: | |
36 | Possible unsafe locking scenario: | |
37 | ||
38 | CPU0 | |
39 | ---- | |
40 | lock(&(&cmd->t_state_lock)->rlock); | |
41 | <Interrupt> | |
42 | lock(&(&cmd->t_state_lock)->rlock); | |
43 | ||
44 | --- | |
45 | drivers/target/iscsi/iscsi_target.c | 4 ++-- | |
46 | 1 file changed, 2 insertions(+), 2 deletions(-) | |
47 | ||
48 | --- a/drivers/target/iscsi/iscsi_target.c | |
49 | +++ b/drivers/target/iscsi/iscsi_target.c | |
50 | @@ -4077,9 +4077,9 @@ static void iscsit_release_commands_from | |
51 | struct se_cmd *se_cmd = &cmd->se_cmd; | |
52 | ||
53 | if (se_cmd->se_tfo != NULL) { | |
54 | - spin_lock(&se_cmd->t_state_lock); | |
55 | + spin_lock_irq(&se_cmd->t_state_lock); | |
56 | se_cmd->transport_state |= CMD_T_FABRIC_STOP; | |
57 | - spin_unlock(&se_cmd->t_state_lock); | |
58 | + spin_unlock_irq(&se_cmd->t_state_lock); | |
59 | } | |
60 | } | |
61 | spin_unlock_bh(&conn->cmd_lock); |