Commit 59a1fbe9 authored by Jim Harris's avatar Jim Harris Committed by Changpeng Liu
Browse files

iscsi: fix hang on high QD large reads



We throttle the number of data_in operations per
connection.  Currently after a read is completed,
we try to send more data_in operations since one
has just been completed.

But we are trying to send more too early.  The data_in_cnt
doesn't actually get decremented until after the PDU is
written on the socket.  So this results in a case
where data_in_cnt == 64, and all 64 read operations
complete before any of those 64 are actually transmitted
onto the TCP socket.  There are no more read operations
waiting, so we won't try to handle the data_in list
again, and if none of these 64 resulted in a SCSI
command completing, then the initiator may not send us
any more read I/O which would have also kicked the data_in
list.

So the solution is to kick the data_in list after the
PDU has been written - not after a read I/O is completed
back from the SCSI layer.

Signed-off-by: default avatarJim Harris <james.r.harris@intel.com>
Change-Id: Ia01cf96e8eb6e08ddcaaeff449386e78de7c5bc5

Reviewed-on: https://review.gerrithub.io/c/spdk/spdk/+/455454


Tested-by: default avatarSPDK CI Jenkins <sys_sgci@intel.com>
Reviewed-by: default avatarBen Walker <benjamin.walker@intel.com>
Reviewed-by: default avatarShuhei Matsumoto <shuhei.matsumoto.xt@hitachi.com>
Reviewed-by: default avatarGangCao <gang.cao@intel.com>
Reviewed-by: default avatarChangpeng Liu <changpeng.liu@intel.com>
parent 462c12d9
Loading
Loading
Loading
Loading
+1 −2
Original line number Diff line number Diff line
@@ -314,6 +314,7 @@ spdk_iscsi_conn_free_pdu(struct spdk_iscsi_conn *conn, struct spdk_iscsi_pdu *pd
					conn->data_in_cnt--;
					spdk_iscsi_task_put(spdk_iscsi_task_get_primary(pdu->task));
				}
				spdk_iscsi_conn_handle_queued_datain_tasks(conn);
			}
		} else if (pdu->bhs.opcode == ISCSI_OP_SCSI_RSP &&
			   pdu->task->scsi.status != SPDK_SCSI_STATUS_GOOD) {
@@ -1012,8 +1013,6 @@ process_read_task_completion(struct spdk_iscsi_conn *conn,
		spdk_iscsi_task_put(task);
	}
	process_completed_read_subtask_list(conn, primary);

	spdk_iscsi_conn_handle_queued_datain_tasks(conn);
}

void