tcm_fc: Wait for command completion before freeing a session
This patch avoids that the following kernel crash can occur with later patches in this patch series: general protection fault: 0000 [#1] SMP CPU: 0 PID: 6 Comm: kworker/u8:0 Not tainted 4.3.0-rc1-debug+ #1 Workqueue: tmr-fileio target_tmr_work [target_core_mod] Call Trace: [<ffffffff810a6915>] lock_acquire+0x65/0x90 [<ffffffff815e740b>] _raw_spin_lock_irqsave+0x4b/0x60 [<ffffffffa03bc7ca>] target_release_cmd_kref+0x2a/0xa0 [target_core_mod] [<ffffffffa03bd418>] target_put_sess_cmd+0x28/0x50 [target_core_mod] [<ffffffffa03bad50>] core_tmr_lun_reset+0x390/0x640 [target_core_mod] [<ffffffffa03bce50>] target_tmr_work+0x80/0xd0 [target_core_mod] [<ffffffff81070e6d>] process_one_work+0x19d/0x430 [<ffffffff8107120f>] worker_thread+0x10f/0x460 [<ffffffff810772ba>] kthread+0xea/0x100 [<ffffffff815e7a2f>] ret_from_fork+0x3f/0x70 Signed-off-by: Bart Van Assche <bart.vanassche@sandisk.com> Cc: Christoph Hellwig <hch@lst.de> Cc: Andy Grover <agrover@redhat.com> Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org>
This commit is contained in:
parent
f0a8afecb2
commit
de7ee9a20c
|
@ -260,6 +260,14 @@ static struct ft_sess *ft_sess_delete(struct ft_tport *tport, u32 port_id)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
static void ft_close_sess(struct ft_sess *sess)
|
||||
{
|
||||
transport_deregister_session_configfs(sess->se_sess);
|
||||
target_sess_cmd_list_set_waiting(sess->se_sess);
|
||||
target_wait_for_sess_cmds(sess->se_sess);
|
||||
ft_sess_put(sess);
|
||||
}
|
||||
|
||||
/*
|
||||
* Delete all sessions from tport.
|
||||
* Caller holds ft_lport_lock.
|
||||
|
@ -273,8 +281,7 @@ static void ft_sess_delete_all(struct ft_tport *tport)
|
|||
head < &tport->hash[FT_SESS_HASH_SIZE]; head++) {
|
||||
hlist_for_each_entry_rcu(sess, head, hash) {
|
||||
ft_sess_unhash(sess);
|
||||
transport_deregister_session_configfs(sess->se_sess);
|
||||
ft_sess_put(sess); /* release from table */
|
||||
ft_close_sess(sess); /* release from table */
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -313,8 +320,7 @@ void ft_sess_close(struct se_session *se_sess)
|
|||
pr_debug("port_id %x\n", port_id);
|
||||
ft_sess_unhash(sess);
|
||||
mutex_unlock(&ft_lport_lock);
|
||||
transport_deregister_session_configfs(se_sess);
|
||||
ft_sess_put(sess);
|
||||
ft_close_sess(sess);
|
||||
/* XXX Send LOGO or PRLO */
|
||||
synchronize_rcu(); /* let transport deregister happen */
|
||||
}
|
||||
|
@ -460,8 +466,7 @@ static void ft_prlo(struct fc_rport_priv *rdata)
|
|||
return;
|
||||
}
|
||||
mutex_unlock(&ft_lport_lock);
|
||||
transport_deregister_session_configfs(sess->se_sess);
|
||||
ft_sess_put(sess); /* release from table */
|
||||
ft_close_sess(sess); /* release from table */
|
||||
rdata->prli_count--;
|
||||
/* XXX TBD - clearing actions. unit attn, see 4.10 */
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue