From nobody Fri Sep 25 15:13:49 2026 Received: from mx0b-001b2d01.pphosted.com (mx0b-001b2d01.pphosted.com [148.163.158.5]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 81870334692; Fri, 11 Sep 2026 05:48:47 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=148.163.158.5 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789105729; cv=none; b=utiUpIo2C2qvIDJf4EsOaKtY0KKx8Sy8ySD/PwukvegVY+b/D1jl3TyuQMfoUdQcfTf7XrMwAfGEyTyUctdK+k9prunUKpU6oBpVQLzogVqgUxnGirW1R/1Shq9wi/k5oc3AM4Bm3loUgaUzowNfHGBDTKwNScw8eJuneDvkV8A= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789105729; c=relaxed/simple; bh=1iAz/FwkFUfRNMCJJcssYt/Vbylm5hF7cCUjALnwLd4=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=k9Fvkrrwom2oxYa+hl9cr1gy4TVCGyVXKXQRKodE3jgBzp/tg3BX7z1ejlrjGLPkwTlb1ryeVpQvEt1NwsoCRNNvD7QllwidaB52dS9iQOUY8+YTNV0Era4bzyC8NceRSgDaPifW6dmwDSoFs+4ILOG4ICnTdBwZrsoBPDse9x8= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.ibm.com; spf=pass smtp.mailfrom=linux.ibm.com; dkim=pass (2048-bit key) header.d=ibm.com header.i=@ibm.com header.b=DGrgTMNS; arc=none smtp.client-ip=148.163.158.5 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.ibm.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linux.ibm.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=ibm.com header.i=@ibm.com header.b="DGrgTMNS" Received: from pps.filterd (m0353725.ppops.net [127.0.0.1]) by mx0a-001b2d01.pphosted.com (8.18.1.11/8.18.1.11) with ESMTP id 68B4VaUC3839771; Fri, 11 Sep 2026 05:48:39 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ibm.com; h=cc :content-transfer-encoding:date:from:in-reply-to:message-id :mime-version:references:subject:to; s=pp1; bh=EpCYtOxPZ2tUA2BZa rIXbS/bz+YQP/qiN7gN/t4xT2M=; b=DGrgTMNSb1WPgvpxhx8mpDjNHsJar39ao ZA+F+1hJ5WTW5yKTzCAHqPu5xjUUMkulJButuV0gdKADMeqs7LZmeHPK/lUPOj4o qwcNkjAYFA/TdROrVH5fat1HiXxnhumzSxfSM3DnN9NUZIGtZey0SqiyF75Stz/r qtICOHiWKxzhTitmtidHJ8RWax8xBtxUVedPLLWu+XySmXMUFvLWfAsKniSaJ1s7 ps1KRXiCct7ZlXjqrwohnGPeJbJds8UKcHnMzVJv4kRqsxddICc34U14YfT7JzLE /r7fNrTt9i1jIW3h6o100NdZSE3OGgpJPdWHlHY73adWQ5QVddKxA== Received: from ppma22.wdc07v.mail.ibm.com (5c.69.3da9.ip4.static.sl-reverse.com [169.61.105.92]) by mx0a-001b2d01.pphosted.com (PPS) with ESMTPS id 4gkd8q9g64-1 (version=TLSv1.3 cipher=TLS_AES_256_GCM_SHA384 bits=256 verify=NOT); Fri, 11 Sep 2026 05:48:39 +0000 (GMT) Received: from pps.filterd (ppma22.wdc07v.mail.ibm.com [127.0.0.1]) by ppma22.wdc07v.mail.ibm.com (8.18.1.11/8.18.1.11) with ESMTP id 68B4K2H11076021; Fri, 11 Sep 2026 05:48:38 GMT Received: from smtprelay02.dal12v.mail.ibm.com ([172.16.1.4]) by ppma22.wdc07v.mail.ibm.com (PPS) with ESMTPS id 4gkvwk4j77-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Fri, 11 Sep 2026 05:48:38 +0000 (GMT) Received: from smtpav02.dal12v.mail.ibm.com (smtpav02.dal12v.mail.ibm.com [10.241.53.101]) by smtprelay02.dal12v.mail.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id 68B5mbP15046974 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Fri, 11 Sep 2026 05:48:37 GMT Received: from smtpav02.dal12v.mail.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 6CB0E58051; Fri, 11 Sep 2026 05:48:37 +0000 (GMT) Received: from smtpav02.dal12v.mail.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id BF1F15805C; Fri, 11 Sep 2026 05:48:36 +0000 (GMT) Received: from li-4c4c4544-0054-3910-8039-c3c04f423534.ibm.com.com (unknown [9.61.103.123]) by smtpav02.dal12v.mail.ibm.com (Postfix) with ESMTP; Fri, 11 Sep 2026 05:48:36 +0000 (GMT) From: Tyrel Datwyler To: james.bottomley@hansenpartnership.com, martin.petersen@oracle.com Cc: linux-scsi@vger.kernel.org, linuxppc-dev@lists.ozlabs.org, linux-kernel@vger.kernel.org, brking@linux.ibm.com, davemarq@linux.ibm.com, Tyrel Datwyler Subject: [PATCH v10 1/9] scsi: ibmvfc: add basic FPIN support Date: Thu, 10 Sep 2026 22:48:24 -0700 Message-ID: <20260911054832.1311668-2-tyreld@linux.ibm.com> X-Mailer: git-send-email 2.55.0 In-Reply-To: <20260911054832.1311668-1-tyreld@linux.ibm.com> References: <20260911054832.1311668-1-tyreld@linux.ibm.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-TM-AS-GCONF: 00 X-Proofpoint-ORIG-GUID: utan3yv07Yj6dE2FSaZNX_C8M-MYQiK_ X-Proofpoint-Spam-Info: AW1haW4tMjYwOTExMDA3NCBTYWx0ZWRfX4OtMWUrTgc2G V+RLiAm8oC1Bc9K8n47P0w+/vuQyuasHIFOl8QhebXOmeD8Qsa4OurGkTfu7RW3yEiCGzKZRTwr DvHyBup3ZV7qk0R9k6RfGWb3h13TyaU= X-Authority-Analysis: v=2.4 cv=E/dYNqdl c=1 sm=1 tr=0 ts=6aa39637 cx=c_pps a=5BHTudwdYE3Te8bg5FgnPg==:117 a=5BHTudwdYE3Te8bg5FgnPg==:17 a=VdqzKS8jKosA:10 a=VkNPw1HP01LnGYTKEx00:22 a=RnoormkPH1_aCDwRdu11:22 a=V8glGbnc2Ofi9Qvn3v5h:22 a=VnNF1IyMAAAA:8 a=spueyG-pivhLj-E1BzsA:9 X-Proofpoint-Spam-Details-Enc: AW1haW4tMjYwOTExMDA3NCBTYWx0ZWRfX4uVXL0PekHKt 7rtPBUitSNNCi48s+Egf2ZcX3XycFCVudUY9T7wc9L6+3/jIm+Pfr7yJ4rnlf6mc7yzCyzjfDjP AktzvgWVJkL0VzVINAeshiS79IaYHHuEcS0/69gnvtiVG0i3eEg2G9M81w0o93SlaU3tVGT3PRN n/pt8Ydhp3vjm/Kq/Ex6zIIt5t1aMREkIy4IK4aufBLYwc39dYxPwX2SprVOIkYIbEhTDusLFYm HiOfTIItmtNI2SEC2g1/ZPbIFV73rZzrJ4SZqFw8A70inZFfzXljI+REig7pacq2gf3+n3nwlCB Nw1Nt7K5kpMnQeuoWa5Y0VM3rvo0afWS3Srh6QC1ElUVxG8Mh3hMYrzVJ8flZWFNUI/Sy3L3IKR lgO2VrBmUGex05LYKCIWrYCDRSSgKNcyLmO+cLNDcYChvUTpzLvnlUldb1H0k4ESP7hsCelVUl/ tY/sry1IHRGWUo3Be7g== X-Proofpoint-GUID: utan3yv07Yj6dE2FSaZNX_C8M-MYQiK_ X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1176,Hydra:6.1.134,FMLib:17.12.100.49 definitions=2026-09-11_02,2026-09-09_02,2025-10-01_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 priorityscore=1501 suspectscore=0 spamscore=0 bulkscore=0 clxscore=1015 impostorscore=0 phishscore=0 adultscore=0 lowpriorityscore=0 malwarescore=0 classifier=typeunknown authscore=0 authtc= authcc= route=outbound adjust=0 reason=mlx scancount=1 engine=8.22.0-2609040000 definitions=main-2609110074 Content-Type: text/plain; charset="utf-8" From: Dave Marquardt Implement support for a basic level of Fabric Performance Impact Notifications (FPIN) in the ibmvfc driver to enable monitoring of fabric congestion and link integrity events. Add async event handler for IBMVFC_AE_FPIN events that offloads FPIN processing to a dedicated workqueue. Convert VIOS FPIN messages to standard fc_els_fpin structures and pass them to fc_host_fpin_rcv() for processing by the FC transport layer. Introduce common FPIN conversion routines that will be reused for full and extended FPIN support in subsequent patches. Add KUnit test infrastructure to validate FPIN event handling and statistics updates. Add ibmvfc_handle_async() support for IBMVFC_AE_FPIN events, a dedicated workqueue for FPIN processing, FPIN message conversion to fc_els_fpin format, handling of link congestion, port congestion, port cleared, port degraded, and congestion cleared events, and a KUnit test module for FPIN functionality. Signed-off-by: Dave Marquardt [tyreld: add & operator to irqsave/restore calls] [tyreld: check for valid fc or nvme port in ibmvfc_find_target] [tyreld: remove kunit tests meant for later patchs] Signed-off-by: Tyrel Datwyler --- drivers/scsi/Kconfig | 10 + drivers/scsi/ibmvscsi/Makefile | 1 + drivers/scsi/ibmvscsi/ibmvfc-core.c | 297 ++++++++++++++++++++++++++- drivers/scsi/ibmvscsi/ibmvfc.h | 17 ++ drivers/scsi/ibmvscsi/ibmvfc_kunit.c | 148 +++++++++++++ 5 files changed, 468 insertions(+), 5 deletions(-) create mode 100644 drivers/scsi/ibmvscsi/ibmvfc_kunit.c diff --git a/drivers/scsi/Kconfig b/drivers/scsi/Kconfig index 1eec66195cf4..320c37c4ab36 100644 --- a/drivers/scsi/Kconfig +++ b/drivers/scsi/Kconfig @@ -760,6 +760,16 @@ config SCSI_IBMVFC To compile this driver as a module, choose M here: the module will be called ibmvfc. =20 +config SCSI_IBMVFC_KUNIT_TEST + tristate "KUnit tests for the IBM POWER Virtual FC Client" if !KUNIT_ALL_= TESTS + depends on SCSI_IBMVFC && KUNIT + default KUNIT_ALL_TESTS + help + Compile IBM POWER Virtual FC client KUnit tests. These tests + specifically test FPIN functionality. To compile this driver + as a module, choose M here: the module will be called + ibmvfc_kunit. + config SCSI_IBMVFC_TRACE bool "enable driver internal trace" depends on SCSI_IBMVFC diff --git a/drivers/scsi/ibmvscsi/Makefile b/drivers/scsi/ibmvscsi/Makefile index 9408c7f4cdee..a227bc633f3a 100644 --- a/drivers/scsi/ibmvscsi/Makefile +++ b/drivers/scsi/ibmvscsi/Makefile @@ -3,3 +3,4 @@ ibmvfc-objs :=3D ibmvfc-core.o ibmvfc-nvme.o =20 obj-$(CONFIG_SCSI_IBMVSCSI) +=3D ibmvscsi.o obj-$(CONFIG_SCSI_IBMVFC) +=3D ibmvfc.o +obj-$(CONFIG_SCSI_IBMVFC_KUNIT_TEST) +=3D ibmvfc_kunit.o diff --git a/drivers/scsi/ibmvscsi/ibmvfc-core.c b/drivers/scsi/ibmvscsi/ib= mvfc-core.c index aa7ae81df41b..514fc87c1017 100644 --- a/drivers/scsi/ibmvscsi/ibmvfc-core.c +++ b/drivers/scsi/ibmvscsi/ibmvfc-core.c @@ -31,6 +31,9 @@ #include #include #include +#include +#include +#include #include "ibmvfc.h" =20 static unsigned int init_timeout =3D IBMVFC_INIT_TIMEOUT; @@ -1433,6 +1436,7 @@ void ibmvfc_release_tgt(struct kref *kref) struct ibmvfc_target *tgt =3D container_of(kref, struct ibmvfc_target, kr= ef); mempool_free(tgt, tgt->vhost->tgt_pool); } +EXPORT_SYMBOL_IF_KUNIT(ibmvfc_release_tgt); =20 /** * ibmvfc_get_starget_node_name - Get SCSI target's node name @@ -3213,6 +3217,7 @@ static const struct ibmvfc_async_desc ae_desc [] =3D { { "Halt", IBMVFC_AE_HALT, IBMVFC_DEFAULT_LOG_LEVEL }, { "Resume", IBMVFC_AE_RESUME, IBMVFC_DEFAULT_LOG_LEVEL }, { "Adapter Failed", IBMVFC_AE_ADAPTER_FAILED, IBMVFC_DEFAULT_LOG_LEVEL }, + { "FPIN", IBMVFC_AE_FPIN, IBMVFC_DEFAULT_LOG_LEVEL }, }; =20 static const struct ibmvfc_async_desc unknown_ae =3D { @@ -3261,16 +3266,259 @@ static const char *ibmvfc_get_link_state(enum ibmv= fc_ae_link_state state) return ""; } =20 +#define IBMVFC_FPIN_CONGN_DESC_SZ (sizeof(struct fc_els_fpin) + sizeof(str= uct fc_fn_congn_desc)) +#define IBMVFC_FPIN_LI_DESC_SZ (sizeof(struct fc_els_fpin) + \ + struct_size_t(struct fc_fn_li_desc, pname_list, 1)) +#define IBMVFC_FPIN_PEER_CONGN_DESC_SZ (sizeof(struct fc_els_fpin) + \ + struct_size_t(struct fc_fn_peer_congn_desc, pname_list, 1)) + +/** + * ibmvfc_fpin_size_helper(): compute fpin structure size based on fpin st= atus + * @fpin_status: status value + * + * Return: + * 0: invalid fpin_status + * other: valid size + */ +static size_t ibmvfc_fpin_size_helper(u8 fpin_status) +{ + size_t size =3D 0; + + switch (fpin_status) { + case IBMVFC_AE_FPIN_LINK_CONGESTED: + case IBMVFC_AE_FPIN_CONGESTION_CLEARED: + size =3D IBMVFC_FPIN_CONGN_DESC_SZ; + break; + case IBMVFC_AE_FPIN_PORT_CONGESTED: + case IBMVFC_AE_FPIN_PORT_CLEARED: + size =3D IBMVFC_FPIN_PEER_CONGN_DESC_SZ; + break; + case IBMVFC_AE_FPIN_PORT_DEGRADED: + size =3D IBMVFC_FPIN_LI_DESC_SZ; + break; + default: + break; + } + + return size; +} + +/** + * ibmvfc_common_fpin_to_desc(): allocate and populate a struct fc_els_fpi= n struct + * containing a descriptor. + * + * 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_common_fpin_to_desc(u8 fpin_status, __be64 wwpn, __be16 type, __be1= 6 modifier, + __be32 threshold, __be32 event_count) +{ + struct fc_fn_peer_congn_desc *pdesc; + struct fc_fn_congn_desc *cdesc; + struct fc_fn_li_desc *ldesc; + struct fc_els_fpin *fpin; + size_t size; + + size =3D ibmvfc_fpin_size_helper(fpin_status); + if (!size) + return NULL; + + fpin =3D kzalloc(size, GFP_KERNEL); + if (!fpin) + return NULL; + + fpin->fpin_cmd =3D ELS_FPIN; + + switch (fpin_status) { + case IBMVFC_AE_FPIN_CONGESTION_CLEARED: + case IBMVFC_AE_FPIN_LINK_CONGESTED: + fpin->desc_len =3D cpu_to_be32(sizeof(struct fc_fn_congn_desc)); + cdesc =3D (struct fc_fn_congn_desc *)fpin->fpin_desc; + cdesc->desc_tag =3D cpu_to_be32(ELS_DTAG_CONGESTION); + cdesc->desc_len =3D cpu_to_be32(FC_TLV_DESC_LENGTH_FROM_SZ(*cdesc)); + cdesc->event_type =3D type; + cdesc->event_modifier =3D modifier; + cdesc->event_period =3D cpu_to_be32(IBMVFC_FPIN_DEFAULT_EVENT_PERIOD); + cdesc->severity =3D FPIN_CONGN_SEVERITY_WARNING; + break; + case IBMVFC_AE_FPIN_PORT_CONGESTED: + case IBMVFC_AE_FPIN_PORT_CLEARED: + fpin->desc_len =3D + cpu_to_be32(struct_size_t(struct fc_fn_peer_congn_desc, pname_list, 1)); + pdesc =3D (struct fc_fn_peer_congn_desc *)fpin->fpin_desc; + pdesc->desc_tag =3D cpu_to_be32(ELS_DTAG_PEER_CONGEST); + pdesc->desc_len =3D cpu_to_be32(struct_size_t(struct fc_fn_peer_congn_de= sc, + pname_list, 1) - FC_TLV_DESC_HDR_SZ); + pdesc->event_type =3D type; + pdesc->event_modifier =3D modifier; + pdesc->event_period =3D cpu_to_be32(IBMVFC_FPIN_DEFAULT_EVENT_PERIOD); + pdesc->attached_wwpn =3D wwpn; + pdesc->pname_count =3D cpu_to_be32(1); + pdesc->pname_list[0] =3D wwpn; + break; + case IBMVFC_AE_FPIN_PORT_DEGRADED: + fpin->desc_len =3D cpu_to_be32(struct_size_t(struct fc_fn_li_desc, pname= _list, 1)); + ldesc =3D (struct fc_fn_li_desc *)fpin->fpin_desc; + ldesc->desc_tag =3D cpu_to_be32(ELS_DTAG_LNK_INTEGRITY); + ldesc->desc_len =3D cpu_to_be32(struct_size_t(struct fc_fn_li_desc, + pname_list, 1) - FC_TLV_DESC_HDR_SZ); + ldesc->event_type =3D type; + ldesc->event_modifier =3D modifier; + ldesc->event_threshold =3D threshold; + ldesc->event_count =3D event_count; + ldesc->attached_wwpn =3D wwpn; + ldesc->pname_count =3D cpu_to_be32(1); + ldesc->pname_list[0] =3D wwpn; + break; + default: + /* This should be caught above. */ + kfree(fpin); + fpin =3D NULL; + break; + } + + return fpin; +} + +/** + * ibmvfc_basic_fpin_to_desc(): allocate and populate a struct fc_els_fpin= struct + * containing a descriptor. + * @ibmvfc_fpin: Pointer to async crq + * + * 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_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 =3D cpu_to_be16(FPIN_CONGN_DEVICE_SPEC); + break; + case IBMVFC_AE_FPIN_PORT_CLEARED: + case IBMVFC_AE_FPIN_CONGESTION_CLEARED: + type =3D cpu_to_be16(FPIN_CONGN_CLEAR); + break; + case IBMVFC_AE_FPIN_PORT_DEGRADED: + type =3D cpu_to_be16(FPIN_LI_UNKNOWN); + break; + default: + return NULL; + } + + return ibmvfc_common_fpin_to_desc(crq->fpin_status, cpu_to_be64(wwpn), + type, cpu_to_be16(0), + cpu_to_be32(IBMVFC_FPIN_DEFAULT_EVENT_THRESHOLD), + cpu_to_be32(1)); +} + +/** + * ibmvfc_find_target - Search for a target in a target list + * @target_list: list head of targets to search + * @scsi_id: SCSI ID to match (0 to skip this check) + * @wwpn: WWPN to match (0 to skip this check) + * @node_name: Node name to match (0 to skip this check) + * + * Returns: + * Pointer to matching target, or NULL if not found + **/ +static struct ibmvfc_target *ibmvfc_find_target(struct list_head *target_l= ist, + __be64 scsi_id, __be64 wwpn, + __be64 node_name) +{ + struct ibmvfc_target *tgt; + + list_for_each_entry(tgt, target_list, queue) { + if (scsi_id && cpu_to_be64(tgt->scsi_id) !=3D scsi_id) + continue; + if (wwpn && cpu_to_be64(tgt->ids.port_name) !=3D wwpn) + continue; + if (node_name && cpu_to_be64(tgt->ids.node_name) !=3D node_name) + continue; + if (!tgt->rport && !tgt->nvme_remote_port) + continue; + return tgt; + } + + return NULL; +} + +/** + * ibmvfc_process_async_work - Process IBMVFC_AE_FPIN async CRQ from work = queue + * @work: pointer to work_struct + */ +static void ibmvfc_process_async_work(struct work_struct *work) +{ + struct ibmvfc_async_work *aw; + struct ibmvfc_async_crq *crq; + struct ibmvfc_target *tgt; + struct ibmvfc_host *vhost; + struct fc_els_fpin *fpin; + unsigned long flags; + + aw =3D container_of_const(work, struct ibmvfc_async_work, async_work_s); + vhost =3D aw->vhost; + crq =3D &aw->crq; + + if (!crq->scsi_id && !crq->wwpn && !crq->node_name) + goto free; + + spin_lock_irqsave(&vhost->host->host_lock, flags); + tgt =3D ibmvfc_find_target(&vhost->scsi_scrqs.targets, crq->scsi_id, + crq->wwpn, crq->node_name); + if (!tgt) { + /* Target not found in scsi_scrqs, search nvme_scrqs */ + tgt =3D ibmvfc_find_target(&vhost->nvme_scrqs.targets, + crq->scsi_id, crq->wwpn, + crq->node_name); + } + + if (tgt) { + kref_get(&tgt->kref); + spin_unlock_irqrestore(&vhost->host->host_lock, flags); + } else { + spin_unlock_irqrestore(&vhost->host->host_lock, flags); + dev_err_ratelimited(vhost->dev, "Invalid target for FPIN\n"); + goto free; + } + + fpin =3D ibmvfc_basic_fpin_to_desc(crq, tgt->wwpn); + 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 received, unable to process\= n"); + + kref_put(&tgt->kref, ibmvfc_release_tgt); + free: + kfree(aw); +} + /** * ibmvfc_handle_async - Handle an async event from the adapter * @crq: crq to process * @vhost: ibmvfc host struct * **/ -static void ibmvfc_handle_async(struct ibmvfc_async_crq *crq, - struct ibmvfc_host *vhost) +VISIBLE_IF_KUNIT void ibmvfc_handle_async(struct ibmvfc_async_crq *crq, + struct ibmvfc_host *vhost) { const struct ibmvfc_async_desc *desc =3D ibmvfc_get_ae_desc(be64_to_cpu(c= rq->event)); + struct ibmvfc_async_work *aw; struct ibmvfc_target *tgt; =20 ibmvfc_log(vhost, desc->log_level, "%s event received. scsi_id: %llx, wwp= n: %llx," @@ -3361,11 +3609,23 @@ static void ibmvfc_handle_async(struct ibmvfc_async= _crq *crq, case IBMVFC_AE_HALT: ibmvfc_link_down(vhost, IBMVFC_HALTED); break; + case IBMVFC_AE_FPIN: + aw =3D kzalloc(sizeof(struct ibmvfc_async_work), GFP_ATOMIC); + if (aw) { + INIT_WORK(&aw->async_work_s, ibmvfc_process_async_work); + aw->vhost =3D vhost; + aw->crq =3D *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); break; } } +EXPORT_SYMBOL_IF_KUNIT(ibmvfc_handle_async); =20 /** * ibmvfc_handle_crq - Handles and frees received events in the CRQ @@ -6875,9 +7135,15 @@ static int ibmvfc_probe(struct vio_dev *vdev, const = struct vio_device_id *id) INIT_WORK(&vhost->rport_add_work_q, ibmvfc_rport_add_thread); mutex_init(&vhost->passthru_mutex); =20 - if ((rc =3D ibmvfc_alloc_mem(vhost))) + vhost->fpin_workq =3D alloc_workqueue("%s-fpin-workq-%u", WQ_UNBOUND, 0, + IBMVFC_NAME, shost->host_no); + if (vhost->fpin_workq =3D=3D NULL) goto free_scsi_host; =20 + rc =3D ibmvfc_alloc_mem(vhost); + if (rc) + goto free_workq; + vhost->work_thread =3D kthread_run(ibmvfc_work, vhost, "%s_%d", IBMVFC_NA= ME, shost->host_no); =20 @@ -6923,6 +7189,9 @@ static int ibmvfc_probe(struct vio_dev *vdev, const s= truct vio_device_id *id) kthread_stop(vhost->work_thread); free_host_mem: ibmvfc_free_mem(vhost); +free_workq: + destroy_workqueue(vhost->fpin_workq); + vhost->fpin_workq =3D NULL; free_scsi_host: scsi_host_put(shost); out: @@ -6953,8 +7222,6 @@ static void ibmvfc_remove(struct vio_dev *vdev) ibmvfc_wait_while_resetting(vhost); kthread_stop(vhost->work_thread); flush_work(&vhost->rport_add_work_q); - fc_remove_host(vhost->host); - scsi_remove_host(vhost->host); =20 spin_lock_irqsave(&vhost->host->host_lock, flags); ibmvfc_purge_requests(vhost, DID_ERROR); @@ -6963,6 +7230,10 @@ static void ibmvfc_remove(struct vio_dev *vdev) ibmvfc_complete_purge(&purge); ibmvfc_release_sub_crqs(vhost); ibmvfc_release_crq_queue(vhost); + destroy_workqueue(vhost->fpin_workq); + vhost->fpin_workq =3D NULL; + fc_remove_host(vhost->host); + scsi_remove_host(vhost->host); =20 ibmvfc_free_mem(vhost); spin_lock(&ibmvfc_driver_lock); @@ -7115,5 +7386,21 @@ static void __exit ibmvfc_module_exit(void) fc_release_transport(ibmvfc_transport_template); } =20 +#if IS_ENABLED(CONFIG_KUNIT) +VISIBLE_IF_KUNIT struct ibmvfc_host *ibmvfc_get_first_vhost(void) +{ + struct ibmvfc_host *vhost =3D NULL; + + spin_lock(&ibmvfc_driver_lock); + if (!list_empty(&ibmvfc_head)) + vhost =3D list_first_entry(&ibmvfc_head, struct ibmvfc_host, queue); + if (vhost) + scsi_host_get(vhost->host); + spin_unlock(&ibmvfc_driver_lock); + return vhost; +} +EXPORT_SYMBOL_IF_KUNIT(ibmvfc_get_first_vhost); +#endif + module_init(ibmvfc_module_init); module_exit(ibmvfc_module_exit); diff --git a/drivers/scsi/ibmvscsi/ibmvfc.h b/drivers/scsi/ibmvscsi/ibmvfc.h index ca80ceffe53a..d7a30e7a4a28 100644 --- a/drivers/scsi/ibmvscsi/ibmvfc.h +++ b/drivers/scsi/ibmvscsi/ibmvfc.h @@ -750,8 +750,12 @@ enum ibmvfc_ae_fpin_status { IBMVFC_AE_FPIN_PORT_CONGESTED =3D 0x2, IBMVFC_AE_FPIN_PORT_CLEARED =3D 0x3, IBMVFC_AE_FPIN_PORT_DEGRADED =3D 0x4, + IBMVFC_AE_FPIN_CONGESTION_CLEARED =3D 0x5, }; =20 +#define IBMVFC_FPIN_DEFAULT_EVENT_PERIOD (5*60*MSEC_PER_SEC) /* 5 minutes = */ +#define IBMVFC_FPIN_DEFAULT_EVENT_THRESHOLD (5*60*MSEC_PER_SEC/2) /* 2.5 m= inutes */ + struct ibmvfc_async_crq { volatile u8 valid; u8 link_state; @@ -781,6 +785,12 @@ struct ibmvfc_async_sub_crq { } id; } __packed __aligned(8); =20 +struct ibmvfc_async_work { + struct ibmvfc_host *vhost; + struct ibmvfc_async_crq crq; + struct work_struct async_work_s; +}; + union ibmvfc_iu { struct ibmvfc_mad_common mad_common; struct ibmvfc_npiv_login_mad npiv_login; @@ -1022,6 +1032,7 @@ struct ibmvfc_host { wait_queue_head_t work_wait_q; struct nvme_fc_local_port *nvme_local_port; struct completion nvme_delete_done; + struct workqueue_struct *fpin_workq; }; =20 struct ibmvfc_event *__ibmvfc_get_event(struct ibmvfc_queue *queue, int re= served); @@ -1088,4 +1099,10 @@ static inline struct ibmvfc_host *ibmvfc_channels_to= _vhost(struct ibmvfc_channel #define ibmvfc_remove_trace_file(kobj, attr) do { } while (0) #endif =20 +#if IS_ENABLED(CONFIG_KUNIT) +#include +VISIBLE_IF_KUNIT void ibmvfc_handle_async(struct ibmvfc_async_crq *crq, st= ruct ibmvfc_host *vhost); +VISIBLE_IF_KUNIT struct ibmvfc_host *ibmvfc_get_first_vhost(void); +#endif + #endif diff --git a/drivers/scsi/ibmvscsi/ibmvfc_kunit.c b/drivers/scsi/ibmvscsi/i= bmvfc_kunit.c new file mode 100644 index 000000000000..67bd3922a49f --- /dev/null +++ b/drivers/scsi/ibmvscsi/ibmvfc_kunit.c @@ -0,0 +1,148 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +#include +#include +#include +#include +#include +#include +#include +#include "ibmvfc.h" + +MODULE_IMPORT_NS("EXPORTED_FOR_KUNIT_TESTING"); + +/** + * ibmvfc_async_fpin_event_test - unit test for IBMVFC_AE_FPIN parts of + * ibmvfc_handle_async + * @test: pointer to kunit structure + * + * Tests + * - error returns from ibmvfc_handle_async + * - statistics updates + * + * Return: void + */ +static void ibmvfc_async_fpin_test(struct kunit *test) +{ + u64 post[IBMVFC_AE_FPIN_CONGESTION_CLEARED + 1]; + u64 pre[IBMVFC_AE_FPIN_CONGESTION_CLEARED + 1]; + struct ibmvfc_async_crq ae[IBMVFC_AE_FPIN_CONGESTION_CLEARED + 1]; + enum ibmvfc_ae_fpin_status fs; + struct fc_host_attrs *fc_host; + struct ibmvfc_target *tgt; + struct ibmvfc_host *vhost; + struct fc_rport *rport; + unsigned long flags; + + vhost =3D ibmvfc_get_first_vhost(); + if (!vhost) + kunit_skip(test, "No ibmvfc devices available"); + + spin_lock_irqsave(&vhost->host->host_lock, flags); + if (vhost->scsi_scrqs.num_targets < 1) { + spin_unlock_irqrestore(&vhost->host->host_lock, flags); + scsi_host_put(vhost->host); + kunit_skip(test, "No targets"); + } + tgt =3D list_first_entry(&vhost->scsi_scrqs.targets, struct ibmvfc_target= , queue); + if (!tgt->rport) { + spin_unlock_irqrestore(&vhost->host->host_lock, flags); + scsi_host_put(vhost->host); + kunit_skip(test, "No rport"); + } + rport =3D tgt->rport; + get_device(&rport->dev); + kref_get(&tgt->kref); + spin_unlock_irqrestore(&vhost->host->host_lock, flags); + + fc_host =3D shost_to_fc_host(vhost->host); + + pre[IBMVFC_AE_FPIN_LINK_CONGESTED] =3D READ_ONCE(fc_host->fpin_stats.cn_d= evice_specific); + pre[IBMVFC_AE_FPIN_PORT_CONGESTED] =3D READ_ONCE(rport->fpin_stats.cn_dev= ice_specific); + pre[IBMVFC_AE_FPIN_PORT_CLEARED] =3D READ_ONCE(rport->fpin_stats.cn_clear= ); + pre[IBMVFC_AE_FPIN_PORT_DEGRADED] =3D READ_ONCE(rport->fpin_stats.li_fail= ure_unknown); + pre[IBMVFC_AE_FPIN_CONGESTION_CLEARED] =3D READ_ONCE(fc_host->fpin_stats.= cn_clear); + + for (fs =3D IBMVFC_AE_FPIN_LINK_CONGESTED; fs <=3D IBMVFC_AE_FPIN_CONGEST= ION_CLEARED; fs++) { + ae[fs].valid =3D 0x80; + ae[fs].link_state =3D IBMVFC_AE_LS_LINK_UP; + ae[fs].fpin_status =3D fs; + ae[fs].event =3D cpu_to_be64(IBMVFC_AE_FPIN); + ae[fs].scsi_id =3D cpu_to_be64(tgt->scsi_id); + ae[fs].wwpn =3D cpu_to_be64(tgt->wwpn); + ae[fs].node_name =3D cpu_to_be64(tgt->ids.node_name); + ibmvfc_handle_async(&ae[fs], vhost); + ae[fs].valid =3D 0; + wmb(); /* ensure valid bit clear is visible before checking stats */ + } + flush_workqueue(vhost->fpin_workq); + + post[IBMVFC_AE_FPIN_LINK_CONGESTED] =3D READ_ONCE(fc_host->fpin_stats.cn_= device_specific); + post[IBMVFC_AE_FPIN_PORT_CONGESTED] =3D READ_ONCE(rport->fpin_stats.cn_de= vice_specific); + post[IBMVFC_AE_FPIN_PORT_CLEARED] =3D READ_ONCE(rport->fpin_stats.cn_clea= r); + post[IBMVFC_AE_FPIN_PORT_DEGRADED] =3D READ_ONCE(rport->fpin_stats.li_fai= lure_unknown); + post[IBMVFC_AE_FPIN_CONGESTION_CLEARED] =3D READ_ONCE(fc_host->fpin_stats= .cn_clear); + + KUNIT_EXPECT_GE(test, post[IBMVFC_AE_FPIN_LINK_CONGESTED], + pre[IBMVFC_AE_FPIN_LINK_CONGESTED]+1); + KUNIT_EXPECT_GE(test, post[IBMVFC_AE_FPIN_PORT_CONGESTED], + pre[IBMVFC_AE_FPIN_PORT_CONGESTED]+1); + KUNIT_EXPECT_GE(test, post[IBMVFC_AE_FPIN_PORT_CLEARED], + pre[IBMVFC_AE_FPIN_PORT_CLEARED]+1); + KUNIT_EXPECT_GE(test, post[IBMVFC_AE_FPIN_PORT_DEGRADED], + pre[IBMVFC_AE_FPIN_PORT_DEGRADED]+1); + KUNIT_EXPECT_GE(test, post[IBMVFC_AE_FPIN_CONGESTION_CLEARED], + pre[IBMVFC_AE_FPIN_CONGESTION_CLEARED]+1); + + /* bad path */ + pre[IBMVFC_AE_FPIN_LINK_CONGESTED] =3D READ_ONCE(fc_host->fpin_stats.cn_d= evice_specific); + pre[IBMVFC_AE_FPIN_PORT_CONGESTED] =3D READ_ONCE(rport->fpin_stats.cn_dev= ice_specific); + pre[IBMVFC_AE_FPIN_PORT_CLEARED] =3D READ_ONCE(rport->fpin_stats.cn_clear= ); + pre[IBMVFC_AE_FPIN_PORT_DEGRADED] =3D READ_ONCE(rport->fpin_stats.li_fail= ure_unknown); + pre[IBMVFC_AE_FPIN_CONGESTION_CLEARED] =3D READ_ONCE(fc_host->fpin_stats.= cn_clear); + + ae[0].valid =3D 0x80; + ae[0].link_state =3D IBMVFC_AE_LS_LINK_UP; + ae[0].fpin_status =3D 0; /* bad value */ + ae[0].event =3D cpu_to_be64(IBMVFC_AE_FPIN); + ae[0].scsi_id =3D cpu_to_be64(tgt->scsi_id); + ae[0].wwpn =3D cpu_to_be64(tgt->wwpn); + ae[0].node_name =3D cpu_to_be64(tgt->ids.node_name); + ibmvfc_handle_async(&ae[0], vhost); + ae[0].valid =3D 0; + wmb(); /* ensure valid bit clear is visible before checking stats */ + flush_workqueue(vhost->fpin_workq); + + post[IBMVFC_AE_FPIN_LINK_CONGESTED] =3D READ_ONCE(fc_host->fpin_stats.cn_= device_specific); + post[IBMVFC_AE_FPIN_PORT_CONGESTED] =3D READ_ONCE(rport->fpin_stats.cn_de= vice_specific); + post[IBMVFC_AE_FPIN_PORT_CLEARED] =3D READ_ONCE(rport->fpin_stats.cn_clea= r); + post[IBMVFC_AE_FPIN_PORT_DEGRADED] =3D READ_ONCE(rport->fpin_stats.li_fai= lure_unknown); + post[IBMVFC_AE_FPIN_CONGESTION_CLEARED] =3D READ_ONCE(fc_host->fpin_stats= .cn_clear); + + KUNIT_EXPECT_EQ(test, pre[IBMVFC_AE_FPIN_LINK_CONGESTED], + post[IBMVFC_AE_FPIN_LINK_CONGESTED]); + KUNIT_EXPECT_EQ(test, pre[IBMVFC_AE_FPIN_PORT_CONGESTED], + post[IBMVFC_AE_FPIN_PORT_CONGESTED]); + KUNIT_EXPECT_EQ(test, pre[IBMVFC_AE_FPIN_PORT_CLEARED], + post[IBMVFC_AE_FPIN_PORT_CLEARED]); + KUNIT_EXPECT_EQ(test, pre[IBMVFC_AE_FPIN_PORT_DEGRADED], + post[IBMVFC_AE_FPIN_PORT_DEGRADED]); + KUNIT_EXPECT_EQ(test, pre[IBMVFC_AE_FPIN_CONGESTION_CLEARED], + post[IBMVFC_AE_FPIN_CONGESTION_CLEARED]); + + kref_put(&tgt->kref, ibmvfc_release_tgt); +} + +static struct kunit_case ibmvfc_fpin_test_cases[] =3D { + KUNIT_CASE(ibmvfc_async_fpin_test), + {}, +}; + +static struct kunit_suite ibmvfc_fpin_test_suite =3D { + .name =3D "ibmvfc-fpin-test", + .test_cases =3D ibmvfc_fpin_test_cases, +}; +kunit_test_init_section_suite(ibmvfc_fpin_test_suite); + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Dave Marquardt "); +MODULE_DESCRIPTION("Test module for IBM Virtual Fibre Channel Driver"); --=20 2.55.0 From nobody Fri Sep 25 15:13:49 2026 Received: from mx0b-001b2d01.pphosted.com (mx0b-001b2d01.pphosted.com [148.163.158.5]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 039D03A8743; Fri, 11 Sep 2026 05:48:48 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=148.163.158.5 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789105730; cv=none; b=IPMQhqlefhPCf2Oe3hZDsHQub7mDQQEe0dWTIogG2QNfy/tdxcWmxYnUZaDrtJ8/bLzjW43oyoR+qlvctW8Lg+A1ieleK/U1eZ7AQWE/iKubcP2Rul2gG/1Mtn3FNOlJjGGk81SKrps2n0MbdVKRTPYoCujN5KKlyqApLlxIAoQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789105730; c=relaxed/simple; bh=KG2kjkAPxLky//8NmFR12ncjOkzWRkyap6n9wI0w6Z8=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=qpagqgiu7qDhoZh29ewkf0Or1GWS+6FUKcKoPQfKX1SoxslJTUHx7KCI7w0aqJeCaIVpDBJ739rTqhYTseQzM6dwNXLYu7GKvN+7xnCWp+YDPjLghs9qCMjMo5nV6/cHCvFyFECfJ22qMrAY32CvXYjJaobV1BAg68WXlju7/34= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.ibm.com; spf=pass smtp.mailfrom=linux.ibm.com; dkim=pass (2048-bit key) header.d=ibm.com header.i=@ibm.com header.b=Gy4jwLl8; arc=none smtp.client-ip=148.163.158.5 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.ibm.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linux.ibm.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=ibm.com header.i=@ibm.com header.b="Gy4jwLl8" Received: from pps.filterd (m0353725.ppops.net [127.0.0.1]) by mx0a-001b2d01.pphosted.com (8.18.1.11/8.18.1.11) with ESMTP id 68B4VWXC3839649; Fri, 11 Sep 2026 05:48:40 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ibm.com; h=cc :content-transfer-encoding:date:from:in-reply-to:message-id :mime-version:references:subject:to; s=pp1; bh=bhkyNldRALFzL88Dc 97VKPpfC22k6vquq1VzX/7ZfKk=; b=Gy4jwLl8Tqpy5H4WKoHqNVgZy/8CHuPhK i4ASdIAwT2Y2/VN9RKcRvmGMxS8JcVao3TZClc+4/qrc8UjMFtjQ7foLsd4asQ1d BCOJk85PZCeGiz/jkA6VFHd+/eaAnpEgugaQZdQ2GXZno5xH/5SJlCISyr0c/dQy xC8P/4T5HiUrT6AUdChsvygdPzDqWCWOQc1vTOj4dcxcv7ue+W+yjYs6DzcRwIOm aXSe2ydSkueEEiYCH8R09fQxiuqFTafpMWKIMdWhYe1h7K1SSMBgSeRNKwHKLWPG m0mphlimIXUR1Me7stNRJ0saLteb7PbITAoq//C63vfADfQ7o+YHA== Received: from ppma12.dal12v.mail.ibm.com (dc.9e.1632.ip4.static.sl-reverse.com [50.22.158.220]) by mx0a-001b2d01.pphosted.com (PPS) with ESMTPS id 4gkd8q9g68-1 (version=TLSv1.3 cipher=TLS_AES_256_GCM_SHA384 bits=256 verify=NOT); Fri, 11 Sep 2026 05:48:39 +0000 (GMT) Received: from pps.filterd (ppma12.dal12v.mail.ibm.com [127.0.0.1]) by ppma12.dal12v.mail.ibm.com (8.18.1.11/8.18.1.11) with ESMTP id 68B4K1NX1101863; Fri, 11 Sep 2026 05:48:39 GMT Received: from smtprelay03.dal12v.mail.ibm.com ([172.16.1.5]) by ppma12.dal12v.mail.ibm.com (PPS) with ESMTPS id 4gkvnrmkrq-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Fri, 11 Sep 2026 05:48:39 +0000 (GMT) Received: from smtpav02.dal12v.mail.ibm.com (smtpav02.dal12v.mail.ibm.com [10.241.53.101]) by smtprelay03.dal12v.mail.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id 68B5mch731916728 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Fri, 11 Sep 2026 05:48:38 GMT Received: from smtpav02.dal12v.mail.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 2967858051; Fri, 11 Sep 2026 05:48:38 +0000 (GMT) Received: from smtpav02.dal12v.mail.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 87E8D5805A; Fri, 11 Sep 2026 05:48:37 +0000 (GMT) Received: from li-4c4c4544-0054-3910-8039-c3c04f423534.ibm.com.com (unknown [9.61.103.123]) by smtpav02.dal12v.mail.ibm.com (Postfix) with ESMTP; Fri, 11 Sep 2026 05:48:37 +0000 (GMT) From: Tyrel Datwyler To: james.bottomley@hansenpartnership.com, martin.petersen@oracle.com Cc: linux-scsi@vger.kernel.org, linuxppc-dev@lists.ozlabs.org, linux-kernel@vger.kernel.org, brking@linux.ibm.com, davemarq@linux.ibm.com, Tyrel Datwyler Subject: [PATCH v10 2/9] scsi: ibmvfc: add NOOP command support Date: Thu, 10 Sep 2026 22:48:25 -0700 Message-ID: <20260911054832.1311668-3-tyreld@linux.ibm.com> X-Mailer: git-send-email 2.55.0 In-Reply-To: <20260911054832.1311668-1-tyreld@linux.ibm.com> References: <20260911054832.1311668-1-tyreld@linux.ibm.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-TM-AS-GCONF: 00 X-Proofpoint-ORIG-GUID: lY_kdvx6irn4ToNTyG1b1HFVa1ijdi72 X-Proofpoint-Spam-Info: AW1haW4tMjYwOTExMDA3NCBTYWx0ZWRfX0WK26R6/OPPd IG/wTIOUwLAaK6NtKq2tQGfj8UbAAXnUNW4lFyUHJ2z+R8CKX73WWKidzqfhK7+tTKRv1ltFRmA O+eA0BwacS1pUjX64X/rWHBP39FHgBE= X-Authority-Analysis: v=2.4 cv=E/dYNqdl c=1 sm=1 tr=0 ts=6aa39637 cx=c_pps a=bLidbwmWQ0KltjZqbj+ezA==:117 a=bLidbwmWQ0KltjZqbj+ezA==:17 a=VdqzKS8jKosA:10 a=VkNPw1HP01LnGYTKEx00:22 a=RnoormkPH1_aCDwRdu11:22 a=V8glGbnc2Ofi9Qvn3v5h:22 a=VnNF1IyMAAAA:8 a=dMUBAgKGejxRm0SXrm0A:9 X-Proofpoint-Spam-Details-Enc: AW1haW4tMjYwOTExMDA3NCBTYWx0ZWRfX3tgJ6shHhmQi SSrshCqbRvvA8TnGbgwvIY1dYW7J2gji6ycYKbkpfcZk3iUavRWNfFkohPRq+q7PpMvgCaPt87f 89ptqRDbmDCvoRRKnWvWaVcbpqr4I/xiHrOhL757KAszflFAOYaC0iwm+LvpevFUBiMCvudSwIt A/wOurJ3IEWaRIGxHqKOB+5RWjt+B5/qJrYEMQnLogttdBWGDgCA6npNcrkWmceuCFOzhB3pDgl GNmgVEvjF12/caKzF4GIkHJRwFffoTGd2g/J0SRTtFNLYsCIxqlU/qlL0BCCA1gYn/p0sAiG5ni sIh+wOxsJM1wkS1dOGIZgJTojXdQA552yIZ/FKDsNKdxGmZe0DodYkhMQMsK2BG+tUI4yLHJT5I bapRCfa5tgL6muMe96LQWx4V8nPHENmp5x5BZVkBDB87uVs/Wa+hR/pqVmL2pLqAIf0QsYG/w69 DxTZ/tzRfGEIUNz6fQQ== X-Proofpoint-GUID: lY_kdvx6irn4ToNTyG1b1HFVa1ijdi72 X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1176,Hydra:6.1.134,FMLib:17.12.100.49 definitions=2026-09-11_02,2026-09-09_02,2025-10-01_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 priorityscore=1501 suspectscore=0 spamscore=0 bulkscore=0 clxscore=1015 impostorscore=0 phishscore=0 adultscore=0 lowpriorityscore=0 malwarescore=0 classifier=typeunknown authscore=0 authtc= authcc= route=outbound adjust=0 reason=mlx scancount=1 engine=8.22.0-2609040000 definitions=main-2609110074 Content-Type: text/plain; charset="utf-8" From: Dave Marquardt Add support for handling IBMVFC_NOOP format CRQ messages from the VIOS partner. Advertise the client's ability to handle NOOP commands by setting the IBMVFC_CAN_USE_NOOP_CMD capability in ibmvfc_set_login_info(). Handle and ignore IBMVFC_NOOP format messages in both ibmvfc_handle_crq() and ibmvfc_handle_scrq(). In both handlers, log a rate-limited error if a NOOP is received while in the IBMVFC_ACTIVE state without the partner having advertised IBMVFC_SUPPORT_NOOP_CMD. In ibmvfc_handle_scrq(), also fix a typo ("Got and invalid" -> "Got an invalid"), add a missing return on invalid message types, and guard against null event pointers before processing CRQ responses. Signed-off-by: Dave Marquardt Acked-by: Tyrel Datwyler --- drivers/scsi/ibmvscsi/ibmvfc-core.c | 27 +++++++++++++++++++++++++-- 1 file changed, 25 insertions(+), 2 deletions(-) diff --git a/drivers/scsi/ibmvscsi/ibmvfc-core.c b/drivers/scsi/ibmvscsi/ib= mvfc-core.c index 514fc87c1017..7ea64956653e 100644 --- a/drivers/scsi/ibmvscsi/ibmvfc-core.c +++ b/drivers/scsi/ibmvscsi/ibmvfc-core.c @@ -1578,7 +1578,9 @@ static void ibmvfc_set_login_info(struct ibmvfc_host = *vhost) login_info->flags |=3D cpu_to_be16(IBMVFC_CLIENT_MIGRATED); =20 login_info->max_cmds =3D cpu_to_be32(max_cmds); - login_info->capabilities =3D cpu_to_be64(IBMVFC_CAN_MIGRATE | IBMVFC_CAN_= SEND_VF_WWPN); + login_info->capabilities =3D + cpu_to_be64(IBMVFC_CAN_MIGRATE | IBMVFC_CAN_SEND_VF_WWPN | + IBMVFC_CAN_USE_NOOP_CMD); =20 if (vhost->mq_enabled || vhost->using_channels) { login_info->capabilities |=3D cpu_to_be64(IBMVFC_CAN_USE_CHANNELS); @@ -3693,6 +3695,14 @@ static void ibmvfc_handle_crq(struct ibmvfc_crq *crq= , struct ibmvfc_host *vhost, if (crq->format =3D=3D IBMVFC_ASYNC_EVENT) return; =20 + if (crq->format =3D=3D IBMVFC_NOOP) { + if (vhost->state =3D=3D IBMVFC_ACTIVE && + !ibmvfc_check_caps(vhost, IBMVFC_SUPPORT_NOOP_CMD)) + dev_err_ratelimited(vhost->dev, + "Received unexpected NOOP command from partner\n"); + return; + } + /* The only kind of payload CRQs we should get are responses to * things we send. Make sure this response is to something we * actually sent @@ -4223,7 +4233,20 @@ static void ibmvfc_handle_scrq(struct ibmvfc_crq *cr= q, struct ibmvfc_host *vhost case IBMVFC_CRQ_XPORT_EVENT: return; default: - dev_err(vhost->dev, "Got and invalid message type 0x%02x\n", crq->valid); + dev_err(vhost->dev, "Got an invalid message type 0x%02x\n", crq->valid); + return; + } + + if (crq->format =3D=3D IBMVFC_NOOP) { + if (vhost->state =3D=3D IBMVFC_ACTIVE && + !ibmvfc_check_caps(vhost, IBMVFC_SUPPORT_NOOP_CMD)) + dev_err_ratelimited(vhost->dev, + "Received unexpected NOOP command from partner\n"); + return; + } + + if (unlikely(!evt)) { + dev_err(vhost->dev, "Received null event\n"); return; } =20 --=20 2.55.0 From nobody Fri Sep 25 15:13:49 2026 Received: from mx0b-001b2d01.pphosted.com (mx0b-001b2d01.pphosted.com [148.163.158.5]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id BB641381AE5; Fri, 11 Sep 2026 05:48:49 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=148.163.158.5 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789105731; cv=none; b=DiK9gFEvmm+MxtlK7hHZ48m8C+XjG27CQeB6opzkGJ9dPrLj+ttuDxQwa6LcUfFpnEP0NS8bche4I7TD0EJfy4kjTJ1zjmnE/GcNhM2bdaz7NxpYkomAWLBmmCwQ+PKZWRY1RrVCrS8t8Ei2bfYL5A1Ck9PXwZyF45Vx4flLSqc= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789105731; c=relaxed/simple; bh=Yy0OU3dKq8cR/JdYCoiXYE3T/GnzwysU3idedb1DPV4=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=Vso9fNR/u69kEjcPESsAZEvZHTxqTvbAT5qsOcdJBPbIRf0/2KgsIVpu+nGbgNycNvtkYXxoJgdXtDFKH9x8smA06fhMZ/Eec2plNZazZ31+s0VuodVTi7pkoC3qKTXRxcyFheIyyhVkNt90ZlSu0zSsow9u2sWFyfWWh82Wn24= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.ibm.com; spf=pass smtp.mailfrom=linux.ibm.com; dkim=pass (2048-bit key) header.d=ibm.com header.i=@ibm.com header.b=QKAzd0Nr; arc=none smtp.client-ip=148.163.158.5 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.ibm.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linux.ibm.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=ibm.com header.i=@ibm.com header.b="QKAzd0Nr" Received: from pps.filterd (m0360072.ppops.net [127.0.0.1]) by mx0a-001b2d01.pphosted.com (8.18.1.11/8.18.1.11) with ESMTP id 68B4W35k820706; Fri, 11 Sep 2026 05:48:40 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ibm.com; h=cc :content-transfer-encoding:date:from:in-reply-to:message-id :mime-version:references:subject:to; s=pp1; bh=bVsy6e7RIWsa4inSY VWZiBsIlesxYTQaoaS4XZ8tKXk=; b=QKAzd0NrzjR2mKb9QeTvLQGgJbI5vLlDJ o/4JlVlt59iUKRpUD+QgGa0cCzaDpRXlnzJ1MMsPqvlsVjGXtpistjau9O33C+PW aq8HaNzo1vNixWMb/ytw7l+tyvR4NgD+ybZAS2EHdkmH5XrozQE4xqNNZg8yUWR8 BeI9ELfSY2kMWzNJj1+BhnRiMWQHN7mBr2rSufp2VG5ETnqjRcScP5M4X2NNARip RJyQ8vAD0UXg74uUfYQVEPgX//0CxT/V7lZ8PE0ImSfyAEZpmcZ0upawqxb5SYRl zSC4N3/D8tEDkJccwphG1hPyC9SP8SV4WV+5chv/WvLhGWYJPJRbw== Received: from ppma21.wdc07v.mail.ibm.com (5b.69.3da9.ip4.static.sl-reverse.com [169.61.105.91]) by mx0a-001b2d01.pphosted.com (PPS) with ESMTPS id 4gkd8t1fh0-1 (version=TLSv1.3 cipher=TLS_AES_256_GCM_SHA384 bits=256 verify=NOT); Fri, 11 Sep 2026 05:48:40 +0000 (GMT) Received: from pps.filterd (ppma21.wdc07v.mail.ibm.com [127.0.0.1]) by ppma21.wdc07v.mail.ibm.com (8.18.1.11/8.18.1.11) with ESMTP id 68B4K4ML1056152; Fri, 11 Sep 2026 05:48:40 GMT Received: from smtprelay03.dal12v.mail.ibm.com ([172.16.1.5]) by ppma21.wdc07v.mail.ibm.com (PPS) with ESMTPS id 4gkvvrchr2-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Fri, 11 Sep 2026 05:48:40 +0000 (GMT) Received: from smtpav02.dal12v.mail.ibm.com (smtpav02.dal12v.mail.ibm.com [10.241.53.101]) by smtprelay03.dal12v.mail.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id 68B5md8J32572010 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Fri, 11 Sep 2026 05:48:39 GMT Received: from smtpav02.dal12v.mail.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id E76AB5805E; Fri, 11 Sep 2026 05:48:38 +0000 (GMT) Received: from smtpav02.dal12v.mail.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 46B255805A; Fri, 11 Sep 2026 05:48:38 +0000 (GMT) Received: from li-4c4c4544-0054-3910-8039-c3c04f423534.ibm.com.com (unknown [9.61.103.123]) by smtpav02.dal12v.mail.ibm.com (Postfix) with ESMTP; Fri, 11 Sep 2026 05:48:38 +0000 (GMT) From: Tyrel Datwyler To: james.bottomley@hansenpartnership.com, martin.petersen@oracle.com Cc: linux-scsi@vger.kernel.org, linuxppc-dev@lists.ozlabs.org, linux-kernel@vger.kernel.org, brking@linux.ibm.com, davemarq@linux.ibm.com, Tyrel Datwyler Subject: [PATCH v10 3/9] scsi: ibmvfc: add FPIN extended flag and async sub-CRQ queue handle Date: Thu, 10 Sep 2026 22:48:26 -0700 Message-ID: <20260911054832.1311668-4-tyreld@linux.ibm.com> X-Mailer: git-send-email 2.55.0 In-Reply-To: <20260911054832.1311668-1-tyreld@linux.ibm.com> References: <20260911054832.1311668-1-tyreld@linux.ibm.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-TM-AS-GCONF: 00 X-Proofpoint-Spam-Info: AW1haW4tMjYwOTExMDA3NCBTYWx0ZWRfX44wsF1sI+bH5 Hm+FJizKOtttYntWsCR/xOQUDL15JD/q5deuPrjxB9Zd2SzcHSlk03JbLCKvf4dR50+B5DrV0Hi BrNbY2cxIT8ETdUOC+KGRTGJIcdz0dU= X-Proofpoint-ORIG-GUID: U0fMvZgXOoe18jAYnN7gOdFbxoQwi9dJ X-Proofpoint-GUID: U0fMvZgXOoe18jAYnN7gOdFbxoQwi9dJ X-Proofpoint-Spam-Details-Enc: AW1haW4tMjYwOTExMDA3NCBTYWx0ZWRfX3UESG9sBXvBn KCUVKb0jJMwiOfz/kNB2GbRvCRD4NNNUBHQhBYSLThtgkquKKe4N9u0kBUvFf3Cx8I40N1o1NCD xmR02gI72CX1Q7fgxbhDSnWX7CG+Wd45gTY9PvpmYD0vNOBRGhkC877gw7jpxEGs6K6kHKMTg2o Ric3QrJLRbQL+DBs/o/X9iq3Bz1nu/bzGM07j8aH2d9yR/DGsESNHQl/tfZZH/8WwzNKt/7ZydB wDdPIE+n/c7wRgXDJBlOwCyRnaHnSAWkzyw9iHlOe9j+NBw8zPRgQP3XVPfms7DFL7nxTxdj2ep EILt/fJZiB5ap6vxRUy+Lf6VzATk0+KXv4oaLm6pT7HHkuyuyGttBxMhWELUVO31wbjX+UYdVRH jmQoSoCAdfURez+h7Elb26edfiILcnPBhXX5D4KAw0HrwQu/3N0AIpQCmA0dP6fNt9jIlN0xuQs XvR+BW5OH/rf8ip/Pow== X-Authority-Analysis: v=2.4 cv=PIGaavqC c=1 sm=1 tr=0 ts=6aa39638 cx=c_pps a=GFwsV6G8L6GxiO2Y/PsHdQ==:117 a=GFwsV6G8L6GxiO2Y/PsHdQ==:17 a=VdqzKS8jKosA:10 a=VkNPw1HP01LnGYTKEx00:22 a=RnoormkPH1_aCDwRdu11:22 a=RzCfie-kr_QcCd8fBx8p:22 a=VnNF1IyMAAAA:8 a=dC3NDtCKD2fC6gceAXcA:9 X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1176,Hydra:6.1.134,FMLib:17.12.100.49 definitions=2026-09-11_02,2026-09-09_02,2025-10-01_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 phishscore=0 priorityscore=1501 bulkscore=0 adultscore=0 suspectscore=0 lowpriorityscore=0 impostorscore=0 clxscore=1015 spamscore=0 malwarescore=0 classifier=typeunknown authscore=0 authtc= authcc= route=outbound adjust=0 reason=mlx scancount=1 engine=8.22.0-2609040000 definitions=main-2609110074 Content-Type: text/plain; charset="utf-8" From: Dave Marquardt Add IBMVFC_ASYNC_IS_FPIN_EXT flag bit (0x02) to ibmvfc_async_sub_crq.flags to distinguish extended FPIN events from standard ones. Add async_sub_crq field of type ibmvfc_queue to ibmvfc_host to hold the queue handle for the asynchronous sub-CRQ, alongside the existing crq and async_crq queues. Signed-off-by: Dave Marquardt Acked-by: Tyrel Datwyler --- drivers/scsi/ibmvscsi/ibmvfc.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/scsi/ibmvscsi/ibmvfc.h b/drivers/scsi/ibmvscsi/ibmvfc.h index d7a30e7a4a28..a8a063d99564 100644 --- a/drivers/scsi/ibmvscsi/ibmvfc.h +++ b/drivers/scsi/ibmvscsi/ibmvfc.h @@ -773,6 +773,7 @@ struct ibmvfc_async_sub_crq { volatile u8 valid; u8 flags; #define IBMVFC_ASYNC_ID_IS_ASSOC_ID 0x01 +#define IBMVFC_ASYNC_IS_FPIN_EXT 0x02 u8 link_state; u8 fpin_status; __be16 event; @@ -990,6 +991,7 @@ struct ibmvfc_host { mempool_t *tgt_pool; struct ibmvfc_queue crq; struct ibmvfc_queue async_crq; + struct ibmvfc_queue async_sub_crq; struct ibmvfc_channels scsi_scrqs; struct ibmvfc_channels nvme_scrqs; struct ibmvfc_npiv_login login_info; --=20 2.55.0 From nobody Fri Sep 25 15:13:49 2026 Received: from mx0a-001b2d01.pphosted.com (mx0a-001b2d01.pphosted.com [148.163.156.1]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id A73DB3A4521; Fri, 11 Sep 2026 05:48:55 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=148.163.156.1 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789105737; cv=none; b=NQ8ETpmW2NClW4iOZNgna0mh9zwHEQJDzn03waiisMvyUzgmPTHPuCQM35rJ/ht3v/Wew2Nqs5okaVZ0oYD/fX1Bg2d2Bld89vPiMSKDsKoAZYGXr7foBepyLQcxFO5TEg25TcohyH/0FbcNguac8z4GtgC+7NfzrCuNR5m/oSs= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789105737; c=relaxed/simple; bh=AlpUAzVWXGPH8pKQr+lJetqHE3DRm1z450tG0ZitdNA=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=W4c/N8QcRvX7hwz2WnIWl8/ibfgkDPtuzLzw5bLAEVC/HC9n2Kak5BU4pDstFGKiWfWRH5ztat1G/aJVQBKLiCRWgeAY9pHgvDRAf/cZ/NcjMRIJhEdFqwtfNNsd4LCP9oLtQCZV4blgnK4HVL9w6Aqc5bBZCV1uxtD54Z8ZtA8= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.ibm.com; spf=pass smtp.mailfrom=linux.ibm.com; dkim=pass (2048-bit key) header.d=ibm.com header.i=@ibm.com header.b=QosNU02l; arc=none smtp.client-ip=148.163.156.1 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.ibm.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linux.ibm.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=ibm.com header.i=@ibm.com header.b="QosNU02l" Received: from pps.filterd (m0353729.ppops.net [127.0.0.1]) by mx0a-001b2d01.pphosted.com (8.18.1.11/8.18.1.11) with ESMTP id 68B4VT4q3104516; Fri, 11 Sep 2026 05:48:41 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ibm.com; h=cc :content-transfer-encoding:date:from:in-reply-to:message-id :mime-version:references:subject:to; s=pp1; bh=erJa6tbdZ9iRtaxRC CeehSEpav1G5CFxWCJc9TIvjR4=; b=QosNU02lgyhMzVGS7HRU4A5U9kYcMZYkA f6iyJq2e4pAr11gP9NFbtCsHxvpDvvIisMdnIE3AKg3osPCmJgExGRKfToUpD7wk c/OO0lPK57mzsi6AHJKmt2GSz1bU1ROv1Tg4xEaqh4cF+YW+ibAQvHAZ3kwqeDiG lill8I2n5L2cXRGWyxZtVHg4BzQ3rbKeY4zxftXjJRInCrVA7rhNA+KaMteXUqQE ssZwKYmJfVClReeAE6xs916p5YZVFUTE3DteCf+9QMG7AgK5B4tkGWCfDAkx7Jfu wUdISSit+Hnd6W9KHf8y7ZJ7nLIDG7O25b3P7s4xsOknsqb55rGiA== Received: from ppma12.dal12v.mail.ibm.com (dc.9e.1632.ip4.static.sl-reverse.com [50.22.158.220]) by mx0a-001b2d01.pphosted.com (PPS) with ESMTPS id 4gkd8n9hpp-1 (version=TLSv1.3 cipher=TLS_AES_256_GCM_SHA384 bits=256 verify=NOT); Fri, 11 Sep 2026 05:48:41 +0000 (GMT) Received: from pps.filterd (ppma12.dal12v.mail.ibm.com [127.0.0.1]) by ppma12.dal12v.mail.ibm.com (8.18.1.11/8.18.1.11) with ESMTP id 68B4K3WG1101917; Fri, 11 Sep 2026 05:48:40 GMT Received: from smtprelay04.dal12v.mail.ibm.com ([172.16.1.6]) by ppma12.dal12v.mail.ibm.com (PPS) with ESMTPS id 4gkvnrmkrv-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Fri, 11 Sep 2026 05:48:40 +0000 (GMT) Received: from smtpav02.dal12v.mail.ibm.com (smtpav02.dal12v.mail.ibm.com [10.241.53.101]) by smtprelay04.dal12v.mail.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id 68B5mdMj27132576 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Fri, 11 Sep 2026 05:48:39 GMT Received: from smtpav02.dal12v.mail.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id B076D5805C; Fri, 11 Sep 2026 05:48:39 +0000 (GMT) Received: from smtpav02.dal12v.mail.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 128275805A; Fri, 11 Sep 2026 05:48:39 +0000 (GMT) Received: from li-4c4c4544-0054-3910-8039-c3c04f423534.ibm.com.com (unknown [9.61.103.123]) by smtpav02.dal12v.mail.ibm.com (Postfix) with ESMTP; Fri, 11 Sep 2026 05:48:38 +0000 (GMT) From: Tyrel Datwyler To: james.bottomley@hansenpartnership.com, martin.petersen@oracle.com Cc: linux-scsi@vger.kernel.org, linuxppc-dev@lists.ozlabs.org, linux-kernel@vger.kernel.org, brking@linux.ibm.com, davemarq@linux.ibm.com, Tyrel Datwyler Subject: [PATCH v10 4/9] scsi: ibmvfc: extend async event handlers for async sub-CRQ events Date: Thu, 10 Sep 2026 22:48:27 -0700 Message-ID: <20260911054832.1311668-5-tyreld@linux.ibm.com> X-Mailer: git-send-email 2.55.0 In-Reply-To: <20260911054832.1311668-1-tyreld@linux.ibm.com> References: <20260911054832.1311668-1-tyreld@linux.ibm.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-TM-AS-GCONF: 00 X-Authority-Analysis: v=2.4 cv=NMVAaE6g c=1 sm=1 tr=0 ts=6aa39639 cx=c_pps a=bLidbwmWQ0KltjZqbj+ezA==:117 a=bLidbwmWQ0KltjZqbj+ezA==:17 a=VdqzKS8jKosA:10 a=VkNPw1HP01LnGYTKEx00:22 a=RnoormkPH1_aCDwRdu11:22 a=uAbxVGIbfxUO_5tXvNgY:22 a=VnNF1IyMAAAA:8 a=iW4PeHjXF5vBxW_ITg0A:9 X-Proofpoint-GUID: wossEmEjdPHzicVUrXQ3K5uUqvsmUKoh X-Proofpoint-Spam-Details-Enc: AW1haW4tMjYwOTExMDA3NCBTYWx0ZWRfX5CfytU2t9kwh yS4xCaa4Mr5A7MwYK/doQE2VTdx7VVvNh4U7htMyP7tt3e5a7MiLLQ3F5iNvUfqK88YgRLLRvZe 3WBsDX3f+tNdFjOF3xuBS5MPuoVs55GEjn7tQ6MyeRkGTaMZOEXjetxSW4DR3ryijwMw56WVIwg cL8D4qxNBApj8FwX5gjxAXLP/SESH3qvAGKj14n9o5CaP45no5dTXU1ml3aw+Z6k5cse6gL9VAO 3P8K9dVwA4XTXX+8ShI59cTWHYGqx+XAsyRBjXnKIY/jEI4KXgB11fTWM3XFJqScWCWHyXVF7Nu 460IpM8YMRJDCocwX9erL5igJjIHoIcpR02vlPwxE/PpbJMe9Zb6s2yiycuhrBleAJ+VeLJRwy5 oXVh2+fo9e9gf5X4MyRv6cEGb0bOaJpRqzkRy5hXR3bxy+M5skQx0B8n4RRavtQYkXzfxA2KXrt YWHuSoXkMjdq6CNAnyQ== X-Proofpoint-ORIG-GUID: wossEmEjdPHzicVUrXQ3K5uUqvsmUKoh X-Proofpoint-Spam-Info: AW1haW4tMjYwOTExMDA3NCBTYWx0ZWRfX0WgNm6aUjyL+ iwFzmN28UptHH7/lJ1faR6vdBw9odh9ll+FLYieKjeRTYQhUlJWmuVLuAiXD9S8LfnmZYFl8Wft GKrtVmU8jOFCuSzRLkrex0ksZBgdDTY= X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1176,Hydra:6.1.134,FMLib:17.12.100.49 definitions=2026-09-11_02,2026-09-09_02,2025-10-01_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 spamscore=0 bulkscore=0 clxscore=1015 malwarescore=0 lowpriorityscore=0 priorityscore=1501 adultscore=0 suspectscore=0 impostorscore=0 phishscore=0 classifier=typeunknown authscore=0 authtc= authcc= route=outbound adjust=0 reason=mlx scancount=1 engine=8.22.0-2609040000 definitions=main-2609110074 Content-Type: text/plain; charset="utf-8" From: Dave Marquardt Refactor async event handling to support both traditional async CRQs and new asynchronous sub-queue CRQs. Introduce struct ibmvfc_async_crq_event, a tagged union that wraps either an ibmvfc_async_crq (main CRQ) or an ibmvfc_async_sub_crq (async sub-CRQ), with an enum ibmvfc_async_crq_type discriminator. Replace the ibmvfc_async_work bare union and is_subq bool with a single event field of this type. Modify ibmvfc_handle_async() to accept a struct ibmvfc_async_crq_event * instead of a void * plus a bool flag. Update ibmvfc_process_async_work() to dispatch based on event.type. Add ibmvfc_full_fpin_to_desc() to convert full FPIN messages from async sub-queue format to fc_els_fpin structures. Update FPIN processing logic to extract WWPN, node_name, and scsi_id from the appropriate union member based on event type. Update KUnit tests to use struct ibmvfc_async_crq_event arrays at call sites. Signed-off-by: Dave Marquardt [tyreld: added & operator to irqsave/restore calls] [tyreld: updated main crq unit test to use new async event union type] Signed-off-by: Tyrel Datwyler --- drivers/scsi/ibmvscsi/ibmvfc-core.c | 163 +++++++++++++++++++++------ drivers/scsi/ibmvscsi/ibmvfc.h | 18 ++- drivers/scsi/ibmvscsi/ibmvfc_kunit.c | 161 +++++++++++++++++++++++--- 3 files changed, 285 insertions(+), 57 deletions(-) diff --git a/drivers/scsi/ibmvscsi/ibmvfc-core.c b/drivers/scsi/ibmvscsi/ib= mvfc-core.c index 7ea64956653e..9b66b45871b1 100644 --- a/drivers/scsi/ibmvscsi/ibmvfc-core.c +++ b/drivers/scsi/ibmvscsi/ibmvfc-core.c @@ -3426,6 +3426,45 @@ ibmvfc_basic_fpin_to_desc(struct ibmvfc_async_crq *c= rq, u64 wwpn) cpu_to_be32(1)); } =20 +/** + * 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_sub_crq *ibmvfc_fpin) +{ + __be16 type; + + switch (ibmvfc_fpin->fpin_status) { + case IBMVFC_AE_FPIN_LINK_CONGESTED: + case IBMVFC_AE_FPIN_PORT_CONGESTED: + type =3D cpu_to_be16(FPIN_CONGN_DEVICE_SPEC); + break; + case IBMVFC_AE_FPIN_PORT_CLEARED: + case IBMVFC_AE_FPIN_CONGESTION_CLEARED: + type =3D cpu_to_be16(FPIN_CONGN_CLEAR); + break; + case IBMVFC_AE_FPIN_PORT_DEGRADED: + type =3D cpu_to_be16(FPIN_LI_UNKNOWN); + break; + default: + return NULL; + } + + return ibmvfc_common_fpin_to_desc(ibmvfc_fpin->fpin_status, ibmvfc_fpin->= wwpn, + type, cpu_to_be16(0), + cpu_to_be32(IBMVFC_FPIN_DEFAULT_EVENT_THRESHOLD), + cpu_to_be32(1)); +} + /** * ibmvfc_find_target - Search for a target in a target list * @target_list: list head of targets to search @@ -3463,28 +3502,40 @@ static struct ibmvfc_target *ibmvfc_find_target(str= uct list_head *target_list, */ static void ibmvfc_process_async_work(struct work_struct *work) { + struct ibmvfc_async_sub_crq *subq =3D NULL; struct ibmvfc_async_work *aw; - struct ibmvfc_async_crq *crq; + struct ibmvfc_async_crq *crq =3D NULL; struct ibmvfc_target *tgt; struct ibmvfc_host *vhost; - struct fc_els_fpin *fpin; + struct fc_els_fpin *fpin =3D NULL; unsigned long flags; + __be64 node_name; + __be64 scsi_id; + __be64 wwpn; =20 aw =3D container_of_const(work, struct ibmvfc_async_work, async_work_s); vhost =3D aw->vhost; - crq =3D &aw->crq; + if (aw->event.type =3D=3D IBMVFC_ASYNC_CRQ_SUB) { + subq =3D &aw->event.subq; + scsi_id =3D 0; + wwpn =3D subq->wwpn; + node_name =3D (subq->flags & IBMVFC_ASYNC_ID_IS_ASSOC_ID) ? 0 : subq->id= .node_name; + } else { + crq =3D &aw->event.async_crq; + scsi_id =3D crq->scsi_id; + wwpn =3D crq->wwpn; + node_name =3D crq->node_name; + } =20 - if (!crq->scsi_id && !crq->wwpn && !crq->node_name) + if (!scsi_id && !wwpn && !node_name) goto free; =20 spin_lock_irqsave(&vhost->host->host_lock, flags); - tgt =3D ibmvfc_find_target(&vhost->scsi_scrqs.targets, crq->scsi_id, - crq->wwpn, crq->node_name); + tgt =3D ibmvfc_find_target(&vhost->scsi_scrqs.targets, scsi_id, wwpn, nod= e_name); + if (!tgt) { /* Target not found in scsi_scrqs, search nvme_scrqs */ - tgt =3D ibmvfc_find_target(&vhost->nvme_scrqs.targets, - crq->scsi_id, crq->wwpn, - crq->node_name); + tgt =3D ibmvfc_find_target(&vhost->nvme_scrqs.targets, scsi_id, wwpn, no= de_name); } =20 if (tgt) { @@ -3496,7 +3547,11 @@ static void ibmvfc_process_async_work(struct work_st= ruct *work) goto free; } =20 - fpin =3D ibmvfc_basic_fpin_to_desc(crq, tgt->wwpn); + if (crq) + fpin =3D ibmvfc_basic_fpin_to_desc(crq, tgt->wwpn); + else + fpin =3D ibmvfc_full_fpin_to_desc(subq); + if (fpin) { fc_host_fpin_rcv(tgt->vhost->host, sizeof(*fpin) + be32_to_cpu(fpin->desc_len), @@ -3512,25 +3567,51 @@ static void ibmvfc_process_async_work(struct work_s= truct *work) =20 /** * ibmvfc_handle_async - Handle an async event from the adapter - * @crq: crq to process + * @ae: tagged union wrapping either an ibmvfc_async_crq (main CRQ) or an + * ibmvfc_async_sub_crq (async sub-CRQ); the type field identifies which * @vhost: ibmvfc host struct * **/ -VISIBLE_IF_KUNIT void ibmvfc_handle_async(struct ibmvfc_async_crq *crq, +VISIBLE_IF_KUNIT void ibmvfc_handle_async(struct ibmvfc_async_crq_event *a= e, struct ibmvfc_host *vhost) { - const struct ibmvfc_async_desc *desc =3D ibmvfc_get_ae_desc(be64_to_cpu(c= rq->event)); + struct ibmvfc_async_crq *async_crq =3D NULL; + struct ibmvfc_async_sub_crq *subq =3D 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, wwp= n: %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 (ae->type =3D=3D IBMVFC_ASYNC_CRQ_SUB) { + subq =3D &ae->subq; + event =3D be16_to_cpu(subq->event); + link_state =3D subq->link_state; + scsi_id =3D 0; + wwpn =3D subq->wwpn; + node_name =3D subq->flags & IBMVFC_ASYNC_ID_IS_ASSOC_ID ? 0 : subq->id.n= ode_name; + } else { + async_crq =3D &ae->async_crq; + event =3D be64_to_cpu(async_crq->event); + link_state =3D async_crq->link_state; + scsi_id =3D async_crq->scsi_id; + wwpn =3D async_crq->wwpn; + node_name =3D async_crq->node_name; + } + + desc =3D ibmvfc_get_ae_desc(event); + ibmvfc_log(vhost, desc->log_level, + "%s event received. scsi_id: %llx, wwpn: %llx, node_name: %llx, event= %llx%s\n", + desc->desc, be64_to_cpu(scsi_id), + be64_to_cpu(wwpn), be64_to_cpu(node_name), event, + ibmvfc_get_link_state(link_state)); + + switch (event) { case IBMVFC_AE_RESUME: - switch (crq->link_state) { + switch (link_state) { case IBMVFC_AE_LS_LINK_DOWN: ibmvfc_link_down(vhost, IBMVFC_LINK_DOWN); break; @@ -3569,33 +3650,33 @@ VISIBLE_IF_KUNIT void ibmvfc_handle_async(struct ib= mvfc_async_crq *crq, case IBMVFC_AE_ELS_PRLO: case IBMVFC_AE_ELS_PLOGI: list_for_each_entry(tgt, &vhost->scsi_scrqs.targets, queue) { - if (!crq->scsi_id && !crq->wwpn && !crq->node_name) + if (!scsi_id && !wwpn && !node_name) break; - if (crq->scsi_id && cpu_to_be64(tgt->scsi_id) !=3D crq->scsi_id) + if (scsi_id && cpu_to_be64(tgt->scsi_id) !=3D scsi_id) continue; - if (crq->wwpn && cpu_to_be64(tgt->ids.port_name) !=3D crq->wwpn) + if (wwpn && cpu_to_be64(tgt->ids.port_name) !=3D wwpn) continue; - if (crq->node_name && cpu_to_be64(tgt->ids.node_name) !=3D crq->node_na= me) + if (node_name && cpu_to_be64(tgt->ids.node_name) !=3D node_name) continue; - if (tgt->need_login && be64_to_cpu(crq->event) =3D=3D IBMVFC_AE_ELS_LOG= O) + if (tgt->need_login && event =3D=3D IBMVFC_AE_ELS_LOGO) tgt->logo_rcvd =3D 1; - if (!tgt->need_login || be64_to_cpu(crq->event) =3D=3D IBMVFC_AE_ELS_PL= OGI) { + if (!tgt->need_login || event =3D=3D IBMVFC_AE_ELS_PLOGI) { ibmvfc_del_tgt(tgt); ibmvfc_reinit_host(vhost); } } list_for_each_entry(tgt, &vhost->nvme_scrqs.targets, queue) { - if (!crq->scsi_id && !crq->wwpn && !crq->node_name) + if (!scsi_id && !wwpn && !node_name) break; - if (crq->scsi_id && cpu_to_be64(tgt->scsi_id) !=3D crq->scsi_id) + if (scsi_id && cpu_to_be64(tgt->scsi_id) !=3D scsi_id) continue; - if (crq->wwpn && cpu_to_be64(tgt->ids.port_name) !=3D crq->wwpn) + if (wwpn && cpu_to_be64(tgt->ids.port_name) !=3D wwpn) continue; - if (crq->node_name && cpu_to_be64(tgt->ids.node_name) !=3D crq->node_na= me) + if (node_name && cpu_to_be64(tgt->ids.node_name) !=3D node_name) continue; - if (tgt->need_login && be64_to_cpu(crq->event) =3D=3D IBMVFC_AE_ELS_LOG= O) + if (tgt->need_login && event =3D=3D IBMVFC_AE_ELS_LOGO) tgt->logo_rcvd =3D 1; - if (!tgt->need_login || be64_to_cpu(crq->event) =3D=3D IBMVFC_AE_ELS_PL= OGI) { + if (!tgt->need_login || event =3D=3D IBMVFC_AE_ELS_PLOGI) { ibmvfc_del_tgt(tgt); ibmvfc_reinit_host(vhost); } @@ -3616,14 +3697,14 @@ VISIBLE_IF_KUNIT void ibmvfc_handle_async(struct ib= mvfc_async_crq *crq, if (aw) { INIT_WORK(&aw->async_work_s, ibmvfc_process_async_work); aw->vhost =3D vhost; - aw->crq =3D *crq; + aw->event =3D *ae; 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; } } @@ -4164,7 +4245,11 @@ static void ibmvfc_tasklet(void *data) while (!done) { /* Pull all the valid messages off the async CRQ */ while ((async =3D ibmvfc_next_async_crq(vhost)) !=3D NULL) { - ibmvfc_handle_async(async, vhost); + struct ibmvfc_async_crq_event ae =3D { + .type =3D IBMVFC_ASYNC_CRQ_MAIN, + .async_crq =3D *async, + }; + ibmvfc_handle_async(&ae, vhost); async->valid =3D 0; wmb(); } @@ -4178,8 +4263,12 @@ static void ibmvfc_tasklet(void *data) =20 vio_enable_interrupts(vdev); if ((async =3D ibmvfc_next_async_crq(vhost)) !=3D NULL) { + struct ibmvfc_async_crq_event ae =3D { + .type =3D IBMVFC_ASYNC_CRQ_MAIN, + .async_crq =3D *async, + }; vio_disable_interrupts(vdev); - ibmvfc_handle_async(async, vhost); + ibmvfc_handle_async(&ae, vhost); async->valid =3D 0; wmb(); } else if ((crq =3D ibmvfc_next_crq(vhost)) !=3D NULL) { diff --git a/drivers/scsi/ibmvscsi/ibmvfc.h b/drivers/scsi/ibmvscsi/ibmvfc.h index a8a063d99564..6fce7a4922bb 100644 --- a/drivers/scsi/ibmvscsi/ibmvfc.h +++ b/drivers/scsi/ibmvscsi/ibmvfc.h @@ -786,9 +786,22 @@ struct ibmvfc_async_sub_crq { } id; } __packed __aligned(8); =20 +enum ibmvfc_async_crq_type { + IBMVFC_ASYNC_CRQ_MAIN =3D 0, + IBMVFC_ASYNC_CRQ_SUB, +}; + +struct ibmvfc_async_crq_event { + enum ibmvfc_async_crq_type type; + union { + struct ibmvfc_async_crq async_crq; + struct ibmvfc_async_sub_crq subq; + }; +}; + struct ibmvfc_async_work { struct ibmvfc_host *vhost; - struct ibmvfc_async_crq crq; + struct ibmvfc_async_crq_event event; struct work_struct async_work_s; }; =20 @@ -1103,7 +1116,8 @@ static inline struct ibmvfc_host *ibmvfc_channels_to_= vhost(struct ibmvfc_channel =20 #if IS_ENABLED(CONFIG_KUNIT) #include -VISIBLE_IF_KUNIT void ibmvfc_handle_async(struct ibmvfc_async_crq *crq, st= ruct ibmvfc_host *vhost); +VISIBLE_IF_KUNIT void ibmvfc_handle_async(struct ibmvfc_async_crq_event *e= vent, + struct ibmvfc_host *vhost); VISIBLE_IF_KUNIT struct ibmvfc_host *ibmvfc_get_first_vhost(void); #endif =20 diff --git a/drivers/scsi/ibmvscsi/ibmvfc_kunit.c b/drivers/scsi/ibmvscsi/i= bmvfc_kunit.c index 67bd3922a49f..5c67d405dbfc 100644 --- a/drivers/scsi/ibmvscsi/ibmvfc_kunit.c +++ b/drivers/scsi/ibmvscsi/ibmvfc_kunit.c @@ -3,7 +3,6 @@ #include #include #include -#include #include #include #include "ibmvfc.h" @@ -25,7 +24,9 @@ static void ibmvfc_async_fpin_test(struct kunit *test) { u64 post[IBMVFC_AE_FPIN_CONGESTION_CLEARED + 1]; u64 pre[IBMVFC_AE_FPIN_CONGESTION_CLEARED + 1]; - struct ibmvfc_async_crq ae[IBMVFC_AE_FPIN_CONGESTION_CLEARED + 1]; + struct ibmvfc_async_crq_event ae[IBMVFC_AE_FPIN_CONGESTION_CLEARED + 1] = =3D { + [0 ... IBMVFC_AE_FPIN_CONGESTION_CLEARED] =3D { .type =3D IBMVFC_ASYNC_C= RQ_MAIN }, + }; enum ibmvfc_ae_fpin_status fs; struct fc_host_attrs *fc_host; struct ibmvfc_target *tgt; @@ -63,15 +64,15 @@ static void ibmvfc_async_fpin_test(struct kunit *test) pre[IBMVFC_AE_FPIN_CONGESTION_CLEARED] =3D READ_ONCE(fc_host->fpin_stats.= cn_clear); =20 for (fs =3D IBMVFC_AE_FPIN_LINK_CONGESTED; fs <=3D IBMVFC_AE_FPIN_CONGEST= ION_CLEARED; fs++) { - ae[fs].valid =3D 0x80; - ae[fs].link_state =3D IBMVFC_AE_LS_LINK_UP; - ae[fs].fpin_status =3D fs; - ae[fs].event =3D cpu_to_be64(IBMVFC_AE_FPIN); - ae[fs].scsi_id =3D cpu_to_be64(tgt->scsi_id); - ae[fs].wwpn =3D cpu_to_be64(tgt->wwpn); - ae[fs].node_name =3D cpu_to_be64(tgt->ids.node_name); + ae[fs].async_crq.valid =3D 0x80; + ae[fs].async_crq.link_state =3D IBMVFC_AE_LS_LINK_UP; + ae[fs].async_crq.fpin_status =3D fs; + ae[fs].async_crq.event =3D cpu_to_be64(IBMVFC_AE_FPIN); + ae[fs].async_crq.scsi_id =3D cpu_to_be64(tgt->scsi_id); + ae[fs].async_crq.wwpn =3D cpu_to_be64(tgt->wwpn); + ae[fs].async_crq.node_name =3D cpu_to_be64(tgt->ids.node_name); ibmvfc_handle_async(&ae[fs], vhost); - ae[fs].valid =3D 0; + ae[fs].async_crq.valid =3D 0; wmb(); /* ensure valid bit clear is visible before checking stats */ } flush_workqueue(vhost->fpin_workq); @@ -100,15 +101,15 @@ static void ibmvfc_async_fpin_test(struct kunit *test) pre[IBMVFC_AE_FPIN_PORT_DEGRADED] =3D READ_ONCE(rport->fpin_stats.li_fail= ure_unknown); pre[IBMVFC_AE_FPIN_CONGESTION_CLEARED] =3D READ_ONCE(fc_host->fpin_stats.= cn_clear); =20 - ae[0].valid =3D 0x80; - ae[0].link_state =3D IBMVFC_AE_LS_LINK_UP; - ae[0].fpin_status =3D 0; /* bad value */ - ae[0].event =3D cpu_to_be64(IBMVFC_AE_FPIN); - ae[0].scsi_id =3D cpu_to_be64(tgt->scsi_id); - ae[0].wwpn =3D cpu_to_be64(tgt->wwpn); - ae[0].node_name =3D cpu_to_be64(tgt->ids.node_name); + ae[0].async_crq.valid =3D 0x80; + ae[0].async_crq.link_state =3D IBMVFC_AE_LS_LINK_UP; + ae[0].async_crq.fpin_status =3D 0; /* bad value */ + ae[0].async_crq.event =3D cpu_to_be64(IBMVFC_AE_FPIN); + ae[0].async_crq.scsi_id =3D cpu_to_be64(tgt->scsi_id); + ae[0].async_crq.wwpn =3D cpu_to_be64(tgt->wwpn); + ae[0].async_crq.node_name =3D cpu_to_be64(tgt->ids.node_name); ibmvfc_handle_async(&ae[0], vhost); - ae[0].valid =3D 0; + ae[0].async_crq.valid =3D 0; wmb(); /* ensure valid bit clear is visible before checking stats */ flush_workqueue(vhost->fpin_workq); =20 @@ -132,8 +133,132 @@ static void ibmvfc_async_fpin_test(struct kunit *test) kref_put(&tgt->kref, ibmvfc_release_tgt); } =20 +/** + * ibmvfc_full_fpin_test - unit test for IBMVFC_AE_FPIN parts of ibmvfc_ha= ndle_async + * @test: pointer to kunit structure + * + * Tests + * - error returns from ibmvfc_handle_async + * - statistics updates + * + * Return: void + */ +static void ibmvfc_full_fpin_test(struct kunit *test) +{ + u64 post[IBMVFC_AE_FPIN_CONGESTION_CLEARED + 1]; + u64 pre[IBMVFC_AE_FPIN_CONGESTION_CLEARED + 1]; + struct ibmvfc_async_crq_event ae[IBMVFC_AE_FPIN_CONGESTION_CLEARED + 1] = =3D { + [0 ... IBMVFC_AE_FPIN_CONGESTION_CLEARED] =3D { .type =3D IBMVFC_ASYNC_C= RQ_SUB }, + }; + enum ibmvfc_ae_fpin_status fs; + struct fc_host_attrs *fc_host; + struct ibmvfc_target *tgt; + struct ibmvfc_host *vhost; + struct fc_rport *rport; + unsigned long flags; + + vhost =3D ibmvfc_get_first_vhost(); + if (!vhost) + kunit_skip(test, "No ibmvfc devices available"); + + spin_lock_irqsave(&vhost->host->host_lock, flags); + if (vhost->scsi_scrqs.num_targets < 1) { + spin_unlock_irqrestore(&vhost->host->host_lock, flags); + scsi_host_put(vhost->host); + kunit_skip(test, "No targets"); + } + tgt =3D list_first_entry(&vhost->scsi_scrqs.targets, struct ibmvfc_target= , queue); + if (!tgt->rport) { + spin_unlock_irqrestore(&vhost->host->host_lock, flags); + scsi_host_put(vhost->host); + kunit_skip(test, "No rport"); + } + rport =3D tgt->rport; + get_device(&rport->dev); + kref_get(&tgt->kref); + spin_unlock_irqrestore(&vhost->host->host_lock, flags); + + fc_host =3D shost_to_fc_host(vhost->host); + + pre[IBMVFC_AE_FPIN_LINK_CONGESTED] =3D READ_ONCE(fc_host->fpin_stats.cn_d= evice_specific); + pre[IBMVFC_AE_FPIN_PORT_CONGESTED] =3D READ_ONCE(rport->fpin_stats.cn_dev= ice_specific); + pre[IBMVFC_AE_FPIN_PORT_CLEARED] =3D READ_ONCE(rport->fpin_stats.cn_clear= ); + pre[IBMVFC_AE_FPIN_PORT_DEGRADED] =3D READ_ONCE(rport->fpin_stats.li_fail= ure_unknown); + pre[IBMVFC_AE_FPIN_CONGESTION_CLEARED] =3D READ_ONCE(fc_host->fpin_stats.= cn_clear); + + for (fs =3D IBMVFC_AE_FPIN_LINK_CONGESTED; fs <=3D IBMVFC_AE_FPIN_CONGEST= ION_CLEARED; fs++) { + ae[fs].subq.valid =3D 0x80; + ae[fs].subq.link_state =3D IBMVFC_AE_LS_LINK_UP; + ae[fs].subq.fpin_status =3D fs; + ae[fs].subq.event =3D cpu_to_be16(IBMVFC_AE_FPIN); + ae[fs].subq.wwpn =3D cpu_to_be64(tgt->wwpn); + ae[fs].subq.id.node_name =3D cpu_to_be64(tgt->ids.node_name); + ibmvfc_handle_async(&ae[fs], vhost); + ae[fs].subq.valid =3D 0; + wmb(); /* ensure valid bit clear is visible before checking stats */ + } + flush_workqueue(vhost->fpin_workq); + + post[IBMVFC_AE_FPIN_LINK_CONGESTED] =3D READ_ONCE(fc_host->fpin_stats.cn_= device_specific); + post[IBMVFC_AE_FPIN_PORT_CONGESTED] =3D READ_ONCE(rport->fpin_stats.cn_de= vice_specific); + post[IBMVFC_AE_FPIN_PORT_CLEARED] =3D READ_ONCE(rport->fpin_stats.cn_clea= r); + post[IBMVFC_AE_FPIN_PORT_DEGRADED] =3D READ_ONCE(rport->fpin_stats.li_fai= lure_unknown); + post[IBMVFC_AE_FPIN_CONGESTION_CLEARED] =3D READ_ONCE(fc_host->fpin_stats= .cn_clear); + + KUNIT_EXPECT_GE(test, post[IBMVFC_AE_FPIN_LINK_CONGESTED], + pre[IBMVFC_AE_FPIN_LINK_CONGESTED]+1); + KUNIT_EXPECT_GE(test, post[IBMVFC_AE_FPIN_PORT_CONGESTED], + pre[IBMVFC_AE_FPIN_PORT_CONGESTED]+1); + KUNIT_EXPECT_GE(test, post[IBMVFC_AE_FPIN_PORT_CLEARED], + pre[IBMVFC_AE_FPIN_PORT_CLEARED]+1); + KUNIT_EXPECT_GE(test, post[IBMVFC_AE_FPIN_PORT_DEGRADED], + pre[IBMVFC_AE_FPIN_PORT_DEGRADED]+1); + KUNIT_EXPECT_GE(test, post[IBMVFC_AE_FPIN_CONGESTION_CLEARED], + pre[IBMVFC_AE_FPIN_CONGESTION_CLEARED]+1); + + /* bad path */ + pre[IBMVFC_AE_FPIN_LINK_CONGESTED] =3D READ_ONCE(fc_host->fpin_stats.cn_d= evice_specific); + pre[IBMVFC_AE_FPIN_PORT_CONGESTED] =3D READ_ONCE(rport->fpin_stats.cn_dev= ice_specific); + pre[IBMVFC_AE_FPIN_PORT_CLEARED] =3D READ_ONCE(rport->fpin_stats.cn_clear= ); + pre[IBMVFC_AE_FPIN_PORT_DEGRADED] =3D READ_ONCE(rport->fpin_stats.li_fail= ure_unknown); + pre[IBMVFC_AE_FPIN_CONGESTION_CLEARED] =3D READ_ONCE(fc_host->fpin_stats.= cn_clear); + + ae[0].subq.valid =3D 0x80; + ae[0].subq.link_state =3D IBMVFC_AE_LS_LINK_UP; + ae[0].subq.fpin_status =3D 0; /* bad value */ + ae[0].subq.event =3D cpu_to_be16(IBMVFC_AE_FPIN); + ae[0].subq.wwpn =3D cpu_to_be64(tgt->wwpn); + ae[0].subq.id.node_name =3D cpu_to_be64(tgt->ids.node_name); + ibmvfc_handle_async(&ae[0], vhost); + ae[0].subq.valid =3D 0; + wmb(); /* ensure valid bit clear is visible before checking stats */ + flush_workqueue(vhost->fpin_workq); + + post[IBMVFC_AE_FPIN_LINK_CONGESTED] =3D READ_ONCE(fc_host->fpin_stats.cn_= device_specific); + post[IBMVFC_AE_FPIN_PORT_CONGESTED] =3D READ_ONCE(rport->fpin_stats.cn_de= vice_specific); + post[IBMVFC_AE_FPIN_PORT_CLEARED] =3D READ_ONCE(rport->fpin_stats.cn_clea= r); + post[IBMVFC_AE_FPIN_PORT_DEGRADED] =3D READ_ONCE(rport->fpin_stats.li_fai= lure_unknown); + post[IBMVFC_AE_FPIN_CONGESTION_CLEARED] =3D READ_ONCE(fc_host->fpin_stats= .cn_clear); + + KUNIT_EXPECT_EQ(test, pre[IBMVFC_AE_FPIN_LINK_CONGESTED], + post[IBMVFC_AE_FPIN_LINK_CONGESTED]); + KUNIT_EXPECT_EQ(test, pre[IBMVFC_AE_FPIN_PORT_CONGESTED], + post[IBMVFC_AE_FPIN_PORT_CONGESTED]); + KUNIT_EXPECT_EQ(test, pre[IBMVFC_AE_FPIN_PORT_CLEARED], + post[IBMVFC_AE_FPIN_PORT_CLEARED]); + KUNIT_EXPECT_EQ(test, pre[IBMVFC_AE_FPIN_PORT_DEGRADED], + post[IBMVFC_AE_FPIN_PORT_DEGRADED]); + KUNIT_EXPECT_EQ(test, pre[IBMVFC_AE_FPIN_CONGESTION_CLEARED], + post[IBMVFC_AE_FPIN_CONGESTION_CLEARED]); + + put_device(&rport->dev); + kref_put(&tgt->kref, ibmvfc_release_tgt); + scsi_host_put(vhost->host); +} + static struct kunit_case ibmvfc_fpin_test_cases[] =3D { KUNIT_CASE(ibmvfc_async_fpin_test), + KUNIT_CASE(ibmvfc_full_fpin_test), {}, }; =20 --=20 2.55.0 From nobody Fri Sep 25 15:13:49 2026 Received: from mx0b-001b2d01.pphosted.com (mx0b-001b2d01.pphosted.com [148.163.158.5]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 8FB523E49FC; Fri, 11 Sep 2026 05:48:51 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=148.163.158.5 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789105736; cv=none; b=RgpRt6ql5jj0HSGtGeSsDqTgDcoO3d0SgHTzwvdI4S4V9IDgR7ag8z2GwSEjdqtgstZEqY6l/4YoSGP6375JXc4bPED1UyOQu6ay8jDuq0QPqKG2ezJpH0egHdj3FjviWToIngAocVRd+Ps+4y3jrdinPqCyEEKrGtbwaxoUNU8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789105736; c=relaxed/simple; bh=p5vXNsatcsKu6BTWGdich00Ioopo731jxFYI9h8+j+I=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=d2gjHKBGqlJmVfNmha9ZjqtBpsx0FPDn4J0Rr/EDh3St+1EkdSN2JutItjlXFkXW/PnCqPJDr3wJtxhZalLxr4/WTzNtgokCPEvw2nf0SJBJc3Xxya2mDY0I2nzWilns6t/0iWCMXZPSwcBlofpNJdpsLHWFsiQI42zLGcSz/TI= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.ibm.com; spf=pass smtp.mailfrom=linux.ibm.com; dkim=pass (2048-bit key) header.d=ibm.com header.i=@ibm.com header.b=j0ekOoTI; arc=none smtp.client-ip=148.163.158.5 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.ibm.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linux.ibm.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=ibm.com header.i=@ibm.com header.b="j0ekOoTI" Received: from pps.filterd (m0356516.ppops.net [127.0.0.1]) by mx0a-001b2d01.pphosted.com (8.18.1.11/8.18.1.11) with ESMTP id 68B4VdkE649768; Fri, 11 Sep 2026 05:48:42 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ibm.com; h=cc :content-transfer-encoding:date:from:in-reply-to:message-id :mime-version:references:subject:to; s=pp1; bh=ni+/3gohnG3MAW9Q0 OSbSgTG99SHlk1/YroGK6/ZAyM=; b=j0ekOoTIo1nYAMfDwR3SoDkF6wNTOLTMx /WPwaugD0G3G7Qnd73yNvzBDHnBM9nLQXceXE3i/iZN+Y3y3RVegNwLbFOQvft1T iprhqNKiZ2dhrfMQsZ/Q3WO/CPgEtw0V4hYVnr+fZw5Fi1UMexeP1FfTrcsQI7W/ RdDJ/nYxsg2+JfLfi/li+y+xMNusfF1z9Fq52Pgl8IaewZrH31DrGy/AoJEHQs81 r0dUqUnq1pf/pc9HP0MCgfkFqYuGK1SYApakUzqyQAr6vprPQoLePR8swjNEFGdR KUuVyIqUhJbwWPZLo++nO+wrc3g/MJcASO++Bov2CuzockdY3Zo3A== Received: from ppma21.wdc07v.mail.ibm.com (5b.69.3da9.ip4.static.sl-reverse.com [169.61.105.91]) by mx0a-001b2d01.pphosted.com (PPS) with ESMTPS id 4gkd8s9f2x-1 (version=TLSv1.3 cipher=TLS_AES_256_GCM_SHA384 bits=256 verify=NOT); Fri, 11 Sep 2026 05:48:42 +0000 (GMT) Received: from pps.filterd (ppma21.wdc07v.mail.ibm.com [127.0.0.1]) by ppma21.wdc07v.mail.ibm.com (8.18.1.11/8.18.1.11) with ESMTP id 68B4K1cB1055905; Fri, 11 Sep 2026 05:48:41 GMT Received: from smtprelay05.dal12v.mail.ibm.com ([172.16.1.7]) by ppma21.wdc07v.mail.ibm.com (PPS) with ESMTPS id 4gkvvrchr5-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Fri, 11 Sep 2026 05:48:41 +0000 (GMT) Received: from smtpav02.dal12v.mail.ibm.com (smtpav02.dal12v.mail.ibm.com [10.241.53.101]) by smtprelay05.dal12v.mail.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id 68B5mekG25101046 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Fri, 11 Sep 2026 05:48:40 GMT Received: from smtpav02.dal12v.mail.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 6C9D45805C; Fri, 11 Sep 2026 05:48:40 +0000 (GMT) Received: from smtpav02.dal12v.mail.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id CCEA658051; Fri, 11 Sep 2026 05:48:39 +0000 (GMT) Received: from li-4c4c4544-0054-3910-8039-c3c04f423534.ibm.com.com (unknown [9.61.103.123]) by smtpav02.dal12v.mail.ibm.com (Postfix) with ESMTP; Fri, 11 Sep 2026 05:48:39 +0000 (GMT) From: Tyrel Datwyler To: james.bottomley@hansenpartnership.com, martin.petersen@oracle.com Cc: linux-scsi@vger.kernel.org, linuxppc-dev@lists.ozlabs.org, linux-kernel@vger.kernel.org, brking@linux.ibm.com, davemarq@linux.ibm.com, Tyrel Datwyler Subject: [PATCH v10 5/9] scsi: ibmvfc: add interrupt routine for asynchronous sub CRQ Date: Thu, 10 Sep 2026 22:48:28 -0700 Message-ID: <20260911054832.1311668-6-tyreld@linux.ibm.com> X-Mailer: git-send-email 2.55.0 In-Reply-To: <20260911054832.1311668-1-tyreld@linux.ibm.com> References: <20260911054832.1311668-1-tyreld@linux.ibm.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-TM-AS-GCONF: 00 X-Proofpoint-ORIG-GUID: WnmdxE_bVVe8hDInH5-725gmFTVI4Lbg X-Proofpoint-Spam-Details-Enc: AW1haW4tMjYwOTExMDA3NCBTYWx0ZWRfX26alpVCKcs+Y ZXyicQw2okKXH/0pgPt56sCw5a5iuMfT7d38+ymHr1T9Kq1BCVfu5pG9cee/Ae5cl1N3Zi5Ts88 3XsbscEFek3OC7rz2Xeql9PxeazsDu2bf+Rxp6lzqc6YLwcxzHh1usq+YL85+54u5mTaZqhUDpx rt9LJT4dtprh9/Nu4rk1EPHlxt8G+BLtWm+20er6kxTL0xB8B85XIVZsPq5y09ni0Y4IM/zUj7i JJl7dS+OyZpwWd/9IQVV//yNUE1a63qg0+m/RSbOAns0nqgI/kGSckD9b7NdcVfVYUJuVtYtciK M3QBb6yNXDGSffrRSK/eZB1m+T3/JSdLDghpA+Abx6JP6InNLgO6sgkNj4L4sSxPK9kO9i9+TX9 LawDUrqFGRbyxB3XF9ophto+him7P23BeREao3q68965JeuAMmDETgQJTN++K+dpLPmTJyJw7IF VJ0w8gASIak6qxY0Xnw== X-Proofpoint-Spam-Info: AW1haW4tMjYwOTExMDA3NCBTYWx0ZWRfX3DeekEi9BYrd Zw7BuAoSPDwVMFVEush0aaOaCgksDgoMPZfOHV5Ua7HmD/y+4ABZV9D9fdQ93UfQqA+unDnkUkw hm69rDMjTfmAB0CG2AfhJoYQPzaeQ/Y= X-Authority-Analysis: v=2.4 cv=MpXHeGae c=1 sm=1 tr=0 ts=6aa3963a cx=c_pps a=GFwsV6G8L6GxiO2Y/PsHdQ==:117 a=GFwsV6G8L6GxiO2Y/PsHdQ==:17 a=VdqzKS8jKosA:10 a=VkNPw1HP01LnGYTKEx00:22 a=RnoormkPH1_aCDwRdu11:22 a=Y2IxJ9c9Rs8Kov3niI8_:22 a=VnNF1IyMAAAA:8 a=xcGneSeZEGXdk-36SaIA:9 X-Proofpoint-GUID: WnmdxE_bVVe8hDInH5-725gmFTVI4Lbg X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1176,Hydra:6.1.134,FMLib:17.12.100.49 definitions=2026-09-11_02,2026-09-09_02,2025-10-01_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 phishscore=0 suspectscore=0 priorityscore=1501 clxscore=1015 impostorscore=0 adultscore=0 spamscore=0 lowpriorityscore=0 bulkscore=0 malwarescore=0 classifier=typeunknown authscore=0 authtc= authcc= route=outbound adjust=0 reason=mlx scancount=1 engine=8.22.0-2609040000 definitions=main-2609110074 Content-Type: text/plain; charset="utf-8" From: Dave Marquardt Add ibmvfc_interrupt_async_subq(), an IRQ handler dedicated to asynchronous sub-CRQ events from the adapter. The handler disables the sub-CRQ IRQ and then calls ibmvfc_drain_async_subq() to consume all pending entries before re-enabling interrupts. The handler is marked as __maybe_unused until a later patch when it is used. ibmvfc_drain_async_subq() holds the per-queue q_lock while processing. It loops over available CRQ entries via ibmvfc_next_scrq(), wrapping each in a typed struct ibmvfc_async_crq_event and dispatching it to ibmvfc_handle_async(), then clears the valid bit and issues a write barrier. After draining, it re-enables the sub-CRQ IRQ and performs one final check for a newly arrived entry to close the IRQ-enable race; if one is found it is processed before exiting the loop. Signed-off-by: Dave Marquardt [tyreld: added & operator to irqsave/restore calls] Signed-off-by: Tyrel Datwyler --- drivers/scsi/ibmvscsi/ibmvfc-core.c | 54 +++++++++++++++++++++++++++++ 1 file changed, 54 insertions(+) diff --git a/drivers/scsi/ibmvscsi/ibmvfc-core.c b/drivers/scsi/ibmvscsi/ib= mvfc-core.c index 9b66b45871b1..670f6b3a5476 100644 --- a/drivers/scsi/ibmvscsi/ibmvfc-core.c +++ b/drivers/scsi/ibmvscsi/ibmvfc-core.c @@ -4375,6 +4375,60 @@ static struct ibmvfc_crq *ibmvfc_next_scrq(struct ib= mvfc_queue *scrq) return crq; } =20 +static void ibmvfc_drain_async_subq(struct ibmvfc_queue *scrq) +{ + struct ibmvfc_host *vhost =3D scrq->vhost; + unsigned long flags; + struct ibmvfc_crq *crq; + int done =3D 0; + + spin_lock_irqsave(&vhost->host->host_lock, flags); + spin_lock(scrq->q_lock); + while (!done) { + while ((crq =3D ibmvfc_next_scrq(scrq)) !=3D NULL) { + struct ibmvfc_async_crq_event ae =3D { + .type =3D IBMVFC_ASYNC_CRQ_SUB, + .subq =3D *(struct ibmvfc_async_sub_crq *)crq, + }; + ibmvfc_handle_async(&ae, scrq->vhost); + crq->valid =3D 0; + wmb(); /* complete write */ + } + + ibmvfc_toggle_scrq_irq(scrq, 1); + crq =3D ibmvfc_next_scrq(scrq); + if (crq !=3D NULL) { + struct ibmvfc_async_crq_event ae =3D { + .type =3D IBMVFC_ASYNC_CRQ_SUB, + .subq =3D *(struct ibmvfc_async_sub_crq *)crq, + }; + ibmvfc_toggle_scrq_irq(scrq, 0); + ibmvfc_handle_async(&ae, scrq->vhost); + crq->valid =3D 0; + wmb(); /* complete write */ + } else + done =3D 1; + } + spin_unlock(scrq->q_lock); + spin_unlock_irqrestore(&vhost->host->host_lock, flags); +} + +/** + * ibmvfc_interrupt_async_subq - Handle an async event from the adapter + * @irq: interrupt request + * @scrq_instance: async subq + * + **/ +static irqreturn_t __maybe_unused ibmvfc_interrupt_async_subq(int irq, voi= d *scrq_instance) +{ + struct ibmvfc_queue *scrq =3D (struct ibmvfc_queue *)scrq_instance; + + ibmvfc_toggle_scrq_irq(scrq, 0); + ibmvfc_drain_async_subq(scrq); + + return IRQ_HANDLED; +} + static void ibmvfc_drain_sub_crq(struct ibmvfc_queue *scrq) { struct ibmvfc_crq *crq; --=20 2.55.0 From nobody Fri Sep 25 15:13:49 2026 Received: from mx0b-001b2d01.pphosted.com (mx0b-001b2d01.pphosted.com [148.163.158.5]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 7B0303E959C; Fri, 11 Sep 2026 05:48:53 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=148.163.158.5 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789105741; cv=none; b=apW9/oCtrr71GMG22+hBKzURm3PECd0Lk3HOKjEmS9ep6m5ifda6+Vosb+G1HBdMhVpIGO5xNYU5t9xI8i/vzb4JuONsL/OlEoytw7lZb7215FC0TRp302Mx1A8W0h2uFgf5NI03B16D3+vlbEA26LO2HPLCL+Nv3YfEwJLXXoQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789105741; c=relaxed/simple; bh=iLdvs15P3ysVadyLr8qlQ7V2/Y/r6bj/sTY4Lhnu8Ck=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=FZpgwSQqe1dk3mcEOkkZxJ4dvAyksEMIqN87o6HN/EfG8U2eJjMdyeu3cNWHzy5j3bJNOo6tGbhl81ybTeSrsJJYz/IuCgbMVlqt8iAQY/6/PIvu8G7LDpR6ySA60EFWMwJd5pjLjh2iSZTC7voFH1Y3Rmvg3gMj/Rc5g8gm9/0= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.ibm.com; spf=pass smtp.mailfrom=linux.ibm.com; dkim=pass (2048-bit key) header.d=ibm.com header.i=@ibm.com header.b=W/I9ON3N; arc=none smtp.client-ip=148.163.158.5 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.ibm.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linux.ibm.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=ibm.com header.i=@ibm.com header.b="W/I9ON3N" Received: from pps.filterd (m0360072.ppops.net [127.0.0.1]) by mx0a-001b2d01.pphosted.com (8.18.1.11/8.18.1.11) with ESMTP id 68B4VZ8v820147; Fri, 11 Sep 2026 05:48:43 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ibm.com; h=cc :content-transfer-encoding:date:from:in-reply-to:message-id :mime-version:references:subject:to; s=pp1; bh=TYHO+nXJ7SnSiN/7a yKGLs7OHWE0chEalKH2Z7LXRWc=; b=W/I9ON3NHwv/DPkEoRY1sIzYrOm+iSKDR PRxc+McDRnfMZRytMNu+hcKtavKW2joxSGEO2mlS6+3p6Q9eg21OPdEMkEQHpFgq MtX3tt9U+J4mAeHrZpr4rNnxD4kW2jAab9ai516+gWjKLjvhArTjqbvHZcfEOCGN WiW6hJAGgaMiEcWwOs6L3P90QLAFuje7RQQGlLiyGgA33XHbBGBIKNkNLXvF6i6H 4e7EcAxiEnMv8+VFN+0rvGLI2aaZwb8Xirbyp0ayb+RfO626Wa+luprrXWTh4yS8 QXCJ3M9mqLfcUnQ6K/2QowVUDNeZdWyTILs+DcQxfezk8hVoZsSGA== Received: from ppma13.dal12v.mail.ibm.com (dd.9e.1632.ip4.static.sl-reverse.com [50.22.158.221]) by mx0a-001b2d01.pphosted.com (PPS) with ESMTPS id 4gkd8t1fh4-1 (version=TLSv1.3 cipher=TLS_AES_256_GCM_SHA384 bits=256 verify=NOT); Fri, 11 Sep 2026 05:48:42 +0000 (GMT) Received: from pps.filterd (ppma13.dal12v.mail.ibm.com [127.0.0.1]) by ppma13.dal12v.mail.ibm.com (8.18.1.11/8.18.1.11) with ESMTP id 68B4K9ZM1120663; Fri, 11 Sep 2026 05:48:42 GMT Received: from smtprelay06.dal12v.mail.ibm.com ([172.16.1.8]) by ppma13.dal12v.mail.ibm.com (PPS) with ESMTPS id 4gkvmhmmk9-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Fri, 11 Sep 2026 05:48:42 +0000 (GMT) Received: from smtpav02.dal12v.mail.ibm.com (smtpav02.dal12v.mail.ibm.com [10.241.53.101]) by smtprelay06.dal12v.mail.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id 68B5mfCG67043598 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Fri, 11 Sep 2026 05:48:41 GMT Received: from smtpav02.dal12v.mail.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 1F83D5805C; Fri, 11 Sep 2026 05:48:41 +0000 (GMT) Received: from smtpav02.dal12v.mail.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 888BB58051; Fri, 11 Sep 2026 05:48:40 +0000 (GMT) Received: from li-4c4c4544-0054-3910-8039-c3c04f423534.ibm.com.com (unknown [9.61.103.123]) by smtpav02.dal12v.mail.ibm.com (Postfix) with ESMTP; Fri, 11 Sep 2026 05:48:40 +0000 (GMT) From: Tyrel Datwyler To: james.bottomley@hansenpartnership.com, martin.petersen@oracle.com Cc: linux-scsi@vger.kernel.org, linuxppc-dev@lists.ozlabs.org, linux-kernel@vger.kernel.org, brking@linux.ibm.com, davemarq@linux.ibm.com, Tyrel Datwyler Subject: [PATCH v10 6/9] scsi: ibmvfc: extend channel reg/dereg helpers for async sub-CRQ Date: Thu, 10 Sep 2026 22:48:29 -0700 Message-ID: <20260911054832.1311668-7-tyreld@linux.ibm.com> X-Mailer: git-send-email 2.55.0 In-Reply-To: <20260911054832.1311668-1-tyreld@linux.ibm.com> References: <20260911054832.1311668-1-tyreld@linux.ibm.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-TM-AS-GCONF: 00 X-Proofpoint-Spam-Info: AW1haW4tMjYwOTExMDA3NCBTYWx0ZWRfX03tdwiR0kRgR WEk+Z8b9e0vOolEeXlhdItAU+OILzwon5cKAO7ke7WhJ9U/IK7Kh2XeXSP+XvbP/TVHe5hTX6VR fAYy+NsheB7UsYJt6P+5U873blaMxUc= X-Proofpoint-ORIG-GUID: bladGZOKwHUDQLQnbp4IrZPcttVyrY0n X-Proofpoint-GUID: bladGZOKwHUDQLQnbp4IrZPcttVyrY0n X-Proofpoint-Spam-Details-Enc: AW1haW4tMjYwOTExMDA3NCBTYWx0ZWRfX0IFlD9yeF9/z y2zgL0X7sli2G4yUMtEh+lB4yjVIdUjLmu00ciJnl7YeQSRtcN3LNy9Bx/WIRHyJ6yqmF/pR4Pq d2yQtsdjP8F2jHbFNnIDZfAbvbLDp7wd0uDQpSKpvVnEgIs94xO65SoASK3n8h3OJsoasmlkZLv ZOvmJPUtCN0DGElrZFJK81sCMFRult6NFl8lKU5T9QtLVQVzFedJqISdUNcdfU+CA0evV3T6siN Aqdd6uflhN7EObOzNJMDVvDIE8hnAkLrkPorRrq8tZMIq1UgFCzaQiOHkejlD3SQkznydGXjUvU v0TRLU1OZpPsKpXCUGhOyjXUAzY8An9dnxcE77+8ey7S7nsmNsM9lDgzvweO99qplbX1WJiSRLS iWyJJf6YUOllnOFlLAsE4KtcFVRvWb4oG9ub5JowFF1vwyM+TeVkMODB2Otek/Ty6+Q9i/iecHe z5vJQDaM6EtEwiM30Dw== X-Authority-Analysis: v=2.4 cv=PIGaavqC c=1 sm=1 tr=0 ts=6aa3963a cx=c_pps a=AfN7/Ok6k8XGzOShvHwTGQ==:117 a=AfN7/Ok6k8XGzOShvHwTGQ==:17 a=VdqzKS8jKosA:10 a=VkNPw1HP01LnGYTKEx00:22 a=RnoormkPH1_aCDwRdu11:22 a=RzCfie-kr_QcCd8fBx8p:22 a=VnNF1IyMAAAA:8 a=tu7rfeQ3xgwDIMifKtoA:9 X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1176,Hydra:6.1.134,FMLib:17.12.100.49 definitions=2026-09-11_02,2026-09-09_02,2025-10-01_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 phishscore=0 priorityscore=1501 bulkscore=0 adultscore=0 suspectscore=0 lowpriorityscore=0 impostorscore=0 clxscore=1015 spamscore=0 malwarescore=0 classifier=typeunknown authscore=0 authtc= authcc= route=outbound adjust=0 reason=mlx scancount=1 engine=8.22.0-2609040000 definitions=main-2609110074 Content-Type: text/plain; charset="utf-8" From: Dave Marquardt ibmvfc_register_channel() and ibmvfc_deregister_channel() previously only handled indexed sub-CRQ channels drawn from the channels->scrqs[] array. The async sub-CRQ (vhost->async_sub_crq) had no registration path through these helpers, requiring separate handling. Extend both functions to accept a negative index as a sentinel value signalling that the async sub-CRQ should be operated on instead of an indexed scrq entry. When index < 0, the queue pointer is set to &vhost->async_sub_crq, the IRQ is named "ibmvfc--async", and the handler is set to ibmvfc_interrupt_async_subq rather than the per-protocol ibmvfc_interrupt_mq handler. hwq_id assignment is skipped for the async queue since it has no meaningful hardware queue index. Stopped marking ibmvfc_interrupt_async_subq as __maybe_unused. Error messages in both paths are updated to distinguish async sub-CRQ failures from indexed sub-CRQ failures. Kernel-doc headers are added to both functions documenting the negative-index convention. Signed-off-by: Dave Marquardt Acked-by: Tyrel Datwyler --- drivers/scsi/ibmvscsi/ibmvfc-core.c | 93 ++++++++++++++++++++++------- 1 file changed, 70 insertions(+), 23 deletions(-) diff --git a/drivers/scsi/ibmvscsi/ibmvfc-core.c b/drivers/scsi/ibmvscsi/ib= mvfc-core.c index 670f6b3a5476..a9cf1096e755 100644 --- a/drivers/scsi/ibmvscsi/ibmvfc-core.c +++ b/drivers/scsi/ibmvscsi/ibmvfc-core.c @@ -4419,7 +4419,7 @@ static void ibmvfc_drain_async_subq(struct ibmvfc_que= ue *scrq) * @scrq_instance: async subq * **/ -static irqreturn_t __maybe_unused ibmvfc_interrupt_async_subq(int irq, voi= d *scrq_instance) +static irqreturn_t ibmvfc_interrupt_async_subq(int irq, void *scrq_instanc= e) { struct ibmvfc_queue *scrq =3D (struct ibmvfc_queue *)scrq_instance; =20 @@ -6810,13 +6810,29 @@ static int ibmvfc_init_crq(struct ibmvfc_host *vhos= t) return retrc; } =20 +/** + * ibmvfc_register_channel - Register a sub-CRQ channel with the hypervisor + * @vhost: ibmvfc host struct + * @channels: ibmvfc channels struct containing the channel array and prot= ocol + * @index: index into the channels array for the queue to register, or + * a negative value to register the async sub-CRQ + * + * Register a sub-CRQ with the hypervisor via h_reg_sub_crq, map its hardw= are + * IRQ to a Linux IRQ, and bind an interrupt handler to it. The handler is + * selected based on the channel protocol (SCSI or NVMe) for normal queues= , or + * set to the async sub-CRQ handler when @index is negative. + * + * Return value: + * 0 on success / non-zero on failure + **/ static int ibmvfc_register_channel(struct ibmvfc_host *vhost, struct ibmvfc_channels *channels, int index) { struct device *dev =3D vhost->dev; struct vio_dev *vdev =3D to_vio_dev(dev); - struct ibmvfc_queue *scrq =3D &channels->scrqs[index]; + bool is_async =3D index < 0; + struct ibmvfc_queue *scrq =3D !is_async ? &channels->scrqs[index] : &vhos= t->async_sub_crq; int rc =3D -ENOMEM; =20 ENTER; @@ -6836,36 +6852,49 @@ static int ibmvfc_register_channel(struct ibmvfc_ho= st *vhost, =20 if (!scrq->irq) { rc =3D -EINVAL; - dev_err(dev, "Error mapping sub-crq[%d] irq\n", index); + if (!is_async) + dev_err(dev, "Error mapping sub-crq[%d] irq\n", index); + else + dev_err(dev, "Error mapping async sub-crq irq\n"); goto irq_failed; } =20 - switch (channels->protocol) { - case IBMVFC_PROTO_SCSI: - snprintf(scrq->name, sizeof(scrq->name), "ibmvfc-%x-scsi%d", - vdev->unit_address, index); - scrq->handler =3D ibmvfc_interrupt_mq; - break; - case IBMVFC_PROTO_NVME: - snprintf(scrq->name, sizeof(scrq->name), "ibmvfc-%x-nvmf%d", - vdev->unit_address, index); - scrq->handler =3D ibmvfc_interrupt_mq; - break; - default: - dev_err(dev, "Unknown channel protocol (%d)\n", - channels->protocol); - goto irq_failed; + if (!is_async) { + switch (channels->protocol) { + case IBMVFC_PROTO_SCSI: + snprintf(scrq->name, sizeof(scrq->name), "ibmvfc-%x-scsi%d", + vdev->unit_address, index); + scrq->handler =3D ibmvfc_interrupt_mq; + break; + case IBMVFC_PROTO_NVME: + snprintf(scrq->name, sizeof(scrq->name), "ibmvfc-%x-nvmf%d", + vdev->unit_address, index); + scrq->handler =3D ibmvfc_interrupt_mq; + break; + default: + dev_err(dev, "Unknown channel protocol (%d)\n", + channels->protocol); + goto irq_failed; + } + } else { + snprintf(scrq->name, sizeof(scrq->name), "ibmvfc-%x-async", + vdev->unit_address); + scrq->handler =3D ibmvfc_interrupt_async_subq; } =20 rc =3D request_irq(scrq->irq, scrq->handler, 0, scrq->name, scrq); =20 if (rc) { - dev_err(dev, "Couldn't register sub-crq[%d] irq\n", index); + if (!is_async) + dev_err(dev, "Couldn't register sub-crq[%d] irq\n", index); + else + dev_err(dev, "Couldn't register async sub-crq irq\n"); irq_dispose_mapping(scrq->irq); goto irq_failed; } =20 - scrq->hwq_id =3D index; + if (!is_async) + scrq->hwq_id =3D index; =20 LEAVE; return 0; @@ -6879,13 +6908,26 @@ static int ibmvfc_register_channel(struct ibmvfc_ho= st *vhost, return rc; } =20 +/** + * ibmvfc_deregister_channel - Deregister a sub-CRQ channel with the hyper= visor + * @vhost: ibmvfc host struct + * @channels: ibmvfc channels struct containing the sub-CRQ array + * @index: index into the sub-CRQ array, or -1 to deregister the + * asynchronous sub-CRQ + * + * Frees the IRQ, disposes of the IRQ mapping, and calls H_FREE_SUB_CRQ to + * release the sub-CRQ with the hypervisor. On success the queue message + * buffer is zeroed and the current index is reset. If H_FREE_SUB_CRQ fail= s, + * an error is logged but the channel resources are cleaned up regardless. + */ static void ibmvfc_deregister_channel(struct ibmvfc_host *vhost, struct ibmvfc_channels *channels, int index) { struct device *dev =3D vhost->dev; struct vio_dev *vdev =3D to_vio_dev(dev); - struct ibmvfc_queue *scrq =3D &channels->scrqs[index]; + bool is_async =3D index < 0; + struct ibmvfc_queue *scrq =3D !is_async ? &channels->scrqs[index] : &vhos= t->async_sub_crq; long rc; =20 ENTER; @@ -6899,8 +6941,13 @@ static void ibmvfc_deregister_channel(struct ibmvfc_= host *vhost, scrq->cookie); } while (rc =3D=3D H_BUSY || H_IS_LONG_BUSY(rc)); =20 - if (rc) - dev_err(dev, "Failed to free sub-crq[%d]: rc=3D%ld\n", index, rc); + if (rc) { + if (!is_async) + dev_err(dev, "Failed to free sub-crq[%d]: rc=3D%ld\n", + index, rc); + else + dev_err(dev, "Failed to free async sub-crq: rc=3D%ld\n", rc); + } =20 /* Clean out the queue */ memset(scrq->msgs.crq, 0, PAGE_SIZE); --=20 2.55.0 From nobody Fri Sep 25 15:13:49 2026 Received: from mx0b-001b2d01.pphosted.com (mx0b-001b2d01.pphosted.com [148.163.158.5]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id E415E3E7167; Fri, 11 Sep 2026 05:48:51 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=148.163.158.5 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789105736; cv=none; b=hgX+Wj1zMqHieyQV4T1cMMNpl7fJrIsvWQolL9yTz42yyLybJstwQHRA2KsJbc3S3Dg9R62eAOjs0lUVrNhAQv4tci9xXRQuKjO1izcsnE+VO8etqnk44qM1sJ5swB517JfUrPPuKeGLXduueCRmY3HXBWH2rDIezfDYFNtF1tU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789105736; c=relaxed/simple; bh=+AvUvffUGjI7fGaMCoznYhBp6jgOsbcLJhmNgaJj378=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=j/9fEJDWfjqXJgtIn80fS+zksBkVlzi5yxKHRSmVcVvOsx7UD4FDEgHEJ+rBYXMVJ3mUaDS7IAsGp+jWKQhTJvA6VsgMpLu6osKraH2Ex+kpgw7L4Y0pIMNUgMTRqj3/LEibeDqJUps6/d2dwSg7NYrpC8yfQRk5g06pujYs3zs= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.ibm.com; spf=pass smtp.mailfrom=linux.ibm.com; dkim=pass (2048-bit key) header.d=ibm.com header.i=@ibm.com header.b=K7Hvvlhj; arc=none smtp.client-ip=148.163.158.5 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.ibm.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linux.ibm.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=ibm.com header.i=@ibm.com header.b="K7Hvvlhj" Received: from pps.filterd (m0353725.ppops.net [127.0.0.1]) by mx0a-001b2d01.pphosted.com (8.18.1.11/8.18.1.11) with ESMTP id 68B4VoNe3840229; Fri, 11 Sep 2026 05:48:43 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ibm.com; h=cc :content-transfer-encoding:date:from:in-reply-to:message-id :mime-version:references:subject:to; s=pp1; bh=gQjnOVWar+06Fhskk FF16z5SSEaTQAHdxSv6WMoTh7w=; b=K7HvvlhjbPidot/cWLYBsE0ND8lW5avpm Ixfc+zyrzLGyYGF+0IU+1G6zZb6Rr9JKFKuQudFZWxMpCKK+RdU219Gg9PCuOx3A 7PseqiZo/u8Buvue/EQspVVKA38IPb8UoeaibZArrkMEQTX8QwH6Ysr4GGJ4eGPu 2REMV7APWKE7tVOcY4fEmvSyfQppTV1iJjvggcOQJciXZJgYYtJKw+A5rVk3VtQ2 qJGnqbEwSx8CWk9oDS2t4Se2eNcMfFFUqtoIOoRUYoHoDrgDqhRD3ypZqVz0uB76 GUKFsJOOsIIVyNrhumf7u6BZ0nPEEa0aOWzvFszQGrBOgPkP/QIhw== Received: from ppma22.wdc07v.mail.ibm.com (5c.69.3da9.ip4.static.sl-reverse.com [169.61.105.92]) by mx0a-001b2d01.pphosted.com (PPS) with ESMTPS id 4gkd8q9g6h-1 (version=TLSv1.3 cipher=TLS_AES_256_GCM_SHA384 bits=256 verify=NOT); Fri, 11 Sep 2026 05:48:43 +0000 (GMT) Received: from pps.filterd (ppma22.wdc07v.mail.ibm.com [127.0.0.1]) by ppma22.wdc07v.mail.ibm.com (8.18.1.11/8.18.1.11) with ESMTP id 68B4K2H21076021; Fri, 11 Sep 2026 05:48:43 GMT Received: from smtprelay06.dal12v.mail.ibm.com ([172.16.1.8]) by ppma22.wdc07v.mail.ibm.com (PPS) with ESMTPS id 4gkvwk4j7e-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Fri, 11 Sep 2026 05:48:43 +0000 (GMT) Received: from smtpav02.dal12v.mail.ibm.com (smtpav02.dal12v.mail.ibm.com [10.241.53.101]) by smtprelay06.dal12v.mail.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id 68B5mfPU33096314 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Fri, 11 Sep 2026 05:48:42 GMT Received: from smtpav02.dal12v.mail.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id E0A9858051; Fri, 11 Sep 2026 05:48:41 +0000 (GMT) Received: from smtpav02.dal12v.mail.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 44F1E5805F; Fri, 11 Sep 2026 05:48:41 +0000 (GMT) Received: from li-4c4c4544-0054-3910-8039-c3c04f423534.ibm.com.com (unknown [9.61.103.123]) by smtpav02.dal12v.mail.ibm.com (Postfix) with ESMTP; Fri, 11 Sep 2026 05:48:41 +0000 (GMT) From: Tyrel Datwyler To: james.bottomley@hansenpartnership.com, martin.petersen@oracle.com Cc: linux-scsi@vger.kernel.org, linuxppc-dev@lists.ozlabs.org, linux-kernel@vger.kernel.org, brking@linux.ibm.com, davemarq@linux.ibm.com, Tyrel Datwyler Subject: [PATCH v10 7/9] scsi: ibmvfc: fix IRQ leak and guard deregister on channel reg failure Date: Thu, 10 Sep 2026 22:48:30 -0700 Message-ID: <20260911054832.1311668-8-tyreld@linux.ibm.com> X-Mailer: git-send-email 2.55.0 In-Reply-To: <20260911054832.1311668-1-tyreld@linux.ibm.com> References: <20260911054832.1311668-1-tyreld@linux.ibm.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-TM-AS-GCONF: 00 X-Proofpoint-ORIG-GUID: bCGSt3HNmsDIotuNP2T3OA9BvyHUOo9I X-Proofpoint-Spam-Info: AW1haW4tMjYwOTExMDA3NCBTYWx0ZWRfX8QHSmrNpSJ6m kkdOGdV2L9WRikEAV+BHiO84KGDyVdaKv0cJHkEeL9ZZoy+fklZc6Wcn0MxVF7TZ1le/lqs7H5c Hm7TJjkTu5JVZNycwT258XZ2aPw28qY= X-Authority-Analysis: v=2.4 cv=E/dYNqdl c=1 sm=1 tr=0 ts=6aa3963b cx=c_pps a=5BHTudwdYE3Te8bg5FgnPg==:117 a=5BHTudwdYE3Te8bg5FgnPg==:17 a=VdqzKS8jKosA:10 a=VkNPw1HP01LnGYTKEx00:22 a=RnoormkPH1_aCDwRdu11:22 a=V8glGbnc2Ofi9Qvn3v5h:22 a=VnNF1IyMAAAA:8 a=acainBHvso6FeXtkDgYA:9 X-Proofpoint-Spam-Details-Enc: AW1haW4tMjYwOTExMDA3NCBTYWx0ZWRfX7y6sPU2x3hPc bOEKw4Opx/UjfTXYu0MwbkP7LhNIvDvDARs1ErK/eQU6UhjnUyA7g3i9dJTrIS3c7Cxpsb3bN4m gyeAcDlh/mnd9/GArf3CD3rBnbZtRFzDRtgshZtZFUgK7E8pQjGscgwjzlWN6CNbnSrFazRDNuj oHHNpiyVpFowp5Oxee7zKf4ValQa1Hg9YEy8H3Nhj+3xIb2d7xW6cPxwfyqHmkvhl4KDCPzPNmm OO8mSUwHqCZRnUJau1TJWWAMwnrvfW7LTwn8f6/6/2rHmnjVNoW/0+pka5K3WMCgx5mQzuNI1F8 4L16Yq1naqss6AAOGRdAcH61+b7NibXXYZadAe4UdlJFoM+OmbPkVkOzG3FZwyd2sl90Xi5jTbY KwJS6PM7uwctAbXw17n3/RxXmMgKIASaGjtn7NQqKm5zKrxKFAUkWSzlUS333rJudBIazOsm69a ImvWtuAvg/WKf0tALUA== X-Proofpoint-GUID: bCGSt3HNmsDIotuNP2T3OA9BvyHUOo9I X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1176,Hydra:6.1.134,FMLib:17.12.100.49 definitions=2026-09-11_02,2026-09-09_02,2025-10-01_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 priorityscore=1501 suspectscore=0 spamscore=0 bulkscore=0 clxscore=1015 impostorscore=0 phishscore=0 adultscore=0 lowpriorityscore=0 malwarescore=0 classifier=typeunknown authscore=0 authtc= authcc= route=outbound adjust=0 reason=mlx scancount=1 engine=8.22.0-2609040000 definitions=main-2609110074 Content-Type: text/plain; charset="utf-8" From: Dave Marquardt If request_irq() fails during ibmvfc_register_channel(), the error path disposes of the IRQ mapping via irq_dispose_mapping() but leaves scrq->irq populated with the stale virq number. A subsequent call to ibmvfc_deregister_channel() during teardown or reset cleanup then unconditionally invokes free_irq() and irq_dispose_mapping() on the stale IRQ descriptor, triggering kernel warnings. Fix this by: 1. Explicitly setting scrq->irq to 0 after irq_dispose_mapping() in the ibmvfc_register_channel() error path. 2. Guarding free_irq() and irq_dispose_mapping() with a check for scrq->irq in ibmvfc_deregister_channel() so unmapped or unregistered queues are safely skipped. Signed-off-by: Dave Marquardt Acked-by: Tyrel Datwyler --- drivers/scsi/ibmvscsi/ibmvfc-core.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/drivers/scsi/ibmvscsi/ibmvfc-core.c b/drivers/scsi/ibmvscsi/ib= mvfc-core.c index a9cf1096e755..c78e221f182a 100644 --- a/drivers/scsi/ibmvscsi/ibmvfc-core.c +++ b/drivers/scsi/ibmvscsi/ibmvfc-core.c @@ -6890,6 +6890,7 @@ static int ibmvfc_register_channel(struct ibmvfc_host= *vhost, else dev_err(dev, "Couldn't register async sub-crq irq\n"); irq_dispose_mapping(scrq->irq); + scrq->irq =3D 0; goto irq_failed; } =20 @@ -6932,9 +6933,11 @@ static void ibmvfc_deregister_channel(struct ibmvfc_= host *vhost, =20 ENTER; =20 - free_irq(scrq->irq, scrq); - irq_dispose_mapping(scrq->irq); - scrq->irq =3D 0; + if (scrq->irq) { + free_irq(scrq->irq, scrq); + irq_dispose_mapping(scrq->irq); + scrq->irq =3D 0; + } =20 do { rc =3D plpar_hcall_norets(H_FREE_SUB_CRQ, vdev->unit_address, --=20 2.55.0 From nobody Fri Sep 25 15:13:49 2026 Received: from mx0a-001b2d01.pphosted.com (mx0a-001b2d01.pphosted.com [148.163.156.1]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id ECC253A48CA; Fri, 11 Sep 2026 05:48:54 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=148.163.156.1 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789105737; cv=none; b=IHTaTQWnBFDnTUKlnLCesY7s/InBhqFL/GNdmKMAYqMB1L+Azh5fHWf+0cwp5SYdT1YhL8Fo9CE8kuD1erhKaHh+Y5A2mF84bnSxBmnWR+mzQi/wLnG3aSNg6NPF3Nr/2uMkPO8zJWE6Fz6wi1z8/MfuRbnEc1fQgIdoAC5Oha8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789105737; c=relaxed/simple; bh=xa9ZFwSNLxpXxPfcW5YLy9ilvFwH6Udy56FUeciO6zo=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=WFObSdzWc7E8Mfs7gYJTpo+gLGsA7s0zwd4tJ14oOZamJpeFVdmt24hrwcwBNPhEwexMacG7qM9tFBdht148S4KO1YGLHg2cwicdxyUw58q8UxcfqSWpZKClnEfbOkaqAmyP93nwNIxfg9ZWppnKcjBz9Psq6ea+xJyWeNngu9M= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.ibm.com; spf=pass smtp.mailfrom=linux.ibm.com; dkim=pass (2048-bit key) header.d=ibm.com header.i=@ibm.com header.b=AGGCooqx; arc=none smtp.client-ip=148.163.156.1 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.ibm.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linux.ibm.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=ibm.com header.i=@ibm.com header.b="AGGCooqx" Received: from pps.filterd (m0356517.ppops.net [127.0.0.1]) by mx0a-001b2d01.pphosted.com (8.18.1.11/8.18.1.11) with ESMTP id 68B4VQk1783552; Fri, 11 Sep 2026 05:48:45 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ibm.com; h=cc :content-transfer-encoding:date:from:in-reply-to:message-id :mime-version:references:subject:to; s=pp1; bh=S4D4zSL5CZaLxX1fb liTHpLx9ksNqGwiA3jn2bfOHNM=; b=AGGCooqx9lbaoRVP+Ot1Km58k/vDH0n1G xfOG0JW97MBMzXpQo/6DtT8eWpi8cBW/q4OfBa+7zdl3oY6MLDU3s7admAkLVjrV QhZbIrKtGefbvjEsjiKxhT7cwU3bjH1q8gXnVia8f4i4eAkoeq6u/spBvOyj1Q8H Y1wnTCdaESIMlc7SE3+qlEGrgci0wAlHY8GKCugxKll7vBMJcK8T3IqVlbUzEc0c t3u1z9VLOtQqr4iGqtps7T2sLlqX0e+SA3l632FCaqewD6dcrGVuD9BNr8TJ/2Vu DO8MhagDlwNoQcERhcQ1/O+feS/9DlIppDJsbvny+vDIXq73EOyZg== Received: from ppma21.wdc07v.mail.ibm.com (5b.69.3da9.ip4.static.sl-reverse.com [169.61.105.91]) by mx0a-001b2d01.pphosted.com (PPS) with ESMTPS id 4gkd8psjw1-1 (version=TLSv1.3 cipher=TLS_AES_256_GCM_SHA384 bits=256 verify=NOT); Fri, 11 Sep 2026 05:48:44 +0000 (GMT) Received: from pps.filterd (ppma21.wdc07v.mail.ibm.com [127.0.0.1]) by ppma21.wdc07v.mail.ibm.com (8.18.1.11/8.18.1.11) with ESMTP id 68B4K3Du1056110; Fri, 11 Sep 2026 05:48:43 GMT Received: from smtprelay07.dal12v.mail.ibm.com ([172.16.1.9]) by ppma21.wdc07v.mail.ibm.com (PPS) with ESMTPS id 4gkvvrchr8-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Fri, 11 Sep 2026 05:48:43 +0000 (GMT) Received: from smtpav02.dal12v.mail.ibm.com (smtpav02.dal12v.mail.ibm.com [10.241.53.101]) by smtprelay07.dal12v.mail.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id 68B5mg8f17826538 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Fri, 11 Sep 2026 05:48:42 GMT Received: from smtpav02.dal12v.mail.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 9BBEF58051; Fri, 11 Sep 2026 05:48:42 +0000 (GMT) Received: from smtpav02.dal12v.mail.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 078295805A; Fri, 11 Sep 2026 05:48:42 +0000 (GMT) Received: from li-4c4c4544-0054-3910-8039-c3c04f423534.ibm.com.com (unknown [9.61.103.123]) by smtpav02.dal12v.mail.ibm.com (Postfix) with ESMTP; Fri, 11 Sep 2026 05:48:41 +0000 (GMT) From: Tyrel Datwyler To: james.bottomley@hansenpartnership.com, martin.petersen@oracle.com Cc: linux-scsi@vger.kernel.org, linuxppc-dev@lists.ozlabs.org, linux-kernel@vger.kernel.org, brking@linux.ibm.com, davemarq@linux.ibm.com, Tyrel Datwyler Subject: [PATCH v10 8/9] scsi: ibmvfc: register and use asynchronous sub CRQ for events Date: Thu, 10 Sep 2026 22:48:31 -0700 Message-ID: <20260911054832.1311668-9-tyreld@linux.ibm.com> X-Mailer: git-send-email 2.55.0 In-Reply-To: <20260911054832.1311668-1-tyreld@linux.ibm.com> References: <20260911054832.1311668-1-tyreld@linux.ibm.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-TM-AS-GCONF: 00 X-Authority-Analysis: v=2.4 cv=eM2GH3p1 c=1 sm=1 tr=0 ts=6aa3963c cx=c_pps a=GFwsV6G8L6GxiO2Y/PsHdQ==:117 a=GFwsV6G8L6GxiO2Y/PsHdQ==:17 a=VdqzKS8jKosA:10 a=VkNPw1HP01LnGYTKEx00:22 a=RnoormkPH1_aCDwRdu11:22 a=U7nrCbtTmkRpXpFmAIza:22 a=VnNF1IyMAAAA:8 a=EqnsHTcO9pxfbuvt6BcA:9 X-Proofpoint-ORIG-GUID: TCx2wwys1-aXwVct8NF8x8xA8Y2oMxw8 X-Proofpoint-GUID: TCx2wwys1-aXwVct8NF8x8xA8Y2oMxw8 X-Proofpoint-Spam-Info: AW1haW4tMjYwOTExMDA3NCBTYWx0ZWRfX5fljWYFg3pIs DgJttsC5yMnOn/aUtaPwg+NAlpJdFBvY/HODt+4JWBsvnP8q4tTANHntxRUZNaCFkdnJzpGsydF jPlHQtyCfF/M2wq6UKcRYXNIS1XsZjs= X-Proofpoint-Spam-Details-Enc: AW1haW4tMjYwOTExMDA3NCBTYWx0ZWRfXzNsD41Bz2klJ pcH2KkMrMpund+/03cp0+HLb2NQTATuhggBeNkpxJNgniW2bDYT1InA0zKowTcc2+i7orlnpwqu sQYsz2VQbY7whDzSSK8VgErMSK6cGCzCQmawaoaQPdpqzxd9O7FLYD2vYDpOAbEfpYLi5QbcO7o n34o8t1FAYDVYyt6TH5UTDGLx9rdKPbOecP3lCXKIrAtQ/Gb8lrqNS5Zzf3QivSjQwwK8m6v7BB nzSJOBqU44mYUZrOH4CoBt/aCPtPYpYFq8yhqpRFDMAamuuT2c24LQ2WngkGTssnjrans3s9VQf N/zx5+EBY8piwgccFYMNcGliINoQBulpzGlMPHmjQzH+hYTikta+GzrTAiwliBU+QajxJqF18lk TEGlrUrcZ9nbggrtJFIBUznf5833a0acuT4igX55nsFV23jBJmg9zOjbvZMf9t34Pegaqn7OnMo XLZxRx7kNiMYwPvDJHw== X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1176,Hydra:6.1.134,FMLib:17.12.100.49 definitions=2026-09-11_02,2026-09-09_02,2025-10-01_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 clxscore=1015 impostorscore=0 malwarescore=0 adultscore=0 phishscore=0 lowpriorityscore=0 suspectscore=0 spamscore=0 priorityscore=1501 bulkscore=0 classifier=typeunknown authscore=0 authtc= authcc= route=outbound adjust=0 reason=mlx scancount=1 engine=8.22.0-2609040000 definitions=main-2609110074 Content-Type: text/plain; charset="utf-8" From: Dave Marquardt Wire the async sub-CRQ into the sub-CRQ lifecycle so it is allocated, registered, and freed alongside the SCSI channel queues. In ibmvfc_init_sub_crqs(), allocate the async sub-CRQ queue buffer via ibmvfc_alloc_queue() before allocating the SCSI channels. Register it with the VIOS by calling ibmvfc_register_channel() with index -1 (the negative-index sentinel introduced in the previous commit). Either failure disables multi-queue and aborts init. In ibmvfc_release_sub_crqs(), ibmvfc_reenable_crq_queue(), and ibmvfc_reset_crq(), deregister and re-register the async sub-CRQ alongside the SCSI channel queues. In ibmvfc_channel_setup_done(), capture the async sub-CRQ handle returned by the VIOS in the channel setup response and store it in vhost->async_sub_crq.vios_cookie. In ibmvfc_set_login_info(), advertise IBMVFC_USE_ASYNC_SUBQ, IBMVFC_CAN_HANDLE_FPIN, and IBMVFC_YES_SCSI capabilities whenever multi-queue channels are enabled. IBMVFC_YES_SCSI was previously only set for NVMe-enabled configurations; move it to the common multi-queue path so it is always advertised when channels are in use. Fix a variable-shadowing bug in ibmvfc_register_channel() where the irq_failed cleanup loop reused rc for the H_FREE_SUB_CRQ hcall result, clobbering the error code returned to the caller. Introduce hcall_rc for the cleanup loop instead. Guard the memset() in ibmvfc_deregister_channel() behind a check of scrq->msgs.handle to prevent a NULL dereference when the function is called on a queue that was never allocated, such as async_sub_crq when multi-queue is disabled or initialization failed before ibmvfc_alloc_queue() was reached. Signed-off-by: Dave Marquardt Acked-by: Tyrel Datwyler --- drivers/scsi/ibmvscsi/ibmvfc-core.c | 51 +++++++++++++++++++++++++---- 1 file changed, 44 insertions(+), 7 deletions(-) diff --git a/drivers/scsi/ibmvscsi/ibmvfc-core.c b/drivers/scsi/ibmvscsi/ib= mvfc-core.c index c78e221f182a..70a3046135c7 100644 --- a/drivers/scsi/ibmvscsi/ibmvfc-core.c +++ b/drivers/scsi/ibmvscsi/ibmvfc-core.c @@ -192,6 +192,8 @@ static void ibmvfc_tgt_move_login(struct ibmvfc_target = *); =20 static void ibmvfc_dereg_sub_crqs(struct ibmvfc_host *, struct ibmvfc_chan= nels *); static void ibmvfc_reg_sub_crqs(struct ibmvfc_host *, struct ibmvfc_channe= ls *); +static void ibmvfc_deregister_channel(struct ibmvfc_host *, struct ibmvfc_= channels *, int); +static int ibmvfc_register_channel(struct ibmvfc_host *, struct ibmvfc_cha= nnels *, int); =20 static const char *unknown_error =3D "unknown error"; =20 @@ -964,6 +966,7 @@ static int ibmvfc_reenable_crq_queue(struct ibmvfc_host= *vhost) struct vio_dev *vdev =3D to_vio_dev(vhost->dev); unsigned long flags; =20 + ibmvfc_deregister_channel(vhost, &vhost->scsi_scrqs, -1); ibmvfc_dereg_sub_crqs(vhost, &vhost->scsi_scrqs); ibmvfc_dereg_sub_crqs(vhost, &vhost->nvme_scrqs); =20 @@ -986,6 +989,7 @@ static int ibmvfc_reenable_crq_queue(struct ibmvfc_host= *vhost) spin_unlock(vhost->crq.q_lock); spin_unlock_irqrestore(&vhost->host->host_lock, flags); =20 + ibmvfc_register_channel(vhost, &vhost->scsi_scrqs, -1); ibmvfc_reg_sub_crqs(vhost, &vhost->scsi_scrqs); ibmvfc_reg_sub_crqs(vhost, &vhost->nvme_scrqs); =20 @@ -1006,6 +1010,7 @@ static int ibmvfc_reset_crq(struct ibmvfc_host *vhost) struct vio_dev *vdev =3D to_vio_dev(vhost->dev); struct ibmvfc_queue *crq =3D &vhost->crq; =20 + ibmvfc_deregister_channel(vhost, &vhost->scsi_scrqs, -1); ibmvfc_dereg_sub_crqs(vhost, &vhost->scsi_scrqs); ibmvfc_dereg_sub_crqs(vhost, &vhost->nvme_scrqs); =20 @@ -1042,6 +1047,7 @@ static int ibmvfc_reset_crq(struct ibmvfc_host *vhost) spin_unlock(vhost->crq.q_lock); spin_unlock_irqrestore(&vhost->host->host_lock, flags); =20 + ibmvfc_register_channel(vhost, &vhost->scsi_scrqs, -1); ibmvfc_reg_sub_crqs(vhost, &vhost->scsi_scrqs); ibmvfc_reg_sub_crqs(vhost, &vhost->nvme_scrqs); =20 @@ -1584,9 +1590,11 @@ static void ibmvfc_set_login_info(struct ibmvfc_host= *vhost) =20 if (vhost->mq_enabled || vhost->using_channels) { login_info->capabilities |=3D cpu_to_be64(IBMVFC_CAN_USE_CHANNELS); + login_info->capabilities |=3D cpu_to_be64(IBMVFC_USE_ASYNC_SUBQ); + login_info->capabilities |=3D cpu_to_be64(IBMVFC_CAN_HANDLE_FPIN); + login_info->capabilities |=3D cpu_to_be64(IBMVFC_YES_SCSI); if (vhost->nvme_enabled) { login_info->capabilities |=3D cpu_to_be64(IBMVFC_YES_NVMEOF); - login_info->capabilities |=3D cpu_to_be64(IBMVFC_YES_SCSI); login_info->capabilities |=3D cpu_to_be64(IBMVFC_CAN_USE_WWPN_ALL); } } @@ -5811,6 +5819,7 @@ static void ibmvfc_channel_setup_done(struct ibmvfc_e= vent *evt) for (i =3D 0; i < nvme->active_queues; i++) nvme->scrqs[i].vios_cookie =3D be64_to_cpu(setup->channel_handles[scsi->active_queues + i]); + vhost->async_sub_crq.vios_cookie =3D be64_to_cpu(setup->async_sub_crq_ha= ndle); =20 ibmvfc_dbg(vhost, "Using %u SCSI channels\n", scsi->active_queues); @@ -5870,6 +5879,7 @@ static void ibmvfc_channel_setup(struct ibmvfc_host *= vhost) for (i =3D 0; i < nvme_channels; i++) setup_buf->channel_handles[scsi_channels + i] =3D cpu_to_be64(nvme->scrqs[i].cookie); + setup_buf->async_sub_crq_handle =3D cpu_to_be64(vhost->async_sub_crq.coo= kie); } =20 ibmvfc_init_event(evt, ibmvfc_channel_setup_done, IBMVFC_MAD_FORMAT); @@ -6834,6 +6844,7 @@ static int ibmvfc_register_channel(struct ibmvfc_host= *vhost, bool is_async =3D index < 0; struct ibmvfc_queue *scrq =3D !is_async ? &channels->scrqs[index] : &vhos= t->async_sub_crq; int rc =3D -ENOMEM; + int hcall_rc; =20 ENTER; =20 @@ -6902,8 +6913,8 @@ static int ibmvfc_register_channel(struct ibmvfc_host= *vhost, =20 irq_failed: do { - rc =3D plpar_hcall_norets(H_FREE_SUB_CRQ, vdev->unit_address, scrq->cook= ie); - } while (rc =3D=3D H_BUSY || H_IS_LONG_BUSY(rc)); + hcall_rc =3D plpar_hcall_norets(H_FREE_SUB_CRQ, vdev->unit_address, scrq= ->cookie); + } while (hcall_rc =3D=3D H_BUSY || H_IS_LONG_BUSY(hcall_rc)); reg_failed: LEAVE; return rc; @@ -6953,8 +6964,10 @@ static void ibmvfc_deregister_channel(struct ibmvfc_= host *vhost, } =20 /* Clean out the queue */ - memset(scrq->msgs.crq, 0, PAGE_SIZE); - scrq->cur =3D 0; + if (scrq->msgs.handle) { + memset(scrq->msgs.crq, 0, PAGE_SIZE); + scrq->cur =3D 0; + } =20 LEAVE; } @@ -6971,7 +6984,9 @@ static void ibmvfc_reg_sub_crqs(struct ibmvfc_host *v= host, for (i =3D 0; i < channels->max_queues; i++) { if (ibmvfc_register_channel(vhost, channels, i)) { for (j =3D i; j > 0; j--) - ibmvfc_deregister_channel(vhost, channels, j - 1); + ibmvfc_deregister_channel( + vhost, channels, j - 1); + vhost->do_enquiry =3D 0; return; } @@ -7026,16 +7041,26 @@ static int ibmvfc_alloc_channels(struct ibmvfc_host= *vhost, =20 static void ibmvfc_init_sub_crqs(struct ibmvfc_host *vhost) { + int rc =3D 0; + ENTER; if (!vhost->mq_enabled) return; =20 - if (ibmvfc_alloc_channels(vhost, &vhost->scsi_scrqs)) { + rc =3D ibmvfc_alloc_queue(vhost, &vhost->async_sub_crq, IBMVFC_SUB_CRQ_FM= T); + if (rc) { vhost->do_enquiry =3D 0; vhost->mq_enabled =3D 0; return; } =20 + /* register async_sub_crq channel */ + if (ibmvfc_register_channel(vhost, &vhost->scsi_scrqs, -1)) + goto free_async_sub_crq; + + if (ibmvfc_alloc_channels(vhost, &vhost->scsi_scrqs)) + goto deregister_async_sub_crq; + ibmvfc_reg_sub_crqs(vhost, &vhost->scsi_scrqs); =20 if (vhost->nvme_enabled) { @@ -7046,6 +7071,15 @@ static void ibmvfc_init_sub_crqs(struct ibmvfc_host = *vhost) } =20 LEAVE; + return; + + deregister_async_sub_crq: + ibmvfc_deregister_channel(vhost, &vhost->scsi_scrqs, -1); +free_async_sub_crq: + ibmvfc_free_queue(vhost, &vhost->async_sub_crq); + vhost->do_enquiry =3D 0; + vhost->mq_enabled =3D 0; + return; } =20 static void ibmvfc_release_channels(struct ibmvfc_host *vhost, @@ -7069,6 +7103,9 @@ static void ibmvfc_release_channels(struct ibmvfc_hos= t *vhost, static void ibmvfc_release_sub_crqs(struct ibmvfc_host *vhost) { ENTER; + ibmvfc_deregister_channel(vhost, &vhost->scsi_scrqs, -1); + ibmvfc_free_queue(vhost, &vhost->async_sub_crq); + if (!vhost->scsi_scrqs.scrqs) return; =20 --=20 2.55.0 From nobody Fri Sep 25 15:13:49 2026 Received: from mx0a-001b2d01.pphosted.com (mx0a-001b2d01.pphosted.com [148.163.156.1]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 7581C381AE5; Fri, 11 Sep 2026 05:48:55 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=148.163.156.1 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789105737; cv=none; b=EOamZEzdEx9jkPMFVLGA9lSjn7emChF/Dk9KEfA75l7GQqbinH6p+rP+/FGw6RoI3MYPGzkCVb0DkTcw8OOII24XzjXj9Zg7jTs6swlA/U/Zt4g4593MnZfvtfKpEBzxiOfhIlW8LrLUWxRBedrhjYJnRQLzSpovKOfrShcyCDY= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789105737; c=relaxed/simple; bh=uiw4G9BdB8Dr7il3q0UnBe2uzucij0FDWXymthuZ+n0=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=dJF4QpJ3t2GWCIvk8UIYa5FA1NOrStjAA7FTz7yu6v1byHc0suBp13cDinBjS5KuOwMy4I4zKAws4WCFpn5oDJU7yPyfbzkwPI2DELuvzhX0Z+bcJFK1ZgmGpsiyJN5PUfmeJ6TWWj7xj9DvIaEpUcWBrul1ZTWlS8IK/nW9cG0= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.ibm.com; spf=pass smtp.mailfrom=linux.ibm.com; dkim=pass (2048-bit key) header.d=ibm.com header.i=@ibm.com header.b=UKC6NhMm; arc=none smtp.client-ip=148.163.156.1 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.ibm.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linux.ibm.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=ibm.com header.i=@ibm.com header.b="UKC6NhMm" Received: from pps.filterd (m0353729.ppops.net [127.0.0.1]) by mx0a-001b2d01.pphosted.com (8.18.1.11/8.18.1.11) with ESMTP id 68B4VOfW3104472; Fri, 11 Sep 2026 05:48:46 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ibm.com; h=cc :content-transfer-encoding:date:from:in-reply-to:message-id :mime-version:references:subject:to; s=pp1; bh=2oRrNonF6UtzijnIP 8Pwo2tCnoLRm+qLpEW4YvAE3Yw=; b=UKC6NhMmucY7zE/IfJqHS5+Qu9ToX7x0Y BWoNiCQlHgak2WV8RLr9232CkVcd9v42XHQAGVSZvb+gUi4roj2NS1g41gQjOC56 OicvGDHGRiGz1GDerRhDF6uxNTX66iDheVgonQ3h4KacQ6uzbmOq+UsFyGFZgTAV u0nnfFv7GcdOKNADqroAxVRa2KmdvAAATS8TvrD80FQyoyu34dh4rvOV2z5QUzUw x8YCZ/wYIax7oLNm9/4KCysVixN7a6TmYVTjcvPgMigPSjRh+CZnZb4s1EXQfKlo cc52+zeN61pYdw7/lXHpOx3J27/Jkle0gYS6WHNFxMl5jHfEeHwbQ== Received: from ppma13.dal12v.mail.ibm.com (dd.9e.1632.ip4.static.sl-reverse.com [50.22.158.221]) by mx0a-001b2d01.pphosted.com (PPS) with ESMTPS id 4gkd8n9hpw-1 (version=TLSv1.3 cipher=TLS_AES_256_GCM_SHA384 bits=256 verify=NOT); Fri, 11 Sep 2026 05:48:46 +0000 (GMT) Received: from pps.filterd (ppma13.dal12v.mail.ibm.com [127.0.0.1]) by ppma13.dal12v.mail.ibm.com (8.18.1.11/8.18.1.11) with ESMTP id 68B4K8k71120658; Fri, 11 Sep 2026 05:48:45 GMT Received: from smtprelay01.wdc07v.mail.ibm.com ([172.16.1.68]) by ppma13.dal12v.mail.ibm.com (PPS) with ESMTPS id 4gkvmhmmke-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Fri, 11 Sep 2026 05:48:45 +0000 (GMT) Received: from smtpav02.dal12v.mail.ibm.com (smtpav02.dal12v.mail.ibm.com [10.241.53.101]) by smtprelay01.wdc07v.mail.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id 68B5mhkw59572560 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Fri, 11 Sep 2026 05:48:43 GMT Received: from smtpav02.dal12v.mail.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 5CEDB5805E; Fri, 11 Sep 2026 05:48:43 +0000 (GMT) Received: from smtpav02.dal12v.mail.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id B91465805C; Fri, 11 Sep 2026 05:48:42 +0000 (GMT) Received: from li-4c4c4544-0054-3910-8039-c3c04f423534.ibm.com.com (unknown [9.61.103.123]) by smtpav02.dal12v.mail.ibm.com (Postfix) with ESMTP; Fri, 11 Sep 2026 05:48:42 +0000 (GMT) From: Tyrel Datwyler To: james.bottomley@hansenpartnership.com, martin.petersen@oracle.com Cc: linux-scsi@vger.kernel.org, linuxppc-dev@lists.ozlabs.org, linux-kernel@vger.kernel.org, brking@linux.ibm.com, davemarq@linux.ibm.com, Tyrel Datwyler Subject: [PATCH v10 9/9] scsi: ibmvfc: handle extended FPIN events Date: Thu, 10 Sep 2026 22:48:32 -0700 Message-ID: <20260911054832.1311668-10-tyreld@linux.ibm.com> X-Mailer: git-send-email 2.55.0 In-Reply-To: <20260911054832.1311668-1-tyreld@linux.ibm.com> References: <20260911054832.1311668-1-tyreld@linux.ibm.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-TM-AS-GCONF: 00 X-Authority-Analysis: v=2.4 cv=NMVAaE6g c=1 sm=1 tr=0 ts=6aa3963e cx=c_pps a=AfN7/Ok6k8XGzOShvHwTGQ==:117 a=AfN7/Ok6k8XGzOShvHwTGQ==:17 a=VdqzKS8jKosA:10 a=VkNPw1HP01LnGYTKEx00:22 a=RnoormkPH1_aCDwRdu11:22 a=uAbxVGIbfxUO_5tXvNgY:22 a=VnNF1IyMAAAA:8 a=YunXX2DFvQEblV2KXBkA:9 X-Proofpoint-GUID: RWYRaRgQTBig8zoMXee48pjQR_6ihRih X-Proofpoint-Spam-Details-Enc: AW1haW4tMjYwOTExMDA3NCBTYWx0ZWRfX1IoeuEMe8xMa scoojrons9WyfLP1j46D2vj3LiJklc/BBndHq1m5w4/bEt2pms8XSioucH8p5jId8nAofFpjQc+ Gtc66l+Xjj+jvmwIJDnDf05oUNV5+fSHk7mpsAB/C+flpTKFkRVq7yYfrLZrMw587JOtFytK3Rv vSVev59N7BWMIRg2nPf6pPfSgZ3F7N/k8O43D7BHfgHgm7kwGc1iDFYR7URQ+2FInTINMe4BYj8 WgWClDD2J+R/KCROTcISEvpTfGk17Iu7OX1hCyzkyDvK1YdgISMgipl3H73oMBK1XtKHD4/cV/F YQ/WZiThdaqRB6P+d//4jXvFbEC+iScNLG3r3Zk/pgpgBXEW80P8BhaZKfK/J+2iXWpEWO0zx04 mQrU5IPZGWTwq65NHBYXynmxmw8e2l1E1GLvSEmtWLzJkbXxKiI8+BTmqSOMzhnoQCBcipeVieh LQ8POXQFi1s5mT273IA== X-Proofpoint-ORIG-GUID: RWYRaRgQTBig8zoMXee48pjQR_6ihRih X-Proofpoint-Spam-Info: AW1haW4tMjYwOTExMDA3NCBTYWx0ZWRfXwpCucWnIJg6U 7jJlhXQv+/Y61rirQEG3ybNiTOZPJBBaIMZ3nD2RVga+25doMUP52FCHDkTN0keWtWynpwhBuYq waTuEzkoBAh4diO9LQnpogt6t9jvVuI= X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1176,Hydra:6.1.134,FMLib:17.12.100.49 definitions=2026-09-11_02,2026-09-09_02,2025-10-01_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 spamscore=0 bulkscore=0 clxscore=1015 malwarescore=0 lowpriorityscore=0 priorityscore=1501 adultscore=0 suspectscore=0 impostorscore=0 phishscore=0 classifier=typeunknown authscore=0 authtc= authcc= route=outbound adjust=0 reason=mlx scancount=1 engine=8.22.0-2609040000 definitions=main-2609110074 Content-Type: text/plain; charset="utf-8" From: Dave Marquardt Implement support for extended FPIN messages received via the asynchronous sub-queue, completing full FPIN functionality. Extended FPIN messages provide more detailed information about fabric events compared to basic FPIN messages, including specific event types, modifiers, thresholds, and event counts. Add ibmvfc_ext_fpin_to_desc() to convert extended FPIN messages from async sub-queue format to fc_els_fpin structures with complete descriptor information. Update ibmvfc_process_async_work() and ibmvfc_handle_async() to zero node_name and dispatch to ibmvfc_ext_fpin_to_desc() when the IBMVFC_ASYNC_IS_FPIN_EXT flag is set. Set the IBMVFC_CAN_HANDLE_FPIN_EXT capability bit during login to inform VIOS that the client can process extended FPIN messages. Also add the IBMVFC_SUPPORT_FPIN_EXT response capability bit definition used to gate extended FPIN processing. Add KUnit tests to exercise extended FPIN event handling across all FPIN status and event type combinations. struct ibmvfc_async_subq_fpin uses volatile on its valid and wwpn fields, consistent with the existing ibmvfc_crq, ibmvfc_async_crq, and ibmvfc_async_sub_crq structs in ibmvfc.h, all of which mark their hardware-owned ring-buffer fields volatile to prevent the compiler from caching or eliminating reads of memory written directly by the VIOS. Signed-off-by: Dave Marquardt [tyreld: add & operator to irqsave/restore calls in kunit test] Signed-off-by: Tyrel Datwyler --- drivers/scsi/ibmvscsi/ibmvfc-core.c | 67 ++++++++++++- drivers/scsi/ibmvscsi/ibmvfc.h | 30 ++++++ drivers/scsi/ibmvscsi/ibmvfc_kunit.c | 135 +++++++++++++++++++++++++++ 3 files changed, 228 insertions(+), 4 deletions(-) diff --git a/drivers/scsi/ibmvscsi/ibmvfc-core.c b/drivers/scsi/ibmvscsi/ib= mvfc-core.c index 70a3046135c7..0f6fde779f6c 100644 --- a/drivers/scsi/ibmvscsi/ibmvfc-core.c +++ b/drivers/scsi/ibmvscsi/ibmvfc-core.c @@ -1593,6 +1593,7 @@ static void ibmvfc_set_login_info(struct ibmvfc_host = *vhost) login_info->capabilities |=3D cpu_to_be64(IBMVFC_USE_ASYNC_SUBQ); login_info->capabilities |=3D cpu_to_be64(IBMVFC_CAN_HANDLE_FPIN); login_info->capabilities |=3D cpu_to_be64(IBMVFC_YES_SCSI); + login_info->capabilities |=3D cpu_to_be64(IBMVFC_CAN_HANDLE_FPIN_EXT); if (vhost->nvme_enabled) { login_info->capabilities |=3D cpu_to_be64(IBMVFC_YES_NVMEOF); login_info->capabilities |=3D cpu_to_be64(IBMVFC_CAN_USE_WWPN_ALL); @@ -3473,6 +3474,41 @@ ibmvfc_full_fpin_to_desc(struct ibmvfc_async_sub_crq= *ibmvfc_fpin) cpu_to_be32(1)); } =20 +/** + * ibmvfc_ext_fpin_to_desc(): allocate and populate a struct fc_els_fpin s= truct + * 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) +{ + u8 flags =3D ibmvfc_fpin->fpin_data.flags; + __be32 threshold =3D cpu_to_be32(IBMVFC_FPIN_DEFAULT_EVENT_THRESHOLD); + __be16 modifier =3D 0; + __be32 count =3D cpu_to_be32(1); + __be16 type =3D 0; + + if (flags & IBMVFC_FPIN_EVENT_TYPE_VALID) + type =3D ibmvfc_fpin->fpin_data.event_type; + if (flags & IBMVFC_FPIN_MODIFIER_VALID) + modifier =3D ibmvfc_fpin->fpin_data.event_type_modifier; + if (flags & IBMVFC_FPIN_THRESHOLD_VALID) + threshold =3D ibmvfc_fpin->fpin_data.event_threshold; + if (flags & IBMVFC_FPIN_EVENT_COUNT_VALID) + count =3D ibmvfc_fpin->fpin_data.event_data.event_count; + + return ibmvfc_common_fpin_to_desc(ibmvfc_fpin->fpin_status, + ibmvfc_fpin->wwpn, type, + modifier, threshold, count); +} + /** * ibmvfc_find_target - Search for a target in a target list * @target_list: list head of targets to search @@ -3511,6 +3547,7 @@ static struct ibmvfc_target *ibmvfc_find_target(struc= t list_head *target_list, static void ibmvfc_process_async_work(struct work_struct *work) { struct ibmvfc_async_sub_crq *subq =3D NULL; + struct ibmvfc_async_subq_fpin *sqfpin; struct ibmvfc_async_work *aw; struct ibmvfc_async_crq *crq =3D NULL; struct ibmvfc_target *tgt; @@ -3527,7 +3564,10 @@ static void ibmvfc_process_async_work(struct work_st= ruct *work) subq =3D &aw->event.subq; scsi_id =3D 0; wwpn =3D subq->wwpn; - node_name =3D (subq->flags & IBMVFC_ASYNC_ID_IS_ASSOC_ID) ? 0 : subq->id= .node_name; + if (subq->flags & (IBMVFC_ASYNC_IS_FPIN_EXT | IBMVFC_ASYNC_ID_IS_ASSOC_I= D)) + node_name =3D 0; + else + node_name =3D subq->id.node_name; } else { crq =3D &aw->event.async_crq; scsi_id =3D crq->scsi_id; @@ -3557,8 +3597,24 @@ static void ibmvfc_process_async_work(struct work_st= ruct *work) =20 if (crq) fpin =3D ibmvfc_basic_fpin_to_desc(crq, tgt->wwpn); - else - fpin =3D ibmvfc_full_fpin_to_desc(subq); + else { + static_assert(sizeof(struct ibmvfc_async_subq_fpin) =3D=3D + sizeof(struct ibmvfc_async_sub_crq)); + static_assert(offsetof(struct ibmvfc_async_subq_fpin, fpin_data) =3D=3D + offsetof(struct ibmvfc_async_sub_crq, nport_id)); + sqfpin =3D (struct ibmvfc_async_subq_fpin *)subq; + if ((subq->flags & IBMVFC_ASYNC_IS_FPIN_EXT) =3D=3D 0) { + fpin =3D 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 =3D ibmvfc_ext_fpin_to_desc(sqfpin); + } + } =20 if (fpin) { fc_host_fpin_rcv(tgt->vhost->host, @@ -3600,7 +3656,10 @@ VISIBLE_IF_KUNIT void ibmvfc_handle_async(struct ibm= vfc_async_crq_event *ae, link_state =3D subq->link_state; scsi_id =3D 0; wwpn =3D subq->wwpn; - node_name =3D subq->flags & IBMVFC_ASYNC_ID_IS_ASSOC_ID ? 0 : subq->id.n= ode_name; + if (subq->flags & (IBMVFC_ASYNC_IS_FPIN_EXT | IBMVFC_ASYNC_ID_IS_ASSOC_I= D)) + node_name =3D 0; + else + node_name =3D subq->id.node_name; } else { async_crq =3D &ae->async_crq; event =3D be64_to_cpu(async_crq->event); diff --git a/drivers/scsi/ibmvscsi/ibmvfc.h b/drivers/scsi/ibmvscsi/ibmvfc.h index 6fce7a4922bb..20933af59d48 100644 --- a/drivers/scsi/ibmvscsi/ibmvfc.h +++ b/drivers/scsi/ibmvscsi/ibmvfc.h @@ -210,6 +210,7 @@ struct ibmvfc_npiv_login { #define IBMVFC_CAN_USE_WWPN_ALL 0x080 #define IBMVFC_USE_ASYNC_SUBQ 0x100 #define IBMVFC_CAN_USE_NOOP_CMD 0x200 +#define IBMVFC_CAN_HANDLE_FPIN_EXT 0x800 __be64 node_name; struct srp_direct_buf async; u8 partition_name[IBMVFC_MAX_NAME]; @@ -261,6 +262,7 @@ struct ibmvfc_npiv_login_resp { #define IBMVFC_SUPPORT_WWPN_ALL 0x0400 #define IBMVFC_ASYNC_SUBQ 0x0800 #define IBMVFC_SUPPORT_NOOP_CMD 0x1000 +#define IBMVFC_SUPPORT_FPIN_EXT 0x2000 __be32 max_cmds; __be32 scsi_id_sz; __be64 max_dma_len; @@ -786,6 +788,34 @@ struct ibmvfc_async_sub_crq { } id; } __packed __aligned(8); =20 +struct ibmvfc_fpin_data { +#define IBMVFC_FPIN_EVENT_TYPE_VALID 0x01 +#define IBMVFC_FPIN_MODIFIER_VALID 0x02 +#define IBMVFC_FPIN_THRESHOLD_VALID 0x04 +#define IBMVFC_FPIN_SEVERITY_VALID 0x08 +#define IBMVFC_FPIN_EVENT_COUNT_VALID 0x10 + u8 flags; + u8 reserved[3]; + __be16 event_type; + __be16 event_type_modifier; + __be32 event_threshold; + union { + u8 severity; + __be32 event_count; + } event_data; +} __packed __aligned(8); + +struct ibmvfc_async_subq_fpin { + volatile u8 valid; + u8 flags; + u8 link_state; + u8 fpin_status; + __be16 event; + __be16 pad; + volatile __be64 wwpn; + struct ibmvfc_fpin_data fpin_data; +} __packed __aligned(8); + enum ibmvfc_async_crq_type { IBMVFC_ASYNC_CRQ_MAIN =3D 0, IBMVFC_ASYNC_CRQ_SUB, diff --git a/drivers/scsi/ibmvscsi/ibmvfc_kunit.c b/drivers/scsi/ibmvscsi/i= bmvfc_kunit.c index 5c67d405dbfc..44a411350529 100644 --- a/drivers/scsi/ibmvscsi/ibmvfc_kunit.c +++ b/drivers/scsi/ibmvscsi/ibmvfc_kunit.c @@ -3,6 +3,7 @@ #include #include #include +#include #include #include #include "ibmvfc.h" @@ -256,9 +257,143 @@ static void ibmvfc_full_fpin_test(struct kunit *test) scsi_host_put(vhost->host); } =20 +#define IBMVFC_TEST_FPIN_EXT(fs, ev, stat, crq) { \ + struct ibmvfc_async_crq_event ae =3D { .type =3D IBMVFC_ASYNC_CRQ_SUB }; \ + (crq).valid =3D 0x80; \ + (crq).flags =3D IBMVFC_ASYNC_IS_FPIN_EXT; \ + (crq).link_state =3D IBMVFC_AE_LS_LINK_UP; \ + (crq).fpin_status =3D (fs); \ + (crq).event =3D cpu_to_be16(IBMVFC_AE_FPIN); \ + (crq).wwpn =3D cpu_to_be64(tgt->wwpn); \ + (crq).fpin_data.flags =3D IBMVFC_FPIN_EVENT_TYPE_VALID; \ + (crq).fpin_data.event_type =3D cpu_to_be16((ev)); \ + ae.subq =3D *(struct ibmvfc_async_sub_crq *)&(crq); \ + pre =3D READ_ONCE(rport->fpin_stats.stat); \ + ibmvfc_handle_async(&ae, vhost); \ + flush_workqueue(vhost->fpin_workq); \ + post =3D READ_ONCE(rport->fpin_stats.stat); \ +} + +/** + * ibmvfc_extended_fpin_test - unit test for extended FPIN events + * @test: pointer to kunit structure + * + * Note: This test exercises extended FPIN code paths but does not check + * that statistics are correctly updated. + * + * Return: void + */ +static void ibmvfc_extended_fpin_test(struct kunit *test) +{ + enum ibmvfc_ae_fpin_status fs; + struct ibmvfc_async_subq_fpin crq[IBMVFC_AE_FPIN_CONGESTION_CLEARED+1] = =3D {}; + struct ibmvfc_async_subq_fpin + crqcn[IBMVFC_AE_FPIN_PORT_CONGESTED][FPIN_CONGN_DEVICE_SPEC+1] =3D {}; + struct ibmvfc_async_subq_fpin crqportdg[FPIN_LI_DEVICE_SPEC+1] =3D {}; + struct ibmvfc_target *tgt; + struct ibmvfc_host *vhost; + struct fc_rport *rport; + LIST_HEAD(evt_doneq); + unsigned long flags; + u64 pre, post; + + vhost =3D ibmvfc_get_first_vhost(); + if (!vhost) + kunit_skip(test, "No ibmvfc devices available"); + + spin_lock_irqsave(&vhost->host->host_lock, flags); + if (vhost->scsi_scrqs.num_targets < 1) { + spin_unlock_irqrestore(&vhost->host->host_lock, flags); + scsi_host_put(vhost->host); + kunit_skip(test, "No targets"); + } + tgt =3D list_first_entry(&vhost->scsi_scrqs.targets, struct ibmvfc_target= , queue); + if (!tgt->rport) { + spin_unlock_irqrestore(&vhost->host->host_lock, flags); + scsi_host_put(vhost->host); + kunit_skip(test, "No rport"); + } + rport =3D tgt->rport; + get_device(&rport->dev); + kref_get(&tgt->kref); + spin_unlock_irqrestore(&vhost->host->host_lock, flags); + + for (fs =3D IBMVFC_AE_FPIN_LINK_CONGESTED; fs <=3D IBMVFC_AE_FPIN_CONGEST= ION_CLEARED; fs++) { + switch (fs) { + case IBMVFC_AE_FPIN_PORT_CLEARED: + case IBMVFC_AE_FPIN_CONGESTION_CLEARED: { + struct ibmvfc_async_crq_event ae =3D { .type =3D IBMVFC_ASYNC_CRQ_SUB }; + + crq[fs].valid =3D 0x80; + crq[fs].flags =3D IBMVFC_ASYNC_IS_FPIN_EXT; + crq[fs].link_state =3D IBMVFC_AE_LS_LINK_UP; + crq[fs].fpin_status =3D fs; + crq[fs].event =3D cpu_to_be16(IBMVFC_AE_FPIN); + crq[fs].wwpn =3D cpu_to_be64(tgt->wwpn); + crq[fs].fpin_data.flags =3D IBMVFC_FPIN_EVENT_TYPE_VALID; + crq[fs].fpin_data.event_type =3D cpu_to_be16(FPIN_CONGN_CLEAR); + ae.subq =3D *(struct ibmvfc_async_sub_crq *)&crq[fs]; + pre =3D READ_ONCE(rport->fpin_stats.cn_clear); + ibmvfc_handle_async(&ae, vhost); + flush_workqueue(vhost->fpin_workq); + post =3D READ_ONCE(rport->fpin_stats.cn_clear); + break; + } + case IBMVFC_AE_FPIN_LINK_CONGESTED: + case IBMVFC_AE_FPIN_PORT_CONGESTED: + IBMVFC_TEST_FPIN_EXT(fs, FPIN_CONGN_CLEAR, cn_clear, + crqcn[fs-1][FPIN_CONGN_CLEAR]); + IBMVFC_TEST_FPIN_EXT(fs, FPIN_CONGN_LOST_CREDIT, + cn_lost_credit, + crqcn[fs-1][FPIN_CONGN_LOST_CREDIT]); + IBMVFC_TEST_FPIN_EXT(fs, FPIN_CONGN_CREDIT_STALL, + cn_credit_stall, + crqcn[fs-1][FPIN_CONGN_CREDIT_STALL]); + IBMVFC_TEST_FPIN_EXT(fs, FPIN_CONGN_OVERSUBSCRIPTION, + cn_oversubscription, + crqcn[fs-1][FPIN_CONGN_OVERSUBSCRIPTION]); + IBMVFC_TEST_FPIN_EXT(fs, FPIN_CONGN_DEVICE_SPEC, + cn_device_specific, + crqcn[fs-1][FPIN_CONGN_DEVICE_SPEC]); + break; + case IBMVFC_AE_FPIN_PORT_DEGRADED: + IBMVFC_TEST_FPIN_EXT(fs, FPIN_LI_UNKNOWN, + li_failure_unknown, + crqportdg[FPIN_LI_UNKNOWN]); + IBMVFC_TEST_FPIN_EXT(fs, FPIN_LI_LINK_FAILURE, + li_link_failure_count, + crqportdg[FPIN_LI_LINK_FAILURE]); + IBMVFC_TEST_FPIN_EXT(fs, FPIN_LI_LOSS_OF_SYNC, + li_loss_of_sync_count, + crqportdg[FPIN_LI_LOSS_OF_SYNC]); + IBMVFC_TEST_FPIN_EXT(fs, FPIN_LI_LOSS_OF_SIG, + li_loss_of_signals_count, + crqportdg[FPIN_LI_LOSS_OF_SIG]); + IBMVFC_TEST_FPIN_EXT(fs, FPIN_LI_PRIM_SEQ_ERR, + li_prim_seq_err_count, + crqportdg[FPIN_LI_PRIM_SEQ_ERR]); + IBMVFC_TEST_FPIN_EXT(fs, FPIN_LI_INVALID_TX_WD, + li_invalid_tx_word_count, + crqportdg[FPIN_LI_INVALID_TX_WD]); + IBMVFC_TEST_FPIN_EXT(fs, FPIN_LI_INVALID_CRC, + li_invalid_crc_count, + crqportdg[FPIN_LI_INVALID_CRC]); + IBMVFC_TEST_FPIN_EXT(fs, FPIN_LI_DEVICE_SPEC, + li_device_specific, + crqportdg[FPIN_LI_DEVICE_SPEC]); + break; + } + } + + put_device(&rport->dev); + kref_put(&tgt->kref, ibmvfc_release_tgt); + scsi_host_put(vhost->host); +} + static struct kunit_case ibmvfc_fpin_test_cases[] =3D { KUNIT_CASE(ibmvfc_async_fpin_test), KUNIT_CASE(ibmvfc_full_fpin_test), + KUNIT_CASE(ibmvfc_extended_fpin_test), {}, }; =20 --=20 2.55.0