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

iscsi: optimization for read process.



This patch aimed at avoid run out of large rbuf for read commands.

Change-Id: If10f45292da5d5a26c2e338f1ddeafccedb88a4c
Signed-off-by: default avatarCunyin Chang <cunyin.chang@intel.com>
parent dfe5d837
Loading
Loading
Loading
Loading
+6 −9
Original line number Diff line number Diff line
@@ -1093,17 +1093,14 @@ spdk_iscsi_conn_flush_pdus_internal(struct spdk_iscsi_conn *conn)
						  tailq);
			} else {
				if (pdu->task) {
					if (pdu->bhs.opcode == ISCSI_OP_SCSI_DATAIN) {
						if (pdu->task->scsi.offset > 0) {
					if (pdu->bhs.opcode == ISCSI_OP_SCSI_DATAIN &&
					    pdu->task->scsi.length > SPDK_BDEV_SMALL_RBUF_MAX_SIZE) {
						conn->data_in_cnt--;
						if (pdu->bhs.flags & ISCSI_DATAIN_STATUS) {
							spdk_iscsi_task_put(spdk_iscsi_task_get_primary(pdu->task));
						}
						spdk_iscsi_conn_handle_queued_tasks(conn);
					}

						spdk_iscsi_conn_handle_queued_datain(conn);
					}

					spdk_iscsi_task_put(pdu->task);
				}
				spdk_put_pdu(pdu);
+16 −12
Original line number Diff line number Diff line
@@ -2846,15 +2846,21 @@ static void spdk_iscsi_queue_mgmt_task(struct spdk_iscsi_conn *conn,
	spdk_scsi_dev_queue_mgmt_task(conn->dev, &task->scsi);
}

int spdk_iscsi_conn_handle_queued_datain(struct spdk_iscsi_conn *conn)
int spdk_iscsi_conn_handle_queued_tasks(struct spdk_iscsi_conn *conn)
{
	struct spdk_iscsi_task *task;

	while (!TAILQ_EMPTY(&conn->queued_datain_tasks) &&
	       conn->data_in_cnt < MAX_EXTRA_DATAIN_PER_CONNECTION) {
	       conn->data_in_cnt < MAX_LARGE_DATAIN_PER_CONNECTION) {
		task = TAILQ_FIRST(&conn->queued_datain_tasks);
		assert(task->current_datain_offset <= task->scsi.transfer_len);

		if (task->current_datain_offset == 0) {
			task->current_datain_offset = task->scsi.length;
			conn->data_in_cnt++;
			spdk_iscsi_queue_task(conn, task);
			continue;
		}
		if (task->current_datain_offset < task->scsi.transfer_len) {
			struct spdk_iscsi_task *subtask;
			uint32_t remaining_size = 0;
@@ -2879,24 +2885,22 @@ 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)
{
	int32_t remaining_size = 0;

	TAILQ_INIT(&task->scsi.subtask_list);
	task->scsi.dxfer_dir = SPDK_SCSI_DIR_FROM_DEV;
	task->scsi.parent = NULL;
	task->scsi.offset = 0;
	task->scsi.length = DMIN32(SPDK_BDEV_LARGE_RBUF_MAX_SIZE, task->scsi.transfer_len);
	task->scsi.rbuf = NULL;
	spdk_iscsi_queue_task(conn, task);
	task->current_datain_offset = 0;

	remaining_size = task->scsi.transfer_len - task->scsi.length;
	task->current_datain_offset = task->scsi.length;
	if (task->scsi.transfer_len <= SPDK_BDEV_SMALL_RBUF_MAX_SIZE) {
		spdk_iscsi_queue_task(conn, task);
		return 0;
	}

	if (remaining_size > 0) {
	TAILQ_INSERT_TAIL(&conn->queued_datain_tasks, task, link);
		return spdk_iscsi_conn_handle_queued_datain(conn);
	}
	return 0;

	return spdk_iscsi_conn_handle_queued_tasks(conn);
}

static int
+5 −6
Original line number Diff line number Diff line
@@ -107,13 +107,12 @@

/*
 * Defines maximum number of data in buffers each connection can have in
 *  use at any given time.  An "extra data in buffer" means any buffer after
 *  the first for the iSCSI I/O command.  So this limit does not affect I/O
 *  smaller than SPDK_ISCSI_MAX_SEND_DATA_SEGMENT_LENGTH.
 *  use at any given time. So this limit does not affect I/O smaller than
 *  SPDK_BDEV_SMALL_RBUF_MAX_SIZE.
 */
#define MAX_EXTRA_DATAIN_PER_CONNECTION 64
#define MAX_LARGE_DATAIN_PER_CONNECTION 64

#define NUM_PDU_PER_CONNECTION	(2 * (SPDK_ISCSI_MAX_QUEUE_DEPTH + MAX_EXTRA_DATAIN_PER_CONNECTION + 8))
#define NUM_PDU_PER_CONNECTION	(2 * (SPDK_ISCSI_MAX_QUEUE_DEPTH + MAX_LARGE_DATAIN_PER_CONNECTION + 8))

#define SPDK_ISCSI_MAX_BURST_LENGTH	\
		(SPDK_ISCSI_MAX_RECV_DATA_SEGMENT_LENGTH * MAX_DATA_OUT_PER_CONNECTION)
@@ -358,7 +357,7 @@ void process_task_mgmt_completion(spdk_event_t event);
/* Memory management */
void spdk_put_pdu(struct spdk_iscsi_pdu *pdu);
struct spdk_iscsi_pdu *spdk_get_pdu(void);
int spdk_iscsi_conn_handle_queued_datain(struct spdk_iscsi_conn *conn);
int spdk_iscsi_conn_handle_queued_tasks(struct spdk_iscsi_conn *conn);

static inline int
spdk_get_immediate_data_buffer_size(void)