From: Dave Marquardt <davemarq@linux.ibm.com>
To: Tyrel Datwyler <tyreld@linux.ibm.com>
Cc: "James E.J. Bottomley" <James.Bottomley@HansenPartnership.com>,
"Martin K. Petersen" <martin.petersen@oracle.com>,
Madhavan Srinivasan <maddy@linux.ibm.com>,
Michael Ellerman <mpe@ellerman.id.au>,
Nicholas Piggin <npiggin@gmail.com>,
"Christophe Leroy (CS GROUP)" <chleroy@kernel.org>,
linux-kernel@vger.kernel.org, linux-scsi@vger.kernel.org,
linuxppc-dev@lists.ozlabs.org, Brian King <brking@linux.ibm.com>,
Greg Joyce <gjoyce@linux.ibm.com>,
Kyle Mahlkuch <kmahlkuc@linux.ibm.com>
Subject: Re: [PATCH v2 6/7] ibmvfc: register and use asynchronous sub-queue
Date: Thu, 25 Jun 2026 16:31:52 -0500 [thread overview]
Message-ID: <87fr2aparb.fsf@linux.ibm.com> (raw)
In-Reply-To: <03239655-0c9a-42af-b6a1-8141f44149f9@linux.ibm.com>
Tyrel Datwyler <tyreld@linux.ibm.com> writes:
> On 6/8/26 11:30 AM, Dave Marquardt via B4 Relay wrote:
>> From: Dave Marquardt <davemarq@linux.ibm.com>
>>
>> Refactor existing code for async events into a common routine,
>> register a channel and interrupt handler for the asynchronous
>> sub-queue, and set capability bits to request that VIOS use the
>> asynchronous sub-queue.
>
> Again, all your patches need Signed-off-by: tags to be accepted.
>
> Also, there is still a lot of different things happening in this patch
>
> You seem to be reworking the fpin_desc helpers which I'm not really seeing any
> reason that you couldn't squash those changes into patch 2. It seems like
> needless churn since, unless I'm missing something, there doesn't seem to be any
> new definitions added since patch 2 just reworking of the input parameters such
> that period goes away and is hardcoded and a new type paramerter is added.
Okay, I'll roll the ibmvfc_common_fpin_to_desc changes into patch 2.
> I would also help reduce the patch size and make it more reviewable if you split
> the the interrupt handler definition and queue registration into separate
> patches as well.
>
>> ---
>> drivers/scsi/ibmvscsi/ibmvfc.c | 376 +++++++++++++++++++++++++++--------
>> drivers/scsi/ibmvscsi/ibmvfc.h | 3 +
>> drivers/scsi/ibmvscsi/ibmvfc_kunit.c | 2 +-
>> 3 files changed, 298 insertions(+), 83 deletions(-)
>>
>> diff --git a/drivers/scsi/ibmvscsi/ibmvfc.c b/drivers/scsi/ibmvscsi/ibmvfc.c
>> index ad1f5636e879..a2252cd2f44b 100644
>> --- a/drivers/scsi/ibmvscsi/ibmvfc.c
>> +++ b/drivers/scsi/ibmvscsi/ibmvfc.c
>> @@ -1514,7 +1514,8 @@ static void ibmvfc_set_login_info(struct ibmvfc_host *vhost)
>> login_info->max_cmds = cpu_to_be32(max_cmds);
>> login_info->capabilities =
>> cpu_to_be64(IBMVFC_CAN_MIGRATE | IBMVFC_CAN_SEND_VF_WWPN |
>> - IBMVFC_CAN_USE_NOOP_CMD);
>> + IBMVFC_CAN_USE_NOOP_CMD | IBMVFC_YES_SCSI |
>> + IBMVFC_USE_ASYNC_SUBQ | IBMVFC_CAN_HANDLE_FPIN);
>>
>> if (vhost->mq_enabled || vhost->using_channels)
>> login_info->capabilities |= cpu_to_be64(IBMVFC_CAN_USE_CHANNELS);
>> @@ -3240,8 +3241,8 @@ static size_t ibmvfc_fpin_size_helper(u8 fpin_status)
>> * non-NULL - pointer to populated struct fc_els_fpin
>> */
>> static struct fc_els_fpin *
>> -ibmvfc_common_fpin_to_desc(u8 fpin_status, __be64 wwpn, __be16 modifier,
>> - __be32 period, __be32 threshold, __be32 event_count)
>> +ibmvfc_common_fpin_to_desc(u8 fpin_status, __be64 wwpn, __be16 type, __be16 modifier,
>> + __be32 threshold, __be32 event_count)
>> {
>
> This function signature changes here, and looking at the implemenation below I'm
> struggling to see why this couldn't just be all implmented immediatly in Patch #2.
>
>> struct fc_fn_peer_congn_desc *pdesc;
>> struct fc_fn_congn_desc *cdesc;
>> @@ -3253,7 +3254,7 @@ ibmvfc_common_fpin_to_desc(u8 fpin_status, __be64 wwpn, __be16 modifier,
>> if (size == 0)
>> return NULL;
>>
>> - fpin = kzalloc(size, GFP_KERNEL);
>> + fpin = kzalloc(size, GFP_ATOMIC);
>
> Why are we changing this to GFP_ATOMIC? Isn't this only ever called from work
> queue context?
I've restored this for my next version of the patch series.
>> if (fpin == NULL)
>> return NULL;
>>
>> @@ -3266,12 +3267,9 @@ ibmvfc_common_fpin_to_desc(u8 fpin_status, __be64 wwpn, __be16 modifier,
>> cdesc = (struct fc_fn_congn_desc *)fpin->fpin_desc;
>> cdesc->desc_tag = cpu_to_be32(ELS_DTAG_CONGESTION);
>> cdesc->desc_len = cpu_to_be32(FC_TLV_DESC_LENGTH_FROM_SZ(*cdesc));
>> - if (fpin_status == IBMVFC_AE_FPIN_CONGESTION_CLEARED)
>> - cdesc->event_type = cpu_to_be16(FPIN_CONGN_CLEAR);
>> - else
>> - cdesc->event_type = cpu_to_be16(FPIN_CONGN_DEVICE_SPEC);
>> + cdesc->event_type = type;
>> cdesc->event_modifier = modifier;
>> - cdesc->event_period = period;
>> + cdesc->event_period = cpu_to_be32(IBMVFC_FPIN_DEFAULT_EVENT_PERIOD);
>> cdesc->severity = FPIN_CONGN_SEVERITY_WARNING;
>> break;
>> case IBMVFC_AE_FPIN_PORT_CONGESTED:
>> @@ -3281,12 +3279,9 @@ ibmvfc_common_fpin_to_desc(u8 fpin_status, __be64 wwpn, __be16 modifier,
>> pdesc = (struct fc_fn_peer_congn_desc *)fpin->fpin_desc;
>> pdesc->desc_tag = cpu_to_be32(ELS_DTAG_PEER_CONGEST);
>> pdesc->desc_len = cpu_to_be32(FC_TLV_DESC_LENGTH_FROM_SZ(*pdesc));
>> - if (fpin_status == IBMVFC_AE_FPIN_PORT_CLEARED)
>> - pdesc->event_type = cpu_to_be16(FPIN_CONGN_CLEAR);
>> - else
>> - pdesc->event_type = cpu_to_be16(FPIN_CONGN_DEVICE_SPEC);
>> + pdesc->event_type = type;
>> pdesc->event_modifier = modifier;
>> - pdesc->event_period = period;
>> + pdesc->event_period = cpu_to_be32(IBMVFC_FPIN_DEFAULT_EVENT_PERIOD);
>> pdesc->detecting_wwpn = cpu_to_be64(0);
>> pdesc->attached_wwpn = wwpn;
>> pdesc->pname_count = cpu_to_be32(1);
>> @@ -3297,7 +3292,7 @@ ibmvfc_common_fpin_to_desc(u8 fpin_status, __be64 wwpn, __be16 modifier,
>> ldesc = (struct fc_fn_li_desc *)fpin->fpin_desc;
>> ldesc->desc_tag = cpu_to_be32(ELS_DTAG_LNK_INTEGRITY);
>> ldesc->desc_len = cpu_to_be32(FC_TLV_DESC_LENGTH_FROM_SZ(*ldesc));
>> - ldesc->event_type = cpu_to_be16(FPIN_LI_UNKNOWN);
>> + ldesc->event_type = type;
>> ldesc->event_modifier = modifier;
>> ldesc->event_threshold = threshold;
>> ldesc->event_count = event_count;
>> @@ -3331,9 +3326,47 @@ ibmvfc_common_fpin_to_desc(u8 fpin_status, __be64 wwpn, __be16 modifier,
>> static struct fc_els_fpin *
>> ibmvfc_basic_fpin_to_desc(struct ibmvfc_async_crq *crq, u64 wwpn)
>> {
>> + __be16 type;
>> +
>> + switch (crq->fpin_status) {
>> + case IBMVFC_AE_FPIN_LINK_CONGESTED:
>> + case IBMVFC_AE_FPIN_PORT_CONGESTED:
>> + type = cpu_to_be16(FPIN_CONGN_DEVICE_SPEC);
>> + break;
>> + case IBMVFC_AE_FPIN_PORT_CLEARED:
>> + case IBMVFC_AE_FPIN_CONGESTION_CLEARED:
>> + type = cpu_to_be16(FPIN_CONGN_CLEAR);
>> + break;
>> + case IBMVFC_AE_FPIN_PORT_DEGRADED:
>> + type = cpu_to_be16(FPIN_LI_UNKNOWN);
>> + break;
>> + default:
>> + return (NULL);
>> + }
>> +
>> return ibmvfc_common_fpin_to_desc(crq->fpin_status, cpu_to_be64(wwpn),
>> - cpu_to_be16(0),
>> - cpu_to_be32(IBMVFC_FPIN_DEFAULT_EVENT_PERIOD),
>> + type, cpu_to_be16(0),
>> + cpu_to_be32(IBMVFC_FPIN_DEFAULT_EVENT_THRESHOLD),
>> + cpu_to_be32(1));
>> +}
>> +
>> +/**
>> + * ibmvfc_full_fpin_to_desc(): allocate and populate a struct fc_els_fpin struct
>> + * containing a descriptor.
>> + * @ibmvfc_fpin: Pointer to async subq FPIN data
>> + *
>> + * Allocate a struct fc_els_fpin containing a descriptor and populate
>> + * based on data from *ibmvfc_fpin.
>> + *
>> + * Return:
>> + * NULL - unable to allocate structure
>> + * non-NULL - pointer to populated struct fc_els_fpin
>> + */
>> +static struct fc_els_fpin *
>> +ibmvfc_full_fpin_to_desc(struct ibmvfc_async_subq *ibmvfc_fpin)
>> +{
>> + return ibmvfc_common_fpin_to_desc(ibmvfc_fpin->fpin_status, ibmvfc_fpin->wwpn,
>> + cpu_to_be16(0), cpu_to_be16(0),
>> cpu_to_be32(IBMVFC_FPIN_DEFAULT_EVENT_THRESHOLD),
>> cpu_to_be32(1));
>> }
>> @@ -3344,67 +3377,99 @@ ibmvfc_basic_fpin_to_desc(struct ibmvfc_async_crq *crq, u64 wwpn)
>> */
>> static void ibmvfc_process_async_work(struct work_struct *work)
>> {
>> + struct ibmvfc_async_subq_fpin *sqfpin;
>> + struct ibmvfc_target *tgt, *next;
>> + struct ibmvfc_async_subq *subq;
>> struct ibmvfc_async_work *aw;
>> struct ibmvfc_async_crq *crq;
>> - struct ibmvfc_target *tgt;
>> struct ibmvfc_host *vhost;
>> struct fc_els_fpin *fpin;
>> + __be64 node_name;
>> + __be64 scsi_id;
>> + __be64 wwpn;
>>
>> aw = container_of(work, struct ibmvfc_async_work, async_work_s);
>> crq = aw->crq;
>> + subq = aw->subq;
>> vhost = aw->vhost;
>>
>> - if (!crq->scsi_id && !crq->wwpn && !crq->node_name)
>> + if ((!crq && !subq) || (crq && subq)) {
>> + dev_err_ratelimited(vhost->dev,
>> + "FPIN event received, unable to process\n");
>> goto end;
>> - list_for_each_entry(tgt, &vhost->targets, queue) {
>> - if (crq->scsi_id && cpu_to_be64(tgt->scsi_id) != crq->scsi_id)
>> + }
>> +
>> + if (crq) {
>> + wwpn = crq->wwpn;
>> + node_name = crq->node_name;
>> + scsi_id = crq->scsi_id;
>> + } else {
>> + wwpn = subq->wwpn;
>> + node_name = subq->id.node_name;
>> + scsi_id = 0;
>> + }
>> +
>> + if (!scsi_id && !wwpn && !node_name)
>> + goto end;
>> +
>> + list_for_each_entry_safe(tgt, next, &vhost->targets, queue) {
>> + if (scsi_id && cpu_to_be64(tgt->scsi_id) != scsi_id)
>> continue;
>> - if (crq->wwpn && cpu_to_be64(tgt->ids.port_name) != crq->wwpn)
>> + if (wwpn && cpu_to_be64(tgt->ids.port_name) != wwpn)
>> continue;
>> - if (crq->node_name && cpu_to_be64(tgt->ids.node_name) != crq->node_name)
>> + if (node_name && cpu_to_be64(tgt->ids.node_name) != node_name)
>> continue;
>> if (!tgt->rport)
>> continue;
>> - fpin = ibmvfc_basic_fpin_to_desc(crq, tgt->wwpn);
>> + if (crq) {
>> + fpin = ibmvfc_basic_fpin_to_desc(crq, tgt->wwpn);
>> + } else {
>> + sqfpin = (struct ibmvfc_async_subq_fpin *)subq;
>> + fpin = ibmvfc_full_fpin_to_desc(subq);
>> + }
>> if (fpin) {
>> fc_host_fpin_rcv(tgt->vhost->host,
>> sizeof(*fpin) + be32_to_cpu(fpin->desc_len),
>> (char *)fpin, 0);
>> kfree(fpin);
>> } else
>> - dev_err_ratelimited(vhost->dev,
>> - "FPIN event %u received, unable to process\n",
>> - crq->fpin_status);
>> + dev_err_ratelimited(vhost->dev, "FPIN event received, unable to process\n");
>> }
>>
>> end:
>> - crq->valid = 0;
>> + if (crq)
>> + crq->valid = 0;
>> + if (subq)
>> + subq->valid = 0;
>>
>> kfree(aw);
>> }
>>
>> /**
>> - * ibmvfc_handle_async - Handle an async event from the adapter
>> - * @crq: crq to process
>> + * ibmvfc_handle_async_common - Handle an async event from the adapter
>> + * @event: event to process
>> + * @link_state: link state
>> * @vhost: ibmvfc host struct
>> + * @scsi_id: scsi_id (0 if not applicable)
>> + * @wwpn: wwpn
>> + * @node_name: node_name
>> + * @aw_crq: crq pointer for async work (NULL if not needed)
>> + * @aw_subq: subq pointer for async work (NULL if not needed)
>> *
>> **/
>> -VISIBLE_IF_KUNIT void ibmvfc_handle_async(struct ibmvfc_async_crq *crq,
>> - struct ibmvfc_host *vhost)
>> +static void ibmvfc_handle_async_common(u64 event, u8 link_state,
>> + struct ibmvfc_host *vhost,
>> + u64 scsi_id, u64 wwpn, u64 node_name,
>> + struct ibmvfc_async_crq *aw_crq,
>> + struct ibmvfc_async_subq *aw_subq)
>
> This is a lot of parameters which could be extracted here in the function if it
> just knew the type of async_crq. Would it be easier to no just take a void
> *async_instance parameter, and an is_subq boolean to determine if you cast the
> void * to ibmvfc_async_crq * or ibmvfc_async_sub_crq *?
Yes, good idea. I've changed this to
VISIBLE_IF_KUNIT void ibmvfc_handle_async(void *crq,
struct ibmvfc_host *vhost,
bool is_subq)
and will extract all of these parameters from crq.
>> +/**
>> + * ibmvfc_handle_async - Handle an async event from the adapter
>> + * @crq: crq to process
>> + * @vhost: ibmvfc host struct
>> + *
>> + **/
>> +VISIBLE_IF_KUNIT void ibmvfc_handle_async(struct ibmvfc_async_crq *crq,
>> + struct ibmvfc_host *vhost)
>
> async and asyncq as in the function name below can be hard to notice the
> difference in name convention. Maybe async_subq would be a better ender, but as
> it might be eaiser to just call ibmvfc_handle_async_common(crq, 0) and
> ibmfvc_handle_async(sub_crq, 1), as I outlined above in each of the interrupt
> handlers.
I agree. I've refactored to a singled ibmvfc_handle_async() with a
boolean parameter indicating whether the CRQ is a subqueue CRQ or not.
>> +{
>> + const struct ibmvfc_async_desc *desc = ibmvfc_get_ae_desc(be64_to_cpu(crq->event));
>> + u64 event = be64_to_cpu(crq->event);
>> +
>> + 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));
>> +
>> + ibmvfc_handle_async_common(event, crq->link_state, vhost,
>> + crq->scsi_id, crq->wwpn, crq->node_name,
>> + crq, NULL);
>> }
>> EXPORT_SYMBOL_IF_KUNIT(ibmvfc_handle_async);
>>
>> +VISIBLE_IF_KUNIT void ibmvfc_handle_asyncq(struct ibmvfc_crq *crq_instance,
>> + struct ibmvfc_host *vhost)
>> +{
>> + struct ibmvfc_async_subq *crq = (struct ibmvfc_async_subq *)crq_instance;
>> + const struct ibmvfc_async_desc *desc = ibmvfc_get_ae_desc(be16_to_cpu(crq->event));
>> + u64 event = be16_to_cpu(crq->event);
>> +
>> + ibmvfc_log(vhost, desc->log_level,
>> + "%s event received. wwpn: %llx, node_name: %llx%s event 0x%x\n",
>> + desc->desc, be64_to_cpu(crq->wwpn), be64_to_cpu(crq->id.node_name),
>> + ibmvfc_get_link_state(crq->link_state), be16_to_cpu(crq->event));
>> +
>> + ibmvfc_handle_async_common(event, crq->link_state, vhost,
>> + 0, crq->wwpn, crq->id.node_name,
>> + NULL, crq);
>> +}
>> +EXPORT_SYMBOL_IF_KUNIT(ibmvfc_handle_asyncq);
>> +
>> /**
>> * ibmvfc_handle_crq - Handles and frees received events in the CRQ
>> * @crq: Command/Response queue
>> @@ -4117,6 +4229,13 @@ static void ibmvfc_handle_scrq(struct ibmvfc_crq *crq, struct ibmvfc_host *vhost
>> spin_unlock(&evt->queue->l_lock);
>> }
>>
>> +/**
>> + * ibmvfc_next_scrq - Returns the next entry in message subqueue
>> + * @scrq: Pointer to message subqueue
>> + *
>> + * Returns:
>> + * Pointer to next entry in queue / NULL if empty
>> + **/
>> static struct ibmvfc_crq *ibmvfc_next_scrq(struct ibmvfc_queue *scrq)
>> {
>> struct ibmvfc_crq *crq;
>> @@ -4132,6 +4251,57 @@ static struct ibmvfc_crq *ibmvfc_next_scrq(struct ibmvfc_queue *scrq)
>> return crq;
>> }
>>
>> +static void ibmvfc_drain_async_subq(struct ibmvfc_queue *scrq)
>> +{
>> + struct ibmvfc_crq *crq;
>> + unsigned long flags;
>> + int done = 0;
>> +
>> + ENTER;
>> +
>> + spin_lock_irqsave(scrq->q_lock, flags);
>> + while (!done) {
>> + while ((crq = ibmvfc_next_scrq(scrq)) != NULL) {
>> + ibmvfc_handle_asyncq(crq, scrq->vhost);
>> + crq->valid = 0;
>
> Isn't up to the handle_async_common to clear the valid crq bit depending on the
> type of async action?
I've moved clearing the valid bit to ibmvfc_handle_async().
>> + wmb(); /* complete write */
>> + }
>> +
>> + ibmvfc_toggle_scrq_irq(scrq, 1);
>> + crq = ibmvfc_next_scrq(scrq);
>> + if (crq != NULL) {
>> + ibmvfc_toggle_scrq_irq(scrq, 0);
>> + ibmvfc_handle_asyncq(crq, scrq->vhost);
>> + crq->valid = 0;
>
> Same comment as above.
>
>> + wmb(); /* complete write */
>> + } else
>> + done = 1;
>> + }
>> + spin_unlock_irqrestore(scrq->q_lock, flags);
>> +
>> + LEAVE;
>> +}
>> +
>> +/**
>> + * ibmvfc_interrupt_asyncq - Handle an async event from the adapter
>> + * @irq: interrupt request
>> + * @scrq_instance: async subq
>> + *
>> + **/
>> +static irqreturn_t ibmvfc_interrupt_asyncq(int irq, void *scrq_instance)
>> +{
>> + struct ibmvfc_queue *scrq = (struct ibmvfc_queue *)scrq_instance;
>> +
>> + ENTER;
>> +
>> + ibmvfc_toggle_scrq_irq(scrq, 0);
>> + ibmvfc_drain_async_subq(scrq);
>> +
>> + LEAVE;
>> +
>> + return IRQ_HANDLED;
>> +}
>> +
>> static void ibmvfc_drain_sub_crq(struct ibmvfc_queue *scrq)
>> {
>> struct ibmvfc_crq *crq;
>> @@ -5500,6 +5670,8 @@ static void ibmvfc_npiv_login_done(struct ibmvfc_event *evt)
>> unsigned int npiv_max_sectors;
>> int level = IBMVFC_DEFAULT_LOG_LEVEL;
>>
>> + ENTER;
>> +
>> switch (mad_status) {
>> case IBMVFC_MAD_SUCCESS:
>> ibmvfc_free_event(evt);
>> @@ -5578,6 +5750,8 @@ static void ibmvfc_npiv_login_done(struct ibmvfc_event *evt)
>> ibmvfc_set_host_action(vhost, IBMVFC_HOST_ACTION_QUERY);
>> wake_up(&vhost->work_wait_q);
>> }
>> +
>> + LEAVE;
>
> Also, please drop the ENTER/LEAVE macros as these look like debug artifacts.
> Especially, in common code paths like the interrupt handlers.
Done.
-Dave
next prev parent reply other threads:[~2026-06-25 21:32 UTC|newest]
Thread overview: 29+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-06-08 18:30 [PATCH v2 0/7] ibmvfc: make ibmvfc support FPIN messages Dave Marquardt
2026-06-08 18:30 ` Dave Marquardt via B4 Relay
2026-06-08 18:30 ` [PATCH v2 1/7] ibmvfc: add basic FPIN support Dave Marquardt
2026-06-08 18:30 ` Dave Marquardt via B4 Relay
2026-06-12 22:35 ` Tyrel Datwyler
2026-06-15 20:37 ` Dave Marquardt
2026-06-15 22:10 ` Tyrel Datwyler
2026-06-15 23:38 ` Tyrel Datwyler
2026-06-08 18:30 ` [PATCH v2 2/7] ibmvfc: Add NOOP command support Dave Marquardt
2026-06-08 18:30 ` Dave Marquardt via B4 Relay
2026-06-08 18:30 ` [PATCH v2 3/7] ibmvfc: make ibmvfc login to fabric Dave Marquardt
2026-06-08 18:30 ` Dave Marquardt via B4 Relay
2026-06-12 23:11 ` Tyrel Datwyler
2026-06-15 13:42 ` Dave Marquardt
2026-06-08 18:30 ` [PATCH v2 4/7] ibmvfc: define asynchronous sub-queue Dave Marquardt
2026-06-08 18:30 ` Dave Marquardt via B4 Relay
2026-06-15 19:27 ` Tyrel Datwyler
2026-06-15 20:15 ` Dave Marquardt
2026-06-08 18:30 ` [PATCH v2 5/7] ibmvfc: allocate " Dave Marquardt
2026-06-08 18:30 ` Dave Marquardt via B4 Relay
2026-06-15 19:54 ` Tyrel Datwyler
2026-06-17 19:46 ` Dave Marquardt
2026-06-08 18:30 ` [PATCH v2 6/7] ibmvfc: register and use " Dave Marquardt
2026-06-08 18:30 ` Dave Marquardt via B4 Relay
2026-06-15 20:58 ` Tyrel Datwyler
2026-06-25 21:31 ` Dave Marquardt [this message]
2026-06-08 18:30 ` [PATCH v2 7/7] ibmvfc: handle extended FPIN events Dave Marquardt
2026-06-08 18:30 ` Dave Marquardt via B4 Relay
2026-06-15 21:52 ` Tyrel Datwyler
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=87fr2aparb.fsf@linux.ibm.com \
--to=davemarq@linux.ibm.com \
--cc=James.Bottomley@HansenPartnership.com \
--cc=brking@linux.ibm.com \
--cc=chleroy@kernel.org \
--cc=gjoyce@linux.ibm.com \
--cc=kmahlkuc@linux.ibm.com \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-scsi@vger.kernel.org \
--cc=linuxppc-dev@lists.ozlabs.org \
--cc=maddy@linux.ibm.com \
--cc=martin.petersen@oracle.com \
--cc=mpe@ellerman.id.au \
--cc=npiggin@gmail.com \
--cc=tyreld@linux.ibm.com \
/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.