Skip to content

Commit 9ff9d15

Browse files
Bart Van AsscheNicholas Bellinger
Bart Van Assche
authored and
Nicholas Bellinger
committed
target: Invoke release_cmd() callback without holding a spinlock
This patch fixes the following kernel warning because it avoids that IRQs are disabled while ft_release_cmd() is invoked (fc_seq_set_resp() invokes spin_unlock_bh()): WARNING: CPU: 3 PID: 117 at kernel/softirq.c:150 __local_bh_enable_ip+0xaa/0x110() Call Trace: [<ffffffff814f71eb>] dump_stack+0x4f/0x7b [<ffffffff8105e56a>] warn_slowpath_common+0x8a/0xc0 [<ffffffff8105e65a>] warn_slowpath_null+0x1a/0x20 [<ffffffff81062b2a>] __local_bh_enable_ip+0xaa/0x110 [<ffffffff814ff229>] _raw_spin_unlock_bh+0x39/0x40 [<ffffffffa03a7f94>] fc_seq_set_resp+0xe4/0x100 [libfc] [<ffffffffa02e604a>] ft_free_cmd+0x4a/0x90 [tcm_fc] [<ffffffffa02e6972>] ft_release_cmd+0x12/0x20 [tcm_fc] [<ffffffffa042bd66>] target_release_cmd_kref+0x56/0x90 [target_core_mod] [<ffffffffa042caf0>] target_put_sess_cmd+0xc0/0x110 [target_core_mod] [<ffffffffa042cb81>] transport_release_cmd+0x41/0x70 [target_core_mod] [<ffffffffa042d975>] transport_generic_free_cmd+0x35/0x420 [target_core_mod] Signed-off-by: Bart Van Assche <bart.vanassche@sandisk.com> Acked-by: Joern Engel <joern@logfs.org> Reviewed-by: Andy Grover <agrover@redhat.com> Cc: Christoph Hellwig <hch@lst.de> Cc: Hannes Reinecke <hare@suse.de> Cc: Sagi Grimberg <sagig@mellanox.com> Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org>
1 parent 057085e commit 9ff9d15

File tree

2 files changed

+12
-7
lines changed

2 files changed

+12
-7
lines changed

drivers/target/target_core_tmr.c

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,9 @@ void core_tmr_abort_task(
130130
if (tmr->ref_task_tag != ref_tag)
131131
continue;
132132

133+
if (!kref_get_unless_zero(&se_cmd->cmd_kref))
134+
continue;
135+
133136
printk("ABORT_TASK: Found referenced %s task_tag: %llu\n",
134137
se_cmd->se_tfo->get_fabric_name(), ref_tag);
135138

@@ -139,13 +142,15 @@ void core_tmr_abort_task(
139142
" skipping\n", ref_tag);
140143
spin_unlock(&se_cmd->t_state_lock);
141144
spin_unlock_irqrestore(&se_sess->sess_cmd_lock, flags);
145+
146+
target_put_sess_cmd(se_cmd);
147+
142148
goto out;
143149
}
144150
se_cmd->transport_state |= CMD_T_ABORTED;
145151
spin_unlock(&se_cmd->t_state_lock);
146152

147153
list_del_init(&se_cmd->se_cmd_list);
148-
kref_get(&se_cmd->cmd_kref);
149154
spin_unlock_irqrestore(&se_sess->sess_cmd_lock, flags);
150155

151156
cancel_work_sync(&se_cmd->work);

drivers/target/target_core_transport.c

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2509,23 +2509,24 @@ int target_get_sess_cmd(struct se_cmd *se_cmd, bool ack_kref)
25092509
EXPORT_SYMBOL(target_get_sess_cmd);
25102510

25112511
static void target_release_cmd_kref(struct kref *kref)
2512-
__releases(&se_cmd->se_sess->sess_cmd_lock)
25132512
{
25142513
struct se_cmd *se_cmd = container_of(kref, struct se_cmd, cmd_kref);
25152514
struct se_session *se_sess = se_cmd->se_sess;
2515+
unsigned long flags;
25162516

2517+
spin_lock_irqsave(&se_sess->sess_cmd_lock, flags);
25172518
if (list_empty(&se_cmd->se_cmd_list)) {
2518-
spin_unlock(&se_sess->sess_cmd_lock);
2519+
spin_unlock_irqrestore(&se_sess->sess_cmd_lock, flags);
25192520
se_cmd->se_tfo->release_cmd(se_cmd);
25202521
return;
25212522
}
25222523
if (se_sess->sess_tearing_down && se_cmd->cmd_wait_set) {
2523-
spin_unlock(&se_sess->sess_cmd_lock);
2524+
spin_unlock_irqrestore(&se_sess->sess_cmd_lock, flags);
25242525
complete(&se_cmd->cmd_wait_comp);
25252526
return;
25262527
}
25272528
list_del(&se_cmd->se_cmd_list);
2528-
spin_unlock(&se_sess->sess_cmd_lock);
2529+
spin_unlock_irqrestore(&se_sess->sess_cmd_lock, flags);
25292530

25302531
se_cmd->se_tfo->release_cmd(se_cmd);
25312532
}
@@ -2541,8 +2542,7 @@ int target_put_sess_cmd(struct se_cmd *se_cmd)
25412542
se_cmd->se_tfo->release_cmd(se_cmd);
25422543
return 1;
25432544
}
2544-
return kref_put_spinlock_irqsave(&se_cmd->cmd_kref, target_release_cmd_kref,
2545-
&se_sess->sess_cmd_lock);
2545+
return kref_put(&se_cmd->cmd_kref, target_release_cmd_kref);
25462546
}
25472547
EXPORT_SYMBOL(target_put_sess_cmd);
25482548

0 commit comments

Comments
 (0)