Commit dadbf52d authored by Cunyin Chang's avatar Cunyin Chang Committed by Jim Harris
Browse files

iscsi: optimization for read command.



flush the data in pdu to client if the pdu are ready and sequential.

Change-Id: Idf0ec0c7f6058790a85407dff324900fd36c9527
Signed-off-by: default avatarCunyin Chang <cunyin.chang@intel.com>
parent dafac529
Loading
Loading
Loading
Loading
+45 −20
Original line number Diff line number Diff line
@@ -781,16 +781,43 @@ process_task_mgmt_completion(spdk_event_t event)
	spdk_iscsi_task_put(task);
}

static void
process_completed_read_subtask_list(struct spdk_iscsi_conn *conn,
				    struct spdk_iscsi_task *primary)
{
	struct spdk_scsi_task *tmp;

	while (!TAILQ_EMPTY(&primary->scsi.subtask_list)) {
		tmp = TAILQ_FIRST(&primary->scsi.subtask_list);
		if (tmp->offset == primary->scsi.bytes_completed) {
			TAILQ_REMOVE(&primary->scsi.subtask_list, tmp, scsi_link);
			primary->scsi.bytes_completed += tmp->length;
			spdk_iscsi_task_response(conn, (struct spdk_iscsi_task *)tmp);
			spdk_iscsi_task_put((struct spdk_iscsi_task *)tmp);
		} else {
			break;
		}
	}

}

static void
process_read_task_completion(struct spdk_iscsi_conn *conn,
			     struct spdk_iscsi_task *task)
{
	struct spdk_iscsi_task *primary;
	struct spdk_scsi_task *tmp, *tmp1;
	struct spdk_scsi_task *tmp;
	bool flag = false;

	primary = spdk_iscsi_task_get_primary(task);
	if (task != primary) {
		if (task->scsi.offset == primary->scsi.bytes_completed) {
			primary->scsi.bytes_completed += task->scsi.length;
			spdk_iscsi_task_response(conn, task);
			spdk_iscsi_task_put(task);
			process_completed_read_subtask_list(conn, primary);
			return;
		}
		TAILQ_FOREACH(tmp, &primary->scsi.subtask_list, scsi_link) {
			if (task->scsi.offset < tmp->offset) {
				TAILQ_INSERT_BEFORE(tmp, &task->scsi, scsi_link);
@@ -798,22 +825,13 @@ process_read_task_completion(struct spdk_iscsi_conn *conn,
				break;
			}
		}
		if (!flag)
		if (!flag) {
			TAILQ_INSERT_TAIL(&primary->scsi.subtask_list, &task->scsi, scsi_link);
		}

	if (primary->scsi.bytes_completed != primary->scsi.transfer_len)
		return;

	/* reset this value to 0 */
	primary->scsi.bytes_completed = 0;
	} else {
		primary->scsi.bytes_completed += primary->scsi.length;
		spdk_iscsi_task_response(conn, primary);
	spdk_iscsi_task_put(primary);

	TAILQ_FOREACH_SAFE(tmp, &primary->scsi.subtask_list, scsi_link, tmp1) {
		TAILQ_REMOVE(&primary->scsi.subtask_list, tmp, scsi_link);
		spdk_iscsi_task_response(conn, (struct spdk_iscsi_task *)tmp);
		spdk_iscsi_task_put((struct spdk_iscsi_task *)tmp);
		process_completed_read_subtask_list(conn, primary);
	}
}

@@ -828,13 +846,12 @@ void process_task_completion(spdk_event_t event)
	conn->last_activity_tsc = rte_get_timer_cycles();

	primary = spdk_iscsi_task_get_primary(task);
	primary->scsi.bytes_completed += task->scsi.length;

	if (spdk_iscsi_task_is_read(primary)) {
		process_read_task_completion(conn, task);
		return;
	} else {

		primary->scsi.bytes_completed += task->scsi.length;
		if (task->scsi.parent != NULL && task->scsi.status != SPDK_SCSI_STATUS_GOOD) {
			memcpy(primary->scsi.sense_data, task->scsi.sense_data,
			       task->scsi.sense_data_len);
@@ -1016,8 +1033,16 @@ spdk_iscsi_conn_flush_pdus_internal(struct spdk_iscsi_conn *conn)
						  tailq);
			} else {
				if (pdu->task) {
					if (pdu->bhs.opcode == ISCSI_OP_SCSI_DATAIN && pdu->task->scsi.offset > 0) {
					if (pdu->bhs.opcode == ISCSI_OP_SCSI_DATAIN) {
						struct spdk_iscsi_task *primary;

						primary = spdk_iscsi_task_get_primary(pdu->task);
						if (pdu->task->scsi.offset > 0) {
							conn->data_in_cnt--;
						}
						if (pdu->bhs.flags & ISCSI_DATAIN_STATUS) {
							spdk_iscsi_task_put(primary);
						}
						spdk_iscsi_conn_handle_queued_datain(conn);
					}
					spdk_iscsi_task_put(pdu->task);
+0 −25
Original line number Diff line number Diff line
@@ -2846,19 +2846,6 @@ static void spdk_iscsi_queue_mgmt_task(struct spdk_iscsi_conn *conn,
	spdk_scsi_dev_queue_mgmt_task(conn->dev, &task->scsi);
}

static int spdk_iscsi_get_extra_data_in_count(struct spdk_iscsi_task *task)
{
	uint32_t transfer_len;
	size_t segment_len;
	int data_in_req = 0;

	transfer_len = task->scsi.transfer_len;
	segment_len = g_spdk_iscsi.MaxRecvDataSegmentLength;
	if (transfer_len)
		data_in_req = (transfer_len - 1) / segment_len;
	return data_in_req;
}

int spdk_iscsi_conn_handle_queued_datain(struct spdk_iscsi_conn *conn)
{
	struct spdk_iscsi_task *task;
@@ -2892,19 +2879,8 @@ int spdk_iscsi_conn_handle_queued_datain(struct spdk_iscsi_conn *conn)
static int spdk_iscsi_op_scsi_read(struct spdk_iscsi_conn *conn,
				   struct spdk_iscsi_task *task)
{
	int extra_data_in_count;
	int32_t remaining_size = 0;

	extra_data_in_count = spdk_iscsi_get_extra_data_in_count(task);
	if (extra_data_in_count > MAX_EXTRA_DATAIN_PER_CONNECTION) {
		SPDK_ERRLOG("Unsupported read size\n");
		spdk_scsi_task_set_check_condition(&task->scsi, SPDK_SCSI_SENSE_ILLEGAL_REQUEST, 0x25, 0x00);
		task->scsi.bytes_completed = task->scsi.transfer_len;
		spdk_iscsi_task_response(conn, task);
		spdk_iscsi_task_put(task);
		return 0;
	}

	TAILQ_INIT(&task->scsi.subtask_list);
	task->scsi.dxfer_dir = SPDK_SCSI_DIR_FROM_DEV;
	task->scsi.parent = NULL;
@@ -3134,7 +3110,6 @@ void spdk_iscsi_task_response(struct spdk_iscsi_conn *conn,
	/* transfer data from logical unit */
	/* (direction is view of initiator side) */
	if (spdk_iscsi_task_is_read(primary)) {
		primary->scsi.bytes_completed += task->scsi.length;
		if ((task->scsi.status == SPDK_SCSI_STATUS_GOOD) ||
		    (task->scsi.sense_data_len != 0)) {
			rc = spdk_iscsi_transfer_in(conn, task);