Commit 35e0e757 authored by Christoph Hellwig's avatar Christoph Hellwig Committed by Nicholas Bellinger

target: use a workqueue for I/O completions

Instead of abusing the target processing thread for offloading I/O
completion in the backends to user context add a new workqueue.  This means
completions can be processed as fast as available CPU time allows it,
including in parallel with other completions and more importantly I/O
submission or QUEUE FULL retries.  This should give much better performance
especially on loaded systems.

As a fallout we can merge all the completed states into a single
one.

On the downside this change complicates lun reset handling a bit by
requiring us to cancel a work item only for those states that have it
initialized.  The alternative would be to either always initialize the work
item to a dummy handler, or always use the same handler and do a switch on
the state. The long term solution will be a flag that says that the command
has an initialized work item, but that's only going to be useful once we
have more users.
Signed-off-by: default avatarChristoph Hellwig <hch@lst.de>
Signed-off-by: default avatarNicholas Bellinger <nab@linux-iscsi.org>
parent 59aaad1e
...@@ -255,6 +255,16 @@ static void core_tmr_drain_task_list( ...@@ -255,6 +255,16 @@ static void core_tmr_drain_task_list(
atomic_read(&cmd->t_transport_stop), atomic_read(&cmd->t_transport_stop),
atomic_read(&cmd->t_transport_sent)); atomic_read(&cmd->t_transport_sent));
/*
* If the command may be queued onto a workqueue cancel it now.
*
* This is equivalent to removal from the execute queue in the
* loop above, but we do it down here given that
* cancel_work_sync may block.
*/
if (cmd->t_state == TRANSPORT_COMPLETE)
cancel_work_sync(&cmd->work);
spin_lock_irqsave(&cmd->t_state_lock, flags); spin_lock_irqsave(&cmd->t_state_lock, flags);
target_stop_task(task, &flags); target_stop_task(task, &flags);
......
This diff is collapsed.
...@@ -86,9 +86,7 @@ enum transport_state_table { ...@@ -86,9 +86,7 @@ enum transport_state_table {
TRANSPORT_WRITE_PENDING = 3, TRANSPORT_WRITE_PENDING = 3,
TRANSPORT_PROCESS_WRITE = 4, TRANSPORT_PROCESS_WRITE = 4,
TRANSPORT_PROCESSING = 5, TRANSPORT_PROCESSING = 5,
TRANSPORT_COMPLETE_OK = 6, TRANSPORT_COMPLETE = 6,
TRANSPORT_COMPLETE_FAILURE = 7,
TRANSPORT_COMPLETE_TIMEOUT = 8,
TRANSPORT_PROCESS_TMR = 9, TRANSPORT_PROCESS_TMR = 9,
TRANSPORT_ISTATE_PROCESSING = 11, TRANSPORT_ISTATE_PROCESSING = 11,
TRANSPORT_NEW_CMD_MAP = 16, TRANSPORT_NEW_CMD_MAP = 16,
...@@ -492,6 +490,8 @@ struct se_cmd { ...@@ -492,6 +490,8 @@ struct se_cmd {
struct completion transport_lun_stop_comp; struct completion transport_lun_stop_comp;
struct scatterlist *t_tasks_sg_chained; struct scatterlist *t_tasks_sg_chained;
struct work_struct work;
/* /*
* Used for pre-registered fabric SGL passthrough WRITE and READ * Used for pre-registered fabric SGL passthrough WRITE and READ
* with the special SCF_PASSTHROUGH_CONTIG_TO_SG case for TCM_Loop * with the special SCF_PASSTHROUGH_CONTIG_TO_SG case for TCM_Loop
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment