From: sashiko-bot@kernel.org
To: "Dave Marquardt" <davemarq@linux.ibm.com>
Cc: linux-scsi@vger.kernel.org
Subject: Re: [PATCH v5 7/7] scsi: ibmvfc: handle extended FPIN events
Date: Thu, 06 Aug 2026 15:53:00 +0000 [thread overview]
Message-ID: <20260806155301.39C1C1F00A3D@smtp.kernel.org> (raw)
In-Reply-To: <20260806-ibmvfc-fpin-support-v5-7-13fd6f8a8f8b@linux.ibm.com>
Thank you for your contribution! Sashiko AI review found 4 potential issue(s) to consider:
- [High] Struct union aliasing bug causes valid extended FPIN events to be dropped due to garbage node_name.
- [High] Missing flush_workqueue in ibmvfc_remove causes a Use-After-Free of vhost on module unload or hot-unplug.
- [High] Manual call to destroy_workqueue on a devm-managed workqueue during probe failure causes a double-free crash.
- [Medium] The KUnit tests for extended FPIN events lack assertions and contain race conditions.
--
--- Patch [7]: [PATCH v5 7/7] scsi: ibmvfc: handle extended FPIN events ---
commit a5bae65b668808baf4437c91c70e1618c59070b3
Author: Dave Marquardt <davemarq@linux.ibm.com>
scsi: ibmvfc: handle extended FPIN events
Implement support for extended FPIN messages received via the
asynchronous sub-queue, completing full FPIN functionality.
> diff --git a/drivers/scsi/ibmvscsi/ibmvfc-core.c b/drivers/scsi/ibmvscsi/ibmvfc-core.c
> index b6ac87c2042b5..9cf82c87907a8 100644
> --- a/drivers/scsi/ibmvscsi/ibmvfc-core.c
> +++ b/drivers/scsi/ibmvscsi/ibmvfc-core.c
[ ... ]
> @@ -3485,6 +3521,7 @@ static struct ibmvfc_target *ibmvfc_find_target(struct list_head *target_list,
> */
> static void ibmvfc_process_async_work(struct work_struct *work)
> {
> + struct ibmvfc_async_subq_fpin *sqfpin;
> struct ibmvfc_async_subq *subq = NULL;
> struct ibmvfc_async_work *aw;
> struct ibmvfc_async_crq *crq = NULL;
> @@ -3533,8 +3570,20 @@ static void ibmvfc_process_async_work(struct work_struct *work)
>
> if (crq)
> fpin = ibmvfc_basic_fpin_to_desc(crq, tgt->wwpn);
> - else
> - fpin = ibmvfc_full_fpin_to_desc(subq);
> + else {
> + sqfpin = (struct ibmvfc_async_subq_fpin *)subq;
[Severity: High]
Does this code have a struct union aliasing issue that causes valid extended
FPIN events to be dropped?
Looking at ibmvfc_process_async_work() just above this change, it
unconditionally reads node_name:
node_name = subq->id.node_name;
For extended FPINs, the subq structure is actually ibmvfc_async_subq_fpin.
In ibmvfc_async_subq, id.node_name occupies bytes 24-31. In
ibmvfc_async_subq_fpin, the fpin_data structure begins at byte 16, and its
event_threshold and event_data fields perfectly overlay bytes 24-31.
Since hardware populates these with non-zero values (like
IBMVFC_FPIN_DEFAULT_EVENT_THRESHOLD), node_name is parsed as non-zero garbage.
Then ibmvfc_find_target() attempts a strict match against this garbage
node_name, fails to find the correct target, and drops the valid event.
Can we adjust the extraction logic so we don't read garbage data for the
node_name field when processing extended FPINs?
[Severity: High]
Will the deferred async work item processed here cause a use-after-free of
vhost on module unload or hot-unplug?
In ibmvfc_probe(), vhost->fpin_workq is allocated via devm_alloc_workqueue().
Consequently, its destruction is tied to the driver core's devres mechanism,
which invokes destroy_workqueue() only after ibmvfc_remove() returns.
Inside ibmvfc_remove(), scsi_host_put(vhost->host) is called, dropping the
reference count and freeing the vhost structure. Since there is no explicit
flush_workqueue(vhost->fpin_workq) prior to this, pending asynchronous FPIN
events remain in the queue.
When devres later cleans up the workqueue, destroy_workqueue() flushes it,
executing the pending ibmvfc_process_async_work items. These works
dereference aw->vhost:
spin_lock_irqsave(vhost->host->host_lock, flags);
which now points to the freed memory. Should we add an explicit
flush_workqueue() in ibmvfc_remove()?
[Severity: High]
Can a manual call to destroy_workqueue() on the devm-managed workqueue during
probe failure cause a double-free crash?
In ibmvfc_probe(), vhost->fpin_workq is allocated using
devm_alloc_workqueue(). This registers a devres release action to destroy the
workqueue when the device unbinds or probe fails.
If a subsequent step in probe fails (e.g., ibmvfc_alloc_mem()), the error
path jumps to free_workq, which manually calls
destroy_workqueue(vhost->fpin_workq) and sets the pointer to NULL. When the
probe function returns the error, the devres cleanup framework invokes
devm_workqueue_release(), calling destroy_workqueue() on the original pointer
that was captured at allocation time, causing a double-free crash.
Should we remove the manual destroy_workqueue() in the error path?
> + if ((subq->flags & IBMVFC_ASYNC_IS_FPIN_EXT) == 0) {
> + fpin = ibmvfc_full_fpin_to_desc(subq);
> + } else if (!(sqfpin->fpin_data.flags & IBMVFC_FPIN_EVENT_TYPE_VALID)) {
> + dev_err_ratelimited(vhost->dev,
> + "Invalid extended FPIN event received\n");
> + } else if (!ibmvfc_check_caps(vhost, IBMVFC_SUPPORT_FPIN_EXT)) {
> + dev_err_ratelimited(vhost->dev,
> + "Unexpected extended FPIN event received\n");
> + } else {
> + fpin = ibmvfc_ext_fpin_to_desc(sqfpin);
> + }
> + }
>
> if (fpin) {
> fc_host_fpin_rcv(tgt->vhost->host,
[ ... ]
> diff --git a/drivers/scsi/ibmvscsi/ibmvfc_kunit.c b/drivers/scsi/ibmvscsi/ibmvfc_kunit.c
> index a3e3e3471c5ef..8c9ba748597ba 100644
> --- a/drivers/scsi/ibmvscsi/ibmvfc_kunit.c
> +++ b/drivers/scsi/ibmvscsi/ibmvfc_kunit.c
[ ... ]
> @@ -114,8 +115,117 @@ static void ibmvfc_async_fpin_test(struct kunit *test)
> post[IBMVFC_AE_FPIN_CONGESTION_CLEARED]);
> }
>
> +#define IBMVFC_TEST_FPIN_EXT(fs, ev, stat, crq) { \
> + crq.valid = 0x80; \
> + crq.flags = IBMVFC_ASYNC_IS_FPIN_EXT; \
> + crq.link_state = IBMVFC_AE_LS_LINK_UP; \
> + crq.fpin_status = (fs); \
> + crq.event = cpu_to_be16(IBMVFC_AE_FPIN); \
> + crq.wwpn = cpu_to_be64(tgt->wwpn); \
> + crq.fpin_data.flags = IBMVFC_FPIN_EVENT_TYPE_VALID; \
> + crq.fpin_data.event_type = cpu_to_be16((ev)); \
> + pre = READ_ONCE(tgt->rport->fpin_stats.stat); \
> + ibmvfc_handle_async((struct ibmvfc_crq *)&crq, vhost, true); \
> + msleep(1U); \
> + post = READ_ONCE(tgt->rport->fpin_stats.stat); \
> +}
[Severity: Medium]
Are these KUnit tests missing assertions to actually validate the statistics
changes?
The IBMVFC_TEST_FPIN_EXT macro and ibmvfc_extended_fpin_test() function
invoke ibmvfc_handle_async() and read the post statistics, but completely
omit KUnit assertions (like KUNIT_EXPECT_GE) to verify that the statistics
were incremented. This causes the test to silently pass even if the code
under test is completely broken.
Additionally, the test uses a non-deterministic msleep(1U) rather than
flush_workqueue(vhost->fpin_workq) to wait for the mocked async work to
complete, potentially causing a race condition.
Could we add proper assertions and replace msleep() with flush_workqueue()
to ensure the test is robust and actually validates the changes?
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260806-ibmvfc-fpin-support-v5-0-13fd6f8a8f8b@linux.ibm.com?part=7
prev parent reply other threads:[~2026-08-06 15:53 UTC|newest]
Thread overview: 23+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-08-06 15:17 [PATCH v5 0/7] scsi: ibmvfc: make ibmvfc support FPIN messages Dave Marquardt via B4 Relay
2026-08-06 15:17 ` Dave Marquardt
2026-08-06 15:17 ` [PATCH v5 1/7] scsi: ibmvfc: add basic FPIN support Dave Marquardt via B4 Relay
2026-08-06 15:17 ` Dave Marquardt
2026-08-06 15:32 ` sashiko-bot
2026-08-06 15:17 ` [PATCH v5 2/7] scsi: ibmvfc: Add NOOP command support Dave Marquardt via B4 Relay
2026-08-06 15:17 ` Dave Marquardt
2026-08-06 15:45 ` sashiko-bot
2026-08-06 15:17 ` [PATCH v5 3/7] scsi: ibmvfc: define asynchronous sub-queue Dave Marquardt via B4 Relay
2026-08-06 15:17 ` Dave Marquardt
2026-08-06 15:32 ` sashiko-bot
2026-08-06 15:17 ` [PATCH v5 4/7] scsi: ibmvfc: allocate " Dave Marquardt via B4 Relay
2026-08-06 15:17 ` Dave Marquardt
2026-08-06 15:38 ` sashiko-bot
2026-08-06 15:17 ` [PATCH v5 5/7] scsi: ibmvfc: extend async event handlers to handle async sub queue events Dave Marquardt via B4 Relay
2026-08-06 15:17 ` Dave Marquardt
2026-08-06 15:34 ` sashiko-bot
2026-08-06 15:17 ` [PATCH v5 6/7] scsi: ibmvfc: register and use asynchronous sub-queue for events Dave Marquardt via B4 Relay
2026-08-06 15:17 ` Dave Marquardt
2026-08-06 15:47 ` sashiko-bot
2026-08-06 15:17 ` [PATCH v5 7/7] scsi: ibmvfc: handle extended FPIN events Dave Marquardt via B4 Relay
2026-08-06 15:17 ` Dave Marquardt
2026-08-06 15:53 ` sashiko-bot [this message]
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=20260806155301.39C1C1F00A3D@smtp.kernel.org \
--to=sashiko-bot@kernel.org \
--cc=davemarq@linux.ibm.com \
--cc=linux-scsi@vger.kernel.org \
--cc=sashiko-reviews@lists.linux.dev \
/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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.