Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit fd3a9025 authored by Nicholas Bellinger's avatar Nicholas Bellinger
Browse files

iscsi-target: Fix immediate queue starvation regression with DATAIN



This patch addresses a v3.5+ regression in iscsi-target where TX thread
process context -> handle_response_queue() execution is allowed to run
unbounded while servicing constant outgoing flow of ISTATE_SEND_DATAIN
response state.

This ends up preventing memory release of StatSN acknowledged commands
in a timely manner when under heavy large block streaming DATAIN
workloads.

The regression bug was initially introduced with:

commit 6f3c0e69
Author: Andy Grover <agrover@redhat.com>
Date:   Tue Apr 3 15:51:09 2012 -0700

    target/iscsi: Refactor target_tx_thread immediate+response queue loops

Go ahead and follow original iscsi_target_tx_thread() logic and check
to break for immediate queue processing after each DataIN Sequence and/or
Response PDU has been sent.

Reported-by: default avatarBenjamin ESTRABAUD <be@mpstor.com>
Cc: Andy Grover <agrover@redhat.com>
Cc: <stable@vger.kernel.org>
Signed-off-by: default avatarNicholas Bellinger <nab@linux-iscsi.org>
parent 972b29c8
Loading
Loading
Loading
Loading
+9 −2
Original line number Diff line number Diff line
@@ -3583,6 +3583,10 @@ static int handle_response_queue(struct iscsi_conn *conn)
				spin_lock_bh(&cmd->istate_lock);
				cmd->i_state = ISTATE_SENT_STATUS;
				spin_unlock_bh(&cmd->istate_lock);

				if (atomic_read(&conn->check_immediate_queue))
					return 1;

				continue;
			} else if (ret == 2) {
				/* Still must send status,
@@ -3672,7 +3676,7 @@ static int handle_response_queue(struct iscsi_conn *conn)
		}

		if (atomic_read(&conn->check_immediate_queue))
			break;
			return 1;
	}

	return 0;
@@ -3716,12 +3720,15 @@ int iscsi_target_tx_thread(void *arg)
		     signal_pending(current))
			goto transport_err;

get_immediate:
		ret = handle_immediate_queue(conn);
		if (ret < 0)
			goto transport_err;

		ret = handle_response_queue(conn);
		if (ret == -EAGAIN)
		if (ret == 1)
			goto get_immediate;
		else if (ret == -EAGAIN)
			goto restart;
		else if (ret < 0)
			goto transport_err;