From nobody Sat Jul 25 23:03:45 2026 Received: from mail-pj1-f53.google.com (mail-pj1-f53.google.com [209.85.216.53]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 8B9EB361DA9 for ; Sun, 12 Jul 2026 02:25:18 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.216.53 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1783823120; cv=none; b=GZgqT7wpf5JMqiTlciZKLvZSMYXS67+2sorJWV+VXjg9DlKfJRfJYugCjAxCQra0+eypgDeSeVpyvGJiWiZj6pn74gHDrL5qF72ZWNUi+pjeA+Xv2shjkhJBGLoWBH0i2k7vqmuDa+cMfHxGnSumrZC8J32tegWOryi5vf58P4o= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1783823120; c=relaxed/simple; bh=P/4m2s9rdRNozdt8E8GYkOJJzykSv3TCSg6iPO9OhUs=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=SfbE4Rh4sKfbeJlNvJZNfOCbDCbwKWBpMSz7Ygxw80PWHU1zbxkTwqKoDB1iNz5j26CNaLiBM/GybiMSE6K2LPOKSDPq0cR3jrMalMzb1r/z3/56cVD2v/3M4V9QnRRLbB3qwY+c/DXOtH3fsigoj9EVPckUvBQJ9LpItaKxHeY= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=purestorage.com; spf=pass smtp.mailfrom=purestorage.com; dkim=pass (2048-bit key) header.d=purestorage.com header.i=@purestorage.com header.b=BWhwo1qy; arc=none smtp.client-ip=209.85.216.53 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=purestorage.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=purestorage.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=purestorage.com header.i=@purestorage.com header.b="BWhwo1qy" Received: by mail-pj1-f53.google.com with SMTP id 98e67ed59e1d1-384930ca5e2so2377071a91.3 for ; Sat, 11 Jul 2026 19:25:18 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=purestorage.com; s=google2022; t=1783823118; x=1784427918; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=LJ3eqT5MrrmAjHbEtV8wOhzni/tkslB66Zt2m3a2DuU=; b=BWhwo1qyhr5Y253CKVzn6E29UfnjcyCNEAL65OnRgFglyXl5HyVgQTWMS5P/b5rgoh Hpw74c6GM8T2UDxkypStlbBqTFPpmDFCcib0cLKzmepxyJMeK5ZBEGvTNZ4aqwzdeqG5 WnBZCsRH4fmr76lvf89AmM/wGS4+2caC/Xy8jUkPrJB5ZdGD343vdqnfoPQeaoN3hL8p ZamVJkN+fbT8dxdlB2LYwAl2uqLpNNbhoLJaHwMBUOyamIvHR9xd6KaJswEkn36SaEsg sn4WJ2zjpSK1ypKDl22FVYgBr+If0h7LPHwVwY1RTslqstY4UNXxVVHUU/jFM0yWqYPY HIMQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1783823118; x=1784427918; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to:content-type; bh=LJ3eqT5MrrmAjHbEtV8wOhzni/tkslB66Zt2m3a2DuU=; b=nIZGzW2fzNWJzpfBo9AFVgcbUQ0rvvRu1OkIy7un8xyZ03fEzOkEfzeI70Y2PO5dL9 /5h4qFdXuNHq6lFLTn3pOLcznnSNyvF3uqGE3+WXmMKA1Zr68Ak9sE9SfKnR7s1WBL4b bXmjNqpRduO7TBFVC65cuks6nRv9ulBidmV6bshJ5DghBc8odK876Ea/nJK+sQpRm8B0 PsFA1XP7YLLeU+T2VCfZrArjw6S2UyL6KDxa6wftefwDulo+7v9TP9u9aycLtKYi13oE h/ofDzHg4IedWcNc1/w6Pk1dnlG3+0LLcDfVnz7GDq4Yxs/TTa+g3pAaS4+NwGUlHPY7 kVNA== X-Forwarded-Encrypted: i=1; AHgh+RruvYdM/y0be/ryH+dUEFTGhR+WTCFR7wdvKIbKGUnf8EHEDN9Dnk8yNLckV7znv2wf/6kohvspKUPLxWo=@vger.kernel.org X-Gm-Message-State: AOJu0YwGZoUPhCPTJmvfa8wnriRaKrfE4h5BJ4udGjwlD32CMSykfD5a Rfmgf0EH2mCr0M2uUVJPTu/HRaIk1fqa/vwHV5LG10/VVPjDiUFb3oAlx1BPH1PXi3A= X-Gm-Gg: AfdE7clNxVV9wtM5sPlY15+4hUmgx1p7piKCu+fg7IT2aZX8CfdB9xNlzi/8H1u+J// hY7NfkmItnWYxnyg3DL6IvcmvQGU0qIrmv6oTTqsxbd+cPeNQ6ffUWPD0ordryz8Hui6U3lIuuY zm4jHbTkX1u6FWqTI/7dFZYU/NKO7WlhTpevWg3y3WsYjeUb3uGJf70brPfuH9f/O32+yiXX17L HTlnTQFyB98dd9KFVGVNWpLFL8b/haOiRPTN1jrFCD1gLFE413uHxrEkc6r5iAyeouQivjfPeST 3Q//mLvNm5h54b6ALUrLI6axNOoDZqpCM07dTYsc8jppuHyETJYLU8LHSpUN8AaynX+Vv+QxXBF vB5a20SHFf/A8LrV5c91c7IqRhyrGmJtSlKcLqICvDiyFis8gEdgHhn2VUCObSjUsHVRkBNtw8Z rGUyN/ X-Received: by 2002:a17:90b:5585:b0:37f:db06:229c with SMTP id 98e67ed59e1d1-38dc777b895mr4349898a91.22.1783823117600; Sat, 11 Jul 2026 19:25:17 -0700 (PDT) Received: from ceto.lan ([2607:fb90:9c20:2264::1c31]) by smtp.googlemail.com with ESMTPSA id 5a478bee46e88-3117462f5c7sm60704693eec.0.2026.07.11.19.25.15 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 11 Jul 2026 19:25:16 -0700 (PDT) From: Mohamed Khalfella To: Justin Tee , Naresh Gottumukkala , Paul Ely , Chaitanya Kulkarni , Christoph Hellwig , Jens Axboe , Keith Busch , Sagi Grimberg , James Smart , Hannes Reinecke , Randy Jennings , Dhaval Giani Cc: Aaron Dailey , linux-nvme@lists.infradead.org, linux-kernel@vger.kernel.org, Mohamed Khalfella Subject: [PATCH v5 01/16] nvmet: Rapid Path Failure Recovery set controller identify fields Date: Sat, 11 Jul 2026 19:23:22 -0700 Message-ID: <20260712022437.3743117-2-mkhalfella@purestorage.com> X-Mailer: git-send-email 2.54.0 In-Reply-To: <20260712022437.3743117-1-mkhalfella@purestorage.com> References: <20260712022437.3743117-1-mkhalfella@purestorage.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 Content-Type: text/plain; charset="utf-8" TP8028 Rapid Path Failure Recovery defined new fields in controller identify response. The newly defined fields are: - CIU (Controller Instance Uniquifier): is an 8bit non-zero value that is assigned a random value when controller is first created. The value will be incremented when RDY bit in CSTS register is asserted. - CIRN (Controller Instance Random Number): is 64bit random value that gets generated when controller is created. CIRN is regenerated everytime RDY bit in CSTS register is asserted. - CCRL (Cross-Controller Reset Limit): is an 8bit value that defines the maximum number of in-progress controller reset operations. CCRL is hardcoded to 4 as recommended by TP8028. These fields are set for non-discovery subsystems only. Signed-off-by: Mohamed Khalfella Reviewed-by: Hannes Reinecke --- drivers/nvme/target/admin-cmd.c | 5 +++++ drivers/nvme/target/core.c | 9 +++++++++ drivers/nvme/target/nvmet.h | 2 ++ include/linux/nvme.h | 10 ++++++++-- 4 files changed, 24 insertions(+), 2 deletions(-) diff --git a/drivers/nvme/target/admin-cmd.c b/drivers/nvme/target/admin-cm= d.c index 01b799e92ae6..81988b40d5d5 100644 --- a/drivers/nvme/target/admin-cmd.c +++ b/drivers/nvme/target/admin-cmd.c @@ -691,6 +691,11 @@ static void nvmet_execute_identify_ctrl(struct nvmet_r= eq *req) id->mdts =3D nvmet_ctrl_mdts(req); id->cntlid =3D cpu_to_le16(ctrl->cntlid); id->ver =3D cpu_to_le32(ctrl->subsys->ver); + if (!nvmet_is_disc_subsys(ctrl->subsys)) { + id->ciu =3D ctrl->ciu; + id->cirn =3D cpu_to_le64(ctrl->cirn); + id->ccrl =3D NVMF_CCR_LIMIT; + } =20 /* XXX: figure out what to do about RTD3R/RTD3 */ id->oaes =3D cpu_to_le32(NVMET_AEN_CFG_OPTIONAL); diff --git a/drivers/nvme/target/core.c b/drivers/nvme/target/core.c index a2403a808360..d42421420be6 100644 --- a/drivers/nvme/target/core.c +++ b/drivers/nvme/target/core.c @@ -1406,6 +1406,10 @@ static void nvmet_start_ctrl(struct nvmet_ctrl *ctrl) return; } =20 + if (!nvmet_is_disc_subsys(ctrl->subsys)) { + ctrl->ciu =3D ((u8)(ctrl->ciu + 1)) ? : 1; + ctrl->cirn =3D get_random_u64(); + } ctrl->csts =3D NVME_CSTS_RDY; =20 /* @@ -1671,6 +1675,11 @@ struct nvmet_ctrl *nvmet_alloc_ctrl(struct nvmet_all= oc_ctrl_args *args) } ctrl->cntlid =3D ret; =20 + if (!nvmet_is_disc_subsys(ctrl->subsys)) { + ctrl->ciu =3D get_random_u8() ? : 1; + ctrl->cirn =3D get_random_u64(); + } + /* * Discovery controllers may use some arbitrary high value * in order to cleanup stale discovery sessions diff --git a/drivers/nvme/target/nvmet.h b/drivers/nvme/target/nvmet.h index c672c9bf3053..9c98833e8f3a 100644 --- a/drivers/nvme/target/nvmet.h +++ b/drivers/nvme/target/nvmet.h @@ -268,7 +268,9 @@ struct nvmet_ctrl { =20 uuid_t hostid; u16 cntlid; + u8 ciu; u32 kato; + u64 cirn; =20 struct nvmet_port *port; =20 diff --git a/include/linux/nvme.h b/include/linux/nvme.h index 91ce434a7e8d..cbaf02b0cf07 100644 --- a/include/linux/nvme.h +++ b/include/linux/nvme.h @@ -21,6 +21,8 @@ #define NVMF_TRADDR_SIZE 256 #define NVMF_TSAS_SIZE 256 =20 +#define NVMF_CCR_LIMIT 4 + #define NVME_DISC_SUBSYS_NAME "nqn.2014-08.org.nvmexpress.discovery" =20 #define NVME_NSID_ALL 0xffffffff @@ -328,7 +330,10 @@ struct nvme_id_ctrl { __le16 crdt1; __le16 crdt2; __le16 crdt3; - __u8 rsvd134[122]; + __u8 rsvd134[1]; + __u8 ciu; + __le64 cirn; + __u8 rsvd144[112]; __le16 oacs; __u8 acl; __u8 aerl; @@ -389,7 +394,8 @@ struct nvme_id_ctrl { __u8 msdbd; __u8 rsvd1804[2]; __u8 dctype; - __u8 rsvd1807[241]; + __u8 ccrl; + __u8 rsvd1808[240]; struct nvme_id_power_state psd[32]; __u8 vs[1024]; }; --=20 2.54.0 From nobody Sat Jul 25 23:03:45 2026 Received: from mail-pj1-f45.google.com (mail-pj1-f45.google.com [209.85.216.45]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 2EABC367B89 for ; Sun, 12 Jul 2026 02:25:20 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.216.45 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1783823122; cv=none; b=bC1Ax2756hWWOY+XDBdyOU4w+SKbqtjAetdBMmrRSl7JHAYTQ9saitidY7cgZd2kBbKvz8OAna+kDhrtuRTv3YtdqbXP8C1UWGQ+5ycqPhKCjeOsJ2Z3XFcijhMyySvaxy3PsonnoHXa15qMyDaw+oO0mYCDEFqs4bJJWWPRYoU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1783823122; c=relaxed/simple; bh=VuQGClHWgV80Zww1ata2AkGgeeZ8EDyfJwGqaKGO+KE=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=DC9Mj5jT3BAplCmXTyQN+DVjZ4lP9TlkpZxp3uhBFsFOlqywQXSkq79BZdjncHlP1AN35djobnlvsBu6J3CBxvyMvCf5+uPlPTwCLXZcu5DnQ/uDMY2Hp/AY5yto196TGuDLrpNdEEh0LT2ExgzkrtU/obtMyU1C/1bxchbd93o= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=purestorage.com; spf=pass smtp.mailfrom=purestorage.com; dkim=pass (2048-bit key) header.d=purestorage.com header.i=@purestorage.com header.b=I7NlnjN/; arc=none smtp.client-ip=209.85.216.45 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=purestorage.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=purestorage.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=purestorage.com header.i=@purestorage.com header.b="I7NlnjN/" Received: by mail-pj1-f45.google.com with SMTP id 98e67ed59e1d1-38de840f2f0so97346a91.0 for ; Sat, 11 Jul 2026 19:25:20 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=purestorage.com; s=google2022; t=1783823119; x=1784427919; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=cduHWfRr3cNlL9+U7DXnZtRw2pQyx26+A9+h8FmzaX8=; b=I7NlnjN/Sptuh29wzXHxjJQWG+eLQDHJeZBQ3SwxbJ356/nAO0to5VNJUJX0zXhmue NBuFZCUvSjlQdzQvqqODp++47R2J34u/tMPdADib876VJ57EZ/VL1iO088AMakOb+cFp 8eC7mX8JzQlGU6FSfAQ8tHBeN/Z6xt2zH6Kdbzqc47bEDdbuo5NjLIVmv0yTDdeIM0LK t2fHlgF0ajZF4vWCznt06aBPjj8walpmb8a8ytAKjEfqt05XgrBgtPxGoE3RXgOm3mKI fKY4AYJLcAUVnTDLe5NTJpHaTGRfRXCNIdrCL9kdd6mBX+lqUYJg9CFHWR2BqpEgcR1q cYxQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1783823119; x=1784427919; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to:content-type; bh=cduHWfRr3cNlL9+U7DXnZtRw2pQyx26+A9+h8FmzaX8=; b=eAkZ90xRWzvfbK9azm1liNz++gqyp+rzgYOGrRXYhNiNt5rBykCSkd7WqRR5fEhi/3 hOfkEo8EFUFHuAnE6C8B104MsCI62WGvMhksidcOaWsh19L/rBDLIVcmfY1aKyjjFnPN 96u+0wBnNV5jwZod0H65aO1kEUR/I/bW5bxWIGk1YP7Z6VGI8YIywj+rn/LKDgNJNhkM W3UAc3yzNVh4xYO04HlGrLWVdCrqZXmu+jEiRHJ80cEGqwiu6DAa4ciYk+3z/HG3N1Yx r4GflMAa02UZDk5fkOyA8qBLIW7tHPer+RneUqXFQQwfng3Xx88ATYiB7hFfDR2fmrAy v5Lw== X-Forwarded-Encrypted: i=1; AHgh+Rpr1msX1zjAhN5cbT5HVF/lFVmj+H1vxPONGeAHZSr/MrIEz7jfKk9pHW9IJ5kR2hfQUTpmEnzvYSYLDRY=@vger.kernel.org X-Gm-Message-State: AOJu0YzceQI1MjosK7Hc5uN16LYfV3N/AQSSvd70BE1o1SANMf/qnzuY kjqtbyjlvAokQOlU0hIpzNoS01aCIg8C2/jP8Ns942GV5cH7tCfoknfxOiSOrMllAzc= X-Gm-Gg: AfdE7cnpkvwRWM3pqRMUgXQ9eBMqRE5VWEScjd16NswA6zJszMhTknMnHMEgh4liWEr n1p3VRDSiWHtCk7bxk9iTKcBa7YIRR9yOrvZq1pAfhMUmS1h/NX7zMICfFcjaoAgNdNlYyjOwYr ceCYmpfgEbemh0tOjpY7gm7s2Omf52C9loNCtlk+nodM8RFuCR5nkQf8ZpNhQvg7wCQM+aLEWGR 8OuxepI/zSvTfR2kpfsgEWaGOhOPX+V9bO0SmH8rFjQgNUvEO1sWsm2rgWaz6c94kyLQIP/dOv1 KGaPpV5nvBVbM0K65I588aJb4p7l1MDu/gjHB96K4E3fSZhjv4AspK2yRvebWCwG/GQeRJN4vTu RqTKx2kyWzxJS+JZ6M/nMVoOFCTFaP2GAbWOI1KidAhMsNIefbPZ2tOcVF5r3fIAS8tkbrN5WSp XI5s3FvLDJ6MJ5Ul4= X-Received: by 2002:a17:90b:2d4d:b0:37f:9cdf:f037 with SMTP id 98e67ed59e1d1-38dc7b3f828mr4594731a91.26.1783823119410; Sat, 11 Jul 2026 19:25:19 -0700 (PDT) Received: from ceto.lan ([2607:fb90:9c20:2264::1c31]) by smtp.googlemail.com with ESMTPSA id 5a478bee46e88-3117462f5c7sm60704693eec.0.2026.07.11.19.25.17 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 11 Jul 2026 19:25:18 -0700 (PDT) From: Mohamed Khalfella To: Justin Tee , Naresh Gottumukkala , Paul Ely , Chaitanya Kulkarni , Christoph Hellwig , Jens Axboe , Keith Busch , Sagi Grimberg , James Smart , Hannes Reinecke , Randy Jennings , Dhaval Giani Cc: Aaron Dailey , linux-nvme@lists.infradead.org, linux-kernel@vger.kernel.org, Mohamed Khalfella Subject: [PATCH v5 02/16] nvmet/debugfs: Export controller CIU and CIRN via debugfs Date: Sat, 11 Jul 2026 19:23:23 -0700 Message-ID: <20260712022437.3743117-3-mkhalfella@purestorage.com> X-Mailer: git-send-email 2.54.0 In-Reply-To: <20260712022437.3743117-1-mkhalfella@purestorage.com> References: <20260712022437.3743117-1-mkhalfella@purestorage.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 Content-Type: text/plain; charset="utf-8" Export ctrl->ciu and ctrl->cirn as debugfs files under controller debugfs directory. Signed-off-by: Mohamed Khalfella Reviewed-by: Hannes Reinecke Reviewed-by: Sagi Grimberg --- drivers/nvme/target/debugfs.c | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/drivers/nvme/target/debugfs.c b/drivers/nvme/target/debugfs.c index e85fe1d4c9f8..4de460879d0b 100644 --- a/drivers/nvme/target/debugfs.c +++ b/drivers/nvme/target/debugfs.c @@ -152,6 +152,23 @@ static int nvmet_ctrl_tls_concat_show(struct seq_file = *m, void *p) } NVMET_DEBUGFS_ATTR(nvmet_ctrl_tls_concat); #endif +static int nvmet_ctrl_instance_ciu_show(struct seq_file *m, void *p) +{ + struct nvmet_ctrl *ctrl =3D m->private; + + seq_printf(m, "%02x\n", ctrl->ciu); + return 0; +} +NVMET_DEBUGFS_ATTR(nvmet_ctrl_instance_ciu); + +static int nvmet_ctrl_instance_cirn_show(struct seq_file *m, void *p) +{ + struct nvmet_ctrl *ctrl =3D m->private; + + seq_printf(m, "%016llx\n", ctrl->cirn); + return 0; +} +NVMET_DEBUGFS_ATTR(nvmet_ctrl_instance_cirn); =20 static const char *const nvmet_pr_type_names[] =3D { [NVME_PR_WRITE_EXCLUSIVE] =3D "write_exclusive", @@ -287,6 +304,10 @@ int nvmet_debugfs_ctrl_setup(struct nvmet_ctrl *ctrl) debugfs_create_file("tls_key", S_IRUSR, ctrl->debugfs_dir, ctrl, &nvmet_ctrl_tls_key_fops); #endif + debugfs_create_file("ciu", S_IRUSR, ctrl->debugfs_dir, ctrl, + &nvmet_ctrl_instance_ciu_fops); + debugfs_create_file("cirn", S_IRUSR, ctrl->debugfs_dir, ctrl, + &nvmet_ctrl_instance_cirn_fops); return 0; } =20 --=20 2.54.0 From nobody Sat Jul 25 23:03:45 2026 Received: from mail-pj1-f51.google.com (mail-pj1-f51.google.com [209.85.216.51]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 79109366820 for ; Sun, 12 Jul 2026 02:25:22 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.216.51 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1783823124; cv=none; b=IBm5J2hrzOgraI2dujVX7aBpIAAc1XK7PhLQryRvrGL41tWzGCLCBQziJC3zl2zcuNIkWPl0ATS3Y2mrXMj6gMymdxCXUFLhDpjvRcYs7SNV53BKkIQzvT8g7m/TzV3IDI8EfY6c6AJ8uLvXMxSXaY6n6g6sLGoGqUAhv0Go2FI= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1783823124; c=relaxed/simple; bh=hxRraFlSw6wIBPC/F85K7LFjih+TGy2UuzlrHCBaynE=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=QQFkPlgTT03C5dLWoYT2rqdTkHGgbYrXONUsp0TM/QoyhKSVvL6a0M+/UqO4Og1FUcoHOI6jcx2phxv3V4TDTEM8l6RhoasYrkL8zeG3Bxupea2Fb5Wd0foEaUVApBG7S1WcVn6DJbqBkKzIDTi8PdZQKG5xfXXmCKCn9IKrf3E= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=purestorage.com; spf=pass smtp.mailfrom=purestorage.com; dkim=pass (2048-bit key) header.d=purestorage.com header.i=@purestorage.com header.b=aTdJW/kC; arc=none smtp.client-ip=209.85.216.51 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=purestorage.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=purestorage.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=purestorage.com header.i=@purestorage.com header.b="aTdJW/kC" Received: by mail-pj1-f51.google.com with SMTP id 98e67ed59e1d1-37e0a189b0bso1862367a91.1 for ; Sat, 11 Jul 2026 19:25:22 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=purestorage.com; s=google2022; t=1783823122; x=1784427922; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=sz2oq2nGtu7NQfl5yPr0twovV2PO9NUtvXs1PzpDhTw=; b=aTdJW/kCjAbxxB8AqdJNuMJULNIgSHkLQpOcMEJeRFvpAsSuIlHAAZTc7rfXg3oqkR K30wjJNR/5Gn/PmGQmbLi9RKSDvDkcUZW2b6AY//cUOfZZJM/9KstKlGFyzIpOYYOX8+ KrNUKxYFDYmFByQ77LEuZPl91eQuIviPYhB2CAlA/5Xn6wMDzbw3dhBMahspDV7b8eDl rFnzNBK+yR8i586tJU2Jnt3BOWVyRfhWG79UIUS4vV5U0P+Yfg6asNQByzpHlIZZ/I4T SSD3jZpI3ZaNMLA0aWawG8/QDbwsIJBt9PRhBQ2oWSYfDqL+yzAtGJKm4QALYRVwlC++ YG0g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1783823122; x=1784427922; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to:content-type; bh=sz2oq2nGtu7NQfl5yPr0twovV2PO9NUtvXs1PzpDhTw=; b=ECWfMels41NvvCFmG2HeB/yNWPGTmNvZ4WHsugAbfgbbXW0ZHrSLS3+szIK935MZ3f vamPxmL8eEWouCZzmAswjiVXM6twGkh5ivoazUnzWIpsr1kzfVDrjp3xwWdBPDxL6RyR 0jG0nl/PcKLLl7LQtKqzjEN8/auzduCKfNv2DltWtUOaYNM9+HuRnaUArc6RAIamZMgL WliSzlFgqrNMa6fd7m5g6BYIrpFq+l7AN8Rv5xdAhLO8q+c/wjDeFoMoS8qAVhUI6WAz UE6eZfIe01e9zu3TkKJsIu3LMIE24AtTiRjmjzl1QgrN3GT9qCXWH/9rCwi+xdVzQZs2 AYlQ== X-Forwarded-Encrypted: i=1; AHgh+RqVJfC+NoRgTV1JTuoDTC7Kfn8XSnz4+otTOzeLXVeAsssDGU31VJ30zjoggBICs8/YAtqCR9jUYbHNa7Y=@vger.kernel.org X-Gm-Message-State: AOJu0YxJHQLc2dLDafbDO2m2E2BBIAKyE4/XXI8JRSnOlTQlXF7PjXMC oQQfgND7Qz1D8qM7ygwQQa7J7onG/r6LAhoJCh1fu1etvmtND67LRDv9Q1ib+TLYSa0= X-Gm-Gg: AfdE7ckiOZcR9LgJPLPT6jOmkpOmQW+mVnyOEGqc+XPkv1hfDV7EHNwJ1sp7kLrrurL vR8vGFy4Eaf+76Xq5KbuS3i9/vKcZHAez8jtRivsRtCNWJxKsJXq7VrDInb1AYdwHzxcu0e7263 4Y/XIVcvv2LwRqO/uB4aB4QnbwIT28vsSATts2M/BQlsYete00I1LnlP5ao5jhDLxEuQne7ouAF OoeC/zPmzetfcmk/NFtVMnb11vGNMlYIU4M5gScTzvD2dMJ9GY+RnkTl3fHJ4POl8IIsYx5Y44a GaqaJCYLH893PTrJnIzGiyzygq/Zi+6slypcPf2AbOmQU1LvAjmnoPthciUSAIbIlCqlS+9VMV9 x0KD3d5zbHx8fB/p58w804BU7q4WUTwWCf3BGxvVJMyvLIvtAIeSiIkU7EheIo4Db1XCn9O9D38 wAMObz X-Received: by 2002:a17:90b:4a4f:b0:387:e0db:bc2e with SMTP id 98e67ed59e1d1-38dc7ba6fa9mr4275528a91.36.1783823121315; Sat, 11 Jul 2026 19:25:21 -0700 (PDT) Received: from ceto.lan ([2607:fb90:9c20:2264::1c31]) by smtp.googlemail.com with ESMTPSA id 5a478bee46e88-3117462f5c7sm60704693eec.0.2026.07.11.19.25.19 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 11 Jul 2026 19:25:20 -0700 (PDT) From: Mohamed Khalfella To: Justin Tee , Naresh Gottumukkala , Paul Ely , Chaitanya Kulkarni , Christoph Hellwig , Jens Axboe , Keith Busch , Sagi Grimberg , James Smart , Hannes Reinecke , Randy Jennings , Dhaval Giani Cc: Aaron Dailey , linux-nvme@lists.infradead.org, linux-kernel@vger.kernel.org, Mohamed Khalfella Subject: [PATCH v5 03/16] nvmet: Implement CCR nvme command Date: Sat, 11 Jul 2026 19:23:24 -0700 Message-ID: <20260712022437.3743117-4-mkhalfella@purestorage.com> X-Mailer: git-send-email 2.54.0 In-Reply-To: <20260712022437.3743117-1-mkhalfella@purestorage.com> References: <20260712022437.3743117-1-mkhalfella@purestorage.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 Content-Type: text/plain; charset="utf-8" Defined by TP8028 Rapid Path Failure Recovery, CCR (Cross-Controller Reset) command is an nvme command issued to source controller by initiator to reset impacted controller. Implement CCR command for linux nvme target. Signed-off-by: Mohamed Khalfella Reviewed-by: Hannes Reinecke --- drivers/nvme/target/admin-cmd.c | 76 ++++++++++++++++++++++++++++++++ drivers/nvme/target/core.c | 78 +++++++++++++++++++++++++++++++++ drivers/nvme/target/nvmet.h | 13 ++++++ include/linux/nvme.h | 23 ++++++++++ 4 files changed, 190 insertions(+) diff --git a/drivers/nvme/target/admin-cmd.c b/drivers/nvme/target/admin-cm= d.c index 81988b40d5d5..1b97e1bafa30 100644 --- a/drivers/nvme/target/admin-cmd.c +++ b/drivers/nvme/target/admin-cmd.c @@ -376,6 +376,7 @@ static void nvmet_get_cmd_effects_admin(struct nvmet_ct= rl *ctrl, log->acs[nvme_admin_get_features] =3D log->acs[nvme_admin_async_event] =3D log->acs[nvme_admin_keep_alive] =3D + log->acs[nvme_admin_cross_ctrl_reset] =3D cpu_to_le32(NVME_CMD_EFFECTS_CSUPP); } =20 @@ -1611,6 +1612,78 @@ void nvmet_execute_keep_alive(struct nvmet_req *req) nvmet_req_complete(req, status); } =20 +void nvmet_execute_cross_ctrl_reset(struct nvmet_req *req) +{ + struct nvmet_ctrl *ictrl, *sctrl =3D req->sq->ctrl; + struct nvme_command *cmd =3D req->cmd; + struct nvmet_ccr *ccr, *new_ccr; + int ccr_active, ccr_total; + u16 cntlid, status =3D NVME_SC_SUCCESS; + + if (!nvmet_check_transfer_len(req, 0)) + return; + + cntlid =3D le16_to_cpu(cmd->ccr.icid); + if (sctrl->cntlid =3D=3D cntlid) { + req->error_loc =3D + offsetof(struct nvme_cross_ctrl_reset_cmd, icid); + status =3D NVME_SC_INVALID_FIELD | NVME_STATUS_DNR; + goto out; + } + + /* Find and get impacted controller */ + ictrl =3D nvmet_ctrl_find_get_ccr(sctrl->subsys, sctrl->hostnqn, + cmd->ccr.ciu, cntlid, + le64_to_cpu(cmd->ccr.cirn)); + if (!ictrl) { + /* Immediate Reset Successful */ + nvmet_set_result(req, 1); + status =3D NVME_SC_SUCCESS; + goto out; + } + + ccr_total =3D ccr_active =3D 0; + mutex_lock(&sctrl->lock); + list_for_each_entry(ccr, &sctrl->ccr_list, entry) { + if (ccr->ctrl =3D=3D ictrl) { + status =3D NVME_SC_CCR_IN_PROGRESS | NVME_STATUS_DNR; + goto out_unlock; + } + + ccr_total++; + if (ccr->ctrl) + ccr_active++; + } + + if (ccr_active >=3D NVMF_CCR_LIMIT) { + status =3D NVME_SC_CCR_LIMIT_EXCEEDED; + goto out_unlock; + } + if (ccr_total >=3D NVMF_CCR_PER_PAGE) { + status =3D NVME_SC_CCR_LOGPAGE_FULL; + goto out_unlock; + } + + new_ccr =3D kmalloc_obj(*new_ccr, GFP_KERNEL); + if (!new_ccr) { + status =3D NVME_SC_INTERNAL; + goto out_unlock; + } + + new_ccr->ciu =3D cmd->ccr.ciu; + new_ccr->icid =3D cntlid; + new_ccr->ctrl =3D ictrl; + list_add_tail(&new_ccr->entry, &sctrl->ccr_list); + +out_unlock: + mutex_unlock(&sctrl->lock); + if (status =3D=3D NVME_SC_SUCCESS) + nvmet_ctrl_fatal_error(ictrl); + nvmet_ctrl_put(ictrl); +out: + nvmet_req_complete(req, status); +} + u32 nvmet_admin_cmd_data_len(struct nvmet_req *req) { struct nvme_command *cmd =3D req->cmd; @@ -1688,6 +1761,9 @@ u16 nvmet_parse_admin_cmd(struct nvmet_req *req) case nvme_admin_keep_alive: req->execute =3D nvmet_execute_keep_alive; return 0; + case nvme_admin_cross_ctrl_reset: + req->execute =3D nvmet_execute_cross_ctrl_reset; + return 0; default: return nvmet_report_invalid_opcode(req); } diff --git a/drivers/nvme/target/core.c b/drivers/nvme/target/core.c index d42421420be6..5b4312227222 100644 --- a/drivers/nvme/target/core.c +++ b/drivers/nvme/target/core.c @@ -117,6 +117,20 @@ u16 nvmet_zero_sgl(struct nvmet_req *req, off_t off, s= ize_t len) return 0; } =20 +void nvmet_ctrl_cleanup_ccrs(struct nvmet_ctrl *ctrl, bool all) +{ + struct nvmet_ccr *ccr, *tmp; + + lockdep_assert_held(&ctrl->lock); + + list_for_each_entry_safe(ccr, tmp, &ctrl->ccr_list, entry) { + if (all || ccr->ctrl =3D=3D NULL) { + list_del(&ccr->entry); + kfree(ccr); + } + } +} + static u32 nvmet_max_nsid(struct nvmet_subsys *subsys) { struct nvmet_ns *cur; @@ -1409,6 +1423,7 @@ static void nvmet_start_ctrl(struct nvmet_ctrl *ctrl) if (!nvmet_is_disc_subsys(ctrl->subsys)) { ctrl->ciu =3D ((u8)(ctrl->ciu + 1)) ? : 1; ctrl->cirn =3D get_random_u64(); + nvmet_ctrl_cleanup_ccrs(ctrl, false); } ctrl->csts =3D NVME_CSTS_RDY; =20 @@ -1514,6 +1529,37 @@ struct nvmet_ctrl *nvmet_ctrl_find_get(const char *s= ubsysnqn, return ctrl; } =20 +struct nvmet_ctrl *nvmet_ctrl_find_get_ccr(struct nvmet_subsys *subsys, + const char *hostnqn, u8 ciu, + u16 cntlid, u64 cirn) +{ + struct nvmet_ctrl *ctrl, *ictrl =3D NULL; + bool found =3D false; + + mutex_lock(&subsys->lock); + list_for_each_entry(ctrl, &subsys->ctrls, subsys_entry) { + if (ctrl->cntlid !=3D cntlid) + continue; + if (strncmp(ctrl->hostnqn, hostnqn, NVMF_NQN_SIZE)) + continue; + + /* Avoid racing with a controller that is becoming ready */ + mutex_lock(&ctrl->lock); + if (ctrl->ciu =3D=3D ciu && ctrl->cirn =3D=3D cirn) + found =3D true; + mutex_unlock(&ctrl->lock); + + if (found) { + if (kref_get_unless_zero(&ctrl->ref)) + ictrl =3D ctrl; + break; + } + } + mutex_unlock(&subsys->lock); + + return ictrl; +} + u16 nvmet_check_ctrl_status(struct nvmet_req *req) { if (unlikely(!(req->sq->ctrl->cc & NVME_CC_ENABLE))) { @@ -1639,6 +1685,7 @@ struct nvmet_ctrl *nvmet_alloc_ctrl(struct nvmet_allo= c_ctrl_args *args) subsys->clear_ids =3D 1; #endif =20 + INIT_LIST_HEAD(&ctrl->ccr_list); INIT_WORK(&ctrl->async_event_work, nvmet_async_event_work); INIT_LIST_HEAD(&ctrl->async_events); INIT_RADIX_TREE(&ctrl->p2p_ns_map, GFP_KERNEL); @@ -1749,12 +1796,43 @@ struct nvmet_ctrl *nvmet_alloc_ctrl(struct nvmet_al= loc_ctrl_args *args) } EXPORT_SYMBOL_GPL(nvmet_alloc_ctrl); =20 +static void nvmet_ctrl_complete_pending_ccr(struct nvmet_ctrl *ctrl) +{ + struct nvmet_subsys *subsys =3D ctrl->subsys; + struct nvmet_ctrl *sctrl; + struct nvmet_ccr *ccr; + + lockdep_assert_held(&subsys->lock); + + /* Cleanup all CCRs issued by ctrl as source controller */ + mutex_lock(&ctrl->lock); + nvmet_ctrl_cleanup_ccrs(ctrl, true); + mutex_unlock(&ctrl->lock); + + /* + * Find all CCRs targeting ctrl as impacted controller and + * set ccr->ctrl to NULL. This tells the source controller + * that CCR completed successfully. + */ + list_for_each_entry(sctrl, &subsys->ctrls, subsys_entry) { + mutex_lock(&sctrl->lock); + list_for_each_entry(ccr, &sctrl->ccr_list, entry) { + if (ccr->ctrl =3D=3D ctrl) { + ccr->ctrl =3D NULL; + break; + } + } + mutex_unlock(&sctrl->lock); + } +} + static void nvmet_ctrl_free(struct kref *ref) { struct nvmet_ctrl *ctrl =3D container_of(ref, struct nvmet_ctrl, ref); struct nvmet_subsys *subsys =3D ctrl->subsys; =20 mutex_lock(&subsys->lock); + nvmet_ctrl_complete_pending_ccr(ctrl); nvmet_ctrl_destroy_pr(ctrl); nvmet_release_p2p_ns_map(ctrl); list_del(&ctrl->subsys_entry); diff --git a/drivers/nvme/target/nvmet.h b/drivers/nvme/target/nvmet.h index 9c98833e8f3a..de088986cb4b 100644 --- a/drivers/nvme/target/nvmet.h +++ b/drivers/nvme/target/nvmet.h @@ -272,6 +272,7 @@ struct nvmet_ctrl { u32 kato; u64 cirn; =20 + struct list_head ccr_list; struct nvmet_port *port; =20 u32 aen_enabled; @@ -318,6 +319,13 @@ struct nvmet_ctrl { struct nvmet_pr_log_mgr pr_log_mgr; }; =20 +struct nvmet_ccr { + struct nvmet_ctrl *ctrl; + struct list_head entry; + u16 icid; + u8 ciu; +}; + struct nvmet_subsys { enum nvme_subsys_type type; =20 @@ -583,6 +591,7 @@ void nvmet_req_free_sgls(struct nvmet_req *req); void nvmet_execute_set_features(struct nvmet_req *req); void nvmet_execute_get_features(struct nvmet_req *req); void nvmet_execute_keep_alive(struct nvmet_req *req); +void nvmet_execute_cross_ctrl_reset(struct nvmet_req *req); =20 u16 nvmet_check_cqid(struct nvmet_ctrl *ctrl, u16 cqid, bool create); u16 nvmet_check_io_cqid(struct nvmet_ctrl *ctrl, u16 cqid, bool create); @@ -625,6 +634,10 @@ struct nvmet_ctrl *nvmet_alloc_ctrl(struct nvmet_alloc= _ctrl_args *args); struct nvmet_ctrl *nvmet_ctrl_find_get(const char *subsysnqn, const char *hostnqn, u16 cntlid, struct nvmet_req *req); +struct nvmet_ctrl *nvmet_ctrl_find_get_ccr(struct nvmet_subsys *subsys, + const char *hostnqn, u8 ciu, + u16 cntlid, u64 cirn); +void nvmet_ctrl_cleanup_ccrs(struct nvmet_ctrl *ctrl, bool all); void nvmet_ctrl_put(struct nvmet_ctrl *ctrl); u16 nvmet_check_ctrl_status(struct nvmet_req *req); ssize_t nvmet_ctrl_host_traddr(struct nvmet_ctrl *ctrl, diff --git a/include/linux/nvme.h b/include/linux/nvme.h index cbaf02b0cf07..7e6150d9494a 100644 --- a/include/linux/nvme.h +++ b/include/linux/nvme.h @@ -22,6 +22,7 @@ #define NVMF_TSAS_SIZE 256 =20 #define NVMF_CCR_LIMIT 4 +#define NVMF_CCR_PER_PAGE 511 =20 #define NVME_DISC_SUBSYS_NAME "nqn.2014-08.org.nvmexpress.discovery" =20 @@ -1233,6 +1234,22 @@ struct nvme_zone_mgmt_recv_cmd { __le32 cdw14[2]; }; =20 +struct nvme_cross_ctrl_reset_cmd { + __u8 opcode; + __u8 flags; + __u16 command_id; + __le32 nsid; + __le64 rsvd2[2]; + union nvme_data_ptr dptr; + __le16 icid; + __u8 ciu; + __u8 rsvd10; + __le32 cdw11; + __le64 cirn; + __le32 cdw14; + __le32 cdw15; +}; + struct nvme_io_mgmt_recv_cmd { __u8 opcode; __u8 flags; @@ -1331,6 +1348,7 @@ enum nvme_admin_opcode { nvme_admin_virtual_mgmt =3D 0x1c, nvme_admin_nvme_mi_send =3D 0x1d, nvme_admin_nvme_mi_recv =3D 0x1e, + nvme_admin_cross_ctrl_reset =3D 0x38, nvme_admin_dbbuf =3D 0x7C, nvme_admin_format_nvm =3D 0x80, nvme_admin_security_send =3D 0x81, @@ -1364,6 +1382,7 @@ enum nvme_admin_opcode { nvme_admin_opcode_name(nvme_admin_virtual_mgmt), \ nvme_admin_opcode_name(nvme_admin_nvme_mi_send), \ nvme_admin_opcode_name(nvme_admin_nvme_mi_recv), \ + nvme_admin_opcode_name(nvme_admin_cross_ctrl_reset), \ nvme_admin_opcode_name(nvme_admin_dbbuf), \ nvme_admin_opcode_name(nvme_admin_format_nvm), \ nvme_admin_opcode_name(nvme_admin_security_send), \ @@ -2022,6 +2041,7 @@ struct nvme_command { struct nvme_dbbuf dbbuf; struct nvme_directive_cmd directive; struct nvme_io_mgmt_recv_cmd imr; + struct nvme_cross_ctrl_reset_cmd ccr; }; }; =20 @@ -2186,6 +2206,9 @@ enum { NVME_SC_PMR_SAN_PROHIBITED =3D 0x123, NVME_SC_ANA_GROUP_ID_INVALID =3D 0x124, NVME_SC_ANA_ATTACH_FAILED =3D 0x125, + NVME_SC_CCR_IN_PROGRESS =3D 0x13f, + NVME_SC_CCR_LOGPAGE_FULL =3D 0x140, + NVME_SC_CCR_LIMIT_EXCEEDED =3D 0x141, =20 /* * I/O Command Set Specific - NVM commands: --=20 2.54.0 From nobody Sat Jul 25 23:03:45 2026 Received: from mail-pg1-f175.google.com (mail-pg1-f175.google.com [209.85.215.175]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id A446F366DA5 for ; Sun, 12 Jul 2026 02:25:24 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.215.175 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1783823126; cv=none; b=ntLS6uFfpNuSDeYshMdUWFla/DKAJa7MBDnmNkhfgR40pn6ztwsQOgjdrBya9SEoYmtPnl0Od1ImQOVarRl+qlZx3ASc+TBgBCj3Fr0O7i4x0Vl9qMr9Xi1Y8z9AdMlZNStkF+FL89tkbgeOIe3TEIIB8ty6nffxuppE5pESUhc= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1783823126; c=relaxed/simple; bh=JJ+d0rT8eu+CFW19LY64aYRS/dGQq0+3I2i1YebFK/E=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=ExKQ7zcsAh1RiaGM8ThIxkdi+ncxh35xmx0PWLPj/QxtFOkZ99PMQ154TnaRP7pgKdAie199FKF6SKAQUBzJ5t3niPSjX52jNWVn1vMncooVvpRmVEH9ULDJEROGOF+L2a494I389NvzCEa/rMSX/mKABFV5qxjg1ZOAdMq0Ss0= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=purestorage.com; spf=pass smtp.mailfrom=purestorage.com; dkim=pass (2048-bit key) header.d=purestorage.com header.i=@purestorage.com header.b=Bs7rDmvO; arc=none smtp.client-ip=209.85.215.175 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=purestorage.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=purestorage.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=purestorage.com header.i=@purestorage.com header.b="Bs7rDmvO" Received: by mail-pg1-f175.google.com with SMTP id 41be03b00d2f7-c9c26a5fb98so1249444a12.0 for ; Sat, 11 Jul 2026 19:25:24 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=purestorage.com; s=google2022; t=1783823123; x=1784427923; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=P20skrUm4HZS8JTk5TGJZTP7YmJdI0Mg5/mxR9z/xBU=; b=Bs7rDmvOXlBbLKD2uudF78ZFszPUCtACDm6nZrhinIYBRD0A+VNwQh6Di1YOlkwAy8 6N9tPSwTbwBd9VCEPbRIC8ebYHvcMwI+iDy2MvT/ThU5b3i+VDUMYirjW7X7w6NmK4FP vhAmy6tfI9jaE9rBk2uSdk7sZFaIhdDDpWttJVz5NZP8UYFM7djAuiJ+rnkhmryAgoc/ hnrI53KJfjg6WUQf6dpmFw8dQqN1n/MxCV4Nmyugh4Kb/uami156egSBTOAUdipmHuVq EA3EMU+uHN6X++HNXylyR215DxSLNIHlAFeR3CgV6lw8DkLKosBit5FN/GexYIz+5pnz M6cQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1783823123; x=1784427923; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to:content-type; bh=P20skrUm4HZS8JTk5TGJZTP7YmJdI0Mg5/mxR9z/xBU=; b=YGSzk5PHOCWQN5veHdh20zMCHdgO6r++Go1q7F6a3/DnFWxAo7wJLQKZdmGaXKY10B URERz+wMniqMazWgdI09/8eZCSdL2Dmf7CGrqw7OCfQo591jH+c5fuQL/kPluujZ76VK B3arhSMp/21KfH92BkI6BALPMcYjrZJUtkTF5nKl8T11IczxjB1InT/PqtwST8fS8imq EtNaimlYnjYvpC0nwVxrA0kxggLx2QjnpcWAHtTK75tGbE2IjBafZ7KqWKT6whL+3HZE oX7PPYbTnLSVPRu81lsQzrc8LTU+05nTaeXEiBZuvPAJfQ/0w8W1lvFbrjJKsL4SeFct 2R+g== X-Forwarded-Encrypted: i=1; AHgh+RoWC+9nc7eFdoJjxKoMxKgJhth0uN4qEHpYh41wk94TN+9Y33Iu5VI6Ar0erFNMSGrQhyOwrZNmhf+UxmY=@vger.kernel.org X-Gm-Message-State: AOJu0YyXHpLxQk7o4+iWYmew7s2zQU3Iwglvlp2TQmjPTiUhPkwNdktg WAsP7bmuNoIT7EL/DROVNWuXjc8FzmGATcJAzRBgiTGm/ApgTNTuRQRrgdwv6qxNuEU= X-Gm-Gg: AfdE7cktYW9SNEeyL8Cpcs1C925PqNPki0UvXoRQMT4JXydf4HPCuaWsfXj/KyF5vzk 5Pp2RhAbUH6kDB3Z/Zyoi1FhT9y0eXf+SuQoLmDOeqtcnbISYhWKpS53qRmJivzQgJwm5v19IbO mMQPk+owBNy0GnBHtD+PrccFXEhTHNYbPiQ52xUEaxVWR7dImLIBkRWUswcZa45uIoWC5EpSC/q k4f1qw+e6K0To75DCHmVoyHnhUnRpZUK2oY74wkCUfa+YRg/rt5Uqq0AZ1ARdJDlkV5X2RyohwA N8lxEBXboNnesj3LzCGBLHqQqtnpvBFjIg8+stYQ2iGbzDXOEZvJ5CsTdgn/EYJVy/yU7zNp9Yl UBNeHpAnzmDaDoKHzHFZZW6tk/PFKbLbqpyzpEHVFip1iuy+SgouDy/hqHr1WhweWOuLZMoUwqi omNiqu X-Received: by 2002:a05:6a21:6115:b0:3bf:aa54:4cbc with SMTP id adf61e73a8af0-3c0f0b6fda4mr9262734637.26.1783823123312; Sat, 11 Jul 2026 19:25:23 -0700 (PDT) Received: from ceto.lan ([2607:fb90:9c20:2264::1c31]) by smtp.googlemail.com with ESMTPSA id 5a478bee46e88-3117462f5c7sm60704693eec.0.2026.07.11.19.25.21 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 11 Jul 2026 19:25:22 -0700 (PDT) From: Mohamed Khalfella To: Justin Tee , Naresh Gottumukkala , Paul Ely , Chaitanya Kulkarni , Christoph Hellwig , Jens Axboe , Keith Busch , Sagi Grimberg , James Smart , Hannes Reinecke , Randy Jennings , Dhaval Giani Cc: Aaron Dailey , linux-nvme@lists.infradead.org, linux-kernel@vger.kernel.org, Mohamed Khalfella Subject: [PATCH v5 04/16] nvmet: Implement CCR logpage Date: Sat, 11 Jul 2026 19:23:25 -0700 Message-ID: <20260712022437.3743117-5-mkhalfella@purestorage.com> X-Mailer: git-send-email 2.54.0 In-Reply-To: <20260712022437.3743117-1-mkhalfella@purestorage.com> References: <20260712022437.3743117-1-mkhalfella@purestorage.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 Content-Type: text/plain; charset="utf-8" Defined by TP8028 Rapid Path Failure Recovery, CCR (Cross-Controller Reset) log page contains an entry for each CCR request submitted to source controller. Implement CCR logpage for nvme linux target. Signed-off-by: Mohamed Khalfella Reviewed-by: Hannes Reinecke Reviewed-by: Sagi Grimberg --- drivers/nvme/target/admin-cmd.c | 44 +++++++++++++++++++++++++++++++++ include/linux/nvme.h | 29 ++++++++++++++++++++++ 2 files changed, 73 insertions(+) diff --git a/drivers/nvme/target/admin-cmd.c b/drivers/nvme/target/admin-cm= d.c index 1b97e1bafa30..ea2566a9b83f 100644 --- a/drivers/nvme/target/admin-cmd.c +++ b/drivers/nvme/target/admin-cmd.c @@ -220,6 +220,7 @@ static void nvmet_execute_get_supported_log_pages(struc= t nvmet_req *req) logs->lids[NVME_LOG_FEATURES] =3D cpu_to_le32(NVME_LIDS_LSUPP); logs->lids[NVME_LOG_RMI] =3D cpu_to_le32(NVME_LIDS_LSUPP); logs->lids[NVME_LOG_RESERVATION] =3D cpu_to_le32(NVME_LIDS_LSUPP); + logs->lids[NVME_LOG_CCR] =3D cpu_to_le32(NVME_LIDS_LSUPP); =20 status =3D nvmet_copy_to_sgl(req, 0, logs, sizeof(*logs)); kfree(logs); @@ -606,6 +607,47 @@ static void nvmet_execute_get_log_page_features(struct= nvmet_req *req) nvmet_req_complete(req, status); } =20 +static void nvmet_execute_get_log_page_ccr(struct nvmet_req *req) +{ + struct nvmet_ctrl *ctrl =3D req->sq->ctrl; + struct nvmet_ccr *ccr; + struct nvme_ccr_log *log; + int index =3D 0; + u16 status; + + log =3D kzalloc_obj(*log); + if (!log) { + status =3D NVME_SC_INTERNAL; + goto out; + } + + mutex_lock(&ctrl->lock); + list_for_each_entry(ccr, &ctrl->ccr_list, entry) { + u8 flags =3D NVME_CCR_FLAGS_VALIDATED | NVME_CCR_FLAGS_INITIATED; + u8 ccr_status =3D ccr->ctrl ? NVME_CCR_STATUS_IN_PROGRESS : + NVME_CCR_STATUS_SUCCESS; + + log->entries[index].icid =3D cpu_to_le16(ccr->icid); + log->entries[index].ciu =3D ccr->ciu; + log->entries[index].acid =3D cpu_to_le16(0xffff); + log->entries[index].ccrs =3D ccr_status; + log->entries[index].ccrf =3D flags; + index++; + } + + /* Cleanup completed CCRs if requested */ + if (req->cmd->get_log_page.lsp & 0x1) + nvmet_ctrl_cleanup_ccrs(ctrl, false); + mutex_unlock(&ctrl->lock); + + log->ne =3D cpu_to_le16(index); + nvmet_clear_aen_bit(req, NVME_AEN_BIT_CCR_COMPLETE); + status =3D nvmet_copy_to_sgl(req, 0, log, sizeof(*log)); + kfree(log); +out: + nvmet_req_complete(req, status); +} + static void nvmet_execute_get_log_page(struct nvmet_req *req) { if (!nvmet_check_transfer_len(req, nvmet_get_log_page_len(req->cmd))) @@ -639,6 +681,8 @@ static void nvmet_execute_get_log_page(struct nvmet_req= *req) return nvmet_execute_get_log_page_rmi(req); case NVME_LOG_RESERVATION: return nvmet_execute_get_log_page_resv(req); + case NVME_LOG_CCR: + return nvmet_execute_get_log_page_ccr(req); } pr_debug("unhandled lid %d on qid %d\n", req->cmd->get_log_page.lid, req->sq->qid); diff --git a/include/linux/nvme.h b/include/linux/nvme.h index 7e6150d9494a..70dd0770e032 100644 --- a/include/linux/nvme.h +++ b/include/linux/nvme.h @@ -1440,6 +1440,7 @@ enum { NVME_LOG_ANA =3D 0x0c, NVME_LOG_FEATURES =3D 0x12, NVME_LOG_RMI =3D 0x16, + NVME_LOG_CCR =3D 0x1e, NVME_LOG_FDP_CONFIGS =3D 0x20, NVME_LOG_DISC =3D 0x70, NVME_LOG_RESERVATION =3D 0x80, @@ -1466,6 +1467,34 @@ enum { NVME_FIS_CSCPE =3D 1 << 21, }; =20 +/* NVMe Cross-Controller Reset Status */ +enum { + NVME_CCR_STATUS_IN_PROGRESS, + NVME_CCR_STATUS_SUCCESS, + NVME_CCR_STATUS_FAILED, +}; + +/* NVMe Cross-Controller Reset Flags */ +enum { + NVME_CCR_FLAGS_VALIDATED =3D 0x01, + NVME_CCR_FLAGS_INITIATED =3D 0x02, +}; + +struct nvme_ccr_log_entry { + __le16 icid; + __u8 ciu; + __u8 rsvd3; + __le16 acid; + __u8 ccrs; + __u8 ccrf; +}; + +struct nvme_ccr_log { + __le16 ne; + __u8 rsvd2[6]; + struct nvme_ccr_log_entry entries[NVMF_CCR_PER_PAGE]; +}; + /* NVMe Namespace Write Protect State */ enum { NVME_NS_NO_WRITE_PROTECT =3D 0, --=20 2.54.0 From nobody Sat Jul 25 23:03:45 2026 Received: from mail-pg1-f175.google.com (mail-pg1-f175.google.com [209.85.215.175]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id DE975367B89 for ; Sun, 12 Jul 2026 02:25:25 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.215.175 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1783823129; cv=none; b=Q84wcfbgdmDv6+q0IE5Fb7pvvyAIoVKoDoNsGqlvM3W3Kdi6xG+052i4BLa4fChuJBt+Nuvibg6WE3ZoGVjbmbeSmhIxT/jRxOk/y5roaGMeotKoAukMR7vchQH+o3zN8oSCPcSGBaum8Aw0BvOVuDAFWk8eHdQpbuPNZetCfZU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1783823129; c=relaxed/simple; bh=pY4cn64kyD+lHfYXGmKvHDXhgI+b16Mx5EmMGalia3w=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=jS1fm0kXpC6VKw7X/kFW9JYm/J1pc4+FrG9A7FzteIyDb+4TU3KaBSP9jCLY348JmRJuvlpfftjUNToq89GYmXqCpL8/2O5hwjjJ9ZnsyumAJ87enREbgUGpWHIsodES0SwnJ73Tf1hxulIBzStBGUdXKIH8SzjODA9hP9jZSAE= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=purestorage.com; spf=pass smtp.mailfrom=purestorage.com; dkim=pass (2048-bit key) header.d=purestorage.com header.i=@purestorage.com header.b=ZEfJlk4M; arc=none smtp.client-ip=209.85.215.175 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=purestorage.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=purestorage.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=purestorage.com header.i=@purestorage.com header.b="ZEfJlk4M" Received: by mail-pg1-f175.google.com with SMTP id 41be03b00d2f7-ca7c1176317so1545939a12.1 for ; Sat, 11 Jul 2026 19:25:25 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=purestorage.com; s=google2022; t=1783823125; x=1784427925; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=XL1bNu+U9GqDErYJpXpnJDbFEHkKBxgfcViduksku88=; b=ZEfJlk4MlWioKLk6AFv7uyaFInT6xfAMw+hQDogh6Wic8dJa3gMaclCUsE/5H9Jnws uWFfNyaUyL/2FF2CerRSpHks2/90SgZAqEtvWsYsHgCBXwnRwWcBtJLoN6p5nUPnkxtS JjJPLxlSmmfh76dzGF1+HMmfWgHn5g9zfJYAqNXWdxm4+LOXlaWhLfhYZssDmeR1K8Ye 0uuxXaHOx80a3OD7+d8URekTaJS9ItIbbi9h3kzsFT/zb6UGGfUNJR4AIhckgjfBOXKy mxKa54KHp7tvv0W17E0WXsJ8PmL1u+WwatwdIjgKe0Q5V0vNjO7rOEw7l8R68ECK9OPY PWcw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1783823125; x=1784427925; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to:content-type; bh=XL1bNu+U9GqDErYJpXpnJDbFEHkKBxgfcViduksku88=; b=flgoef2jX+6y4SjVxhy7U9K2r8Ug2mnXtmuQTKYLqm1+fm+s+QlUn7MfXJntQvUY7i p96qHBkuwWpYXIJJlsbhBc+jhvxFPLMeZxbYq1wS5TLWU/eP4cVKQhBAcqCQiaEAj4oT vo+AhDcWbkcdPyodN2SUoSLwra2IjGqrYznRFmxDEfmHNf8glTXQZ2FAdFEdugaOBJXG 9UsKeXIQrQlBGSNUGmv2ysIi/rX3Kvi5hR8sf6P495uUUQ7ETSQOF4i2pCAPur9y0uYv bKd6dsRhW9lm/AtxgEGaSEYHL3Qx3ho+GoyZKVh92ZzC78JImfgeCo8tHSMRK4ZMpgLg HIcQ== X-Forwarded-Encrypted: i=1; AHgh+Rru27CH8+2+7weSJqzEagz+vUrKa70TJODnmNXZBAmeFm7ZVQf65Gw+VbdmoLeDzLTtdsecRqx5BbcqEvg=@vger.kernel.org X-Gm-Message-State: AOJu0Yw310iCHOo+qIeANyugrSU+DkUmT99sSaLdlfB6czkOgUDEWsRw hPcIYckQgohrkk2x11JJCTdd79YJU8V0FTZ6lMzNNMcfuK2xX4q61Xbz8uDMHG3/v/g= X-Gm-Gg: AfdE7cmM5WreNxrRZRRhTrQBXK8uyhgWfeddMJjYPu6T0XTp93bmMGUD1blHpwcsH9T fnP5SCx+jUoWrZAlffVBuSdM8tbN58k05/wwAwwnHd2vbsZK23CRwlKr0DTpHra4s+arrEN6Jzw RSJU0fql2lgiIVAv0tAO9pcmBG1j9ht8/zQppInQuyzMBqXSVCrPeamsCcmD99vTNaOcQYCIcSH kLcQM8vKkgcqZ0ZkPgvUrLNjTvSJjNpbGRFqrUi8aTAYVd9qIzWEiEiOKEk+69Cgo+6Kd9jd0Qe DfQesb+/Cjv2aKPhtFGyQdC3ZYW61vMVwia1UkPAKDsd8RRBlA0kmaQs2p41qIhu9Vpxg/KHhIP AChn5yZchR8zMd4AJwTuB/jRE2BLU3apGBBZOYdD2EuLjwb27yD+E4/xvTK7b+BRQLcC3CYjGev kfLNJf X-Received: by 2002:a05:6a20:72a5:b0:3c0:9c19:65bb with SMTP id adf61e73a8af0-3c110a6e389mr5138000637.67.1783823125107; Sat, 11 Jul 2026 19:25:25 -0700 (PDT) Received: from ceto.lan ([2607:fb90:9c20:2264::1c31]) by smtp.googlemail.com with ESMTPSA id 5a478bee46e88-3117462f5c7sm60704693eec.0.2026.07.11.19.25.23 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 11 Jul 2026 19:25:24 -0700 (PDT) From: Mohamed Khalfella To: Justin Tee , Naresh Gottumukkala , Paul Ely , Chaitanya Kulkarni , Christoph Hellwig , Jens Axboe , Keith Busch , Sagi Grimberg , James Smart , Hannes Reinecke , Randy Jennings , Dhaval Giani Cc: Aaron Dailey , linux-nvme@lists.infradead.org, linux-kernel@vger.kernel.org, Mohamed Khalfella Subject: [PATCH v5 05/16] nvmet: Send an AEN on CCR completion Date: Sat, 11 Jul 2026 19:23:26 -0700 Message-ID: <20260712022437.3743117-6-mkhalfella@purestorage.com> X-Mailer: git-send-email 2.54.0 In-Reply-To: <20260712022437.3743117-1-mkhalfella@purestorage.com> References: <20260712022437.3743117-1-mkhalfella@purestorage.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 Content-Type: text/plain; charset="utf-8" When an impacted controller that is the target of pending CCRs is torn down, send an AEN to each source controller that issued a CCR against it. The notification points to the CCR log page that the source controller can read to check which CCR operation completed. Split nvmet_add_async_event() into a locked helper so the AEN can be queued while ctrl->lock is already held. Signed-off-by: Mohamed Khalfella Reviewed-by: Hannes Reinecke Reviewed-by: Sagi Grimberg Signed-off-by: Mohamed Khalfella Reviewed-by: Hannes Reinecke Reviewed-by: Sagi Grimberg --- drivers/nvme/target/core.c | 25 ++++++++++++++++++++++--- drivers/nvme/target/nvmet.h | 3 ++- include/linux/nvme.h | 3 +++ 3 files changed, 27 insertions(+), 4 deletions(-) diff --git a/drivers/nvme/target/core.c b/drivers/nvme/target/core.c index 5b4312227222..9b16b15f5093 100644 --- a/drivers/nvme/target/core.c +++ b/drivers/nvme/target/core.c @@ -205,7 +205,7 @@ static void nvmet_async_event_work(struct work_struct *= work) nvmet_async_events_process(ctrl); } =20 -void nvmet_add_async_event(struct nvmet_ctrl *ctrl, u8 event_type, +static void nvmet_add_async_event_locked(struct nvmet_ctrl *ctrl, u8 event= _type, u8 event_info, u8 log_page) { struct nvmet_async_event *aen; @@ -218,13 +218,19 @@ void nvmet_add_async_event(struct nvmet_ctrl *ctrl, u= 8 event_type, aen->event_info =3D event_info; aen->log_page =3D log_page; =20 - mutex_lock(&ctrl->lock); list_add_tail(&aen->entry, &ctrl->async_events); - mutex_unlock(&ctrl->lock); =20 queue_work(nvmet_aen_wq, &ctrl->async_event_work); } =20 +void nvmet_add_async_event(struct nvmet_ctrl *ctrl, u8 event_type, + u8 event_info, u8 log_page) +{ + mutex_lock(&ctrl->lock); + nvmet_add_async_event_locked(ctrl, event_type, event_info, log_page); + mutex_unlock(&ctrl->lock); +} + static void nvmet_add_to_changed_ns_log(struct nvmet_ctrl *ctrl, __le32 ns= id) { u32 i; @@ -1796,6 +1802,18 @@ struct nvmet_ctrl *nvmet_alloc_ctrl(struct nvmet_all= oc_ctrl_args *args) } EXPORT_SYMBOL_GPL(nvmet_alloc_ctrl); =20 +static void nvmet_ctrl_notify_ccr(struct nvmet_ctrl *ctrl) +{ + lockdep_assert_held(&ctrl->lock); + + if (nvmet_aen_bit_disabled(ctrl, NVME_AEN_BIT_CCR_COMPLETE)) + return; + + nvmet_add_async_event_locked(ctrl, NVME_AER_NOTICE, + NVME_AER_NOTICE_CCR_COMPLETED, + NVME_LOG_CCR); +} + static void nvmet_ctrl_complete_pending_ccr(struct nvmet_ctrl *ctrl) { struct nvmet_subsys *subsys =3D ctrl->subsys; @@ -1819,6 +1837,7 @@ static void nvmet_ctrl_complete_pending_ccr(struct nv= met_ctrl *ctrl) list_for_each_entry(ccr, &sctrl->ccr_list, entry) { if (ccr->ctrl =3D=3D ctrl) { ccr->ctrl =3D NULL; + nvmet_ctrl_notify_ccr(sctrl); break; } } diff --git a/drivers/nvme/target/nvmet.h b/drivers/nvme/target/nvmet.h index de088986cb4b..da80377c3795 100644 --- a/drivers/nvme/target/nvmet.h +++ b/drivers/nvme/target/nvmet.h @@ -44,7 +44,8 @@ * Supported optional AENs: */ #define NVMET_AEN_CFG_OPTIONAL \ - (NVME_AEN_CFG_NS_ATTR | NVME_AEN_CFG_ANA_CHANGE) + (NVME_AEN_CFG_NS_ATTR | NVME_AEN_CFG_ANA_CHANGE | \ + NVME_AEN_CFG_CCR_COMPLETE) #define NVMET_DISC_AEN_CFG_OPTIONAL \ (NVME_AEN_CFG_DISC_CHANGE) =20 diff --git a/include/linux/nvme.h b/include/linux/nvme.h index 70dd0770e032..3757d11ffea3 100644 --- a/include/linux/nvme.h +++ b/include/linux/nvme.h @@ -871,12 +871,14 @@ enum { NVME_AER_NOTICE_FW_ACT_STARTING =3D 0x01, NVME_AER_NOTICE_ANA =3D 0x03, NVME_AER_NOTICE_DISC_CHANGED =3D 0xf0, + NVME_AER_NOTICE_CCR_COMPLETED =3D 0xf4, }; =20 enum { NVME_AEN_BIT_NS_ATTR =3D 8, NVME_AEN_BIT_FW_ACT =3D 9, NVME_AEN_BIT_ANA_CHANGE =3D 11, + NVME_AEN_BIT_CCR_COMPLETE =3D 20, NVME_AEN_BIT_DISC_CHANGE =3D 31, }; =20 @@ -884,6 +886,7 @@ enum { NVME_AEN_CFG_NS_ATTR =3D 1 << NVME_AEN_BIT_NS_ATTR, NVME_AEN_CFG_FW_ACT =3D 1 << NVME_AEN_BIT_FW_ACT, NVME_AEN_CFG_ANA_CHANGE =3D 1 << NVME_AEN_BIT_ANA_CHANGE, + NVME_AEN_CFG_CCR_COMPLETE =3D 1 << NVME_AEN_BIT_CCR_COMPLETE, NVME_AEN_CFG_DISC_CHANGE =3D 1 << NVME_AEN_BIT_DISC_CHANGE, }; =20 --=20 2.54.0 From nobody Sat Jul 25 23:03:45 2026 Received: from mail-pj1-f50.google.com (mail-pj1-f50.google.com [209.85.216.50]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id C90C1367B88 for ; Sun, 12 Jul 2026 02:25:27 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.216.50 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1783823131; cv=none; b=MfssaBPFl9WkdROqioGVfr45gKpQIoiEmI1L6OaC0bqmZAtmz7PqceOtdf9XoL/T//SIthcv0i8yMo3hzI6eIjiy3Opc8/JE21R3iZa7gt3JrutCz4CV7BZzmjmkEhPGnKmaPk4DZMM1YI7MR3qnmqSo/yMZKDYTB3CC7TdGisE= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1783823131; c=relaxed/simple; bh=bR/WWEGBNigQyDc1HBm7rHqpF+EJnHcuajOKW9WjEQI=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=lQQiuF/cQey8tn+6CVTX8DQ5w7q6HS3ORaooDwORchaTTFoG7crO48jNwd9EFao5gnOM8yVwFXfXcXuFDwo6I3/OKvvGql9+NonbbbcQJhrmM6B4ltbSGYhtyefI4QRB6NPmtQQr+BKVH1rGWO39sEhebde+/dUx1QbZQCi0rK8= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=purestorage.com; spf=pass smtp.mailfrom=purestorage.com; dkim=pass (2048-bit key) header.d=purestorage.com header.i=@purestorage.com header.b=I/D4vCCL; arc=none smtp.client-ip=209.85.216.50 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=purestorage.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=purestorage.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=purestorage.com header.i=@purestorage.com header.b="I/D4vCCL" Received: by mail-pj1-f50.google.com with SMTP id 98e67ed59e1d1-3856d6fbcb3so1774150a91.2 for ; Sat, 11 Jul 2026 19:25:27 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=purestorage.com; s=google2022; t=1783823127; x=1784427927; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=Jt+jFO6RlYQHUjzVHCgosSICrSZ2jTFk9UEpM3tYb70=; b=I/D4vCCLCOIa/vCji3l6CgsO3KJ2j0NYZGZWUbHmsuZfZLJsF8a5K94nlIGfryeW0I Emm0xKCMF04XJf7t++lkeLBV213a31gdup8Z6BV+R1UTTUuGk1g8WT+nA/l9vfAwCfHV Q4yZluf6nDcwcJ1lrsbhCPXisQXSx6LUnuISHrDzrTLdxGJKIXTpl8p4Rv6U0R01L9M5 1lh6nqIzAq4gM5jlc2Svx8DMLwxsNEhp68G6SLELEVApBTiGzocC+xnX7NeLGmEwA5l1 ZYFJAmUkeUInFdNBKrASnaZ4+Z2XxRW1x8AqNKIRPlQ/Gg5e14sqdrMrPk7Jeqx6AhfH VUsw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1783823127; x=1784427927; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to:content-type; bh=Jt+jFO6RlYQHUjzVHCgosSICrSZ2jTFk9UEpM3tYb70=; b=aUZPI9letVQTWuqMHyI5uB0PBZBrNn62d9W4tqP4t+/OJvE+zCZFTpIYDlcaVE9XPx wpmhaaxF63lV7dVkzFHJuVzif2QKF4DyjeStbSx2zJPZJL74TKU6sWJMDil8bSf6V808 SNZxRcdBWl1hAxefJtPcEyLMfnn7ITm0pOK2gyliuIFMcJpzqTr632fFx1JJt31ARrh+ tSE7RKxEtpj1m7ZffWvt6+FjRlW1n19HnRAKxF2zqi8tBg/n4Pi6FsetW5TYqjg8lCsk Mvnrwt6C4XnLUoSsLKaQFnpLvLYiUHnUCjSGC68OtT13WAZzwzQK8g2eLwKmD1dUr/K3 0Kaw== X-Forwarded-Encrypted: i=1; AHgh+Ro7jhXJ48AVEFrSP/qO7wMGY6ywpYFJrO7b3o4XSoFjaL/hAIYa/HlJatqJUB91hbPtAyyiPOB2SCpHcvQ=@vger.kernel.org X-Gm-Message-State: AOJu0Yx4ytnR44sJ5aTTSSDrDvlZneUUkZxi8jJKycB4JcvnXvr4vqKH muvu1AElPJPzEG+HSCEzC+vC0ostEMEP3vQFRut2S3TWpS4sF4Cykhj5ErDg6yeuUCc= X-Gm-Gg: AfdE7clf7RUXX+k8mrMZByhBD+2TRrw6ZEBPPQveJKjO9DwaIcCh9PdwmxUBlABl3Kq VVeXNGsujQlSykk3sqVzBhmmoCIrxOc7jadVh1Kh5CB63dcCMpmkbvP7pSMkkhWJ1tKF1+uX7wj v5J5OPmgSAEDWh9gXQHrysf+lrcnIBVbQJgYTjy8+i+SFaXP2FXykf2Kh9S8SlbuWezwVIrqeld T8gGjGQmgcHCC+ajNG9g1HWIln4PBuN57Tm8tr/x4x+dZVb8lvIZujHDrVq+Le008rqS14Y6K5O fSBZUhBL/nTZEylUyS0VagRG5wovZi8Ar1kqB84HlHSZYdjSSW2UlwxHMrvuHLubY2GQwPqDime Pg/Qp8UXX/3nIqKlAD6C31RCL9FqSXP6NvLJarBJc0JMVyGpeKGwaHs8LGRv5xc5fkdBS5yTzY8 DFenyz X-Received: by 2002:a17:90b:3502:b0:387:e0db:bc32 with SMTP id 98e67ed59e1d1-38dc7bbdb04mr4091119a91.40.1783823126896; Sat, 11 Jul 2026 19:25:26 -0700 (PDT) Received: from ceto.lan ([2607:fb90:9c20:2264::1c31]) by smtp.googlemail.com with ESMTPSA id 5a478bee46e88-3117462f5c7sm60704693eec.0.2026.07.11.19.25.25 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 11 Jul 2026 19:25:26 -0700 (PDT) From: Mohamed Khalfella To: Justin Tee , Naresh Gottumukkala , Paul Ely , Chaitanya Kulkarni , Christoph Hellwig , Jens Axboe , Keith Busch , Sagi Grimberg , James Smart , Hannes Reinecke , Randy Jennings , Dhaval Giani Cc: Aaron Dailey , linux-nvme@lists.infradead.org, linux-kernel@vger.kernel.org, Mohamed Khalfella Subject: [PATCH v5 06/16] nvme: Rapid Path Failure Recovery read controller identify fields Date: Sat, 11 Jul 2026 19:23:27 -0700 Message-ID: <20260712022437.3743117-7-mkhalfella@purestorage.com> X-Mailer: git-send-email 2.54.0 In-Reply-To: <20260712022437.3743117-1-mkhalfella@purestorage.com> References: <20260712022437.3743117-1-mkhalfella@purestorage.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 Content-Type: text/plain; charset="utf-8" TP8028 Rapid Path Failure added new fields to controller identify response. Read CIU (Controller Instance Uniquifier), CIRN (Controller Instance Random Number), and CCRL (Cross-Controller Reset Limit) from controller identify response. Expose CIU and CIRN as sysfs attributes so the values can be used directly by user if needed. Also add the nvme_fence_timeout_ms() helper that derives a fencing timeout from the controller keep-alive timeout (kato). Signed-off-by: Mohamed Khalfella Reviewed-by: Hannes Reinecke Reviewed-by: Sagi Grimberg --- drivers/nvme/host/core.c | 4 ++++ drivers/nvme/host/nvme.h | 10 ++++++++++ drivers/nvme/host/sysfs.c | 23 +++++++++++++++++++++++ 3 files changed, 37 insertions(+) diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c index db0c8ad4628a..203ecafc1aec 100644 --- a/drivers/nvme/host/core.c +++ b/drivers/nvme/host/core.c @@ -3643,6 +3643,10 @@ static int nvme_init_identify(struct nvme_ctrl *ctrl) ctrl->crdt[1] =3D le16_to_cpu(id->crdt2); ctrl->crdt[2] =3D le16_to_cpu(id->crdt3); =20 + ctrl->ciu =3D id->ciu; + ctrl->cirn =3D le64_to_cpu(id->cirn); + ctrl->ccrl =3D id->ccrl; + ctrl->oacs =3D le16_to_cpu(id->oacs); ctrl->oncs =3D le16_to_cpu(id->oncs); ctrl->mtfa =3D le16_to_cpu(id->mtfa); diff --git a/drivers/nvme/host/nvme.h b/drivers/nvme/host/nvme.h index a679a4c61462..9b071076c9f4 100644 --- a/drivers/nvme/host/nvme.h +++ b/drivers/nvme/host/nvme.h @@ -384,11 +384,14 @@ struct nvme_ctrl { u16 crdt[3]; u16 oncs; u8 dmrl; + u8 ciu; u32 dmrsl; + u64 cirn; u16 oacs; u16 sqsize; u32 max_namespaces; atomic_t abort_limit; + u8 ccrl; u8 vwc; u32 vs; u32 sgls; @@ -1313,4 +1316,11 @@ static inline bool nvme_multi_css(struct nvme_ctrl *= ctrl) return (ctrl->ctrl_config & NVME_CC_CSS_MASK) =3D=3D NVME_CC_CSS_CSI; } =20 +static inline unsigned long nvme_fence_timeout_ms(struct nvme_ctrl *ctrl) +{ + if (ctrl->ctratt & NVME_CTRL_ATTR_TBKAS) + return 3 * ctrl->kato * 1000; + return 2 * ctrl->kato * 1000; +} + #endif /* _NVME_H */ diff --git a/drivers/nvme/host/sysfs.c b/drivers/nvme/host/sysfs.c index abf8edaae371..dd48c0989301 100644 --- a/drivers/nvme/host/sysfs.c +++ b/drivers/nvme/host/sysfs.c @@ -487,6 +487,27 @@ nvme_show_int_function(queue_count); nvme_show_int_function(sqsize); nvme_show_int_function(kato); =20 +static ssize_t nvme_sysfs_ciu_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct nvme_ctrl *ctrl =3D dev_get_drvdata(dev); + + return sysfs_emit(buf, "%02x\n", ctrl->ciu); +} +static DEVICE_ATTR(ciu, S_IRUSR, nvme_sysfs_ciu_show, NULL); + +static ssize_t nvme_sysfs_cirn_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct nvme_ctrl *ctrl =3D dev_get_drvdata(dev); + + return sysfs_emit(buf, "%016llx\n", ctrl->cirn); +} +static DEVICE_ATTR(cirn, S_IRUSR, nvme_sysfs_cirn_show, NULL); + + static ssize_t nvme_sysfs_delete(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) @@ -941,6 +962,8 @@ static struct attribute *nvme_dev_attrs[] =3D { &dev_attr_numa_node.attr, &dev_attr_queue_count.attr, &dev_attr_sqsize.attr, + &dev_attr_ciu.attr, + &dev_attr_cirn.attr, &dev_attr_hostnqn.attr, &dev_attr_hostid.attr, &dev_attr_ctrl_loss_tmo.attr, --=20 2.54.0 From nobody Sat Jul 25 23:03:45 2026 Received: from mail-pg1-f177.google.com (mail-pg1-f177.google.com [209.85.215.177]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 3E3C0366820 for ; Sun, 12 Jul 2026 02:25:29 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.215.177 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1783823131; cv=none; b=jVGokgCXw19JMTqjOGQwCWpa083tVe4MrNeSpyXiVv+TfvwzVHx4Nx/oh8/DEpRyCg3j7FIKFc6tOTeHoy/lsUoHg3LF/bCu+z76pQInPy1b4qLHU1VH2H8f/O47MWx/QQ48tXOknwDi8hIZwtF/T64KSaxaCzJttCaMfDP3uUs= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1783823131; c=relaxed/simple; bh=2dFQLb9vXBTHExRKap6xJK4LzB8KuaY/F7pXYmMthQw=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=uRQvzHjlEdcizxYCaF62BX8qsrVbOygV9GJ6q+M2YUeP18RDojNO9CwuEx2sY8Efposi8zNdoUxgWwX7uZaF/cvoGX+RmlwRZhNEWqFrsr1daZjaZQZPaxy3WpJX51scvLAi5s6hUvEx2UkOi+xudqYAZeTit/FCIeRJEka+l5k= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=purestorage.com; spf=pass smtp.mailfrom=purestorage.com; dkim=pass (2048-bit key) header.d=purestorage.com header.i=@purestorage.com header.b=BzeKJZJ8; arc=none smtp.client-ip=209.85.215.177 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=purestorage.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=purestorage.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=purestorage.com header.i=@purestorage.com header.b="BzeKJZJ8" Received: by mail-pg1-f177.google.com with SMTP id 41be03b00d2f7-c9fe3c9bd5fso2122176a12.0 for ; Sat, 11 Jul 2026 19:25:29 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=purestorage.com; s=google2022; t=1783823129; x=1784427929; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=z6DHY+73TsJixrpWZb9EMzOuJGBFm5beeq+D2G4BmDA=; b=BzeKJZJ8EfWMgAnoB6C+Nwwv8WS4K1jkmZETjEA74pZ8m+RrzxiEtxxT2PTP27ARoK 6BDWl0Ezn/sMC5DnejgZrzSx9d5fyE//uYzuJE/G9mPZ3ucvOGedqcFJZL/btHYZ25Sy OL2+cWZN9hfzuAdXk6dwNLosi8c/lngGNZ9gJFpxPGzUaOdesDBuHR88X/q1WjFYaV5v 1Tp0G3uVsk35pg0vo0E7bsBB4SA9ICboNishgapWosmE+WFtZJbey3fgaDCiT5OSqcjN K/sf1CXRvRSj8On6U8GR7CCKx0q8donw/0Shnq/rgs37FMj9G1A4sZY6Xah+6t+0t9L9 nReg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1783823129; x=1784427929; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to:content-type; bh=z6DHY+73TsJixrpWZb9EMzOuJGBFm5beeq+D2G4BmDA=; b=JV3k+AGg2x/jC/J9NzYpeBujxn6rz4KlwNGyJCdCUvfEtlJX2gRW/2I2c1vsRjJPHc 9OcWJvtAPSuUERfBOj0QEKNEfyyOB6coZ+vHpj+m9eUHbKcFg2vpkOJSrRSuEnxu5QBn 4OZIuKbOwuN1X3/qDK1qgzIUwSZVsqApGyIZ0PROXhrZdFQ8o/fHfCEFegiiH+O6/JbR PL1JnCWODP67SbxHKw7fl+XGcL1VKl/rnDknpY2cJklsIN907o0b5yYK7JPYfWuBgsNd O++Ye1InxHYp/1K36jG4QESsz33GvGuqgKvsooqe66s4R13TgIaqDogKDqzqvUCEYisU aD2w== X-Forwarded-Encrypted: i=1; AHgh+RquY+YBcy/OdlCBc13IOtdTxm2DOJZ0iACpY1uUdatIDDVE4lwKVMhg0C6m/FWjDd7YKy4YICthqX4SP1E=@vger.kernel.org X-Gm-Message-State: AOJu0YyteaEA3xleA5n5KjVOweAa4Rvbpa8a6ukqVozkLrW9XzyeopR0 J+6vzMdNP44XMsZEocdNlBGod2JYqFZE1TwTGuRNF38LcS5q7ffc38jy0LUOloHPu2M= X-Gm-Gg: AfdE7ckV4xccmREoZYLx3jDFtTjVH4+1a/exJ+ZXWtKU3MAe9rAyjUkv7gl3PEfhtNx ICOvNySvMhZb9JxEl+6MVH2HUvTtEpxsRl4jGrV5NKcog5kljRUYojJXgMOkKqDhazNceWWmks3 Ejfin5VTpBlkg0v9C9GrVuI8v+tsaKXKKtP1XjqermjDObdFeE1uTBzlz4KBwF51GQT5rUWUQJi 0yWuVSKQAo+YzvAKZm6vU2QgULBU+ct0dJ77RMw6ttoUvESoS4mbwgmpIiv8mN5OQPYsmWKIQNi hCPNmgH02qHIO21rHdcvV6yjSTfpU0SKJ98t0sb+7oqGUk53TF5Nw2iSyDr7vZS6B0ajq++5wud nHpT1HruK0n8Siqc4mr1+rm6wFu57QM+XnSQNOALJJJFtlrZRe/C4TaV2BizdMws4LI1UwVVlUZ xbUM/c X-Received: by 2002:a17:90b:1d09:b0:37e:1620:dabc with SMTP id 98e67ed59e1d1-38d11279610mr10117714a91.0.1783823128742; Sat, 11 Jul 2026 19:25:28 -0700 (PDT) Received: from ceto.lan ([2607:fb90:9c20:2264::1c31]) by smtp.googlemail.com with ESMTPSA id 5a478bee46e88-3117462f5c7sm60704693eec.0.2026.07.11.19.25.27 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 11 Jul 2026 19:25:28 -0700 (PDT) From: Mohamed Khalfella To: Justin Tee , Naresh Gottumukkala , Paul Ely , Chaitanya Kulkarni , Christoph Hellwig , Jens Axboe , Keith Busch , Sagi Grimberg , James Smart , Hannes Reinecke , Randy Jennings , Dhaval Giani Cc: Aaron Dailey , linux-nvme@lists.infradead.org, linux-kernel@vger.kernel.org, Mohamed Khalfella Subject: [PATCH v5 07/16] nvme: Introduce FENCING and FENCED controller states Date: Sat, 11 Jul 2026 19:23:28 -0700 Message-ID: <20260712022437.3743117-8-mkhalfella@purestorage.com> X-Mailer: git-send-email 2.54.0 In-Reply-To: <20260712022437.3743117-1-mkhalfella@purestorage.com> References: <20260712022437.3743117-1-mkhalfella@purestorage.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 Content-Type: text/plain; charset="utf-8" Introduce two new controller states, FENCING and FENCED, and the state machine transitions needed to support them. Transports will move a LIVE controller into these states when an error is encountered; this patch only adds the states themselves. FENCING is entered from LIVE. While in FENCING the queues remain alive but new requests are not allowed to be sent, and the controller can be neither reset nor deleted (there is no transition from FENCING to RESETTING, DELETING or DELETING_NOIO). This is intentional because resetting or deleting the controller cancels inflight IOs, which should be held until either CCR succeeds or time-based recovery completes. FENCED is a short-lived state entered from FENCING before a reset. It is the only state from which RESETTING is reachable, so it exists to prevent a manual reset from taking effect while the controller is still in FENCING. Both states are treated as non-terminal by nvme_state_terminal(), and their names are exposed via the sysfs state attribute. Signed-off-by: Mohamed Khalfella Reviewed-by: Hannes Reinecke Reviewed-by: Randy Jennings --- drivers/nvme/host/core.c | 27 +++++++++++++++++++++++++-- drivers/nvme/host/nvme.h | 4 ++++ drivers/nvme/host/sysfs.c | 2 ++ 3 files changed, 31 insertions(+), 2 deletions(-) diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c index 203ecafc1aec..1ef4dc38f755 100644 --- a/drivers/nvme/host/core.c +++ b/drivers/nvme/host/core.c @@ -591,10 +591,29 @@ bool nvme_change_ctrl_state(struct nvme_ctrl *ctrl, break; } break; + case NVME_CTRL_FENCING: + switch (old_state) { + case NVME_CTRL_LIVE: + changed =3D true; + fallthrough; + default: + break; + } + break; + case NVME_CTRL_FENCED: + switch (old_state) { + case NVME_CTRL_FENCING: + changed =3D true; + fallthrough; + default: + break; + } + break; case NVME_CTRL_RESETTING: switch (old_state) { case NVME_CTRL_NEW: case NVME_CTRL_LIVE: + case NVME_CTRL_FENCED: changed =3D true; atomic_long_inc(&ctrl->nr_reset); fallthrough; @@ -776,6 +795,8 @@ blk_status_t nvme_fail_nonready_command(struct nvme_ctr= l *ctrl, =20 if (state !=3D NVME_CTRL_DELETING_NOIO && state !=3D NVME_CTRL_DELETING && + state !=3D NVME_CTRL_FENCING && + state !=3D NVME_CTRL_FENCED && state !=3D NVME_CTRL_DEAD && !test_bit(NVME_CTRL_FAILFAST_EXPIRED, &ctrl->flags) && !blk_noretry_request(rq) && !(rq->cmd_flags & REQ_NVME_MPATH)) @@ -818,10 +839,12 @@ bool __nvme_check_ready(struct nvme_ctrl *ctrl, struc= t request *rq, req->cmd->fabrics.fctype =3D=3D nvme_fabrics_type_auth_receive)) return true; break; - default: - break; + case NVME_CTRL_FENCING: + case NVME_CTRL_FENCED: case NVME_CTRL_DEAD: return false; + default: + break; } } =20 diff --git a/drivers/nvme/host/nvme.h b/drivers/nvme/host/nvme.h index 9b071076c9f4..e558a19781bd 100644 --- a/drivers/nvme/host/nvme.h +++ b/drivers/nvme/host/nvme.h @@ -305,6 +305,8 @@ static inline u16 nvme_req_qid(struct request *req) enum nvme_ctrl_state { NVME_CTRL_NEW, NVME_CTRL_LIVE, + NVME_CTRL_FENCING, + NVME_CTRL_FENCED, NVME_CTRL_RESETTING, NVME_CTRL_CONNECTING, NVME_CTRL_DELETING, @@ -850,6 +852,8 @@ static inline bool nvme_state_terminal(struct nvme_ctrl= *ctrl) switch (nvme_ctrl_state(ctrl)) { case NVME_CTRL_NEW: case NVME_CTRL_LIVE: + case NVME_CTRL_FENCING: + case NVME_CTRL_FENCED: case NVME_CTRL_RESETTING: case NVME_CTRL_CONNECTING: return false; diff --git a/drivers/nvme/host/sysfs.c b/drivers/nvme/host/sysfs.c index dd48c0989301..3853c9a6356e 100644 --- a/drivers/nvme/host/sysfs.c +++ b/drivers/nvme/host/sysfs.c @@ -542,6 +542,8 @@ static ssize_t nvme_sysfs_show_state(struct device *dev, static const char *const state_name[] =3D { [NVME_CTRL_NEW] =3D "new", [NVME_CTRL_LIVE] =3D "live", + [NVME_CTRL_FENCING] =3D "fencing", + [NVME_CTRL_FENCED] =3D "fenced", [NVME_CTRL_RESETTING] =3D "resetting", [NVME_CTRL_CONNECTING] =3D "connecting", [NVME_CTRL_DELETING] =3D "deleting", --=20 2.54.0 From nobody Sat Jul 25 23:03:45 2026 Received: from mail-pg1-f170.google.com (mail-pg1-f170.google.com [209.85.215.170]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 87CAC367F4A for ; Sun, 12 Jul 2026 02:25:31 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.215.170 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1783823136; cv=none; b=iiM8+t5OAzhbY4DtBC6W4YK4muSVOuHvSExZkQTPBPQLkiRIZajQNhtzafUTF5IH1a9+x9PPoxr4spLJH8vujmM6QsPKsh+ZGFQfqhu096P2PSg/MbDxcfOP1tk5eDoxtu6Qu93lGjh+p68f1EQmY82UGe8NW24Kc8KTusOOklM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1783823136; c=relaxed/simple; bh=ruQEphFFQrlsHc+qKLQTbpvRhPge3WKoRvGLsVvlSc0=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=mQ2A7vrmh+rYS4sVSlopi5GzKT2Y2Zherb057LFTkulXjKJNAaxRz2itw459RnQ8/KuBWtyPjvtqrw68VHwzUzDNl2oWOogAZfVTtBZ8HP+KoqKWcYMQGR/aWibtlJn7aKQnH0MGSVDaMkurh9mai5j7ocisto4o6uT+Y8U5hMY= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=purestorage.com; spf=pass smtp.mailfrom=purestorage.com; dkim=pass (2048-bit key) header.d=purestorage.com header.i=@purestorage.com header.b=DNwu06hU; arc=none smtp.client-ip=209.85.215.170 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=purestorage.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=purestorage.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=purestorage.com header.i=@purestorage.com header.b="DNwu06hU" Received: by mail-pg1-f170.google.com with SMTP id 41be03b00d2f7-ca97d139d5fso1510761a12.0 for ; Sat, 11 Jul 2026 19:25:31 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=purestorage.com; s=google2022; t=1783823131; x=1784427931; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=mVbEu2+Mr7kV1EL18RxKM6hBIrgT5eJTpURd1PTGGYY=; b=DNwu06hUhfnH9q3R6gAGqztztTRQswXIu3gNXK3p8XeEqjwjmTpPy6F6GPIjSJ0PPH Gmerzgp1bSTRaTH+WteA0jgoASZC9Vcf1Yu2KyIwIlkrFhJsvIzvUKFCJe8PR+ZWpp2M 0isjRprgeLiivNiCBcR5IH/yOqc1VsVWyOrav2MkZQdrWKGc0efQ11QnDbxfxobVr2Y0 68n70hcw8pwrxpkBAk49zI3OFax4Du4Kr2oT8nQiEsN3+yVlXkiYqU2eAHxM8bmDEDdF pLZazkThCJNVAd1pOf1XHeWaQRRsnssbZAa1v2RnEDhliL1A3upiRH8W0Y5U2MRgd6OT 4ivg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1783823131; x=1784427931; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to:content-type; bh=mVbEu2+Mr7kV1EL18RxKM6hBIrgT5eJTpURd1PTGGYY=; b=qDv/LppyDr6vrND5slWCjRkRG2//kI86+r0qPdB5cZtF8dqgkKJzK1tJBgYqeiuCe1 xhF6xgay04yOBeOWExissJaamYJxBY/zzEgdb0SbHM3E9u67qq/SOVmd4XB3znGayarN erzcTIXf2uCeony3gc4DHA5nAiSI8U/5YxsvwHlkQGhVGx6+9d6q9NsojzP69dXWre4l kfdyFn04k4w4KqAkTD7xzCJM4LHfYYMkj/D5bW9xzJQA6z8HuRL9TS4P3XiR0NvCjM6k kWTFNEskK+RiF2Rq3o0U82kEhCN61DWsGoE1Fm7DzTv04JPGHl1FeySjpecg13CXiLcR MD6A== X-Forwarded-Encrypted: i=1; AHgh+RqNbhQTq+K1E0wQgMt8cmgfdjtyOSFOqH/lziKcDVQ9fcYKP/PYZfGgMH+TbdLYTCYfUr03MKJsHLJhv+U=@vger.kernel.org X-Gm-Message-State: AOJu0YxfiK9wjuv3UFiCtvKISoHIQLH+CgWBogO1MKJmVqizehq2fdwq lxpda0AdKeNTHS+rHUf78SWJjuXNQOO6k/z3iVP6CErNKOsZHc2WCEIvjEGXrh4Qnw9isPb/0cs hYWRM X-Gm-Gg: AfdE7cnAQmjKvRCVrFDvcxaEFrGeSRVlOIPz0xk83YHtpfzfEFTBQfmJSi/opPccddv 6GZKDwEYgPRxYdCfDP/SEIBqvML2euZgoRej6R+ySSPoZTobXyQnIbLd+z7Sd41pGhc6V3WUcT7 BoCO8xqlRCcSHLMOPL/o1XKUv9/Dz8XQUnLCs77kUPcMx44UfT86nA88Y0LydRh347T1RvIaPxh TsIFiR61owm6Y8pkiMfY1s5zp+RSbg+jSdE8xg7uwDYAPJ34Er7bYE8b5MQ3As+BG8CtUJ4HGzr d3QsH29yKngaqSOfFFfAlu/N+KEE7JR7Xg9uyoZU2NCKxAEI1WJjgDfIigwSXJcV02wTtFRGeIS NS4TXc6LGVanRasOVqQtu+1z9UrM7mYimfD7arTll91lSqvkF+dUhAzcJrsSoR8zqklTG4thGE8 7DAD0K X-Received: by 2002:a17:90b:1848:b0:381:b1ad:c9e4 with SMTP id 98e67ed59e1d1-38dc7755a44mr4819914a91.26.1783823130537; Sat, 11 Jul 2026 19:25:30 -0700 (PDT) Received: from ceto.lan ([2607:fb90:9c20:2264::1c31]) by smtp.googlemail.com with ESMTPSA id 5a478bee46e88-3117462f5c7sm60704693eec.0.2026.07.11.19.25.29 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 11 Jul 2026 19:25:29 -0700 (PDT) From: Mohamed Khalfella To: Justin Tee , Naresh Gottumukkala , Paul Ely , Chaitanya Kulkarni , Christoph Hellwig , Jens Axboe , Keith Busch , Sagi Grimberg , James Smart , Hannes Reinecke , Randy Jennings , Dhaval Giani Cc: Aaron Dailey , linux-nvme@lists.infradead.org, linux-kernel@vger.kernel.org, Mohamed Khalfella Subject: [PATCH v5 08/16] nvme: Implement cross-controller reset recovery Date: Sat, 11 Jul 2026 19:23:29 -0700 Message-ID: <20260712022437.3743117-9-mkhalfella@purestorage.com> X-Mailer: git-send-email 2.54.0 In-Reply-To: <20260712022437.3743117-1-mkhalfella@purestorage.com> References: <20260712022437.3743117-1-mkhalfella@purestorage.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 Content-Type: text/plain; charset="utf-8" A host that has more than one path connecting to an nvme subsystem typically has an nvme controller associated with every path. This is mostly applicable to nvmeof. If one path goes down, inflight IOs on that path should not be retried immediately on another path because this could lead to data corruption as described in TP4129. TP8028 defines cross-controller reset mechanism that can be used by host to terminate IOs on the failed path using one of the remaining healthy paths. Only after IOs are terminated, or long enough time passes as defined by TP4129, inflight IOs should be retried on another path. Implement core cross-controller reset shared logic to be used by the transports. Signed-off-by: Mohamed Khalfella --- drivers/nvme/host/constants.c | 1 + drivers/nvme/host/core.c | 152 ++++++++++++++++++++++++++++++++++ drivers/nvme/host/nvme.h | 10 +++ 3 files changed, 163 insertions(+) diff --git a/drivers/nvme/host/constants.c b/drivers/nvme/host/constants.c index dc90df9e13a2..f679efd5110e 100644 --- a/drivers/nvme/host/constants.c +++ b/drivers/nvme/host/constants.c @@ -46,6 +46,7 @@ static const char * const nvme_admin_ops[] =3D { [nvme_admin_virtual_mgmt] =3D "Virtual Management", [nvme_admin_nvme_mi_send] =3D "NVMe Send MI", [nvme_admin_nvme_mi_recv] =3D "NVMe Receive MI", + [nvme_admin_cross_ctrl_reset] =3D "Cross Controller Reset", [nvme_admin_dbbuf] =3D "Doorbell Buffer Config", [nvme_admin_format_nvm] =3D "Format NVM", [nvme_admin_security_send] =3D "Security Send", diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c index 1ef4dc38f755..a1deffc3cc00 100644 --- a/drivers/nvme/host/core.c +++ b/drivers/nvme/host/core.c @@ -571,6 +571,157 @@ void nvme_cancel_admin_tagset(struct nvme_ctrl *ctrl) } EXPORT_SYMBOL_GPL(nvme_cancel_admin_tagset); =20 +static struct nvme_ctrl *nvme_find_ctrl_ccr(struct nvme_ctrl *ictrl, + u32 min_cntlid) +{ + struct nvme_subsystem *subsys =3D ictrl->subsys; + struct nvme_ctrl *ctrl, *sctrl =3D NULL; + unsigned long flags; + int ccr_used; + + mutex_lock(&nvme_subsystems_lock); + list_for_each_entry(ctrl, &subsys->ctrls, subsys_entry) { + if (ctrl->cntlid < min_cntlid) + continue; + + spin_lock_irqsave(&ctrl->lock, flags); + if (nvme_ctrl_state(ctrl) !=3D NVME_CTRL_LIVE) { + spin_unlock_irqrestore(&ctrl->lock, flags); + continue; + } + + ccr_used =3D atomic_inc_return(&ctrl->ccr_used); + if (ccr_used > ctrl->ccrl) { + atomic_dec(&ctrl->ccr_used); + spin_unlock_irqrestore(&ctrl->lock, flags); + continue; + } + + /* + * We got a good candidate source controller that is locked and + * LIVE. However, no guarantee ctrl will not be deleted after + * ctrl->lock is released. Get a ref of both ctrl and admin_q + * so they do not disappear until we are done with them. + */ + WARN_ON_ONCE(!blk_get_queue(ctrl->admin_q)); + nvme_get_ctrl(ctrl); + spin_unlock_irqrestore(&ctrl->lock, flags); + sctrl =3D ctrl; + break; + } + mutex_unlock(&nvme_subsystems_lock); + return sctrl; +} + +static void nvme_put_ctrl_ccr(struct nvme_ctrl *sctrl) +{ + atomic_dec(&sctrl->ccr_used); + blk_put_queue(sctrl->admin_q); + nvme_put_ctrl(sctrl); +} + +static int nvme_issue_wait_ccr(struct nvme_ctrl *sctrl, struct nvme_ctrl *= ictrl, + unsigned long deadline) +{ + struct nvme_ccr_entry ccr =3D { }; + union nvme_result res =3D { 0 }; + struct nvme_command c =3D { }; + unsigned long flags, now, tmo =3D 0; + bool completed =3D false; + int ret =3D 0; + u32 result; + + init_completion(&ccr.complete); + ccr.ictrl =3D ictrl; + + spin_lock_irqsave(&sctrl->lock, flags); + list_add_tail(&ccr.list, &sctrl->ccr_list); + spin_unlock_irqrestore(&sctrl->lock, flags); + + c.ccr.opcode =3D nvme_admin_cross_ctrl_reset; + c.ccr.ciu =3D ictrl->ciu; + c.ccr.icid =3D cpu_to_le16(ictrl->cntlid); + c.ccr.cirn =3D cpu_to_le64(ictrl->cirn); + ret =3D __nvme_submit_sync_cmd(sctrl->admin_q, &c, &res, + NULL, 0, NVME_QID_ANY, 0); + if (ret) { + ret =3D -EIO; + goto out; + } + + result =3D le32_to_cpu(res.u32); + if (result & 0x01) /* Immediate Reset Successful */ + goto out; + + now =3D jiffies; + if (time_before(now, deadline)) + tmo =3D min_t(unsigned long, + secs_to_jiffies(ictrl->kato), deadline - now); + + if (!wait_for_completion_timeout(&ccr.complete, tmo)) { + ret =3D -ETIMEDOUT; + goto out; + } + + completed =3D true; + +out: + spin_lock_irqsave(&sctrl->lock, flags); + list_del(&ccr.list); + spin_unlock_irqrestore(&sctrl->lock, flags); + if (completed) { + if (ccr.ccrs =3D=3D NVME_CCR_STATUS_SUCCESS) + return 0; + return -EREMOTEIO; + } + return ret; +} + +unsigned long nvme_fence_ctrl(struct nvme_ctrl *ictrl) +{ + unsigned long now, deadline, timeout; + struct nvme_ctrl *sctrl; + u32 min_cntlid =3D 0; + int ret; + + timeout =3D nvme_fence_timeout_ms(ictrl); + dev_info(ictrl->device, "attempting CCR, timeout %lums\n", timeout); + + now =3D jiffies; + deadline =3D jiffies + msecs_to_jiffies(timeout); + while (time_before(now, deadline)) { + sctrl =3D nvme_find_ctrl_ccr(ictrl, min_cntlid); + if (!sctrl) { + dev_dbg(ictrl->device, + "failed to find source controller\n"); + return deadline - now; + } + + ret =3D nvme_issue_wait_ccr(sctrl, ictrl, deadline); + if (!ret) { + dev_info(ictrl->device, "CCR succeeded using %s\n", + dev_name(sctrl->device)); + nvme_put_ctrl_ccr(sctrl); + return 0; + } + + /* + * CCR command or CCR operation failed on this path. + * Try another path as long as we have time. + */ + dev_err(ictrl->device, "CCR failed using %s, ret =3D %d\n", + dev_name(sctrl->device), ret); + min_cntlid =3D sctrl->cntlid + 1; + nvme_put_ctrl_ccr(sctrl); + now =3D jiffies; + } + + /* Fencing timed out call it done */ + dev_info(ictrl->device, "fencing timeout\n"); + return 0; +} +EXPORT_SYMBOL_GPL(nvme_fence_ctrl); + bool nvme_change_ctrl_state(struct nvme_ctrl *ctrl, enum nvme_ctrl_state new_state) { @@ -5205,6 +5356,7 @@ int nvme_init_ctrl(struct nvme_ctrl *ctrl, struct dev= ice *dev, =20 mutex_init(&ctrl->scan_lock); INIT_LIST_HEAD(&ctrl->namespaces); + INIT_LIST_HEAD(&ctrl->ccr_list); xa_init(&ctrl->cels); ctrl->dev =3D dev; ctrl->ops =3D ops; diff --git a/drivers/nvme/host/nvme.h b/drivers/nvme/host/nvme.h index e558a19781bd..90b989302e21 100644 --- a/drivers/nvme/host/nvme.h +++ b/drivers/nvme/host/nvme.h @@ -333,6 +333,13 @@ enum nvme_ctrl_flags { NVME_CTRL_FROZEN =3D 6, }; =20 +struct nvme_ccr_entry { + struct list_head list; + struct completion complete; + struct nvme_ctrl *ictrl; + u8 ccrs; +}; + struct nvme_ctrl { bool comp_seen; bool identified; @@ -350,6 +357,7 @@ struct nvme_ctrl { struct blk_mq_tag_set *tagset; struct blk_mq_tag_set *admin_tagset; struct list_head namespaces; + struct list_head ccr_list; struct mutex namespaces_lock; struct srcu_struct srcu; struct device ctrl_device; @@ -393,6 +401,7 @@ struct nvme_ctrl { u16 sqsize; u32 max_namespaces; atomic_t abort_limit; + atomic_t ccr_used; u8 ccrl; u8 vwc; u32 vs; @@ -887,6 +896,7 @@ blk_status_t nvme_host_path_error(struct request *req); bool nvme_cancel_request(struct request *req, void *data); void nvme_cancel_tagset(struct nvme_ctrl *ctrl); void nvme_cancel_admin_tagset(struct nvme_ctrl *ctrl); +unsigned long nvme_fence_ctrl(struct nvme_ctrl *ctrl); bool nvme_change_ctrl_state(struct nvme_ctrl *ctrl, enum nvme_ctrl_state new_state); int nvme_disable_ctrl(struct nvme_ctrl *ctrl, bool shutdown); --=20 2.54.0 From nobody Sat Jul 25 23:03:45 2026 Received: from mail-pg1-f181.google.com (mail-pg1-f181.google.com [209.85.215.181]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id CD10236894D for ; Sun, 12 Jul 2026 02:25:32 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.215.181 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1783823136; cv=none; b=Uz5H01c0cBijC1yOsZvlVGXKeLbEfYSsuhbufIzUu9w5kBCtH0HuB3iTisA0kB9y0lo/GLCU9R1ShUt5pIf6xTpHmqmUPJ0/qWzBZ/qOsUEIzxlTHWVAjf1CBhsG7h+gKL06lHzI2aW0Y3LBgl7Yh/VIk1IsPJPi37JZdp/NcaQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1783823136; c=relaxed/simple; bh=Uv2r2XntEQARra70I9Rs7oJUanJSxq+RbDgflNeuqQw=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=jS2Z/NLiyqeC08dDmr+dVp1YZSwjEk2YPJPoJpwDDEjg4Xyy19KHrKQyC76mqgyXY1mGqYHtT7/DLDM/FYEeIEBjTsCdTd945rpc0LQcxzRiXW/NGj9x3l/Vxw2cDmfDYyJ5aRsVay3tkII7sYd1QrGowB4DlUngLRzLe38Zbcc= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=purestorage.com; spf=pass smtp.mailfrom=purestorage.com; dkim=pass (2048-bit key) header.d=purestorage.com header.i=@purestorage.com header.b=bNckmLvW; arc=none smtp.client-ip=209.85.215.181 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=purestorage.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=purestorage.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=purestorage.com header.i=@purestorage.com header.b="bNckmLvW" Received: by mail-pg1-f181.google.com with SMTP id 41be03b00d2f7-ca12086c06eso1753155a12.0 for ; Sat, 11 Jul 2026 19:25:32 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=purestorage.com; s=google2022; t=1783823132; x=1784427932; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=2svGMIPbamdfrr6utGGIH21OI5vt/Yz4GZPo9S8rv5I=; b=bNckmLvWOwS3AU0UaQavh1fk3BjB9B7e/Z7tBYz2J3rnj28OlnopPEvY9MHEQYoNcT J0knOppPYeah/lgKplx+rT904xBAobM5nOiPIi1XCqvSRhtzcvlLqkWXGxQpkRAeP25u Vs81YGD+5VjBkuFeweHIEMmQ/f60/DMULnWs87uEa7eKC1K3ICbNx4j4oNuv+9FLnL5L MIw2RoHxmMlVcjdIFvJO/OFyKy2i9e6odu1X4LkqLlilKj/vMgeAGaJe0vcrn62y4fyU yU4LD53IG+uadcf6i1pvCo/dlsZsIL/Qr5eY9n2bXZSvpVIsY0ukXX/+aUlvHdax5qY4 sfeA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1783823132; x=1784427932; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to:content-type; bh=2svGMIPbamdfrr6utGGIH21OI5vt/Yz4GZPo9S8rv5I=; b=ld8Q9sXZMQAAeTxLslpKhaUrPe3Xb8xVmb7YjSvxjqTCgzrux3vWthLFNAcTUfhzWY U8c0x1Bb+tkua28EIaF00ZnYPeAupa8dGDyWuxVwncHtZngvWqPKgMxTZlYTFzYD6u23 hPk62rg/RW0ojXE6/Ug5s5H+EG5zlj51L+cfZj0yDD54wQVvCkErScBLckcVBWo4YV5R BkDJ2zWAFH8DBqqSgD5b7mS3mCwpi3zfP2rSNuj1ILCzdSEADu9CPvu9lTaWLQexhAAX lIEvl8sW55Y6ucMjsDDQBuHADryFH5/wcVvpX4xyfhSp4/ls6hoRSOXKey2WinQEVTkp kTVQ== X-Forwarded-Encrypted: i=1; AHgh+Rr/S47upIWWIqvJ9EoP1E5tQStjrK+94iTDbjRUuZy6KsEyyow8X6dDG7kdmEzJ7/W/OXbsXYAgh0aPLqQ=@vger.kernel.org X-Gm-Message-State: AOJu0Yz5rABapA0f1NK2t2eH9PGposZ5mG6h3cD58wNyABgdQMqQIuzT QcNr/A85coW/mbgYl0wk21i5iSJPSv3vXFkU84uzHNU6Be89e1Udau3rLcz3STatcH4= X-Gm-Gg: AfdE7ckjMwofhr73akERcnjZr2ibdZQjumgwSiCCtjIfHLwXGDs4PAgWf8XOdbx7Pi9 3kfMAXUO+GBer/bJPsBh8iA/hvTdB3qVlJegcR3sraaTDzD73xxqa5HFAiuq0kHHxbqep3iiylT 7Q2Re9mzwPBUOWTeil7mO4GnwNRfugEMNWe/xJbUpbTrO+hEn34LzL5Cxf7lcWvenMMz3wbpTXo yWUF1z13R8oRnx20+rV5V+FC7DFcJosx5vZFF+i08UpwJP4+mQZwG1LpTMj697kkomA8GOPWaLO yHGO3dEMO23KvWCv3A5u+sx9arXdmbLHUK+pOq6Ybht9hfG3rDAFC8M2l+Xs/AEmQpGUoTJVaJ3 bY+ia7X7t5st3s22hRYFDjTao8TZrD0n/OQbyfBH5BTc6vTeFHI0PR9oJzpcvm1Lw4N7OaacckC M0ZeMp X-Received: by 2002:a05:6a21:d83:b0:3bf:6c08:fb97 with SMTP id adf61e73a8af0-3c110a1b5b6mr4347640637.57.1783823132125; Sat, 11 Jul 2026 19:25:32 -0700 (PDT) Received: from ceto.lan ([2607:fb90:9c20:2264::1c31]) by smtp.googlemail.com with ESMTPSA id 5a478bee46e88-3117462f5c7sm60704693eec.0.2026.07.11.19.25.30 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 11 Jul 2026 19:25:31 -0700 (PDT) From: Mohamed Khalfella To: Justin Tee , Naresh Gottumukkala , Paul Ely , Chaitanya Kulkarni , Christoph Hellwig , Jens Axboe , Keith Busch , Sagi Grimberg , James Smart , Hannes Reinecke , Randy Jennings , Dhaval Giani Cc: Aaron Dailey , linux-nvme@lists.infradead.org, linux-kernel@vger.kernel.org, Mohamed Khalfella Subject: [PATCH v5 09/16] nvme: Implement cross-controller reset completion Date: Sat, 11 Jul 2026 19:23:30 -0700 Message-ID: <20260712022437.3743117-10-mkhalfella@purestorage.com> X-Mailer: git-send-email 2.54.0 In-Reply-To: <20260712022437.3743117-1-mkhalfella@purestorage.com> References: <20260712022437.3743117-1-mkhalfella@purestorage.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 Content-Type: text/plain; charset="utf-8" An nvme source controller that issues CCR command expects to receive an NVME_AER_NOTICE_CCR_COMPLETED when pending CCR succeeds or fails. Add ctrl->ccr_work to read NVME_LOG_CCR logpage and wakeup threads waiting on CCR completion. Signed-off-by: Mohamed Khalfella --- drivers/nvme/host/core.c | 50 +++++++++++++++++++++++++++++++++++++++- drivers/nvme/host/nvme.h | 1 + 2 files changed, 50 insertions(+), 1 deletion(-) diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c index a1deffc3cc00..18de3805eff8 100644 --- a/drivers/nvme/host/core.c +++ b/drivers/nvme/host/core.c @@ -1943,7 +1943,8 @@ EXPORT_SYMBOL_GPL(nvme_set_queue_count); =20 #define NVME_AEN_SUPPORTED \ (NVME_AEN_CFG_NS_ATTR | NVME_AEN_CFG_FW_ACT | \ - NVME_AEN_CFG_ANA_CHANGE | NVME_AEN_CFG_DISC_CHANGE) + NVME_AEN_CFG_ANA_CHANGE | NVME_AEN_CFG_CCR_COMPLETE | \ + NVME_AEN_CFG_DISC_CHANGE) =20 static void nvme_enable_aen(struct nvme_ctrl *ctrl) { @@ -4974,6 +4975,48 @@ static void nvme_get_fw_slot_info(struct nvme_ctrl *= ctrl) kfree(log); } =20 +static void nvme_ccr_work(struct work_struct *work) +{ + struct nvme_ctrl *ctrl =3D container_of(work, struct nvme_ctrl, ccr_work); + struct nvme_ccr_entry *ccr; + struct nvme_ccr_log_entry *entry; + struct nvme_ccr_log *log; + int num_entries, ret, i; + unsigned long flags; + + log =3D kmalloc_obj(*log); + if (!log) + return; + + ret =3D nvme_get_log(ctrl, 0, NVME_LOG_CCR, 0x01, + 0x00, log, sizeof(*log), 0); + if (ret) + goto out; + + spin_lock_irqsave(&ctrl->lock, flags); + num_entries =3D min(le16_to_cpu(log->ne), NVMF_CCR_PER_PAGE); + for (i =3D 0; i < num_entries; i++) { + entry =3D &log->entries[i]; + if (entry->ccrs =3D=3D NVME_CCR_STATUS_IN_PROGRESS) + continue; + + list_for_each_entry(ccr, &ctrl->ccr_list, list) { + struct nvme_ctrl *ictrl =3D ccr->ictrl; + + if (ictrl->cntlid !=3D le16_to_cpu(entry->icid) || + ictrl->ciu !=3D entry->ciu) + continue; + + /* Complete matching entry */ + ccr->ccrs =3D entry->ccrs; + complete(&ccr->complete); + } + } + spin_unlock_irqrestore(&ctrl->lock, flags); +out: + kfree(log); +} + static void nvme_fw_act_work(struct work_struct *work) { struct nvme_ctrl *ctrl =3D container_of(work, @@ -5050,6 +5093,9 @@ static bool nvme_handle_aen_notice(struct nvme_ctrl *= ctrl, u32 result) case NVME_AER_NOTICE_DISC_CHANGED: ctrl->aen_result =3D result; break; + case NVME_AER_NOTICE_CCR_COMPLETED: + queue_work(nvme_wq, &ctrl->ccr_work); + break; default: dev_warn(ctrl->device, "async event result %08x\n", result); } @@ -5238,6 +5284,7 @@ void nvme_stop_ctrl(struct nvme_ctrl *ctrl) nvme_stop_failfast_work(ctrl); flush_work(&ctrl->async_event_work); cancel_work_sync(&ctrl->fw_act_work); + cancel_work_sync(&ctrl->ccr_work); if (ctrl->ops->stop_ctrl) ctrl->ops->stop_ctrl(ctrl); } @@ -5363,6 +5410,7 @@ int nvme_init_ctrl(struct nvme_ctrl *ctrl, struct dev= ice *dev, ctrl->quirks =3D quirks; ctrl->numa_node =3D NUMA_NO_NODE; INIT_WORK(&ctrl->scan_work, nvme_scan_work); + INIT_WORK(&ctrl->ccr_work, nvme_ccr_work); INIT_WORK(&ctrl->async_event_work, nvme_async_event_work); INIT_WORK(&ctrl->fw_act_work, nvme_fw_act_work); INIT_WORK(&ctrl->delete_work, nvme_delete_ctrl_work); diff --git a/drivers/nvme/host/nvme.h b/drivers/nvme/host/nvme.h index 90b989302e21..578fedda9946 100644 --- a/drivers/nvme/host/nvme.h +++ b/drivers/nvme/host/nvme.h @@ -422,6 +422,7 @@ struct nvme_ctrl { struct nvme_effects_log *effects; struct xarray cels; struct work_struct scan_work; + struct work_struct ccr_work; struct work_struct async_event_work; struct delayed_work ka_work; struct delayed_work failfast_work; --=20 2.54.0 From nobody Sat Jul 25 23:03:45 2026 Received: from mail-pf1-f171.google.com (mail-pf1-f171.google.com [209.85.210.171]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 0A1F5367B99 for ; Sun, 12 Jul 2026 02:25:34 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.210.171 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1783823136; cv=none; b=Ei9PwNskxpvccd8eazmbZ5YmIjm78K/NgbB8Sq6vSftOWQDWb3S05aO3fn1GvYU2QHfrE/5j5TxinUUYkEa0xTCzzszHusUXvMZ/7h16CKuZ2+HcIHNhV7bIcKKkIGbZM8TXfmfsN2mEaHffyqt01YLEtwPkhb5xODWqiPGoYsc= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1783823136; c=relaxed/simple; bh=M4LDxvt3lbvbG89lj2/hr8mEoWuZXp+mwrSyHMc6V5k=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=To/ezntEjXJO/KSqB3m/ILs415Rwf8OreB/ddhnyeAZjfUzNYmcgv/QmMc+AReuFrtE8YJkDxd6dp9IlYUp41KQNKf5fnHj0BR5PnLzOroNEDxv4JxvLwqgdWIAsmGwIE+AQon6Oa0bqSEBpaUx97tBUyAosGOhPtopEw4iNmp8= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=purestorage.com; spf=pass smtp.mailfrom=purestorage.com; dkim=pass (2048-bit key) header.d=purestorage.com header.i=@purestorage.com header.b=QS2q+xTz; arc=none smtp.client-ip=209.85.210.171 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=purestorage.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=purestorage.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=purestorage.com header.i=@purestorage.com header.b="QS2q+xTz" Received: by mail-pf1-f171.google.com with SMTP id d2e1a72fcca58-848882fdb18so1157405b3a.0 for ; Sat, 11 Jul 2026 19:25:34 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=purestorage.com; s=google2022; t=1783823134; x=1784427934; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=g9uaSQKgRYycyhIZh4YO2D7JgllBA2edWOd9mXDhcfM=; b=QS2q+xTzuswuoa31MEDg3O6/wzD5ZfYFGkuFclDVysdnsPcFvGrdHwy3SZjNgrAIso v1BoVbMWcW4ch3z9eaJYtd+7Nq9x+14xMlhQ2NKU+H8SlWnSk9Fi6sFsd3Sh+mcnh78B McTPjEQ+lVF7qcyT72wZPaO2XwPAV9Fhyx7KKV3Bk4SGIa1hkJb/YJVtHWkbJEDrDJOZ pQ2mEvg0ftQ7OL3oA2Wu2YeMr9XlTEaBzgmdvCS3rOrkAGEYoKwzhu7WwgpvHCykbQ7L 1lxVhDq6L+9zv+jKJC0umcR+AFyZ1NUC7ClMSpZ/fz1FCq0VMm6f503Hcw5xB3tiv8EL Aogg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1783823134; x=1784427934; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to:content-type; bh=g9uaSQKgRYycyhIZh4YO2D7JgllBA2edWOd9mXDhcfM=; b=FYRkbQM3+9h1s8HYzJG9EJihp0Fen6zH3l3sBM2KwdEscK56qwuyBzYImbjkJli1av 1QBaJqs8dWNOa6PrJlaHACEU5UF4Jx6Ej8VSRcXic9kR2cSMVM5UrL7IrZj248aa3hPF hxTvm1E8mvFQR1bNHvyE4V7pIaqZ+FiK3Rqhik/hEG88P0hAm6ZiHzKk3kfUvVf8In3W uvK1EbrjMMo/h346oWh0CWJ29IbVsB9enFKwx45ECifHbv0dZv8EGSxgTgB29S5GnGP8 UgxowY9o76Zu7XUoJmuC2ItfDoEzRnVtuF2PSrWXlP6KG0ABYi596+YPsr7FXOJFVK2+ Pb3g== X-Forwarded-Encrypted: i=1; AHgh+RoEsO1Pa+AUff2lzQLK0aawfXpwUV4YAIux1h2XHg4C4yoWfJadBMphkKdoVXarNcxbTo7NQvlimosdtzw=@vger.kernel.org X-Gm-Message-State: AOJu0YzIemNuaDgSU4MfwJPJYHYIRPC2Ow6KtOaCnHE34Yz+eY6x4oAJ MPgQRVewlZ+VOiCw829qQKJeK8MaFcB3l/3OA6sMSucbip0D1uXvsxklwW7E0zLMFJU= X-Gm-Gg: AfdE7cmsyRgv4YVSxtJPAbubuvH1X+gePaPuQieDXvMh5cygxp1Eq68nEF2L5fzE04M zfNNhkZvnucoL7JehHMs+I14CyuL+odGMpzvkC8DeLZ4Zw/LGYsNtL4TorqZUiTZrpWqR0SVC7t lscYRNxPuQwycStyf/39kF/cZGv2zP7IDSpseQBO47/aWaIib+DZ4qIGvggT1uyIC94mjHc7ujX n0eJVrdZtb/bgNiPF31ZAJq2RsszRKaef1f01JC3lXOHuBJqdVDZBtai0X/1STyHlNfbPAN2ZT5 Jo5FqzNhsOhhOVi6Gi/fTSHiQhVbCwW2JCQE7TmDF/KZoUx/kybDhVq+4QOjg6bqrYUWShbNig5 pPddIr7liDPOYj58aDhtKMmepINOjjTWNg5V00ywD1Cnd4cGW7hq6GmCPSV/c5mdjDl5PmmFnY6 DP29rtj3QDP36940U= X-Received: by 2002:a05:6a21:6f12:b0:3bb:21ad:40d8 with SMTP id adf61e73a8af0-3c1108c79c7mr4770482637.39.1783823134207; Sat, 11 Jul 2026 19:25:34 -0700 (PDT) Received: from ceto.lan ([2607:fb90:9c20:2264::1c31]) by smtp.googlemail.com with ESMTPSA id 5a478bee46e88-3117462f5c7sm60704693eec.0.2026.07.11.19.25.32 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 11 Jul 2026 19:25:33 -0700 (PDT) From: Mohamed Khalfella To: Justin Tee , Naresh Gottumukkala , Paul Ely , Chaitanya Kulkarni , Christoph Hellwig , Jens Axboe , Keith Busch , Sagi Grimberg , James Smart , Hannes Reinecke , Randy Jennings , Dhaval Giani Cc: Aaron Dailey , linux-nvme@lists.infradead.org, linux-kernel@vger.kernel.org, Mohamed Khalfella Subject: [PATCH v5 10/16] nvme-tcp: Use CCR to recover controller that hits an error Date: Sat, 11 Jul 2026 19:23:31 -0700 Message-ID: <20260712022437.3743117-11-mkhalfella@purestorage.com> X-Mailer: git-send-email 2.54.0 In-Reply-To: <20260712022437.3743117-1-mkhalfella@purestorage.com> References: <20260712022437.3743117-1-mkhalfella@purestorage.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 Content-Type: text/plain; charset="utf-8" An alive nvme controller that hits an error now will move to FENCING state instead of RESETTING state. ctrl->fencing_work attempts CCR to terminate inflight IOs. Regardless of the success or failure of CCR operation the controller is transitioned to RESETTING state to continue error recovery process. Signed-off-by: Mohamed Khalfella --- drivers/nvme/host/tcp.c | 30 +++++++++++++++++++++++++++++- 1 file changed, 29 insertions(+), 1 deletion(-) diff --git a/drivers/nvme/host/tcp.c b/drivers/nvme/host/tcp.c index ba5c7b3e2a7c..a1711dd1d3c2 100644 --- a/drivers/nvme/host/tcp.c +++ b/drivers/nvme/host/tcp.c @@ -161,6 +161,7 @@ struct nvme_tcp_ctrl { struct sockaddr_storage src_addr; struct nvme_ctrl ctrl; =20 + struct work_struct fencing_work; struct work_struct err_work; struct delayed_work connect_work; struct nvme_tcp_request async_req; @@ -605,6 +606,12 @@ static void nvme_tcp_init_recv_ctx(struct nvme_tcp_que= ue *queue) =20 static void nvme_tcp_error_recovery(struct nvme_ctrl *ctrl) { + if (nvme_change_ctrl_state(ctrl, NVME_CTRL_FENCING)) { + dev_warn(ctrl->device, "starting controller fencing\n"); + queue_work(nvme_wq, &to_tcp_ctrl(ctrl)->fencing_work); + return; + } + if (!nvme_change_ctrl_state(ctrl, NVME_CTRL_RESETTING)) return; =20 @@ -2494,12 +2501,29 @@ static void nvme_tcp_reconnect_ctrl_work(struct wor= k_struct *work) nvme_tcp_reconnect_or_remove(ctrl, ret); } =20 +static void nvme_tcp_fencing_work(struct work_struct *work) +{ + struct nvme_tcp_ctrl *tcp_ctrl =3D container_of(work, + struct nvme_tcp_ctrl, fencing_work); + struct nvme_ctrl *ctrl =3D &tcp_ctrl->ctrl; + unsigned long rem; + + rem =3D nvme_fence_ctrl(ctrl); + if (rem) + dev_info(ctrl->device, "CCR failed, starting error recovery\n"); + + nvme_change_ctrl_state(ctrl, NVME_CTRL_FENCED); + if (nvme_change_ctrl_state(ctrl, NVME_CTRL_RESETTING)) + queue_work(nvme_reset_wq, &tcp_ctrl->err_work); +} + static void nvme_tcp_error_recovery_work(struct work_struct *work) { struct nvme_tcp_ctrl *tcp_ctrl =3D container_of(work, struct nvme_tcp_ctrl, err_work); struct nvme_ctrl *ctrl =3D &tcp_ctrl->ctrl; =20 + flush_work(&to_tcp_ctrl(ctrl)->fencing_work); if (nvme_tcp_key_revoke_needed(ctrl)) nvme_auth_revoke_tls_key(ctrl); nvme_stop_keep_alive(ctrl); @@ -2542,6 +2566,7 @@ static void nvme_reset_ctrl_work(struct work_struct *= work) container_of(work, struct nvme_ctrl, reset_work); int ret; =20 + flush_work(&to_tcp_ctrl(ctrl)->fencing_work); if (nvme_tcp_key_revoke_needed(ctrl)) nvme_auth_revoke_tls_key(ctrl); nvme_stop_ctrl(ctrl); @@ -2667,13 +2692,15 @@ static enum blk_eh_timer_return nvme_tcp_timeout(st= ruct request *rq) struct nvme_tcp_cmd_pdu *pdu =3D nvme_tcp_req_cmd_pdu(req); struct nvme_command *cmd =3D &pdu->cmd; int qid =3D nvme_tcp_queue_id(req->queue); + enum nvme_ctrl_state state; =20 dev_warn(ctrl->device, "I/O tag %d (%04x) type %d opcode %#x (%s) QID %d timeout\n", rq->tag, nvme_cid(rq), pdu->hdr.type, cmd->common.opcode, nvme_fabrics_opcode_str(qid, cmd), qid); =20 - if (nvme_ctrl_state(ctrl) !=3D NVME_CTRL_LIVE) { + state =3D nvme_ctrl_state(ctrl); + if (state !=3D NVME_CTRL_LIVE && state !=3D NVME_CTRL_FENCING) { /* * If we are resetting, connecting or deleting we should * complete immediately because we may block controller @@ -2928,6 +2955,7 @@ static struct nvme_tcp_ctrl *nvme_tcp_alloc_ctrl(stru= ct device *dev, =20 INIT_DELAYED_WORK(&ctrl->connect_work, nvme_tcp_reconnect_ctrl_work); + INIT_WORK(&ctrl->fencing_work, nvme_tcp_fencing_work); INIT_WORK(&ctrl->err_work, nvme_tcp_error_recovery_work); INIT_WORK(&ctrl->ctrl.reset_work, nvme_reset_ctrl_work); =20 --=20 2.54.0 From nobody Sat Jul 25 23:03:45 2026 Received: from mail-pj1-f47.google.com (mail-pj1-f47.google.com [209.85.216.47]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id AE93636826E for ; Sun, 12 Jul 2026 02:25:36 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.216.47 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1783823138; cv=none; b=eP9Em2Ptyf0bur2s7zHjMuorSaPqDtpOrwTVLdECPQIdhcsmdDaAdGz16J+AC3bjf8JHvgAreNsC3ZaMgADnie3jR6yj3CekAB2LDLsv69e2ZTWyUnKBbEOdxnM0LTDIk8PAcLSQ7DeBj0p1T/RRLUdkVihTun2SircpYab0x08= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1783823138; c=relaxed/simple; bh=TO+ylZNkfWqNxxUrT07xoPKSkmWQo4gW9pLhAf7bPAc=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=qEV4fJp8CTZruff+Dpf2RoGVuJDB52MRWe18YyDnSPCUCDZvwBOFkY55Xr68LEAwFfdmUkzPMO+DhXKMoWWpINLT4s7NMZ8/MVS9fLMAsM9cCB21FUf9lyZ7E4kWviwNwKPp6QEwuX8WLORHJkdtkcRGRnF1z3uMqkOPxm4dw10= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=purestorage.com; spf=pass smtp.mailfrom=purestorage.com; dkim=pass (2048-bit key) header.d=purestorage.com header.i=@purestorage.com header.b=Q3nP3oC8; arc=none smtp.client-ip=209.85.216.47 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=purestorage.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=purestorage.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=purestorage.com header.i=@purestorage.com header.b="Q3nP3oC8" Received: by mail-pj1-f47.google.com with SMTP id 98e67ed59e1d1-381c51fde6bso2049690a91.2 for ; Sat, 11 Jul 2026 19:25:36 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=purestorage.com; s=google2022; t=1783823136; x=1784427936; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=N4ikmBr5mw7p6ycSVAdXvIpwXhHnLZzoeuY1Qg3gT2Y=; b=Q3nP3oC8UiC+Tg+etHcdxJBk0EV8snY/EsjKgxEs0EX2V0FTlZB+GFicYjDrB9+vzU aTHWeKnkJ34c7eEKVijPWnEwIbgjzf7wO7F5yQt59WZG86dqyKhUfPpmkihR/F+rBzTQ q4WvNIE0ALhyv2IC2xT/PzEGicUBvW1RgNrRztouHz/ojK78dAuR/PJ3TRCiYY2itcBf Zt3SC/4bRFrk6UouHvK0822BP7klov1M74yCbr7OyacgG4kLo9NoWPpMfzF+vRWHK4+b BURrUf0BWrYoALtJoxt9G2Lis7uykHyUPaAWzXuzppETzocuQpGijVlBTYOTrrgks0/p HEJA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1783823136; x=1784427936; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to:content-type; bh=N4ikmBr5mw7p6ycSVAdXvIpwXhHnLZzoeuY1Qg3gT2Y=; b=BPJM5p7VzK2Riv6DqM4Qmgj+0octpjL7kIS12ravTWKmhSIGQIEALcKeCYwNDWzLPo pAYx0IhzNY3f3gx3thKEWvVG3DRr6NipINrl2RCsF2YO5m8+R4FVg5ZKucpHT8JOIDuE 142Z1qkdBVO6YNMXNnxCh69Sdc2X3xjpkX2XuNdQifxhT8GQMWYmlXHvxIQSh9mGt+Q4 +uEAryNnVFbhtwII24RmlseS+0eXo7o92ebgz4vq3rtRulbw9rgjls7OumRhEwGS2MJg 0Y9MhKEU1jknj/P4kjuldar5ZtIkj1szFwnIXetDruDnu/dsZB6i1ndpw0+mAz2q4s51 fcfw== X-Forwarded-Encrypted: i=1; AHgh+RrK4QL3YUxK0j4VVKTCcdHxlsTpO3C4NcEm5KT7+vU2GPAU0vdtOHeo09/53UpyiJqI81X80zBMEW3u6lQ=@vger.kernel.org X-Gm-Message-State: AOJu0YxohQpuPuXeo1Fhpj3EdBv1USeRzmWVRh2DTh2Y5gzYAdke/L/W U5oz+VhggkZwVU86bk/EGgMOH+VnNsyODSR1Z3A0m0PE60C78E39ZWxpzerce7b1lCQ= X-Gm-Gg: AfdE7cm0E9DLxDeTmKa9iEEP810KIRGU0VdkHRD6ui1ww8SYHObsBkLNYr+AwUlopYg cLjGG4pS9ZMSIntkpr3+TYvpWPmKIcH/dwk1fn93V2sPjgkQYWW9y/EvmCdFZSz09UrWiagkogk YhQmFgAMJU5FHSfFVCcx/Lv+785P01iPIZTwe4SuXVgW3wQw6mxZpot294ItKoOMumpO1kiqvfP DPGZP+O58fjFNONXmTm3FYhUF6QBmEZ+IO31PeWL/sXx0X143aV09t7whFB+PX7glyNHOA5D33Z J+w5Vokt1/q7LwY2iCCd7i3oDUZiroLJ5IJRpUs+FKswQKgaBvuw/f2q7LkrhBxPDiCiv0X7/2y WmOu3l/GDa8a92gtsiOJE5F/sw4jTxrrGe6KNXOeR764N9eJMkZfGD9b1qo/V8XmxRKq9oPhGHT 79eTBHcCm+MDFUiGc= X-Received: by 2002:a17:90b:4a4e:b0:36d:b9c5:e8f6 with SMTP id 98e67ed59e1d1-38dc75ee9cfmr3966096a91.19.1783823135994; Sat, 11 Jul 2026 19:25:35 -0700 (PDT) Received: from ceto.lan ([2607:fb90:9c20:2264::1c31]) by smtp.googlemail.com with ESMTPSA id 5a478bee46e88-3117462f5c7sm60704693eec.0.2026.07.11.19.25.34 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 11 Jul 2026 19:25:35 -0700 (PDT) From: Mohamed Khalfella To: Justin Tee , Naresh Gottumukkala , Paul Ely , Chaitanya Kulkarni , Christoph Hellwig , Jens Axboe , Keith Busch , Sagi Grimberg , James Smart , Hannes Reinecke , Randy Jennings , Dhaval Giani Cc: Aaron Dailey , linux-nvme@lists.infradead.org, linux-kernel@vger.kernel.org, Mohamed Khalfella Subject: [PATCH v5 11/16] nvme-rdma: Use CCR to recover controller that hits an error Date: Sat, 11 Jul 2026 19:23:32 -0700 Message-ID: <20260712022437.3743117-12-mkhalfella@purestorage.com> X-Mailer: git-send-email 2.54.0 In-Reply-To: <20260712022437.3743117-1-mkhalfella@purestorage.com> References: <20260712022437.3743117-1-mkhalfella@purestorage.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 Content-Type: text/plain; charset="utf-8" An alive nvme controller that hits an error now will move to FENCING state instead of RESETTING state. ctrl->fencing_work attempts CCR to terminate inflight IOs. Regardless of the success or failure of CCR operation the controller is transitioned to RESETTING state to continue error recovery process. Signed-off-by: Mohamed Khalfella --- drivers/nvme/host/rdma.c | 30 +++++++++++++++++++++++++++++- 1 file changed, 29 insertions(+), 1 deletion(-) diff --git a/drivers/nvme/host/rdma.c b/drivers/nvme/host/rdma.c index 52933d11ea03..7c8108523980 100644 --- a/drivers/nvme/host/rdma.c +++ b/drivers/nvme/host/rdma.c @@ -112,6 +112,7 @@ struct nvme_rdma_ctrl { =20 /* other member variables */ struct blk_mq_tag_set tag_set; + struct work_struct fencing_work; struct work_struct err_work; =20 struct nvme_rdma_qe async_event_sqe; @@ -1151,11 +1152,28 @@ static void nvme_rdma_reconnect_ctrl_work(struct wo= rk_struct *work) nvme_rdma_reconnect_or_remove(ctrl, ret); } =20 +static void nvme_rdma_fencing_work(struct work_struct *work) +{ + struct nvme_rdma_ctrl *rdma_ctrl =3D container_of(work, + struct nvme_rdma_ctrl, fencing_work); + struct nvme_ctrl *ctrl =3D &rdma_ctrl->ctrl; + unsigned long rem; + + rem =3D nvme_fence_ctrl(ctrl); + if (rem) + dev_info(ctrl->device, "CCR failed, starting error recovery\n"); + + nvme_change_ctrl_state(ctrl, NVME_CTRL_FENCED); + if (nvme_change_ctrl_state(ctrl, NVME_CTRL_RESETTING)) + queue_work(nvme_reset_wq, &rdma_ctrl->err_work); +} + static void nvme_rdma_error_recovery_work(struct work_struct *work) { struct nvme_rdma_ctrl *ctrl =3D container_of(work, struct nvme_rdma_ctrl, err_work); =20 + flush_work(&ctrl->fencing_work); nvme_stop_keep_alive(&ctrl->ctrl); flush_work(&ctrl->ctrl.async_event_work); nvme_rdma_teardown_io_queues(ctrl, false); @@ -1178,6 +1196,12 @@ static void nvme_rdma_error_recovery_work(struct wor= k_struct *work) =20 static void nvme_rdma_error_recovery(struct nvme_rdma_ctrl *ctrl) { + if (nvme_change_ctrl_state(&ctrl->ctrl, NVME_CTRL_FENCING)) { + dev_warn(ctrl->ctrl.device, "starting controller fencing\n"); + queue_work(nvme_wq, &ctrl->fencing_work); + return; + } + if (!nvme_change_ctrl_state(&ctrl->ctrl, NVME_CTRL_RESETTING)) return; =20 @@ -1988,13 +2012,15 @@ static enum blk_eh_timer_return nvme_rdma_timeout(s= truct request *rq) struct nvme_rdma_ctrl *ctrl =3D queue->ctrl; struct nvme_command *cmd =3D req->req.cmd; int qid =3D nvme_rdma_queue_idx(queue); + enum nvme_ctrl_state state; =20 dev_warn(ctrl->ctrl.device, "I/O tag %d (%04x) opcode %#x (%s) QID %d timeout\n", rq->tag, nvme_cid(rq), cmd->common.opcode, nvme_fabrics_opcode_str(qid, cmd), qid); =20 - if (nvme_ctrl_state(&ctrl->ctrl) !=3D NVME_CTRL_LIVE) { + state =3D nvme_ctrl_state(&ctrl->ctrl); + if (state !=3D NVME_CTRL_LIVE && state !=3D NVME_CTRL_FENCING) { /* * If we are resetting, connecting or deleting we should * complete immediately because we may block controller @@ -2200,6 +2226,7 @@ static void nvme_rdma_reset_ctrl_work(struct work_str= uct *work) container_of(work, struct nvme_rdma_ctrl, ctrl.reset_work); int ret; =20 + flush_work(&ctrl->fencing_work); nvme_stop_ctrl(&ctrl->ctrl); nvme_rdma_shutdown_ctrl(ctrl, false); =20 @@ -2320,6 +2347,7 @@ static struct nvme_rdma_ctrl *nvme_rdma_alloc_ctrl(st= ruct device *dev, =20 INIT_DELAYED_WORK(&ctrl->reconnect_work, nvme_rdma_reconnect_ctrl_work); + INIT_WORK(&ctrl->fencing_work, nvme_rdma_fencing_work); INIT_WORK(&ctrl->err_work, nvme_rdma_error_recovery_work); INIT_WORK(&ctrl->ctrl.reset_work, nvme_rdma_reset_ctrl_work); =20 --=20 2.54.0 From nobody Sat Jul 25 23:03:45 2026 Received: from mail-pj1-f46.google.com (mail-pj1-f46.google.com [209.85.216.46]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id ECD0136896D for ; Sun, 12 Jul 2026 02:25:38 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.216.46 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1783823141; cv=none; b=dIteH78qAmsw9XSVopKTHJoXI9NGk8pQPy99rF59V+wfWFQGZ+tdFM0jDagydvm5pMV6hWL9SAyleQ4dKT8legHlsjOdi2J80W+fxn2C24EUXNXBNAE1s+XTOqWJidHcoIV4Vn0a+/P8thW8M+WxGTrCARJOBORCKg+dhGdFD/k= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1783823141; c=relaxed/simple; bh=k9+W91WgE7B0Ip0L9YWDXIyQ4eak1hWpaGk445QcIHk=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=sICPo8J9cH2Zp2UHJ37ZhpG1WCqKStbfBLcHrFhYAOGU11cEjsK0TJ0e9ATMK0gGx6cmx3QqqDYXVUTWfSc0Eo7MoHXWXP0FVrRCh+kHRUTDFZDS/nC4+ZiOGM0QDVN01uSBHVC4SKF8ahmkMdALxefoeCXHGhdBJAS0EljKgtA= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=purestorage.com; spf=pass smtp.mailfrom=purestorage.com; dkim=pass (2048-bit key) header.d=purestorage.com header.i=@purestorage.com header.b=AbsY92n0; arc=none smtp.client-ip=209.85.216.46 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=purestorage.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=purestorage.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=purestorage.com header.i=@purestorage.com header.b="AbsY92n0" Received: by mail-pj1-f46.google.com with SMTP id 98e67ed59e1d1-384c94c9414so1998693a91.3 for ; Sat, 11 Jul 2026 19:25:38 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=purestorage.com; s=google2022; t=1783823138; x=1784427938; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=k17NZK3iZiYWXEcv1S1Cll44Lxae4D1042zuaqAzmEs=; b=AbsY92n0fhLtmmZAZKkCCF1m+xrEzV1pv4FyOp7dMQiDNsVPKff04jgu6KWcNLoJcC Cide8Z5ehYWrSxf++5U/aOIAlepk8anYPXCewQRrccbNil8o2TtgvzP51KkLMduVc/MQ 0TvLM6ikThq9TvQuXsslKvZQynlnjJsuIRu/jw54vjIsfyrR/ju66m8ctI8U6eYntVee IbmJD0rNH84brHd3ca2z5bZFeGL/RlayrbZghwUIfkxDPKAq3NtS4YAo9Ia3zg5paHTm nxDCtqpTlkvaG+zgZjcEUrdsA0ioIwQC4DyjO9wN0QOcGjn4iHbM1T3qy/dnQesj+rOD NIOw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1783823138; x=1784427938; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to:content-type; bh=k17NZK3iZiYWXEcv1S1Cll44Lxae4D1042zuaqAzmEs=; b=rA4VoheXvsbPQ2FDwJTxrAmw72Bm0lEMbc7ev8J+llH4pZmlzGfUcRHCev2DJOLHRn ipdGopmW8MtsreY47k1yg3EC/kLOyNwp+K55eoexlnubOnUZlGpvYjUSEjIKjzNOH2Ro v6pTvnJJz2Hlv+7EnD73RD40gbv+3oYkBePmVF7Em1uJwoQ27UZkTVLI//8T3Jg1WHck jFwv/n/LeHWUD5ODAwxyAPUNdXzXY/N5hVwUkyeFuRNqfix20SBImf2snR2/6wQssjKv mMFrx7j6zMYwvcAwWVn1JBJY3aCVFmj+njXC8mdn7W7ZOGEXg9McaAIGtnHIKAbaGp/i Yc1A== X-Forwarded-Encrypted: i=1; AHgh+Rqdm0WuxwWDIYyV5XRUwsdPUHha57OQaAbIy/JD3ZNj6C92LSZBMsR47VH2yt0n71ecN2z7Kb4SskbfgqA=@vger.kernel.org X-Gm-Message-State: AOJu0YyTPmLZbm4Wh6Ic3nsetQGGfhP/1OWsgwZRob52C/Tyw0652qTR t2CjG289Yjy590QGccdQFNH0Q1a+g4FgKBltmGuuMot6ZQrYTpFHSFFa70tAxNw78Qo= X-Gm-Gg: AfdE7cnQ/252t4BLWZ1+C1n8sR4AeaRTljzpQJU4WSRZIQ1iZZhSkUNoPVq95zJCVYZ hLkhBotoluYHIQbaWaRG+xUygMfspbxo5ri0r3y1yQBuoQ4euLFmxQiKhO9Q0eCW76VFiKs56F0 9ln5Q/mc0U+OzFMj9gi1OmLg3zG1aDwkmqOmIrkx324nfQw2T6MpCmlSvTr2aUVsIxnGioRDzQe AMV3woGNWfDk8Mihy56nySwrvGVtknfgZoxPYcbuJqAOxKR/L/ZQQ0lo/cxWTSniChIW5wceTha zbW06FLsocrwlsZTI7jLLiajv8PdqVnfiBrlAWvGGeDKuCbarMWICsXdxylL69Ev431OQQc+RUu 7scsKMsNveHaR6bBbxnMEp4op++R92ecUPuxW9ivh/DxrHO+NCkMpKNmbB9JC+5r270IohFZXAT 3vfSb6 X-Received: by 2002:a17:90b:5870:b0:37f:a915:1c29 with SMTP id 98e67ed59e1d1-38dc75faef0mr3582950a91.19.1783823138013; Sat, 11 Jul 2026 19:25:38 -0700 (PDT) Received: from ceto.lan ([2607:fb90:9c20:2264::1c31]) by smtp.googlemail.com with ESMTPSA id 5a478bee46e88-3117462f5c7sm60704693eec.0.2026.07.11.19.25.36 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 11 Jul 2026 19:25:37 -0700 (PDT) From: Mohamed Khalfella To: Justin Tee , Naresh Gottumukkala , Paul Ely , Chaitanya Kulkarni , Christoph Hellwig , Jens Axboe , Keith Busch , Sagi Grimberg , James Smart , Hannes Reinecke , Randy Jennings , Dhaval Giani Cc: Aaron Dailey , linux-nvme@lists.infradead.org, linux-kernel@vger.kernel.org, Mohamed Khalfella Subject: [PATCH v5 12/16] nvme-fc: Refactor IO error recovery Date: Sat, 11 Jul 2026 19:23:33 -0700 Message-ID: <20260712022437.3743117-13-mkhalfella@purestorage.com> X-Mailer: git-send-email 2.54.0 In-Reply-To: <20260712022437.3743117-1-mkhalfella@purestorage.com> References: <20260712022437.3743117-1-mkhalfella@purestorage.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 Content-Type: text/plain; charset="utf-8" Added new nvme_fc_start_ioerr_recovery() to trigger error recovery instead of directly queueing ctrl->ioerr_work. nvme_fc_error_recovery() now called only from ctrl->ioerr_work has been updated to not depend on nvme_reset_ctrl() to handle error recovery. nvme_fc_error_recovery() effectively resets the controller and attempts reconnection if needed. This makes nvme-fc ioerr handling similar to other fabric transports. Update nvme_fc_timeout() to not abort timed out IOs. IOs aborted from nvme_fc_timeout() are not accounted for in ctrl->iocnt and this causes nvme_fc_delete_association() not to wait for them. Instead of aborting IOs nvme_fc_timeout() calls nvme_fc_start_ioerr_recovery() to start IO error recovery. Since error recovery runs in ctrl->ioerr_work this change fixes the issue reported in the link below. Link: https://lore.kernel.org/all/20250529214928.2112990-1-mkhalfella@pures= torage.com/ Signed-off-by: Mohamed Khalfella --- drivers/nvme/host/fc.c | 119 +++++++++++++++++++++++------------------ 1 file changed, 66 insertions(+), 53 deletions(-) diff --git a/drivers/nvme/host/fc.c b/drivers/nvme/host/fc.c index 04363b9c4489..54a09db9716d 100644 --- a/drivers/nvme/host/fc.c +++ b/drivers/nvme/host/fc.c @@ -227,6 +227,10 @@ static DEFINE_IDA(nvme_fc_ctrl_cnt); static struct device *fc_udev_device; =20 static void nvme_fc_complete_rq(struct request *rq); +static void nvme_fc_start_ioerr_recovery(struct nvme_fc_ctrl *ctrl, + char *errmsg); +static void __nvme_fc_abort_outstanding_ios(struct nvme_fc_ctrl *ctrl, + bool start_queues); =20 /* *********************** FC-NVME Port Management ***********************= * */ =20 @@ -788,7 +792,7 @@ nvme_fc_ctrl_connectivity_loss(struct nvme_fc_ctrl *ctr= l) "Reconnect", ctrl->cnum); =20 set_bit(ASSOC_FAILED, &ctrl->flags); - nvme_reset_ctrl(&ctrl->ctrl); + nvme_fc_start_ioerr_recovery(ctrl, "Connectivity Loss"); } =20 /** @@ -985,7 +989,7 @@ fc_dma_unmap_sg(struct device *dev, struct scatterlist = *sg, int nents, static void nvme_fc_ctrl_put(struct nvme_fc_ctrl *); static int nvme_fc_ctrl_get(struct nvme_fc_ctrl *); =20 -static void nvme_fc_error_recovery(struct nvme_fc_ctrl *ctrl, char *errmsg= ); +static void nvme_fc_error_recovery(struct nvme_fc_ctrl *ctrl); =20 static void __nvme_fc_finish_ls_req(struct nvmefc_ls_req_op *lsop) @@ -1567,9 +1571,8 @@ nvme_fc_ls_disconnect_assoc(struct nvmefc_ls_rcv_op *= lsop) * for the association have been ABTS'd by * nvme_fc_delete_association(). */ - - /* fail the association */ - nvme_fc_error_recovery(ctrl, "Disconnect Association LS received"); + nvme_fc_start_ioerr_recovery(ctrl, + "Disconnect Association LS received"); =20 /* release the reference taken by nvme_fc_match_disconn_ls() */ nvme_fc_ctrl_put(ctrl); @@ -1871,7 +1874,22 @@ nvme_fc_ctrl_ioerr_work(struct work_struct *work) struct nvme_fc_ctrl *ctrl =3D container_of(work, struct nvme_fc_ctrl, ioerr_work); =20 - nvme_fc_error_recovery(ctrl, "transport detected io error"); + /* + * if an error (io timeout, etc) while (re)connecting, the remote + * port requested terminating of the association (disconnect_ls) + * or an error (timeout or abort) occurred on an io while creating + * the controller. Abort any ios on the association and let the + * create_association error path resolve things. + */ + if (nvme_ctrl_state(&ctrl->ctrl) =3D=3D NVME_CTRL_CONNECTING) { + __nvme_fc_abort_outstanding_ios(ctrl, true); + dev_warn(ctrl->ctrl.device, + "NVME-FC{%d}: transport error during (re)connect\n", + ctrl->cnum); + return; + } + + nvme_fc_error_recovery(ctrl); } =20 /* @@ -1892,6 +1910,24 @@ char *nvme_fc_io_getuuid(struct nvmefc_fcp_req *req) } EXPORT_SYMBOL_GPL(nvme_fc_io_getuuid); =20 +static void nvme_fc_start_ioerr_recovery(struct nvme_fc_ctrl *ctrl, + char *errmsg) +{ + enum nvme_ctrl_state state =3D nvme_ctrl_state(&ctrl->ctrl); + + if (state =3D=3D NVME_CTRL_CONNECTING || state =3D=3D NVME_CTRL_DELETING = || + state =3D=3D NVME_CTRL_DELETING_NOIO) { + queue_work(nvme_reset_wq, &ctrl->ioerr_work); + return; + } + + if (nvme_change_ctrl_state(&ctrl->ctrl, NVME_CTRL_RESETTING)) { + dev_warn(ctrl->ctrl.device, "NVME-FC{%d}: starting error recovery %s\n", + ctrl->cnum, errmsg); + queue_work(nvme_reset_wq, &ctrl->ioerr_work); + } +} + static void nvme_fc_fcpio_done(struct nvmefc_fcp_req *req) { @@ -2049,9 +2085,8 @@ nvme_fc_fcpio_done(struct nvmefc_fcp_req *req) nvme_fc_complete_rq(rq); =20 check_error: - if (terminate_assoc && - nvme_ctrl_state(&ctrl->ctrl) !=3D NVME_CTRL_RESETTING) - queue_work(nvme_reset_wq, &ctrl->ioerr_work); + if (terminate_assoc) + nvme_fc_start_ioerr_recovery(ctrl, "io error"); } =20 static int @@ -2495,39 +2530,6 @@ __nvme_fc_abort_outstanding_ios(struct nvme_fc_ctrl = *ctrl, bool start_queues) nvme_unquiesce_admin_queue(&ctrl->ctrl); } =20 -static void -nvme_fc_error_recovery(struct nvme_fc_ctrl *ctrl, char *errmsg) -{ - enum nvme_ctrl_state state =3D nvme_ctrl_state(&ctrl->ctrl); - - /* - * if an error (io timeout, etc) while (re)connecting, the remote - * port requested terminating of the association (disconnect_ls) - * or an error (timeout or abort) occurred on an io while creating - * the controller. Abort any ios on the association and let the - * create_association error path resolve things. - */ - if (state =3D=3D NVME_CTRL_CONNECTING) { - __nvme_fc_abort_outstanding_ios(ctrl, true); - dev_warn(ctrl->ctrl.device, - "NVME-FC{%d}: transport error during (re)connect\n", - ctrl->cnum); - return; - } - - /* Otherwise, only proceed if in LIVE state - e.g. on first error */ - if (state !=3D NVME_CTRL_LIVE) - return; - - dev_warn(ctrl->ctrl.device, - "NVME-FC{%d}: transport association event: %s\n", - ctrl->cnum, errmsg); - dev_warn(ctrl->ctrl.device, - "NVME-FC{%d}: resetting controller\n", ctrl->cnum); - - nvme_reset_ctrl(&ctrl->ctrl); -} - static enum blk_eh_timer_return nvme_fc_timeout(struct request *rq) { struct nvme_fc_fcp_op *op =3D blk_mq_rq_to_pdu(rq); @@ -2536,24 +2538,14 @@ static enum blk_eh_timer_return nvme_fc_timeout(str= uct request *rq) struct nvme_fc_cmd_iu *cmdiu =3D &op->cmd_iu; struct nvme_command *sqe =3D &cmdiu->sqe; =20 - /* - * Attempt to abort the offending command. Command completion - * will detect the aborted io and will fail the connection. - */ dev_info(ctrl->ctrl.device, "NVME-FC{%d.%d}: io timeout: opcode %d fctype %d (%s) w10/11: " "x%08x/x%08x\n", ctrl->cnum, qnum, sqe->common.opcode, sqe->fabrics.fctype, nvme_fabrics_opcode_str(qnum, sqe), sqe->common.cdw10, sqe->common.cdw11); - if (__nvme_fc_abort_op(ctrl, op)) - nvme_fc_error_recovery(ctrl, "io timeout abort failed"); =20 - /* - * the io abort has been initiated. Have the reset timer - * restarted and the abort completion will complete the io - * shortly. Avoids a synchronous wait while the abort finishes. - */ + nvme_fc_start_ioerr_recovery(ctrl, "io timeout"); return BLK_EH_RESET_TIMER; } =20 @@ -3359,6 +3351,27 @@ nvme_fc_reset_ctrl_work(struct work_struct *work) } } =20 +static void +nvme_fc_error_recovery(struct nvme_fc_ctrl *ctrl) +{ + nvme_stop_keep_alive(&ctrl->ctrl); + nvme_stop_ctrl(&ctrl->ctrl); + flush_work(&ctrl->ctrl.async_event_work); + + /* will block while waiting for io to terminate */ + nvme_fc_delete_association(ctrl); + + /* Do not reconnect if controller is being deleted */ + if (!nvme_change_ctrl_state(&ctrl->ctrl, NVME_CTRL_CONNECTING)) + return; + + if (ctrl->rport->remoteport.port_state =3D=3D FC_OBJSTATE_ONLINE) { + queue_delayed_work(nvme_wq, &ctrl->connect_work, 0); + return; + } + + nvme_fc_reconnect_or_delete(ctrl, -ENOTCONN); +} =20 static const struct nvme_ctrl_ops nvme_fc_ctrl_ops =3D { .name =3D "fc", --=20 2.54.0 From nobody Sat Jul 25 23:03:45 2026 Received: from mail-pl1-f179.google.com (mail-pl1-f179.google.com [209.85.214.179]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id A02AD368D7F for ; Sun, 12 Jul 2026 02:25:40 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.214.179 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1783823142; cv=none; b=n/+f77qeYTczfweSMaCZTzYL9V+u8lhsdYogcZZXUdaIjJBt1PQ3a4M0stIQObfDkEZDfmNhljCyeA44eTcVsxkR60ovb4KlExWuMAaWF+k69zK48qoOOKM/VfKuhudY6JHsKUxgkJR+7kkRO+bbpqWGjy2c3NlC+NrOfeObIhg= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1783823142; c=relaxed/simple; bh=KD2rtVzAuhf8z4ZUcpIAEQ+TGp2leVjSVv26TPUyCiQ=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=IgN1FBT6tgBl8laPrlAUx9iuK5kDwDngqu/+5deGaXhHz7eTZ56PE4XXjRuFYZXjRR+SuKsrpIrCaAbB/dto12XpMQKoRCYIwrdEDKyiNiiKW1ZrfsUtGmcXala7R2Vnf4xIYWd/3skpe7zhxyRLc+/ve+W/zSv5b0MX9IRJ/1Q= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=purestorage.com; spf=pass smtp.mailfrom=purestorage.com; dkim=pass (2048-bit key) header.d=purestorage.com header.i=@purestorage.com header.b=fw0RjYVD; arc=none smtp.client-ip=209.85.214.179 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=purestorage.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=purestorage.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=purestorage.com header.i=@purestorage.com header.b="fw0RjYVD" Received: by mail-pl1-f179.google.com with SMTP id d9443c01a7336-2ce7d2adef4so27961605ad.3 for ; Sat, 11 Jul 2026 19:25:40 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=purestorage.com; s=google2022; t=1783823140; x=1784427940; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=cHeryY6vgxsV95CWKD2Kjdif2w+1k42bjuOLEzQoEGM=; b=fw0RjYVDYA+od2fHGGv7kq704IxMniOPe4F6GKHWisGoK7mCA5rfRkED9GW3jTowhx YYpz1BLuvLP7t5qYtiRfWxX5oK+yN6A0ugbZSeZ8/3uEdr9k+XpBsgRfvGzYdpT0CWCL sKtE+ApsgEpRyBHZ3b19eIdvEwzACRnL+1LIWV/n7AoT3QIF6wrE4i1ihHZjnjBQ21wu vK7d7/jNiiQJ4hOqbhmkGnZEQKzXA9aOeHQBH8kbmM6poKwdsB+jTH+vxmbPUjYfNAjD BzasXZ7NrMV3I1kTgHyngM1GjbZztqIItFA/lENRKvp294HcD5QeraQLY5spfl/f0SAc /mCw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1783823140; x=1784427940; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to:content-type; bh=cHeryY6vgxsV95CWKD2Kjdif2w+1k42bjuOLEzQoEGM=; b=k5lZJE01mNgqWAk41an0oPjvVCILA6WJiUeg0xRcRnX+1ptt7UzbA4F6uM+MdvZKnB 7kKBmUFvpFPV1xnYAJtv/Ab8sGAluqLAAEZ50KqI5RFqTOtA2OT07gQL8WZOUzS7nPLu rnHxt0XF5JUuWpk2NMXdFBsfZClqFyZjwA8/gufg7fOjIJ64caDqPcZTpMAZRx+QL+dX aZOweJvl3r855Dxo0wGd/IMfzg4h3rOqm9DZnrY5+eEDVVjeMonuQAZj8VphirGcUB9d 2HJU7TH21ZepfpwRNmOeNGd+jNjVTyUB3z3yACXJEcxw+AAgM0X7dl8SaE8dh10nubrZ c94Q== X-Forwarded-Encrypted: i=1; AHgh+RrJofKfmITV1e/wIebQYoLKccb35r/ZyRmMMJcuvu+V0xts/ZBFtzVAdVnpxTbUpoX1Pc0l36fx5cYtngQ=@vger.kernel.org X-Gm-Message-State: AOJu0YyM9IgJIgXDh0yc5TGmRHsCDoyQSNxQ2gaX7K+PVwvHOeTWnm1T l/NISMM1Re+xWZtpZ4PZigpWk2xbjA+QoGMMtG+Ke9HAjrnxY5y4cj6dfgrJe0nmm10= X-Gm-Gg: AfdE7cnQfbhsuXLr2SnVjLE3xeNEameCtBAFUJvudS+xDduwYKTFb9k9t7aSKH+gofB Giy2H71WoCS4Zf3R2kD2q21un7nEdozpGFShDzYPEBo5JEdKE9+bshEe7JVZqc2HgIp/ctqSIfb UqMDUaY8Pt83ipzJ0jnov8NFJSSqejE/hK1tiGcYWBLe1xcWItwKN7Sf8rXYlizZdKvooUniMAH rOcjKf/PUNVJ7RFjBSGKrH3loSR+beNQqvHecILQb+1vJcAA/wXUd199SpoqP8dyUXfGd5X3D7x NCnqok65vUSnEMJx9ygsueBj4MFmwJDJYcHV1hQRhbr6zpSgAE0+JyvLdvL4o/ODNVFZamENzGW /kYrerz26KVcHm1pVfeS1Fl8lQ9uZmHZUEJOvBOpiv7q8nxlwlZ8wyPO5v28jjQSL+5umotMKXW oZs3CuD1QXcyvW/Z0= X-Received: by 2002:a17:90a:da85:b0:387:e0db:3fa9 with SMTP id 98e67ed59e1d1-38dc777018cmr4731701a91.34.1783823139833; Sat, 11 Jul 2026 19:25:39 -0700 (PDT) Received: from ceto.lan ([2607:fb90:9c20:2264::1c31]) by smtp.googlemail.com with ESMTPSA id 5a478bee46e88-3117462f5c7sm60704693eec.0.2026.07.11.19.25.38 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 11 Jul 2026 19:25:39 -0700 (PDT) From: Mohamed Khalfella To: Justin Tee , Naresh Gottumukkala , Paul Ely , Chaitanya Kulkarni , Christoph Hellwig , Jens Axboe , Keith Busch , Sagi Grimberg , James Smart , Hannes Reinecke , Randy Jennings , Dhaval Giani Cc: Aaron Dailey , linux-nvme@lists.infradead.org, linux-kernel@vger.kernel.org, Mohamed Khalfella Subject: [PATCH v5 13/16] nvme-fc: Use CCR to recover controller that hits an error Date: Sat, 11 Jul 2026 19:23:34 -0700 Message-ID: <20260712022437.3743117-14-mkhalfella@purestorage.com> X-Mailer: git-send-email 2.54.0 In-Reply-To: <20260712022437.3743117-1-mkhalfella@purestorage.com> References: <20260712022437.3743117-1-mkhalfella@purestorage.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 Content-Type: text/plain; charset="utf-8" An alive nvme controller that hits an error now will move to FENCING state instead of RESETTING state. ctrl->fencing_work attempts CCR to terminate inflight IOs. Regardless of the success or failure of CCR operation the controller is transitioned to RESETTING state to continue error recovery process. Signed-off-by: Mohamed Khalfella --- drivers/nvme/host/fc.c | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/drivers/nvme/host/fc.c b/drivers/nvme/host/fc.c index 54a09db9716d..03b6c3649210 100644 --- a/drivers/nvme/host/fc.c +++ b/drivers/nvme/host/fc.c @@ -166,6 +166,7 @@ struct nvme_fc_ctrl { struct blk_mq_tag_set admin_tag_set; struct blk_mq_tag_set tag_set; =20 + struct work_struct fencing_work; struct work_struct ioerr_work; struct delayed_work connect_work; =20 @@ -1868,6 +1869,22 @@ __nvme_fc_fcpop_chk_teardowns(struct nvme_fc_ctrl *c= trl, } } =20 +static void nvme_fc_fencing_work(struct work_struct *work) +{ + struct nvme_fc_ctrl *fc_ctrl =3D + container_of(work, struct nvme_fc_ctrl, fencing_work); + struct nvme_ctrl *ctrl =3D &fc_ctrl->ctrl; + unsigned long rem; + + rem =3D nvme_fence_ctrl(ctrl); + if (rem) + dev_info(ctrl->device, "CCR failed, starting error recovery\n"); + + nvme_change_ctrl_state(ctrl, NVME_CTRL_FENCED); + if (nvme_change_ctrl_state(ctrl, NVME_CTRL_RESETTING)) + queue_work(nvme_reset_wq, &fc_ctrl->ioerr_work); +} + static void nvme_fc_ctrl_ioerr_work(struct work_struct *work) { @@ -1889,6 +1906,7 @@ nvme_fc_ctrl_ioerr_work(struct work_struct *work) return; } =20 + flush_work(&ctrl->fencing_work); nvme_fc_error_recovery(ctrl); } =20 @@ -1921,6 +1939,14 @@ static void nvme_fc_start_ioerr_recovery(struct nvme= _fc_ctrl *ctrl, return; } =20 + if (nvme_change_ctrl_state(&ctrl->ctrl, NVME_CTRL_FENCING)) { + dev_warn(ctrl->ctrl.device, + "NVME-FC{%d}: starting controller fencing %s\n", + ctrl->cnum, errmsg); + queue_work(nvme_wq, &ctrl->fencing_work); + return; + } + if (nvme_change_ctrl_state(&ctrl->ctrl, NVME_CTRL_RESETTING)) { dev_warn(ctrl->ctrl.device, "NVME-FC{%d}: starting error recovery %s\n", ctrl->cnum, errmsg); @@ -3328,6 +3354,7 @@ nvme_fc_reset_ctrl_work(struct work_struct *work) struct nvme_fc_ctrl *ctrl =3D container_of(work, struct nvme_fc_ctrl, ctrl.reset_work); =20 + flush_work(&ctrl->fencing_work); nvme_stop_ctrl(&ctrl->ctrl); =20 /* will block will waiting for io to terminate */ @@ -3504,6 +3531,7 @@ nvme_fc_alloc_ctrl(struct device *dev, struct nvmf_ct= rl_options *opts, =20 INIT_WORK(&ctrl->ctrl.reset_work, nvme_fc_reset_ctrl_work); INIT_DELAYED_WORK(&ctrl->connect_work, nvme_fc_connect_ctrl_work); + INIT_WORK(&ctrl->fencing_work, nvme_fc_fencing_work); INIT_WORK(&ctrl->ioerr_work, nvme_fc_ctrl_ioerr_work); spin_lock_init(&ctrl->lock); =20 --=20 2.54.0 From nobody Sat Jul 25 23:03:45 2026 Received: from mail-pj1-f48.google.com (mail-pj1-f48.google.com [209.85.216.48]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id CF05436A01A for ; Sun, 12 Jul 2026 02:25:42 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.216.48 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1783823144; cv=none; b=unHPkUG6HxdX90XUVy8unpvea0ElMhb/El5jmCpUHrMhQnTo495bHUGRrI75Kv+NeKIE5GvQiYEn7sPc8VIlLVFGD45fwnpC0Dt4tqk11JcPug6TknqQ92eYac9/O6CC/hXC0LCVj9UX9HPW5ijMjw2gZ5NVsgnalnHGvXPJMJU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1783823144; c=relaxed/simple; bh=CmhZXORdMTm+BqCDSpuEkk4GAsdEqEMYNb9KnFJtPdQ=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=XMrui7jASUEC2UndfHv17CagLCqfr4+VdbrWdw5JZMyD4yIFnsuLxnrvcg+AcOcjBVxU4/6juGvLrhhxeEOPt/OqVml9+C3FJ1f3NW/jat1xs4Q9kn/OeGwr4Fw1HX/JrHReNU/DuMq1RnrYIpZ2eibLuP1nGUpv47xPh1ZunfE= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=purestorage.com; spf=pass smtp.mailfrom=purestorage.com; dkim=pass (2048-bit key) header.d=purestorage.com header.i=@purestorage.com header.b=Ezs8cnVV; arc=none smtp.client-ip=209.85.216.48 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=purestorage.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=purestorage.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=purestorage.com header.i=@purestorage.com header.b="Ezs8cnVV" Received: by mail-pj1-f48.google.com with SMTP id 98e67ed59e1d1-37df72c9984so3678794a91.3 for ; Sat, 11 Jul 2026 19:25:42 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=purestorage.com; s=google2022; t=1783823142; x=1784427942; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=1HnswPJ/Ga8FPm48i1AzqQaejGi0bjeeJj42xEdxHH0=; b=Ezs8cnVVPUFFJTjG638m5aoeWvwwmEUo6C2Evhn5qwLo7+iPnMJOtaXJty00T4a+EQ 2XhnNTC9YZl3xE235IUhYW6fHOWEnbfV4s/koT99d5iwQto8eC/eCF1rAHp7FmUGe5E/ UH/O3ogOHoBBLBgC3tuLigPkfYTLpv3k4fMIlAMdJXQL3mFEtMYe6H/RYWw20Msk78Pg 4rf40L0acNriN2UkVLEctwiUeMDMN+jQGrr9mfW46OZFnaWo14ZJI2YHyVEGLLHUgkT1 Qdxwvef6Zuz7bZnDs/FV2UxmGQnhy85Z5Nm3L7YRJzKs5AP2ODlrjr6VNRMxxECTxHB6 qk1A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1783823142; x=1784427942; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to:content-type; bh=1HnswPJ/Ga8FPm48i1AzqQaejGi0bjeeJj42xEdxHH0=; b=Ia6seyQpWR15zlW3+lrT0sZolFLdRtj6hN8mEdwnzYAQ9ebmQLR9lUTztsEu8/kpKi M6mJXYQvAqdEXSJnnYpLagdfI7CTkKUwI2w0QRy0/tkJvled2X8b/SeS8VB/1KbtFbp7 NJq8Nw3kwcLkyxH72tDb4ttzP77qjq01e6N/Ryz1uWhZjknkh6DDTqsyBPNULeLHDX6s 5ytMkri2CKQF8QJOjbWF7d1pzH2d+PuZcQbVRS4AZ8oqDoF2CXac1iojcMclDCjbccTt PcKSXGD5Ha0iyKaWXcMIA8gqQ3hvZkcxX4nLNIH3ccgu4NlrhazzsWqz0eT+OiEi4o7t cgxA== X-Forwarded-Encrypted: i=1; AHgh+RorKko67BmmRgrQssomDUwku5QGilQ0z7RP7v3tahuEiyfoBC8smPL+aWguy26bLlcTa/lG2bFVp+Rs1OE=@vger.kernel.org X-Gm-Message-State: AOJu0Yyi2PP+9vTphBei7Jr+K5nRU0Ya6cT0b8Ii2oEbMGvxVFZcSgN/ ksrJAEsAn9Jq1C7XU3M3PQDIXLC7TgDDtJx5SaG6lgS0bvk2XwszcE3It6s+C1CxysY= X-Gm-Gg: AfdE7cmiwsQ81fTAtRhDA5mhkSO3Xssh/n0iDM80IZjoal3MnbftPiLqGLkfH9QUx5v Npb5oqQkhR2vOwnHHv63Fj9N9BCUximzeZ9dhguv26DEQF0ImpAq7T3xODw1LGy2a9jzJyx1vRv vRQtbXTPP2GTg0LFq7aFAy23gnnHLGZ0BA1SF2A6qbLKKhbJ1/ky0Uhjf7duKPyb+iqFLRm5iPz GYAGIAgmdoPDnJi+lKUVK6X/OBfr5XliQ7BsEVFLWjTAcoL0uKUjdabO6KAROXBwSrcK8fT75cu KZG6chSJP8bfzhPf/FBcNfbfSEnAD185rXb50WHaekqiGvj6nhbkcgqCuzTxng15z+7GXgAYlop fbswZCIN5B+56pBX+mt2HwvNY5ts30112Jws7yBhvKc2QqRJUdyZeQOPLwgRcWMVSQJip+H75d2 qfrzID X-Received: by 2002:a17:90b:4c49:b0:37d:ee77:78ac with SMTP id 98e67ed59e1d1-38dc774cd5cmr3948680a91.19.1783823141858; Sat, 11 Jul 2026 19:25:41 -0700 (PDT) Received: from ceto.lan ([2607:fb90:9c20:2264::1c31]) by smtp.googlemail.com with ESMTPSA id 5a478bee46e88-3117462f5c7sm60704693eec.0.2026.07.11.19.25.40 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 11 Jul 2026 19:25:40 -0700 (PDT) From: Mohamed Khalfella To: Justin Tee , Naresh Gottumukkala , Paul Ely , Chaitanya Kulkarni , Christoph Hellwig , Jens Axboe , Keith Busch , Sagi Grimberg , James Smart , Hannes Reinecke , Randy Jennings , Dhaval Giani Cc: Aaron Dailey , linux-nvme@lists.infradead.org, linux-kernel@vger.kernel.org, Mohamed Khalfella Subject: [PATCH v5 14/16] nvme-fc: Hold inflight requests while in FENCING state Date: Sat, 11 Jul 2026 19:23:35 -0700 Message-ID: <20260712022437.3743117-15-mkhalfella@purestorage.com> X-Mailer: git-send-email 2.54.0 In-Reply-To: <20260712022437.3743117-1-mkhalfella@purestorage.com> References: <20260712022437.3743117-1-mkhalfella@purestorage.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 Content-Type: text/plain; charset="utf-8" While in FENCING state, aborted inflight IOs should be held until fencing is done. Update nvme_fc_fcpio_done() to not complete aborted requests or requests with transport errors. These held requests will be canceled in nvme_fc_delete_association() after fencing is done. nvme_fc_fcpio_done() avoids racing with canceling aborted requests by making sure we complete successful requests before waking up the waiting thread. Signed-off-by: Mohamed Khalfella Signed-off-by: James Smart --- drivers/nvme/host/fc.c | 61 +++++++++++++++++++++++++++++++++++------- 1 file changed, 51 insertions(+), 10 deletions(-) diff --git a/drivers/nvme/host/fc.c b/drivers/nvme/host/fc.c index 03b6c3649210..006b5a984dfe 100644 --- a/drivers/nvme/host/fc.c +++ b/drivers/nvme/host/fc.c @@ -172,7 +172,7 @@ struct nvme_fc_ctrl { =20 struct kref ref; unsigned long flags; - u32 iocnt; + atomic_t iocnt; wait_queue_head_t ioabort_wait; =20 struct nvme_fc_fcp_op aen_ops[NVME_NR_AEN_COMMANDS]; @@ -1823,7 +1823,7 @@ __nvme_fc_abort_op(struct nvme_fc_ctrl *ctrl, struct = nvme_fc_fcp_op *op) atomic_set(&op->state, opstate); else if (test_bit(FCCTRL_TERMIO, &ctrl->flags)) { op->flags |=3D FCOP_FLAGS_TERMIO; - ctrl->iocnt++; + atomic_inc(&ctrl->iocnt); } spin_unlock_irqrestore(&ctrl->lock, flags); =20 @@ -1853,20 +1853,29 @@ nvme_fc_abort_aen_ops(struct nvme_fc_ctrl *ctrl) } =20 static inline void +__nvme_fc_fcpop_count_one_down(struct nvme_fc_ctrl *ctrl) +{ + if (atomic_dec_return(&ctrl->iocnt) =3D=3D 0) + wake_up(&ctrl->ioabort_wait); +} + +static inline bool __nvme_fc_fcpop_chk_teardowns(struct nvme_fc_ctrl *ctrl, struct nvme_fc_fcp_op *op, int opstate) { unsigned long flags; + bool ret =3D false; =20 if (opstate =3D=3D FCPOP_STATE_ABORTED) { spin_lock_irqsave(&ctrl->lock, flags); if (test_bit(FCCTRL_TERMIO, &ctrl->flags) && op->flags & FCOP_FLAGS_TERMIO) { - if (!--ctrl->iocnt) - wake_up(&ctrl->ioabort_wait); + ret =3D true; } spin_unlock_irqrestore(&ctrl->lock, flags); } + + return ret; } =20 static void nvme_fc_fencing_work(struct work_struct *work) @@ -1966,7 +1975,8 @@ nvme_fc_fcpio_done(struct nvmefc_fcp_req *req) struct nvme_command *sqe =3D &op->cmd_iu.sqe; __le16 status =3D cpu_to_le16(NVME_SC_SUCCESS << 1); union nvme_result result; - bool terminate_assoc =3D true; + bool op_term, terminate_assoc =3D true; + enum nvme_ctrl_state state; int opstate; =20 /* @@ -2099,16 +2109,38 @@ nvme_fc_fcpio_done(struct nvmefc_fcp_req *req) done: if (op->flags & FCOP_FLAGS_AEN) { nvme_complete_async_event(&queue->ctrl->ctrl, status, &result); - __nvme_fc_fcpop_chk_teardowns(ctrl, op, opstate); + if (__nvme_fc_fcpop_chk_teardowns(ctrl, op, opstate)) + __nvme_fc_fcpop_count_one_down(ctrl); atomic_set(&op->state, FCPOP_STATE_IDLE); op->flags =3D FCOP_FLAGS_AEN; /* clear other flags */ nvme_fc_ctrl_put(ctrl); goto check_error; } =20 - __nvme_fc_fcpop_chk_teardowns(ctrl, op, opstate); + /* + * We can not access op after the request is completed because it can + * be reused immediately. At the same time we want to wakeup the thread + * waiting for ongoing IOs _after_ requests are completed. This is + * necessary because that thread will start canceling inflight IOs + * and we want to avoid request completion racing with cancellation. + */ + op_term =3D __nvme_fc_fcpop_chk_teardowns(ctrl, op, opstate); + + /* + * If we are going to terminate associations and the controller is + * LIVE or FENCING, then do not complete this request now. Let error + * recovery cancel this request when it is safe to do so. + */ + state =3D nvme_ctrl_state(&ctrl->ctrl); + if (terminate_assoc && + (state =3D=3D NVME_CTRL_LIVE || state =3D=3D NVME_CTRL_FENCING)) + goto check_op_term; + if (!nvme_try_complete_req(rq, status, result)) nvme_fc_complete_rq(rq); +check_op_term: + if (op_term) + __nvme_fc_fcpop_count_one_down(ctrl); =20 check_error: if (terminate_assoc) @@ -2747,7 +2779,8 @@ nvme_fc_start_fcp_op(struct nvme_fc_ctrl *ctrl, struc= t nvme_fc_queue *queue, * cmd with the csn was supposed to arrive. */ opstate =3D atomic_xchg(&op->state, FCPOP_STATE_COMPLETE); - __nvme_fc_fcpop_chk_teardowns(ctrl, op, opstate); + if (__nvme_fc_fcpop_chk_teardowns(ctrl, op, opstate)) + __nvme_fc_fcpop_count_one_down(ctrl); =20 if (!(op->flags & FCOP_FLAGS_AEN)) { nvme_fc_unmap_data(ctrl, op->rq, op); @@ -3223,7 +3256,7 @@ nvme_fc_delete_association(struct nvme_fc_ctrl *ctrl) =20 spin_lock_irqsave(&ctrl->lock, flags); set_bit(FCCTRL_TERMIO, &ctrl->flags); - ctrl->iocnt =3D 0; + atomic_set(&ctrl->iocnt, 0); spin_unlock_irqrestore(&ctrl->lock, flags); =20 __nvme_fc_abort_outstanding_ios(ctrl, false); @@ -3232,11 +3265,19 @@ nvme_fc_delete_association(struct nvme_fc_ctrl *ctr= l) nvme_fc_abort_aen_ops(ctrl); =20 /* wait for all io that had to be aborted */ + wait_event(ctrl->ioabort_wait, atomic_read(&ctrl->iocnt) =3D=3D 0); spin_lock_irq(&ctrl->lock); - wait_event_lock_irq(ctrl->ioabort_wait, ctrl->iocnt =3D=3D 0, ctrl->lock); clear_bit(FCCTRL_TERMIO, &ctrl->flags); spin_unlock_irq(&ctrl->lock); =20 + /* + * At this point all inflight requests have been successfully + * aborted. Now it is safe to cancel all requests we decided + * not to complete in nvme_fc_fcpio_done(). + */ + nvme_cancel_tagset(&ctrl->ctrl); + nvme_cancel_admin_tagset(&ctrl->ctrl); + nvme_fc_term_aen_ops(ctrl); =20 /* --=20 2.54.0 From nobody Sat Jul 25 23:03:45 2026 Received: from mail-pl1-f171.google.com (mail-pl1-f171.google.com [209.85.214.171]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id CA9CD368D4B for ; Sun, 12 Jul 2026 02:25:44 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.214.171 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1783823146; cv=none; b=F3rmQZqwTHr6c5k8zRIELO35mFFuO+jRrFbVGn4de81LD7SwUNbxMNlLlOZYTDZbJG+r8r9k8wPUX+Devr7rvJ3cQSmgjb9r78s82SJ+L6w1Q2EmGrsUi6UgUe/JquIKtMebNTqtGqTehvjCW/jT9hHvcsc71CKJPKEhfdaJVLA= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1783823146; c=relaxed/simple; bh=Qn3ESBJqlUky1m3kpQ1XGD/ekrSFBNk/L2EU2hC/V4Y=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=E6LDM11o4r2jDB4EDUfTVEnAHFL7nw7SD2V0n/Fkjzm31Rq3zFolhHESFoyqnluh6DKFz7QeOvrP8h9jMhN26RloSX8kzgsKmHNJ1oDA7SDaKn3DdUOMsIpKXtH/rNMnVA5orIzGwSKTN8I5SbyIPZ4kO/PBqtP/xFhnvLbUywQ= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=purestorage.com; spf=pass smtp.mailfrom=purestorage.com; dkim=pass (2048-bit key) header.d=purestorage.com header.i=@purestorage.com header.b=aDiDcrR/; arc=none smtp.client-ip=209.85.214.171 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=purestorage.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=purestorage.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=purestorage.com header.i=@purestorage.com header.b="aDiDcrR/" Received: by mail-pl1-f171.google.com with SMTP id d9443c01a7336-2cc6dd436c6so24501045ad.2 for ; Sat, 11 Jul 2026 19:25:44 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=purestorage.com; s=google2022; t=1783823144; x=1784427944; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=1rYDxzyuopFsvKHCSX2IcMInl87/tUE3AM2EYHgQ9pk=; b=aDiDcrR/LDTq2/e/Lb2GGanzMpsi2RrJY7T3A19vsugENZlMoCv5tV3PCAVXaRuRhI fTCwS8/ffWX2bKEut11/0seFZkJCdSujWgaworaBlmIqxITrsFxYNm2W0vd5FBKiuK0c kX12Aqcfl94V1mkahZqM1t5rQiKZmmqydVe0NIZc0bYj5HUbGfG92M6iMh9CH0r0fKzT PKg7ITenNGa2lpA5oTMxZ6wLOfZWHO2JdJG2PBt4vDK82UFDVYcdQzLs/PGb+LkzVB8b h+zBFzoV/m2L2sQeAEI0Qd7rdUxhebo4o5bkzD9P4TFUPdtiRUWObujdHTnWldZGSV+A pZ9g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1783823144; x=1784427944; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to:content-type; bh=1rYDxzyuopFsvKHCSX2IcMInl87/tUE3AM2EYHgQ9pk=; b=Q7vHI+Kv4ViTbCg2Gi4Ueim8gGS0k0T4uUjMkblrg+ZaNTJ49s1RTNpOqDgdZ87km1 MbU+fKdunYT/W40wRyN+m6Q8nZJm7eDChzgQ6FltOTIjA6zY3QKoIatPBRnILWtvG5DY mUkBcSdMjaVqoRs8bhBIn+Xqs8DYE1JSiEcNyEo3Q2H9t1wLCfHyJBDYOwv5gVPKuHVZ ysthhBFW9VdNItb1Ea128IU++EujJAydpEgiJW8UnTzkF1C+FpDRlSQ/AxQA94xXHmTH 5RuWVG5rAIRdBwZv9cpfpFdyvSODWtONqDceSAp3Vr36g5HSX48OxusGuAkJ2OKF6ZNG SiMA== X-Forwarded-Encrypted: i=1; AHgh+RpKTtCYJdrVpKsuLPbETXftrrkbtmOP+nXge3N6+r9fS/DNmYkF/BBxthAUQoPIkae+aFxL606yeo1Wk6o=@vger.kernel.org X-Gm-Message-State: AOJu0YzbFftIvNqpj+/dlZt0xaCbLK9SwzREnSCCnG1PNEfB2ogQlTxC DR6tnQHSl328C6MqwMq1CpYOMziOaVr/W9Gcq2nTMTunu1Na9KQu2DxzLnECRQ+4n/0= X-Gm-Gg: AfdE7clXBDcTEoUY+qUZX66jGuQLoNIRn7a5nnW8CllRB5BEfAPsQURxcmHkb2/u+KF ra0oFqAAkgMHChxKgOMm7wvoHrnPgkzGqQW8wA2zjtOSn4j06nbbxnYy3HhFfkwY49A/dpfgwGx osmW8THWsxDKoLMkngnndBm3/6r1U0ceU+5gjADcGJP38LDuv6w5AbeUjGTPF+6QYdAXaYObfvP KHuJm0HHBWVqnO7PNRuvuCAbaY+rDMmiEozDHeYDfGY7Nv6hzEJ6WKtqPs+MWJct7iFi01YL1Aj u60sF3l4sRVwnbqAK1Xs5+xxIs6r1+7z5tiFsQh/77xyOpaTu09PRtyZ9Pp0tsnGJ6LHIH75xpp OynG8jeaBDfPHMwFZiryQLU3ImzROQjNMBXV7mnfh9U7LZx5UHvYS7FrogWG2b2/pHfCtok6uWV GqBHxV93/yeJbrCcXMnpKfkRcOuw== X-Received: by 2002:a17:90b:3a81:b0:37f:e1b6:4c7d with SMTP id 98e67ed59e1d1-38dc782ab92mr4293115a91.6.1783823143929; Sat, 11 Jul 2026 19:25:43 -0700 (PDT) Received: from ceto.lan ([2607:fb90:9c20:2264::1c31]) by smtp.googlemail.com with ESMTPSA id 5a478bee46e88-3117462f5c7sm60704693eec.0.2026.07.11.19.25.42 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 11 Jul 2026 19:25:43 -0700 (PDT) From: Mohamed Khalfella To: Justin Tee , Naresh Gottumukkala , Paul Ely , Chaitanya Kulkarni , Christoph Hellwig , Jens Axboe , Keith Busch , Sagi Grimberg , James Smart , Hannes Reinecke , Randy Jennings , Dhaval Giani Cc: Aaron Dailey , linux-nvme@lists.infradead.org, linux-kernel@vger.kernel.org, Mohamed Khalfella Subject: [PATCH v5 15/16] nvmet: Add support for CQT to nvme target Date: Sat, 11 Jul 2026 19:23:36 -0700 Message-ID: <20260712022437.3743117-16-mkhalfella@purestorage.com> X-Mailer: git-send-email 2.54.0 In-Reply-To: <20260712022437.3743117-1-mkhalfella@purestorage.com> References: <20260712022437.3743117-1-mkhalfella@purestorage.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 Content-Type: text/plain; charset="utf-8" TP4129 KATO Corrections and Clarifications defined CQT (Command Quiesce Time) which is used along with KATO (Keep Alive Timeout) to set an upper time limit for attempting Cross-Controller Recovery. CQT is added as a subsystem attribute that defaults to 0 to maintain the current behavior. Signed-off-by: Mohamed Khalfella Reviewed-by: Hannes Reinecke --- drivers/nvme/target/admin-cmd.c | 1 + drivers/nvme/target/configfs.c | 36 +++++++++++++++++++++++++++++++++ drivers/nvme/target/core.c | 3 +++ drivers/nvme/target/nvmet.h | 2 ++ include/linux/nvme.h | 5 ++++- 5 files changed, 46 insertions(+), 1 deletion(-) diff --git a/drivers/nvme/target/admin-cmd.c b/drivers/nvme/target/admin-cm= d.c index ea2566a9b83f..fbfc226c9830 100644 --- a/drivers/nvme/target/admin-cmd.c +++ b/drivers/nvme/target/admin-cmd.c @@ -737,6 +737,7 @@ static void nvmet_execute_identify_ctrl(struct nvmet_re= q *req) id->cntlid =3D cpu_to_le16(ctrl->cntlid); id->ver =3D cpu_to_le32(ctrl->subsys->ver); if (!nvmet_is_disc_subsys(ctrl->subsys)) { + id->cqt =3D cpu_to_le16(ctrl->cqt); id->ciu =3D ctrl->ciu; id->cirn =3D cpu_to_le64(ctrl->cirn); id->ccrl =3D NVMF_CCR_LIMIT; diff --git a/drivers/nvme/target/configfs.c b/drivers/nvme/target/configfs.c index 2b69ffcfc8df..b99f31c0a640 100644 --- a/drivers/nvme/target/configfs.c +++ b/drivers/nvme/target/configfs.c @@ -1661,6 +1661,41 @@ static ssize_t nvmet_subsys_attr_pi_enable_store(str= uct config_item *item, CONFIGFS_ATTR(nvmet_subsys_, attr_pi_enable); #endif =20 +static ssize_t nvmet_subsys_attr_cqt_show(struct config_item *item, + char *page) +{ + return snprintf(page, PAGE_SIZE, "%u\n", to_subsys(item)->cqt); +} + +static ssize_t nvmet_subsys_attr_cqt_store(struct config_item *item, + const char *page, size_t cnt) +{ + struct nvmet_subsys *subsys =3D to_subsys(item); + struct nvmet_ctrl *ctrl; + u16 cqt; + + if (nvmet_is_disc_subsys(subsys)) + return -EINVAL; + + if (sscanf(page, "%hu\n", &cqt) !=3D 1) + return -EINVAL; + + down_write(&nvmet_config_sem); + mutex_lock(&subsys->lock); + if (subsys->cqt =3D=3D cqt) + goto out; + + subsys->cqt =3D cqt; + /* Force reconnect */ + list_for_each_entry(ctrl, &subsys->ctrls, subsys_entry) + ctrl->ops->delete_ctrl(ctrl); +out: + mutex_unlock(&subsys->lock); + up_write(&nvmet_config_sem); + return cnt; +} +CONFIGFS_ATTR(nvmet_subsys_, attr_cqt); + static ssize_t nvmet_subsys_attr_qid_max_show(struct config_item *item, char *page) { @@ -1701,6 +1736,7 @@ static struct configfs_attribute *nvmet_subsys_attrs[= ] =3D { &nvmet_subsys_attr_attr_vendor_id, &nvmet_subsys_attr_attr_subsys_vendor_id, &nvmet_subsys_attr_attr_model, + &nvmet_subsys_attr_attr_cqt, &nvmet_subsys_attr_attr_qid_max, &nvmet_subsys_attr_attr_ieee_oui, &nvmet_subsys_attr_attr_firmware, diff --git a/drivers/nvme/target/core.c b/drivers/nvme/target/core.c index 9b16b15f5093..e59026ca449f 100644 --- a/drivers/nvme/target/core.c +++ b/drivers/nvme/target/core.c @@ -1729,6 +1729,7 @@ struct nvmet_ctrl *nvmet_alloc_ctrl(struct nvmet_allo= c_ctrl_args *args) ctrl->cntlid =3D ret; =20 if (!nvmet_is_disc_subsys(ctrl->subsys)) { + ctrl->cqt =3D subsys->cqt; ctrl->ciu =3D get_random_u8() ? : 1; ctrl->cirn =3D get_random_u64(); } @@ -1969,10 +1970,12 @@ struct nvmet_subsys *nvmet_subsys_alloc(const char = *subsysnqn, =20 switch (type) { case NVME_NQN_NVME: + subsys->cqt =3D NVMF_CQT_MS; subsys->max_qid =3D NVMET_NR_QUEUES; break; case NVME_NQN_DISC: case NVME_NQN_CURR: + subsys->cqt =3D 0; subsys->max_qid =3D 0; break; default: diff --git a/drivers/nvme/target/nvmet.h b/drivers/nvme/target/nvmet.h index da80377c3795..4ff458c3ccdc 100644 --- a/drivers/nvme/target/nvmet.h +++ b/drivers/nvme/target/nvmet.h @@ -269,6 +269,7 @@ struct nvmet_ctrl { =20 uuid_t hostid; u16 cntlid; + u16 cqt; u8 ciu; u32 kato; u64 cirn; @@ -346,6 +347,7 @@ struct nvmet_subsys { #ifdef CONFIG_NVME_TARGET_DEBUGFS struct dentry *debugfs_dir; #endif + u16 cqt; u16 max_qid; =20 u64 ver; diff --git a/include/linux/nvme.h b/include/linux/nvme.h index 3757d11ffea3..0b69ed53f347 100644 --- a/include/linux/nvme.h +++ b/include/linux/nvme.h @@ -21,6 +21,7 @@ #define NVMF_TRADDR_SIZE 256 #define NVMF_TSAS_SIZE 256 =20 +#define NVMF_CQT_MS 0 #define NVMF_CCR_LIMIT 4 #define NVMF_CCR_PER_PAGE 511 =20 @@ -368,7 +369,9 @@ struct nvme_id_ctrl { __u8 anacap; __le32 anagrpmax; __le32 nanagrpid; - __u8 rsvd352[160]; + __u8 rsvd352[34]; + __le16 cqt; + __u8 rsvd388[124]; __u8 sqes; __u8 cqes; __le16 maxcmd; --=20 2.54.0 From nobody Sat Jul 25 23:03:45 2026 Received: from mail-pj1-f44.google.com (mail-pj1-f44.google.com [209.85.216.44]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 9BF95368D4A for ; Sun, 12 Jul 2026 02:25:46 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.216.44 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1783823148; cv=none; b=a0Maoe4VNt43Olog9SFA68GQSiaYxLW6uKaoVLCmpEwL30aQdgWrA0NOQv9G4rBWkXsrlaD+h2gybx7k3aTAbJhmcjh6bQPw1IgLnjW1Svm4la/FA394zvMNZgA3ALVReIz3pt7PxIQ+1hkIc66chvmp/FcfXOlqHku01V31ewM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1783823148; c=relaxed/simple; bh=SXCYdTVw20SPV7vE3SKk/BCx7TVEEAy3y2NBE/9dnsY=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=VV1HyufyMjRIsXXyTObOWE2FnvYfyvEV4Op7twBKR78Unu6eBpOO6tHe2ALDI8I4oI075u+APe5mn6ED2nHizDIPgGPrm0b/ILATxUaDEs+iNkR/mWvjetN9isChL3eBfjQ2Qn8dxizc5l5Y1mlkZ2E0K7f4tsc5zXXoR2Av9Lk= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=purestorage.com; spf=pass smtp.mailfrom=purestorage.com; dkim=pass (2048-bit key) header.d=purestorage.com header.i=@purestorage.com header.b=VWgEwAGN; arc=none smtp.client-ip=209.85.216.44 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=purestorage.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=purestorage.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=purestorage.com header.i=@purestorage.com header.b="VWgEwAGN" Received: by mail-pj1-f44.google.com with SMTP id 98e67ed59e1d1-382a3fe0d28so2096205a91.0 for ; Sat, 11 Jul 2026 19:25:46 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=purestorage.com; s=google2022; t=1783823146; x=1784427946; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=5Qa2xMYNGZeTkTFfjF7wK7qrZQsQxsgN9mLNQPwLDOE=; b=VWgEwAGNX0P+h1M78btRpees9JpiJF0TA2CkCWxLeIDfXBzLwOJHUVAEIXicusQGl2 YpgrYK1VIxchpMZ90/c6omgAOK7dqPBdmClbv11kWezXiTh+pX4yxaMtNZwCXM8jxW4x QlWCd4Cz++VvTW0FuBCWg93h/Ohz9aQZYKw06lMIfhcQ8QfecbQRBeMLd9bVfaKGd8jO bNZXuEE9PaJieXYE3IVujxRQZIjsugRoDoCjZnaA8QBai4WdUUGBuQEEfte+3UcEgqtS Ryd+MYeDAWUWwAR6yRrVTfl7nGStSR6O3TrxR4hyYTas2KiX7/x8mIo/8DQwNVsmn9tm t+6A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1783823146; x=1784427946; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to:content-type; bh=5Qa2xMYNGZeTkTFfjF7wK7qrZQsQxsgN9mLNQPwLDOE=; b=WLywqe8EMmvG10FACT8JCZZoAY3VXINBORu0YQ5L1CZplfLEowGyx+kWwJQTJfSLCu 5nHEtoMZyhM/H0zOdzUUaGD2CU86SbDVT5zbMwwvHfIF3p70jwumYjl+D8kVhJV7pFpK Dl3Yx3XK1qTu2GEqGG6Hio5BnqvzOCJ5WRmkbXFdRmVUNU6UFph1TQDtzx3JSGNfdCCp 9/93efu/gq16wtiuJUt10u9ZOsH/GWTcyTgf94VhITiQU6OiasAdFt66OzAXEoimImQU EhTwO4wUh+UWENhOQYwazsu7VRuLlvnLq2MIv/YYOvXgDaNfcLVT/wILKTN3dcGY/f53 3rRg== X-Forwarded-Encrypted: i=1; AHgh+RpAGXEknk/fo2iqaQcdZja5rYLbpo4IpexMrvDi5Eyt8PsGgIHopcshxaLfbOzunJdeYhsae2G0xXofu3Y=@vger.kernel.org X-Gm-Message-State: AOJu0YxwF53G//bXQn6rQPmS16FNTmbIBLW50moB1gB36J8i9/6af4Sy vNtoYemJxptnZSlw2n26fIywvmvlnS3OhbkbBNS7WvgkWuDYJ+olJ/k+S9W0EQjAZo4= X-Gm-Gg: AfdE7clOJQ0JaFLGcnpzlU5+lAGWVzhtBNubb89VydEDeWnhTByPzEPHxMEc4XLtCHY zDwwj/oLeA4LKXod86eebgeX4qonziaQoK9YOkiTLgaphBoXtEbGWLRIKTwIVaAi6lQOvZcDrvT esfBHDr3dCJzzwTvgY+cQaEPSSypgmtw00v4N0NjWqsS5ob3EPMQ8ggALAfuixLeq9hCMuYQwJo 9uqzlEAQ+FVmq/SkqG8CzYvMwwvwAdcZbirhvQNnl9YA3BvpLU7IyefZEmvCzWxIdxtQsTHP5vK WMG1Z39RIcIsIIPs/RdKamfvwT2SbYwtYnTQEvpC5fptl3Xh7SGwdCwG7ScG39Qz6qI7VQh8wy8 KE0Z5pxmRjLTbQL5wSwsYyTALk7k2VmCCYNrxUIbLdwA2PXiPfzTH7/zDqZA4CJGv5fi5iRrASP KxzvBfgoyfCMdv8E0= X-Received: by 2002:a17:90b:1645:b0:380:873:49cb with SMTP id 98e67ed59e1d1-38dc774d582mr4427579a91.21.1783823145888; Sat, 11 Jul 2026 19:25:45 -0700 (PDT) Received: from ceto.lan ([2607:fb90:9c20:2264::1c31]) by smtp.googlemail.com with ESMTPSA id 5a478bee46e88-3117462f5c7sm60704693eec.0.2026.07.11.19.25.44 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 11 Jul 2026 19:25:45 -0700 (PDT) From: Mohamed Khalfella To: Justin Tee , Naresh Gottumukkala , Paul Ely , Chaitanya Kulkarni , Christoph Hellwig , Jens Axboe , Keith Busch , Sagi Grimberg , James Smart , Hannes Reinecke , Randy Jennings , Dhaval Giani Cc: Aaron Dailey , linux-nvme@lists.infradead.org, linux-kernel@vger.kernel.org, Mohamed Khalfella Subject: [PATCH v5 16/16] nvme: Add support for CQT to nvme host Date: Sat, 11 Jul 2026 19:23:37 -0700 Message-ID: <20260712022437.3743117-17-mkhalfella@purestorage.com> X-Mailer: git-send-email 2.54.0 In-Reply-To: <20260712022437.3743117-1-mkhalfella@purestorage.com> References: <20260712022437.3743117-1-mkhalfella@purestorage.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 Content-Type: text/plain; charset="utf-8" TP4129 KATO Corrections and Clarifications defined CQT (Command Quiesce Time) which is used along with KATO (Keep Alive Timeout) to set an upper limit for attempting Cross-Controller Recovery. Add ctrl->cqt, read its value from controller identify response, expose it via sysfs, and have nvme_fence_timeout_ms() account for it. Use CQT to drive time-based recovery in fc, rdma, and tcp transports. Add a fenced_work delayed work to each transport controller. If CCR fails, fencing_work switches to error recovery immediately if CQT is not supported. Otherwise it schedules fenced_work after the remaining fence timeout, which also switches to error recovery when scheduled. Signed-off-by: Mohamed Khalfella Reviewed-by: Hannes Reinecke --- drivers/nvme/host/core.c | 1 + drivers/nvme/host/fc.c | 41 +++++++++++++++++++++++++++++++++++---- drivers/nvme/host/nvme.h | 5 +++-- drivers/nvme/host/rdma.c | 41 +++++++++++++++++++++++++++++++++++---- drivers/nvme/host/sysfs.c | 2 ++ drivers/nvme/host/tcp.c | 41 +++++++++++++++++++++++++++++++++++---- 6 files changed, 117 insertions(+), 14 deletions(-) diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c index 18de3805eff8..d3a2db50a89c 100644 --- a/drivers/nvme/host/core.c +++ b/drivers/nvme/host/core.c @@ -3821,6 +3821,7 @@ static int nvme_init_identify(struct nvme_ctrl *ctrl) ctrl->ciu =3D id->ciu; ctrl->cirn =3D le64_to_cpu(id->cirn); ctrl->ccrl =3D id->ccrl; + ctrl->cqt =3D le16_to_cpu(id->cqt); =20 ctrl->oacs =3D le16_to_cpu(id->oacs); ctrl->oncs =3D le16_to_cpu(id->oncs); diff --git a/drivers/nvme/host/fc.c b/drivers/nvme/host/fc.c index 006b5a984dfe..dca7a26a4b15 100644 --- a/drivers/nvme/host/fc.c +++ b/drivers/nvme/host/fc.c @@ -167,6 +167,7 @@ struct nvme_fc_ctrl { struct blk_mq_tag_set tag_set; =20 struct work_struct fencing_work; + struct delayed_work fenced_work; struct work_struct ioerr_work; struct delayed_work connect_work; =20 @@ -1878,6 +1879,18 @@ __nvme_fc_fcpop_chk_teardowns(struct nvme_fc_ctrl *c= trl, return ret; } =20 +static void nvme_fc_fenced_work(struct work_struct *work) +{ + struct nvme_fc_ctrl *fc_ctrl =3D container_of(to_delayed_work(work), + struct nvme_fc_ctrl, fenced_work); + struct nvme_ctrl *ctrl =3D &fc_ctrl->ctrl; + + dev_info(ctrl->device, "Time-based recovery finished\n"); + nvme_change_ctrl_state(ctrl, NVME_CTRL_FENCED); + if (nvme_change_ctrl_state(ctrl, NVME_CTRL_RESETTING)) + queue_work(nvme_reset_wq, &fc_ctrl->ioerr_work); +} + static void nvme_fc_fencing_work(struct work_struct *work) { struct nvme_fc_ctrl *fc_ctrl =3D @@ -1886,14 +1899,33 @@ static void nvme_fc_fencing_work(struct work_struct= *work) unsigned long rem; =20 rem =3D nvme_fence_ctrl(ctrl); - if (rem) - dev_info(ctrl->device, "CCR failed, starting error recovery\n"); + if (!rem) + goto done; + + if (!ctrl->cqt) { + dev_info(ctrl->device, + "CCR failed, CQT not supported, skip time-based recovery\n"); + goto done; + } + + dev_info(ctrl->device, + "CCR failed, switch to time-based recovery, timeout =3D %ums\n", + jiffies_to_msecs(rem)); + queue_delayed_work(nvme_wq, &fc_ctrl->fenced_work, rem); + return; =20 +done: nvme_change_ctrl_state(ctrl, NVME_CTRL_FENCED); if (nvme_change_ctrl_state(ctrl, NVME_CTRL_RESETTING)) queue_work(nvme_reset_wq, &fc_ctrl->ioerr_work); } =20 +static void nvme_fc_flush_fencing_works(struct nvme_fc_ctrl *ctrl) +{ + flush_work(&ctrl->fencing_work); + flush_delayed_work(&ctrl->fenced_work); +} + static void nvme_fc_ctrl_ioerr_work(struct work_struct *work) { @@ -1915,7 +1947,7 @@ nvme_fc_ctrl_ioerr_work(struct work_struct *work) return; } =20 - flush_work(&ctrl->fencing_work); + nvme_fc_flush_fencing_works(ctrl); nvme_fc_error_recovery(ctrl); } =20 @@ -3395,7 +3427,7 @@ nvme_fc_reset_ctrl_work(struct work_struct *work) struct nvme_fc_ctrl *ctrl =3D container_of(work, struct nvme_fc_ctrl, ctrl.reset_work); =20 - flush_work(&ctrl->fencing_work); + nvme_fc_flush_fencing_works(ctrl); nvme_stop_ctrl(&ctrl->ctrl); =20 /* will block will waiting for io to terminate */ @@ -3573,6 +3605,7 @@ nvme_fc_alloc_ctrl(struct device *dev, struct nvmf_ct= rl_options *opts, INIT_WORK(&ctrl->ctrl.reset_work, nvme_fc_reset_ctrl_work); INIT_DELAYED_WORK(&ctrl->connect_work, nvme_fc_connect_ctrl_work); INIT_WORK(&ctrl->fencing_work, nvme_fc_fencing_work); + INIT_DELAYED_WORK(&ctrl->fenced_work, nvme_fc_fenced_work); INIT_WORK(&ctrl->ioerr_work, nvme_fc_ctrl_ioerr_work); spin_lock_init(&ctrl->lock); =20 diff --git a/drivers/nvme/host/nvme.h b/drivers/nvme/host/nvme.h index 578fedda9946..8ea7d22b78f8 100644 --- a/drivers/nvme/host/nvme.h +++ b/drivers/nvme/host/nvme.h @@ -392,6 +392,7 @@ struct nvme_ctrl { u32 max_zone_append; #endif u16 crdt[3]; + u16 cqt; u16 oncs; u8 dmrl; u8 ciu; @@ -1334,8 +1335,8 @@ static inline bool nvme_multi_css(struct nvme_ctrl *c= trl) static inline unsigned long nvme_fence_timeout_ms(struct nvme_ctrl *ctrl) { if (ctrl->ctratt & NVME_CTRL_ATTR_TBKAS) - return 3 * ctrl->kato * 1000; - return 2 * ctrl->kato * 1000; + return 3 * ctrl->kato * 1000 + ctrl->cqt; + return 2 * ctrl->kato * 1000 + ctrl->cqt; } =20 #endif /* _NVME_H */ diff --git a/drivers/nvme/host/rdma.c b/drivers/nvme/host/rdma.c index 7c8108523980..3745b7242fce 100644 --- a/drivers/nvme/host/rdma.c +++ b/drivers/nvme/host/rdma.c @@ -113,6 +113,7 @@ struct nvme_rdma_ctrl { /* other member variables */ struct blk_mq_tag_set tag_set; struct work_struct fencing_work; + struct delayed_work fenced_work; struct work_struct err_work; =20 struct nvme_rdma_qe async_event_sqe; @@ -1152,6 +1153,18 @@ static void nvme_rdma_reconnect_ctrl_work(struct wor= k_struct *work) nvme_rdma_reconnect_or_remove(ctrl, ret); } =20 +static void nvme_rdma_fenced_work(struct work_struct *work) +{ + struct nvme_rdma_ctrl *rdma_ctrl =3D container_of(to_delayed_work(work), + struct nvme_rdma_ctrl, fenced_work); + struct nvme_ctrl *ctrl =3D &rdma_ctrl->ctrl; + + dev_info(ctrl->device, "Time-based recovery finished\n"); + nvme_change_ctrl_state(ctrl, NVME_CTRL_FENCED); + if (nvme_change_ctrl_state(ctrl, NVME_CTRL_RESETTING)) + queue_work(nvme_reset_wq, &rdma_ctrl->err_work); +} + static void nvme_rdma_fencing_work(struct work_struct *work) { struct nvme_rdma_ctrl *rdma_ctrl =3D container_of(work, @@ -1160,20 +1173,39 @@ static void nvme_rdma_fencing_work(struct work_stru= ct *work) unsigned long rem; =20 rem =3D nvme_fence_ctrl(ctrl); - if (rem) - dev_info(ctrl->device, "CCR failed, starting error recovery\n"); + if (!rem) + goto done; + + if (!ctrl->cqt) { + dev_info(ctrl->device, + "CCR failed, CQT not supported, skip time-based recovery\n"); + goto done; + } + + dev_info(ctrl->device, + "CCR failed, switch to time-based recovery, timeout =3D %ums\n", + jiffies_to_msecs(rem)); + queue_delayed_work(nvme_wq, &rdma_ctrl->fenced_work, rem); + return; =20 +done: nvme_change_ctrl_state(ctrl, NVME_CTRL_FENCED); if (nvme_change_ctrl_state(ctrl, NVME_CTRL_RESETTING)) queue_work(nvme_reset_wq, &rdma_ctrl->err_work); } =20 +static void nvme_rdma_flush_fencing_works(struct nvme_rdma_ctrl *ctrl) +{ + flush_work(&ctrl->fencing_work); + flush_delayed_work(&ctrl->fenced_work); +} + static void nvme_rdma_error_recovery_work(struct work_struct *work) { struct nvme_rdma_ctrl *ctrl =3D container_of(work, struct nvme_rdma_ctrl, err_work); =20 - flush_work(&ctrl->fencing_work); + nvme_rdma_flush_fencing_works(ctrl); nvme_stop_keep_alive(&ctrl->ctrl); flush_work(&ctrl->ctrl.async_event_work); nvme_rdma_teardown_io_queues(ctrl, false); @@ -2226,7 +2258,7 @@ static void nvme_rdma_reset_ctrl_work(struct work_str= uct *work) container_of(work, struct nvme_rdma_ctrl, ctrl.reset_work); int ret; =20 - flush_work(&ctrl->fencing_work); + nvme_rdma_flush_fencing_works(ctrl); nvme_stop_ctrl(&ctrl->ctrl); nvme_rdma_shutdown_ctrl(ctrl, false); =20 @@ -2348,6 +2380,7 @@ static struct nvme_rdma_ctrl *nvme_rdma_alloc_ctrl(st= ruct device *dev, INIT_DELAYED_WORK(&ctrl->reconnect_work, nvme_rdma_reconnect_ctrl_work); INIT_WORK(&ctrl->fencing_work, nvme_rdma_fencing_work); + INIT_DELAYED_WORK(&ctrl->fenced_work, nvme_rdma_fenced_work); INIT_WORK(&ctrl->err_work, nvme_rdma_error_recovery_work); INIT_WORK(&ctrl->ctrl.reset_work, nvme_rdma_reset_ctrl_work); =20 diff --git a/drivers/nvme/host/sysfs.c b/drivers/nvme/host/sysfs.c index 3853c9a6356e..7479cd370584 100644 --- a/drivers/nvme/host/sysfs.c +++ b/drivers/nvme/host/sysfs.c @@ -486,6 +486,7 @@ nvme_show_int_function(numa_node); nvme_show_int_function(queue_count); nvme_show_int_function(sqsize); nvme_show_int_function(kato); +nvme_show_int_function(cqt); =20 static ssize_t nvme_sysfs_ciu_show(struct device *dev, struct device_attribute *attr, @@ -966,6 +967,7 @@ static struct attribute *nvme_dev_attrs[] =3D { &dev_attr_sqsize.attr, &dev_attr_ciu.attr, &dev_attr_cirn.attr, + &dev_attr_cqt.attr, &dev_attr_hostnqn.attr, &dev_attr_hostid.attr, &dev_attr_ctrl_loss_tmo.attr, diff --git a/drivers/nvme/host/tcp.c b/drivers/nvme/host/tcp.c index a1711dd1d3c2..13e250110c1b 100644 --- a/drivers/nvme/host/tcp.c +++ b/drivers/nvme/host/tcp.c @@ -162,6 +162,7 @@ struct nvme_tcp_ctrl { struct nvme_ctrl ctrl; =20 struct work_struct fencing_work; + struct delayed_work fenced_work; struct work_struct err_work; struct delayed_work connect_work; struct nvme_tcp_request async_req; @@ -2501,6 +2502,18 @@ static void nvme_tcp_reconnect_ctrl_work(struct work= _struct *work) nvme_tcp_reconnect_or_remove(ctrl, ret); } =20 +static void nvme_tcp_fenced_work(struct work_struct *work) +{ + struct nvme_tcp_ctrl *tcp_ctrl =3D container_of(to_delayed_work(work), + struct nvme_tcp_ctrl, fenced_work); + struct nvme_ctrl *ctrl =3D &tcp_ctrl->ctrl; + + dev_info(ctrl->device, "Time-based recovery finished\n"); + nvme_change_ctrl_state(ctrl, NVME_CTRL_FENCED); + if (nvme_change_ctrl_state(ctrl, NVME_CTRL_RESETTING)) + queue_work(nvme_reset_wq, &tcp_ctrl->err_work); +} + static void nvme_tcp_fencing_work(struct work_struct *work) { struct nvme_tcp_ctrl *tcp_ctrl =3D container_of(work, @@ -2509,21 +2522,40 @@ static void nvme_tcp_fencing_work(struct work_struc= t *work) unsigned long rem; =20 rem =3D nvme_fence_ctrl(ctrl); - if (rem) - dev_info(ctrl->device, "CCR failed, starting error recovery\n"); + if (!rem) + goto done; =20 + if (!ctrl->cqt) { + dev_info(ctrl->device, + "CCR failed, CQT not supported, skip time-based recovery\n"); + goto done; + } + + dev_info(ctrl->device, + "CCR failed, switch to time-based recovery, timeout =3D %ums\n", + jiffies_to_msecs(rem)); + queue_delayed_work(nvme_wq, &tcp_ctrl->fenced_work, rem); + return; + +done: nvme_change_ctrl_state(ctrl, NVME_CTRL_FENCED); if (nvme_change_ctrl_state(ctrl, NVME_CTRL_RESETTING)) queue_work(nvme_reset_wq, &tcp_ctrl->err_work); } =20 +static void nvme_tcp_flush_fencing_works(struct nvme_ctrl *ctrl) +{ + flush_work(&to_tcp_ctrl(ctrl)->fencing_work); + flush_delayed_work(&to_tcp_ctrl(ctrl)->fenced_work); +} + static void nvme_tcp_error_recovery_work(struct work_struct *work) { struct nvme_tcp_ctrl *tcp_ctrl =3D container_of(work, struct nvme_tcp_ctrl, err_work); struct nvme_ctrl *ctrl =3D &tcp_ctrl->ctrl; =20 - flush_work(&to_tcp_ctrl(ctrl)->fencing_work); + nvme_tcp_flush_fencing_works(ctrl); if (nvme_tcp_key_revoke_needed(ctrl)) nvme_auth_revoke_tls_key(ctrl); nvme_stop_keep_alive(ctrl); @@ -2566,7 +2598,7 @@ static void nvme_reset_ctrl_work(struct work_struct *= work) container_of(work, struct nvme_ctrl, reset_work); int ret; =20 - flush_work(&to_tcp_ctrl(ctrl)->fencing_work); + nvme_tcp_flush_fencing_works(ctrl); if (nvme_tcp_key_revoke_needed(ctrl)) nvme_auth_revoke_tls_key(ctrl); nvme_stop_ctrl(ctrl); @@ -2956,6 +2988,7 @@ static struct nvme_tcp_ctrl *nvme_tcp_alloc_ctrl(stru= ct device *dev, INIT_DELAYED_WORK(&ctrl->connect_work, nvme_tcp_reconnect_ctrl_work); INIT_WORK(&ctrl->fencing_work, nvme_tcp_fencing_work); + INIT_DELAYED_WORK(&ctrl->fenced_work, nvme_tcp_fenced_work); INIT_WORK(&ctrl->err_work, nvme_tcp_error_recovery_work); INIT_WORK(&ctrl->ctrl.reset_work, nvme_reset_ctrl_work); =20 --=20 2.54.0