iscsi: fix big READ task release process for ERL1

When we enabled the ERL1 configuation, for the DATAIN task release
process, we will queue the task to the SNACK list firstly, and then
remove the list when got ACK from initiator, but for this part of
logic, the reference count of primary task was not released correctly.

Change-Id: Ic5959cf644c74f676be0b84c5650292dc426b2d8
Signed-off-by: Changpeng Liu <changpeng.liu@intel.com>
This commit is contained in:
Changpeng Liu 2016-12-07 13:02:40 +08:00 committed by Daniel Verkamp
parent 8c119920c9
commit 144065f30c
4 changed files with 29 additions and 19 deletions

View File

@ -413,6 +413,26 @@ error_return:
return 0;
}
void
spdk_iscsi_conn_free_pdu(struct spdk_iscsi_conn *conn, struct spdk_iscsi_pdu *pdu)
{
if (pdu->task) {
if (pdu->bhs.opcode == ISCSI_OP_SCSI_DATAIN) {
if (pdu->task->scsi.offset > 0) {
conn->data_in_cnt--;
if (pdu->bhs.flags & ISCSI_DATAIN_STATUS) {
/* Free the primary task after the last subtask done */
conn->data_in_cnt--;
spdk_iscsi_task_put(spdk_iscsi_task_get_primary(pdu->task));
}
spdk_iscsi_conn_handle_queued_tasks(conn);
}
}
spdk_iscsi_task_put(pdu->task);
}
spdk_put_pdu(pdu);
}
static int spdk_iscsi_conn_free_tasks(struct spdk_iscsi_conn *conn)
{
struct spdk_iscsi_pdu *pdu;
@ -1102,21 +1122,7 @@ spdk_iscsi_conn_flush_pdus_internal(struct spdk_iscsi_conn *conn)
TAILQ_INSERT_TAIL(&conn->snack_pdu_list, pdu,
tailq);
} else {
if (pdu->task) {
if (pdu->bhs.opcode == ISCSI_OP_SCSI_DATAIN) {
if (pdu->task->scsi.offset > 0) {
conn->data_in_cnt--;
if (pdu->bhs.flags & ISCSI_DATAIN_STATUS) {
/* Free the primary task after the last subtask done */
conn->data_in_cnt--;
spdk_iscsi_task_put(spdk_iscsi_task_get_primary(pdu->task));
}
spdk_iscsi_conn_handle_queued_tasks(conn);
}
}
spdk_iscsi_task_put(pdu->task);
}
spdk_put_pdu(pdu);
spdk_iscsi_conn_free_pdu(conn, pdu);
}
pdu = TAILQ_FIRST(&conn->write_pdu_list);

View File

@ -176,4 +176,6 @@ void spdk_iscsi_set_min_conn_idle_interval(int interval_in_us);
int spdk_iscsi_conn_read_data(struct spdk_iscsi_conn *conn, int len,
void *buf);
void spdk_iscsi_conn_free_pdu(struct spdk_iscsi_conn *conn, struct spdk_iscsi_pdu *pdu);
#endif /* SPDK_ISCSI_CONN_H */

View File

@ -3992,10 +3992,7 @@ spdk_remove_acked_pdu(struct spdk_iscsi_conn *conn,
stat_sn = from_be32(&pdu->bhs.stat_sn);
if (SN32_LT(stat_sn, conn->exp_statsn)) {
TAILQ_REMOVE(&conn->snack_pdu_list, pdu, tailq);
if (pdu->task) {
spdk_iscsi_task_put(pdu->task);
}
spdk_put_pdu(pdu);
spdk_iscsi_conn_free_pdu(conn, pdu);
}
}
}

View File

@ -77,6 +77,11 @@ spdk_iscsi_portal_grp_close_all(void)
return 0;
}
void
spdk_iscsi_conn_free_pdu(struct spdk_iscsi_conn *conn, struct spdk_iscsi_pdu *pdu)
{
}
static void
maxburstlength_test(void)
{