SCSI target development
 help / color / mirror / Atom feed
From: Dmitry Bogdanov <d.bogdanov@yadro.com>
To: Maurizio Lombardi <mlombard@redhat.com>
Cc: <martin.petersen@oracle.com>, <mlombard@arkamax.eu>,
	<michael.christie@oracle.com>, <target-devel@vger.kernel.org>,
	<loberman@redhat.com>
Subject: Re: [PATCH 1/1] target: iscsi: Fix hang for aborted WRITE_PENDING commands
Date: Thu, 27 Aug 2026 12:33:01 +0300	[thread overview]
Message-ID: <20260827093301.GA2638@yadro.com> (raw)
In-Reply-To: <20260717143828.76291-2-mlombard@redhat.com>

[-- Attachment #1: Type: text/plain, Size: 2359 bytes --]


On Fri, Jul 17, 2026 at 04:38:28PM +0200, Maurizio Lombardi wrote:
> 
> When a LUN_RESET aborts a WRITE command that is in the
> TRANSPORT_WRITE_PENDING state, the target core sets CMD_T_ABORTED and waits
> for the frontend to finish processing.
> 
> If the initiator subsequently sends the remaining dataout PDUs,
> __iscsit_check_dataout_hdr() catches the payload, stops the dataout timer
> if the sequence is final and finally dumps the data.
> However, the iSCSI target doesn't trigger the completion process for these
> aborted commands. Because of this, the abort path hangs indefinitely in
> target_put_cmd_and_wait(), leading to a deadlocked target worker thread.
> 
> Fix this by explicitly calling target_complete_cmd() when the final dataout
> PDU is received for an aborted WRITE command. target_complete_cmd() detects
> the CMD_T_ABORTED flag and cleanly routes the command into target_abort_work,
> allowing the abort completion to successfully unblock.
> 
> Signed-off-by: Maurizio Lombardi <mlombard@redhat.com>
> ---
>  drivers/target/iscsi/iscsi_target.c | 4 +++-
>  1 file changed, 3 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/target/iscsi/iscsi_target.c b/drivers/target/iscsi/iscsi_target.c
> index 62ada3a52210..124ff269b8e7 100644
> --- a/drivers/target/iscsi/iscsi_target.c
> +++ b/drivers/target/iscsi/iscsi_target.c
> @@ -1533,8 +1533,10 @@ __iscsit_check_dataout_hdr(struct iscsit_conn *conn, void *buf,
>                  */
>                 if (se_cmd->transport_state & CMD_T_ABORTED) {
>                         if (hdr->flags & ISCSI_FLAG_CMD_FINAL &&
> -                           --cmd->outstanding_r2ts < 1)
> +                           --cmd->outstanding_r2ts < 1) {
>                                 iscsit_stop_dataout_timer(cmd);
> +                               target_complete_cmd(se_cmd, SAM_STAT_TASK_ABORTED);
> +                       }
> 
>                         return iscsit_dump_data_payload(conn, payload_length, 1);
>                 }
> --
> 2.55.0
> 

Hi Maurizio,

We also faced that bug several years ago. We solved it by removing all
leftovers of hanling of aborted commands in iscsi, because the handling
of aborted commands moved to target core an age ago. iSCSI will collect
data as usual and pass the command to target core, it in its turns will
abort the command.


BR,
 Dmitry



[-- Attachment #2: 0001-scsi-target-iscsi-fix-hanging-WRITE_PENDING-commands.patch --]
[-- Type: text/x-diff, Size: 3098 bytes --]

From d46bae4973c3467a999818b7a7154109de8facc1 Mon Sep 17 00:00:00 2001
From: Dmitry Bogdanov <d.bogdanov@yadro.com>
Date: Wed, 26 Jun 2024 14:30:34 +0300
Subject: [PATCH] scsi: target: iscsi: fix hanging WRITE_PENDING commands

When Data comes for an aborted WRITE command in WRITE_PENDING state it
is silently received and the command does not pass to the target. That leads
to hanging of other session with LUN_RESET aborting that command.

Pass the aborted WRITE commands when all Data has been gathered.

Signed-off-by: Dmitry Bogdanov <d.bogdanov@yadro.com>
Signed-off-by: Sergey Samoylenko <s.samoylenko@yadro.com>
---
 drivers/target/iscsi/iscsi_target.c      | 17 -----------------
 drivers/target/iscsi/iscsi_target_erl1.c |  8 --------
 2 files changed, 25 deletions(-)

diff --git a/drivers/target/iscsi/iscsi_target.c b/drivers/target/iscsi/iscsi_target.c
index d1887337e..a18fe1c74 100644
--- a/drivers/target/iscsi/iscsi_target.c
+++ b/drivers/target/iscsi/iscsi_target.c
@@ -1536,23 +1536,6 @@ __iscsit_check_dataout_hdr(struct iscsit_conn *conn, void *buf,
 			if (hdr->flags & ISCSI_FLAG_CMD_FINAL)
 				iscsit_stop_dataout_timer(cmd);
 
-			return iscsit_dump_data_payload(conn, payload_length, 1);
-		}
-	} else {
-		/*
-		 * For the normal solicited data path:
-		 *
-		 * Check for a delayed TASK_ABORTED status and dump any
-		 * incoming data out payload if one exists.  Also, when the
-		 * ISCSI_FLAG_CMD_FINAL is set to denote the end of the current
-		 * data out sequence, we decrement outstanding_r2ts.  Once
-		 * outstanding_r2ts reaches zero, go ahead and send the delayed
-		 * TASK_ABORTED status.
-		 */
-		if (se_cmd->transport_state & CMD_T_ABORTED) {
-			if (hdr->flags & ISCSI_FLAG_CMD_FINAL &&
-			    --cmd->outstanding_r2ts < 1)
-				iscsit_stop_dataout_timer(cmd);
 
 			return iscsit_dump_data_payload(conn, payload_length, 1);
 		}
diff --git a/drivers/target/iscsi/iscsi_target_erl1.c b/drivers/target/iscsi/iscsi_target_erl1.c
index 2e69632b3..6e8a0b41f 100644
--- a/drivers/target/iscsi/iscsi_target_erl1.c
+++ b/drivers/target/iscsi/iscsi_target_erl1.c
@@ -892,8 +892,6 @@ int iscsit_execute_cmd(struct iscsit_cmd *cmd, int ooo)
 				return 0;
 			}
 			spin_unlock_bh(&cmd->istate_lock);
-			if (cmd->se_cmd.transport_state & CMD_T_ABORTED)
-				return 0;
 			return transport_send_check_condition_and_sense(se_cmd,
 					cmd->sense_reason, 0);
 		}
@@ -911,9 +909,6 @@ int iscsit_execute_cmd(struct iscsit_cmd *cmd, int ooo)
 
 			if (!(cmd->cmd_flags &
 					ICF_NON_IMMEDIATE_UNSOLICITED_DATA)) {
-				if (cmd->se_cmd.transport_state & CMD_T_ABORTED)
-					return 0;
-
 				iscsit_set_dataout_sequence_values(cmd);
 				conn->conn_transport->iscsit_get_dataout(conn, cmd, false);
 			}
@@ -926,9 +921,6 @@ int iscsit_execute_cmd(struct iscsit_cmd *cmd, int ooo)
 
 		if ((cmd->data_direction == DMA_TO_DEVICE) &&
 		    !(cmd->cmd_flags & ICF_NON_IMMEDIATE_UNSOLICITED_DATA)) {
-			if (cmd->se_cmd.transport_state & CMD_T_ABORTED)
-				return 0;
-
 			iscsit_set_unsolicited_dataout(cmd);
 		}
 		return target_submit(&cmd->se_cmd);
-- 
2.25.1


  parent reply	other threads:[~2026-08-27  9:42 UTC|newest]

Thread overview: 9+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-07-17 14:38 [PATCH 0/1] Write commands abort hang Maurizio Lombardi
2026-07-17 14:38 ` [PATCH 1/1] target: iscsi: Fix hang for aborted WRITE_PENDING commands Maurizio Lombardi
2026-07-17 15:08   ` Laurence Oberman
2026-07-17 16:38   ` Bart Van Assche
2026-07-20 12:41     ` Maurizio Lombardi
2026-08-27  9:33   ` Dmitry Bogdanov [this message]
2026-08-27 10:37     ` Maurizio Lombardi
2026-08-29  2:19   ` Martin K. Petersen (Oracle)
2026-08-27  7:30 ` [PATCH 0/1] Write commands abort hang Maurizio Lombardi

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20260827093301.GA2638@yadro.com \
    --to=d.bogdanov@yadro.com \
    --cc=loberman@redhat.com \
    --cc=martin.petersen@oracle.com \
    --cc=michael.christie@oracle.com \
    --cc=mlombard@arkamax.eu \
    --cc=mlombard@redhat.com \
    --cc=target-devel@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox