iscsi: fix the primary iscsi task free in queued_datain_tasks
Reason: If the task is queued in scsi layer to handle, we should free the task after calling the spdk_iscsi_task_cpl. Otherwise, if only this task is executed (without subread tasks), the task will be freed by the loop early, which will cause the segment fault in spdk_iscsi_task_cpl function. Change-Id: Ifc42399957b24d976af5fd12f6e33459a3ea86ba Signed-off-by: Ziye Yang <ziye.yang@intel.com> Reviewed-on: https://review.gerrithub.io/421706 Chandler-Test-Pool: SPDK Automated Test System <sys_sgsw@intel.com> Tested-by: SPDK CI Jenkins <sys_sgci@intel.com> Reviewed-by: Jim Harris <james.r.harris@intel.com> Reviewed-by: Ben Walker <benjamin.walker@intel.com>
This commit is contained in:
parent
f85f70b40a
commit
c8fd001075
@ -376,9 +376,11 @@ static int spdk_iscsi_conn_free_tasks(struct spdk_iscsi_conn *conn)
|
|||||||
}
|
}
|
||||||
|
|
||||||
TAILQ_FOREACH_SAFE(iscsi_task, &conn->queued_datain_tasks, link, tmp_iscsi_task) {
|
TAILQ_FOREACH_SAFE(iscsi_task, &conn->queued_datain_tasks, link, tmp_iscsi_task) {
|
||||||
|
if (!iscsi_task->is_queued) {
|
||||||
TAILQ_REMOVE(&conn->queued_datain_tasks, iscsi_task, link);
|
TAILQ_REMOVE(&conn->queued_datain_tasks, iscsi_task, link);
|
||||||
spdk_iscsi_task_put(iscsi_task);
|
spdk_iscsi_task_put(iscsi_task);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (conn->pending_task_cnt) {
|
if (conn->pending_task_cnt) {
|
||||||
return -1;
|
return -1;
|
||||||
@ -883,6 +885,7 @@ spdk_iscsi_task_cpl(struct spdk_scsi_task *scsi_task)
|
|||||||
|
|
||||||
spdk_trace_record(TRACE_ISCSI_TASK_DONE, conn->id, 0, (uintptr_t)task, 0);
|
spdk_trace_record(TRACE_ISCSI_TASK_DONE, conn->id, 0, (uintptr_t)task, 0);
|
||||||
|
|
||||||
|
task->is_queued = false;
|
||||||
primary = spdk_iscsi_task_get_primary(task);
|
primary = spdk_iscsi_task_get_primary(task);
|
||||||
|
|
||||||
if (spdk_iscsi_task_is_read(primary)) {
|
if (spdk_iscsi_task_is_read(primary)) {
|
||||||
|
@ -2816,6 +2816,7 @@ static void spdk_iscsi_queue_task(struct spdk_iscsi_conn *conn,
|
|||||||
{
|
{
|
||||||
spdk_trace_record(TRACE_ISCSI_TASK_QUEUE, conn->id, task->scsi.length,
|
spdk_trace_record(TRACE_ISCSI_TASK_QUEUE, conn->id, task->scsi.length,
|
||||||
(uintptr_t)task, (uintptr_t)task->pdu);
|
(uintptr_t)task, (uintptr_t)task->pdu);
|
||||||
|
task->is_queued = true;
|
||||||
spdk_scsi_dev_queue_task(conn->dev, &task->scsi);
|
spdk_scsi_dev_queue_task(conn->dev, &task->scsi);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -97,6 +97,7 @@ struct spdk_iscsi_task {
|
|||||||
|
|
||||||
TAILQ_HEAD(subtask_list, spdk_iscsi_task) subtask_list;
|
TAILQ_HEAD(subtask_list, spdk_iscsi_task) subtask_list;
|
||||||
TAILQ_ENTRY(spdk_iscsi_task) subtask_link;
|
TAILQ_ENTRY(spdk_iscsi_task) subtask_link;
|
||||||
|
bool is_queued; /* is queued in scsi layer for handling */
|
||||||
};
|
};
|
||||||
|
|
||||||
static inline void
|
static inline void
|
||||||
|
Loading…
Reference in New Issue
Block a user