From: Dave Marquardt <davemarq@linux.ibm.com>
To: sashiko-reviews@lists.linux.dev
Cc: linux-scsi@vger.kernel.org
Subject: Re: [PATCH v6 4/8] scsi: ibmvfc: extend async event handlers to handle async sub queue events
Date: Fri, 21 Aug 2026 10:16:02 -0500 [thread overview]
Message-ID: <87wltjwll9.fsf@linux.ibm.com> (raw)
In-Reply-To: <20260817204225.820DC1F000E9@smtp.kernel.org>
sashiko-bot@kernel.org writes:
> Thank you for your contribution! Sashiko AI review found 4 potential issue(s) to consider:
> - [High] Double clear of `valid` in the CRQ ring buffer introduces a race condition that can clobber subsequent hardware events.
> - [High] Missing check for `IBMVFC_ASYNC_ID_IS_ASSOC_ID` causes `assoc_id` to be incorrectly treated as a WWNN, preventing target lookup and dropping events.
> - [Medium] KUnit tests use `msleep()` to wait for asynchronous workqueue execution, leading to flaky test failures.
> - [Low] Dereferencing a `void *` pointer in the unmodified `nvme_scrqs` loop inside `ibmvfc_handle_async` causes a compilation error.
> --
>
>> diff --git a/drivers/scsi/ibmvscsi/ibmvfc-core.c b/drivers/scsi/ibmvscsi/ibmvfc-core.c
>> index 19a3f12615648..4d1630d2ab1b5 100644
>> --- a/drivers/scsi/ibmvscsi/ibmvfc-core.c
>> +++ b/drivers/scsi/ibmvscsi/ibmvfc-core.c
>> @@ -3462,28 +3501,41 @@ 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_sub_crq *subq = NULL;
>> struct ibmvfc_async_work *aw;
>> - struct ibmvfc_async_crq *crq;
>> + struct ibmvfc_async_crq *crq = NULL;
>> struct ibmvfc_target *tgt;
>> struct ibmvfc_host *vhost;
>> - struct fc_els_fpin *fpin;
>> + struct fc_els_fpin *fpin = NULL;
>> unsigned long flags;
>> + __be64 node_name;
>> + __be64 scsi_id;
>> + bool is_subq;
>> + __be64 wwpn;
>>
>> aw = container_of_const(work, struct ibmvfc_async_work, async_work_s);
>> vhost = aw->vhost;
>> - crq = &aw->crq;
>> + is_subq = aw->is_subq;
>> + if (is_subq) {
>> + subq = &aw->crq.subq;
>> + scsi_id = 0;
>> + wwpn = subq->wwpn;
>> + node_name = subq->id.node_name;
>
> [Severity: High]
> Does this incorrectly treat assoc_id as a WWNN? It looks like we should
> check the IBMVFC_ASYNC_ID_IS_ASSOC_ID flag before unconditionally reading
> node_name, as this could prevent target lookups and cause FPIN events
> to be dropped.
The v7 patches now check taht IBMVFC_ASYNC_ID_IS_ASSOC_ID is not set
before using subq->id.node_name.
> [ ... ]
>
>> @@ -3511,25 +3567,52 @@ static void ibmvfc_process_async_work(struct work_struct *work)
>>
>> /**
>> * ibmvfc_handle_async - Handle an async event from the adapter
>> - * @crq: crq to process
>> + * @crq: ibmvfc_async_crq or ibmvfc_async_sub_crq
>> * @vhost: ibmvfc host struct
>> + * @is_sub_crq: indicates whether the crq points to a struct ibmvfc_async_sub_crq
>> *
>> **/
>> -VISIBLE_IF_KUNIT void ibmvfc_handle_async(struct ibmvfc_async_crq *crq,
>> - struct ibmvfc_host *vhost)
>> +VISIBLE_IF_KUNIT void ibmvfc_handle_async(void *crq,
>> + struct ibmvfc_host *vhost,
>> + bool is_sub_crq)
>> {
>
> [Severity: Low]
> Will this cause a compilation error? The crq parameter type is changed to a
> void pointer here, but there is still an unmodified nvme_scrqs loop later in
> ibmvfc_handle_async() that directly dereferences it like crq->scsi_id.
No, this does not cause a compilation error.
>> - const struct ibmvfc_async_desc *desc = ibmvfc_get_ae_desc(be64_to_cpu(crq->event));
>> + struct ibmvfc_async_crq *async_crq = NULL;
>> + struct ibmvfc_async_sub_crq *subq = NULL;
>> const struct ibmvfc_async_desc *desc;
>> struct ibmvfc_async_work *aw;
>> struct ibmvfc_target *tgt;
>> -
>> - ibmvfc_log(vhost, desc->log_level, "%s event received. scsi_id: %llx, wwpn: %llx,"
>> - " node_name: %llx%s\n", desc->desc, be64_to_cpu(crq->scsi_id),
>> - be64_to_cpu(crq->wwpn), be64_to_cpu(crq->node_name),
>> - ibmvfc_get_link_state(crq->link_state));
>> -
>> - switch (be64_to_cpu(crq->event)) {
>> + __be64 node_name;
>> + __be64 scsi_id;
>> + u8 link_state;
>> + __be64 wwpn;
>> + u64 event;
>> +
>> + if (is_sub_crq) {
>> + subq = crq;
>> + event = be16_to_cpu(subq->event);
>> + link_state = subq->link_state;
>> + scsi_id = 0;
>> + wwpn = subq->wwpn;
>> + node_name = subq->id.node_name;
>
> [Severity: High]
> Is it possible to receive an assoc_id here instead of a node_name?
> Missing the check for IBMVFC_ASYNC_ID_IS_ASSOC_ID could result in mismatches
> during target lookup.
Fixed in v7.
> [ ... ]
>
>> @@ -3615,16 +3698,27 @@ VISIBLE_IF_KUNIT void ibmvfc_handle_async(struct ibmvfc_async_crq *crq,
>> if (aw) {
>> INIT_WORK(&aw->async_work_s, ibmvfc_process_async_work);
>> aw->vhost = vhost;
>> - aw->crq = *crq;
>> + aw->is_subq = is_sub_crq;
>> + if (is_sub_crq)
>> + aw->crq.subq = *subq;
>> + else
>> + aw->crq.async_crq = *async_crq;
>> queue_work(vhost->fpin_workq, &aw->async_work_s);
>> } else
>> dev_err_ratelimited(vhost->dev,
>> "can't offload async CRQ to work queue\n");
>> break;
>> default:
>> - dev_err(vhost->dev, "Unknown async event received: %lld\n", crq->event);
>> + dev_err(vhost->dev, "Unknown async event received: %llu\n", event);
>> break;
>> }
>> +
>> + rmb();
>> + if (is_sub_crq)
>> + subq->valid = 0;
>> + else
>> + async_crq->valid = 0;
>> + wmb();
>> }
>
> [Severity: High]
> Can clearing the valid byte here lead to silently dropped events?
>
> Since ibmvfc_handle_async() clears the valid byte to 0, it tells the hardware
> the slot can be reused.
>
> In the caller ibmvfc_tasklet():
>
> while ((async = ibmvfc_next_async_crq(vhost)) != NULL) {
> ibmvfc_handle_async(async, vhost, false);
> async->valid = 0;
> wmb();
> }
>
> If the hardware writes a new event into this slot between the first clear in
> ibmvfc_handle_async() and the redundant clear in ibmvfc_tasklet(), wouldn't
> the second clear overwrite the new event's valid byte and lose it?
In v7, the CRQ valid bit is now cleared by the caller of
ibmvfc_handle_async() in all cases.
> [ ... ]
>
>> diff --git a/drivers/scsi/ibmvscsi/ibmvfc_kunit.c b/drivers/scsi/ibmvscsi/ibmvfc_kunit.c
>> index 64a517a74af8e..0b29c1e6478b5 100644
>> --- a/drivers/scsi/ibmvscsi/ibmvfc_kunit.c
>> +++ b/drivers/scsi/ibmvscsi/ibmvfc_kunit.c
>> @@ -58,7 +58,7 @@ static void ibmvfc_async_fpin_test(struct kunit *test)
>> crq[fs].scsi_id = cpu_to_be64(tgt->scsi_id);
>> crq[fs].wwpn = cpu_to_be64(tgt->wwpn);
>> crq[fs].node_name = cpu_to_be64(tgt->ids.node_name);
>> - ibmvfc_handle_async(&crq[fs], vhost);
>> + ibmvfc_handle_async(&crq[fs], vhost, false);
>> msleep(1U);
>> }
>
> [Severity: Medium]
> Will this lead to flaky tests on heavily loaded systems?
>
> Using msleep(1U) to wait for asynchronous workqueue execution might not give
> the workqueue enough time to run. Could we use flush_workqueue() instead?
In v7 all KUnit tests now use flush_workqueue().
> [ ... ]
>
>> @@ -93,7 +93,110 @@ static void ibmvfc_async_fpin_test(struct kunit *test)
>> crq[0].scsi_id = cpu_to_be64(tgt->scsi_id);
>> crq[0].wwpn = cpu_to_be64(tgt->wwpn);
>> crq[0].node_name = cpu_to_be64(tgt->ids.node_name);
>> - ibmvfc_handle_async(&crq[0], vhost);
>> + ibmvfc_handle_async(&crq[0], vhost, false);
>> + msleep(1U);
>
> [Severity: Medium]
> Should we avoid using msleep(1U) here for synchronizing with the workqueue?
>
> If the workqueue doesn't run within 1 millisecond, the assertions that follow
> could fail.
See above.
> [ ... ]
>
>> + /* bad path */
>> + crq[0].valid = 0x80;
>> + crq[0].link_state = IBMVFC_AE_LS_LINK_UP;
>> + crq[0].fpin_status = 0; /* bad value */
>> + crq[0].event = cpu_to_be16(IBMVFC_AE_FPIN);
>> + crq[0].wwpn = cpu_to_be64(tgt->wwpn);
>> + crq[0].id.node_name = cpu_to_be64(tgt->ids.node_name);
>> + ibmvfc_handle_async(&crq[0], vhost, true);
>> msleep(1U);
>
> [Severity: Medium]
> Same concern here about using msleep(1U) to wait for the workqueue.
See above.
-Dave
next prev parent reply other threads:[~2026-08-21 15:16 UTC|newest]
Thread overview: 35+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-08-17 20:27 [PATCH v6 0/8] scsi: ibmvfc: make ibmvfc support FPIN messages Dave Marquardt via B4 Relay
2026-08-17 20:27 ` Dave Marquardt
2026-08-17 20:27 ` [PATCH v6 1/8] scsi: ibmvfc: add basic FPIN support Dave Marquardt via B4 Relay
2026-08-17 20:27 ` Dave Marquardt
2026-08-17 20:37 ` sashiko-bot
2026-08-21 15:09 ` Dave Marquardt
2026-08-17 20:27 ` [PATCH v6 2/8] scsi: ibmvfc: Add NOOP command support Dave Marquardt via B4 Relay
2026-08-17 20:27 ` Dave Marquardt
2026-08-17 20:41 ` sashiko-bot
2026-08-21 15:11 ` Dave Marquardt
2026-08-17 20:27 ` [PATCH v6 3/8] scsi: ibmvfc: define asynchronous sub-queue Dave Marquardt via B4 Relay
2026-08-17 20:27 ` Dave Marquardt
2026-08-17 20:39 ` sashiko-bot
2026-08-21 15:13 ` Dave Marquardt
2026-08-17 20:27 ` [PATCH v6 4/8] scsi: ibmvfc: extend async event handlers to handle async sub queue events Dave Marquardt via B4 Relay
2026-08-17 20:27 ` Dave Marquardt
2026-08-17 20:42 ` sashiko-bot
2026-08-21 15:16 ` Dave Marquardt [this message]
2026-08-17 20:27 ` [PATCH v6 5/8] scsi: ibmvfc: add interrupt routine for asynchronous sub CRQ Dave Marquardt via B4 Relay
2026-08-17 20:27 ` Dave Marquardt
2026-08-17 20:51 ` sashiko-bot
2026-08-21 15:29 ` Dave Marquardt
2026-08-17 20:27 ` [PATCH v6 6/8] scsi: ibmvfc: extend channel registration and deregistration for async subq Dave Marquardt via B4 Relay
2026-08-17 20:27 ` Dave Marquardt
2026-08-17 20:50 ` sashiko-bot
2026-08-21 15:30 ` Dave Marquardt
2026-08-17 20:28 ` [PATCH v6 7/8] scsi: ibmvfc: register and use asynchronous sub CRQ for events Dave Marquardt via B4 Relay
2026-08-17 20:28 ` Dave Marquardt
2026-08-17 20:42 ` sashiko-bot
2026-08-21 15:44 ` Dave Marquardt
2026-08-26 21:57 ` Tyrel Datwyler
2026-08-17 20:28 ` [PATCH v6 8/8] scsi: ibmvfc: handle extended FPIN events Dave Marquardt via B4 Relay
2026-08-17 20:28 ` Dave Marquardt
2026-08-17 20:41 ` sashiko-bot
2026-08-24 15:25 ` Dave Marquardt
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=87wltjwll9.fsf@linux.ibm.com \
--to=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.