Do not accept new sessions after core_tpg_del_initiator_node_acl() has set acl_stop. Ensure that core_tpg_del_initiator_node_acl() waits until all sessions have dropped their reference on the associated struct se_node_acl object by removing the sess_tearing_down test. Modify all target drivers such that these test the return value of transport_register_session(). This patch avoids that e.g. stopping the ib_srpt driver can hang as follows: INFO: task rmdir:4473 blocked for more than 120 seconds. rmdir Call Trace: [<ffffffff81517132>] schedule+0x42/0x90 [<ffffffff8151b27f>] schedule_timeout+0x17f/0x1d0 [<ffffffff815181b5>] wait_for_completion+0xe5/0x120 [<ffffffffa04aa401>] core_tpg_del_initiator_node_acl+0x171/0x220 [target_core_mod] [<ffffffffa049dcaf>] target_fabric_nacl_base_release+0x4f/0x60 [target_core_mod] [<ffffffffa0482bef>] config_item_release+0x6f/0xc0 [configfs] [<ffffffffa0482c5b>] config_item_put+0x1b/0x20 [configfs] [<ffffffffa0481f88>] configfs_rmdir+0x1e8/0x2e0 [configfs] [<ffffffff81183461>] vfs_rmdir+0x81/0x120 [<ffffffff81187246>] do_rmdir+0x146/0x190 [<ffffffff811872d1>] SyS_rmdir+0x11/0x20 [<ffffffff8151c857>] entry_SYSCALL_64_fastpath+0x12/0x6f Signed-off-by: Bart Van Assche <bart.vanassche@xxxxxxxxxxx> Cc: Andy Grover <agrover@xxxxxxxxxx> Cc: Christoph Hellwig <hch@xxxxxx> Cc: Sagi Grimberg <sagig@xxxxxxxxxxxx> --- drivers/target/target_core_tpg.c | 3 --- drivers/target/target_core_transport.c | 32 +++++++++++++++++++++++--------- 2 files changed, 23 insertions(+), 12 deletions(-) diff --git a/drivers/target/target_core_tpg.c b/drivers/target/target_core_tpg.c index 62103a8..ef99cc7 100644 --- a/drivers/target/target_core_tpg.c +++ b/drivers/target/target_core_tpg.c @@ -324,9 +324,6 @@ void core_tpg_del_initiator_node_acl(struct se_node_acl *acl) list_for_each_entry_safe(sess, sess_tmp, &acl->acl_sess_list, sess_acl_list) { - if (sess->sess_tearing_down != 0) - continue; - target_get_session(sess); list_move(&sess->sess_acl_list, &sess_list); } diff --git a/drivers/target/target_core_transport.c b/drivers/target/target_core_transport.c index 1b5525f..8e1bf50 100644 --- a/drivers/target/target_core_transport.c +++ b/drivers/target/target_core_transport.c @@ -332,14 +332,22 @@ static int __transport_register_session_with_nacl(struct se_node_acl *se_nacl, kref_get(&se_nacl->acl_kref); spin_lock_irq(&se_nacl->nacl_sess_lock); - /* - * The se_nacl->nacl_sess pointer will be set to the - * last active I_T Nexus for each struct se_node_acl. - */ - se_nacl->nacl_sess = se_sess; - list_add_tail(&se_sess->sess_acl_list, &se_nacl->acl_sess_list); + if (!se_nacl->acl_stop) { + /* + * The se_nacl->nacl_sess pointer will be set to the + * last active I_T Nexus for each struct se_node_acl. + */ + se_nacl->nacl_sess = se_sess; + list_add_tail(&se_sess->sess_acl_list, + &se_nacl->acl_sess_list); + } else { + ret = -ENOENT; + } spin_unlock_irq(&se_nacl->nacl_sess_lock); + if (ret < 0) + target_put_nacl(se_nacl); + return ret; } @@ -362,12 +370,17 @@ int __transport_register_session(struct se_portal_group *se_tpg, * eg: *NOT* discovery sessions. */ if (se_nacl) - __transport_register_session_with_nacl(se_nacl, se_sess); + ret = __transport_register_session_with_nacl(se_nacl, se_sess); + + if (ret < 0) + goto out; + list_add_tail(&se_sess->sess_list, &se_tpg->tpg_sess_list); pr_debug("TARGET_CORE[%s]: Registered fabric_sess_ptr: %p\n", se_tpg->se_tpg_tfo->get_fabric_name(), se_sess->fabric_sess_ptr); +out: return ret; } EXPORT_SYMBOL(__transport_register_session); @@ -378,10 +391,11 @@ int transport_register_session(struct se_portal_group *se_tpg, void *fabric_sess_ptr) { unsigned long flags; - int ret = 0; + int ret; spin_lock_irqsave(&se_tpg->session_lock, flags); - __transport_register_session(se_tpg, se_nacl, se_sess, fabric_sess_ptr); + ret = __transport_register_session(se_tpg, se_nacl, se_sess, + fabric_sess_ptr); spin_unlock_irqrestore(&se_tpg->session_lock, flags); return ret; -- 2.1.4 -- To unsubscribe from this list: send the line "unsubscribe target-devel" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html