Several SCSI transport protocols require that SCSI task management functions are processed in the order in which these have been submitted by the initiator system. Hence introduce a workqueue per session for TMF processing. Do not specify WQ_MEM_RECLAIM since only the tcm_loop driver can queue TMF work from inside the memory allocation path and since the tcm_loop driver is only used to debug the SCSI target code. Signed-off-by: Bart Van Assche <bart.vanassche@xxxxxxxxxxx> --- Changes compared to v2 for this patch: test se_sess->tmf_wq before calling destroy_workqueue(). --- drivers/target/target_core_transport.c | 13 ++++++++++++- include/target/target_core_base.h | 1 + 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/drivers/target/target_core_transport.c b/drivers/target/target_core_transport.c index ab4051fbab95..59aa31983303 100644 --- a/drivers/target/target_core_transport.c +++ b/drivers/target/target_core_transport.c @@ -267,9 +267,18 @@ int transport_alloc_session_tags(struct se_session *se_sess, goto free_cmd_map; } + se_sess->tmf_wq = alloc_workqueue("tmf-%p", WQ_UNBOUND, 1, se_sess); + if (!se_sess->tmf_wq) { + pr_err("%s: workqueue allocation failed\n", __func__); + goto free_tag_pool; + } + out: return rc; +free_tag_pool: + percpu_ida_destroy(&se_sess->sess_tag_pool); + free_cmd_map: kvfree(se_sess->sess_cmd_map); se_sess->sess_cmd_map = NULL; @@ -511,6 +520,8 @@ void transport_free_session(struct se_session *se_sess) se_sess->se_node_acl = NULL; target_put_nacl(se_nacl); } + if (se_sess->tmf_wq) + destroy_workqueue(se_sess->tmf_wq); if (se_sess->sess_cmd_map) { percpu_ida_destroy(&se_sess->sess_tag_pool); kvfree(se_sess->sess_cmd_map); @@ -3133,7 +3144,7 @@ int transport_generic_handle_tmr( spin_unlock_irqrestore(&cmd->t_state_lock, flags); INIT_WORK(&cmd->work, target_tmr_work); - queue_work(cmd->se_dev->tmr_wq, &cmd->work); + queue_work(cmd->se_sess->tmf_wq, &cmd->work); return 0; } EXPORT_SYMBOL(transport_generic_handle_tmr); diff --git a/include/target/target_core_base.h b/include/target/target_core_base.h index c9aada11a30c..f6e5fb22f338 100644 --- a/include/target/target_core_base.h +++ b/include/target/target_core_base.h @@ -606,6 +606,7 @@ struct se_session { spinlock_t sess_cmd_lock; void *sess_cmd_map; struct percpu_ida sess_tag_pool; + struct workqueue_struct *tmf_wq; }; struct se_device; -- 2.11.0 -- 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