From: sashiko-bot@kernel.org
To: "Yehyeong Lee" <yhlee@isslab.korea.ac.kr>
Cc: linux-scsi@vger.kernel.org
Subject: Re: [PATCH v2 1/2] scsi: libiscsi: only complete a task that has been sent
Date: Fri, 13 Nov 2026 23:57:35 +0000 [thread overview]
Message-ID: <sashiko-outbox-213889@kernel.org> (raw)
In-Reply-To: <20261113233938.397415-2-yhlee@isslab.korea.ac.kr>
Thank you for your contribution! Sashiko AI review found 1 potential
issue to consider:
- [High] scsi: libiscsi: premature ISCSI_TASK_RUNNING before xmit ref
acquisition
--
commit 7682c2a848ebe294348224903c5fc89275f307e1
Author: Yehyeong Lee <yhlee@isslab.korea.ac.kr>
scsi: libiscsi: only complete a task that has been sent
This commit uses smp_store_release() to mark a task ISCSI_TASK_RUNNING in
iscsi_prep_scsi_cmd_pdu() and iscsi_prep_mgmt_task(), and checks for
ISCSI_TASK_RUNNING with smp_load_acquire() in the RX path before
completing a management or rejected task.
> diff --git a/drivers/scsi/libiscsi.c b/drivers/scsi/libiscsi.c
> index 2d04448432a77..83d726043d3e8 100644
> --- a/drivers/scsi/libiscsi.c
> +++ b/drivers/scsi/libiscsi.c
> @@ -429,7 +429,8 @@ static int iscsi_prep_scsi_cmd_pdu(struct iscsi_task *task)
> if (session->tt->init_task && session->tt->init_task(task))
> return -EIO;
>
> - task->state = ISCSI_TASK_RUNNING;
> + /* Pairs with the acquire in the RX task lookups. */
> + smp_store_release(&task->state, ISCSI_TASK_RUNNING);
> session->cmdsn++;
>
> conn->scsicmd_pdus_cnt++;
> @@ -702,7 +703,8 @@ static int iscsi_prep_mgmt_task(struct iscsi_conn *conn,
> if ((hdr->opcode & ISCSI_OPCODE_MASK) == ISCSI_OP_LOGOUT)
> session->state = ISCSI_STATE_LOGGING_OUT;
>
> - task->state = ISCSI_TASK_RUNNING;
> + /* Pairs with the acquire in the RX task lookups. */
> + smp_store_release(&task->state, ISCSI_TASK_RUNNING);
> ISCSI_DBG_SESSION(session, "mgmtpdu [op 0x%x hdr->itt 0x%x "
> "datalen %d]\n", hdr->opcode & ISCSI_OPCODE_MASK,
> hdr->itt, task->data_count);
[Severity: High]
Can the RX path still complete and free task after
smp_store_release(&task->state, ISCSI_TASK_RUNNING) before the transmit
path finishes using it or acquires its reference?
iscsi_data_xmit() runs under session->frwd_lock and calls
iscsi_prep_mgmt_task() (or iscsi_prep_scsi_cmd_pdu()) while task->refcount
is still 1, before iscsi_xmit_task() takes the transmit reference. Since
__iscsi_complete_pdu() and iscsi_handle_reject() run concurrently under
session->back_lock, an unsolicited response or Reject naming that ITT can
arrive in between:
kworker (CPU0) <softirq> (CPU1)
iscsi_data_xmit()
spin_lock_bh(&session->frwd_lock)
iscsi_prep_mgmt_task(conn, task)
smp_store_release(&task->state,
ISCSI_TASK_RUNNING)
__iscsi_complete_pdu()
spin_lock(&session->back_lock)
smp_load_acquire(&task->state)
== ISCSI_TASK_RUNNING
iscsi_complete_task(task, ...)
__iscsi_put_task(session, task)
iscsi_free_task(task)
ISCSI_DBG_SESSION(...)
hdr->opcode <-- use-after-free if cleanup_task
freed task->hdr
iscsi_xmit_task(..., task, false)
iscsi_get_task(task) <-- fails (refcount == 0),
triggers WARN_ON_ONCE(1)
Even if iscsi_get_task() runs before the RX completion, iscsi_xmit_task()
drops session->frwd_lock around session->tt->xmit_task(task); if RX
completes the task during that window and xmit_task() returns an error
such as -EAGAIN, iscsi_xmit_task() unconditionally calls
iscsi_get_task(task) and saves the completed task in conn->task for
retransmission:
drivers/scsi/libiscsi.c:iscsi_xmit_task() {
...
spin_unlock_bh(&session->frwd_lock);
rc = session->tt->xmit_task(task);
spin_lock_bh(&session->frwd_lock);
if (!rc) {
/* done with this task */
task->last_xfer = jiffies;
} else {
/*
* get an extra ref that is released next time we access it
* as conn->task above.
*/
iscsi_get_task(task);
conn->task = task;
}
...
}
In addition, for transports without ihost->workq, iscsi_send_mgmt_task()
and iscsi_queuecommand() call iscsi_prep_mgmt_task() or
iscsi_prep_scsi_cmd_pdu() and invoke session->tt->xmit_task(task) directly
without taking an extra task reference at all, so an RX completion after
ISCSI_TASK_RUNNING is stored frees task while xmit_task() is running (and
if xmit_task() fails, the caller puts task a second time).
--
Sashiko AI review · https://sashiko.dev/#/patchset/20261113233938.397415-1-yhlee@isslab.korea.ac.kr?part=1
next prev parent reply other threads:[~2026-11-13 23:57 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-11-13 23:39 [PATCH v2 0/2] scsi: libiscsi: tighten management task completion Yehyeong Lee
2026-11-13 23:39 ` [PATCH v2 1/2] scsi: libiscsi: only complete a task that has been sent Yehyeong Lee
2026-11-13 23:57 ` sashiko-bot [this message]
2026-11-13 23:39 ` [PATCH v2 2/2] scsi: libiscsi: do not complete a task sent with a reserved ITT Yehyeong Lee
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=sashiko-outbox-213889@kernel.org \
--to=sashiko-bot@kernel.org \
--cc=linux-scsi@vger.kernel.org \
--cc=sashiko-reviews@lists.linux.dev \
--cc=yhlee@isslab.korea.ac.kr \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox