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: Cunyin Chang <cunyin.chang@intel.com>
This commit is contained in:
parent
dafac529a6
commit
dadbf52dda
@ -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;
|
||||
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);
|
||||
}
|
||||
} else {
|
||||
primary->scsi.bytes_completed += primary->scsi.length;
|
||||
spdk_iscsi_task_response(conn, primary);
|
||||
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) {
|
||||
conn->data_in_cnt--;
|
||||
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);
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user