Re: [PATCH v2 7/7] ibmvfc: handle extended FPIN events
From: Tyrel Datwyler <tyreld@linux.ibm.com>
Date: 2026-06-15 21:53:11
Also in:
linux-scsi, lkml
On 6/8/26 11:30 AM, Dave Marquardt via B4 Relay wrote:
quoted hunk ↗ jump to hunk
From: Dave Marquardt <redacted> Add extended FPIN handling to ibmvfc driver. Tell VIOS ibmvfc can handle extended FPIN messages, convert any received to struct fc_els descriptors, and call fc_host_fpin_rcv to update statistics and send netlink multicast messages to listeners such as multipathd. --- drivers/scsi/ibmvscsi/ibmvfc.c | 41 +++++++++++- drivers/scsi/ibmvscsi/ibmvfc.h | 31 +++++++++ drivers/scsi/ibmvscsi/ibmvfc_kunit.c | 122 +++++++++++++++++++++++++++++++++-- 3 files changed, 186 insertions(+), 8 deletions(-)diff --git a/drivers/scsi/ibmvscsi/ibmvfc.c b/drivers/scsi/ibmvscsi/ibmvfc.c index a2252cd2f44b..b034a894e3ec 100644 --- a/drivers/scsi/ibmvscsi/ibmvfc.c +++ b/drivers/scsi/ibmvscsi/ibmvfc.c@@ -1515,7 +1515,8 @@ static void ibmvfc_set_login_info(struct ibmvfc_host *vhost) login_info->capabilities = cpu_to_be64(IBMVFC_CAN_MIGRATE | IBMVFC_CAN_SEND_VF_WWPN | IBMVFC_CAN_USE_NOOP_CMD | IBMVFC_YES_SCSI | - IBMVFC_USE_ASYNC_SUBQ | IBMVFC_CAN_HANDLE_FPIN); + IBMVFC_USE_ASYNC_SUBQ | IBMVFC_CAN_HANDLE_FPIN | + IBMVFC_CAN_HANDLE_FPIN_EXT); if (vhost->mq_enabled || vhost->using_channels) login_info->capabilities |= cpu_to_be64(IBMVFC_CAN_USE_CHANNELS);@@ -3254,7 +3255,7 @@ ibmvfc_common_fpin_to_desc(u8 fpin_status, __be64 wwpn, __be16 type, __be16 modi if (size == 0) return NULL; - fpin = kzalloc(size, GFP_ATOMIC); + fpin = kzalloc(size, GFP_KERNEL);
I commented on why this was changed in the previous patch, but now its been reverted back here. Looks like a refactoring artifact that needs to be fixed in patch 6.
quoted hunk ↗ jump to hunk
if (fpin == NULL) return NULL;@@ -3371,6 +3372,28 @@ ibmvfc_full_fpin_to_desc(struct ibmvfc_async_subq *ibmvfc_fpin) cpu_to_be32(1)); } +/** + * ibmvfc_ext_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_ext_fpin_to_desc(struct ibmvfc_async_subq_fpin *ibmvfc_fpin) +{ + return ibmvfc_common_fpin_to_desc(ibmvfc_fpin->fpin_status, ibmvfc_fpin->wwpn, + ibmvfc_fpin->fpin_data.event_type, + ibmvfc_fpin->fpin_data.event_type_modifier, + ibmvfc_fpin->fpin_data.event_threshold, + ibmvfc_fpin->fpin_data.event_data.event_count); +} + /** * ibmvfc_process_async_work - Process IBMVFC_AE_FPIN async CRQ from work queue * @work: pointer to work_struct@@ -3425,7 +3448,19 @@ static void ibmvfc_process_async_work(struct work_struct *work) fpin = ibmvfc_basic_fpin_to_desc(crq, tgt->wwpn); } else { sqfpin = (struct ibmvfc_async_subq_fpin *)subq; - fpin = ibmvfc_full_fpin_to_desc(subq);
I think this should be fpin = NULL here.
+ if ((subq->flags & IBMVFC_ASYNC_IS_FPIN_EXT) == 0) {
+ fpin = ibmvfc_full_fpin_to_desc(subq);As you set it here for non-EXT fpins.
+ } else if (!(sqfpin->fpin_data.flags & IBMVFC_FPIN_EVENT_TYPE_VALID)) {
+ dev_err_ratelimited(vhost->dev,
+ "Invalid extended FPIN event received");
+ fpin = NULL;No longer need to set NULL here
+ } else if (!ibmvfc_check_caps(vhost, IBMVFC_SUPPORT_FPIN_EXT)) {
+ dev_err_ratelimited(vhost->dev,
+ "Unexpected extended FPIN event received");
+ fpin = NULL;Or here.
+ } else {
+ fpin = ibmvfc_ext_fpin_to_desc(sqfpin);And here you set the ext-fpin case. -Tyrel