From nobody Fri Jun 19 09:06:06 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id B73D63BE628 for ; Fri, 24 Apr 2026 11:38:21 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1777030701; cv=none; b=CReoCSfUWt6kdkNUPV8iWsQeZDyr1X4VXeNERtcUBIYRdKeH4q9xb+miVVLJm0ezibmwp6E6SH3GKTd/px3YtEdUgpaNv5hfA9l/EREJynmpVc+qfs7kuheiEuSJQknIsvyooLAFpQhr9Ct453d6oK0ner51b5/V5cVnJc1c6QM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1777030701; c=relaxed/simple; bh=4zNJ6loTKjIjSN+QrYsZm8Egd19LSNJXk9dOsf5rVFw=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=lPhROo97R/HySmgNwbR42PEDxnxqgLU1qszovAwqSKa+v0M4j6JUeBK2xcJj3G43pTWdriUxJns3ROAqd9cPx3LcewCmnvxG2fs50+U15wWp906ElvuWpLgTOofVKWncvkZrZuL5NCBQdrRQ+GicTcH9/kI94LJCeQdzlegDvoQ= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=nDvxV33u; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="nDvxV33u" Received: by smtp.kernel.org (Postfix) with ESMTPS id 9BA09C2BCB2; Fri, 24 Apr 2026 11:38:21 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1777030701; bh=4zNJ6loTKjIjSN+QrYsZm8Egd19LSNJXk9dOsf5rVFw=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=nDvxV33uYGQJvOQ+OxQ5BbDazm9UjOaZDRD9SRHX1b2lYBsTf7Gw6+s+lgIshZ4zN u4pm4WSwCboI5xY0VfhMgrRW8e//3TIKlz5fE4bf+WKwLu5HB6ca81ULY+oujcgwQ9 39B9boXKXPd1q+X6prDOUxNpU8b4Q5aUfbt1Iq/3ZEu0D2R+H2fLOm+Iv4c2wJNKr8 SCmX1Ut177jcEELV0gvlYPvMqBEYkqoiwWyelccRvqc0qb0cpIxkvm0rXOCfyZe42Q 6oLmUP/FMCzY1e9jZNPj4OW5mzHtXpW5RVaZ673atld9qYe7QgTGZimAjaD7aXDRRd qqGt4stISGdfA== Received: from aws-us-west-2-korg-lkml-1.web.codeaurora.org (localhost.localdomain [127.0.0.1]) by smtp.lore.kernel.org (Postfix) with ESMTP id 8DB6FFE520D; Fri, 24 Apr 2026 11:38:21 +0000 (UTC) From: Joel Granados Date: Fri, 24 Apr 2026 13:37:51 +0200 Subject: [PATCH RFC 1/5] nvme: Add CDQ data structures to nvme spec header Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260424-jag-cdq-lkml-v1-1-d773343a717c@kernel.org> References: <20260424-jag-cdq-lkml-v1-0-d773343a717c@kernel.org> In-Reply-To: <20260424-jag-cdq-lkml-v1-0-d773343a717c@kernel.org> To: Keith Busch , Jens Axboe , Christoph Hellwig , Sagi Grimberg , Chaitanya Kulkarni , Jason Gunthorpe Cc: linux-nvme@lists.infradead.org, linux-kernel@vger.kernel.org, Joel Granados X-Mailer: b4 0.14.2 X-Developer-Signature: v=1; a=openpgp-sha256; l=2359; i=joel.granados@kernel.org; h=from:subject:message-id; bh=4zNJ6loTKjIjSN+QrYsZm8Egd19LSNJXk9dOsf5rVFw=; b=owJ4nAHtARL+kA0DAAoBupfNUreWQU8ByyZiAGnrVikChr+aVWumC6i1NEray6knJqmhtIjdn LZrhvR9iDi6OokBswQAAQoAHRYhBK5HCVcl5jElzssnkLqXzVK3lkFPBQJp61YpAAoJELqXzVK3 lkFPahEMAI7SmMJOy/dGbCgVfw2dl7JsnbTmjBUqVQqrzJkOoQu/dAxejUEo74twokZ5lSPXoCF IIF5UMKZjuSix+ItI2vxQYh2A5vO20066IUAHCvgRzEBuWFAsc5Bzy7P3FRw0e/BBQPI3LKvHft bBwBS2TZ6dPyMvEAvhDJX2Xe3a5R0TXcavVbWqBiLWaVhnkDmgC+lIlU18yO5KcsaHnaJji5azX kzXJL74j8ULmv9NmIhnDmsAZbKjwH8ci7S2DbWTWNU2fYwJAtWcZtjS+FZwNUSykPzxDfAxwyGK S/oIgrC2OgGk2bE1B611lMHkIAXuvAaG6OwC4Sc3qa3LhKvP/E8BFqdv3d2uLgBWuyhOggu1Z0p odADU07+heji/vQq7R/944g+bbs32CpSTpQSGE++yG72I2HuLwXB9IEzCjpk4TZaB66o4GGuP/P apBIn2FJF3QJ4J3+TQ1JyGcu2uBIFHfkeEKZt1lEp12QKSJnEmKEIjjEG6+YuXai5G/Bw9tetg5 t0= X-Developer-Key: i=joel.granados@kernel.org; a=openpgp; fpr=F1F8E46D30F0F6C4A45FF4465895FAAC338C6E77 X-Endpoint-Received: by B4 Relay for joel.granados@kernel.org/default with auth_id=239 Add Controller Data Queue (CDQ) related data structures and definitions to include/linux/nvme.h. These are just the data structures. No functional implementation yet. Signed-off-by: Joel Granados --- include/linux/nvme.h | 45 ++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 44 insertions(+), 1 deletion(-) diff --git a/include/linux/nvme.h b/include/linux/nvme.h index 655d194f8e722c3400ac00f76841e1af0281f38f..4a42f1614de962b9d448193193f= 68fe1968dfb6f 100644 --- a/include/linux/nvme.h +++ b/include/linux/nvme.h @@ -1314,6 +1314,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_cdq =3D 0x45, nvme_admin_dbbuf =3D 0x7C, nvme_admin_format_nvm =3D 0x80, nvme_admin_security_send =3D 0x81, @@ -1352,7 +1353,8 @@ enum nvme_admin_opcode { nvme_admin_opcode_name(nvme_admin_security_send), \ nvme_admin_opcode_name(nvme_admin_security_recv), \ nvme_admin_opcode_name(nvme_admin_sanitize_nvm), \ - nvme_admin_opcode_name(nvme_admin_get_lba_status)) + nvme_admin_opcode_name(nvme_admin_get_lba_status), \ + nvme_admin_opcode_name(nvme_admin_cdq)) =20 enum { NVME_QUEUE_PHYS_CONTIG =3D (1 << 0), @@ -1412,6 +1414,10 @@ enum { NVME_FWACT_ACTV =3D (2 << 3), }; =20 +enum { + NVME_FEAT_CDQ_ID_MASK =3D GENMASK(15, 0), +}; + struct nvme_supported_log { __le32 lids[256]; }; @@ -1590,6 +1596,42 @@ struct nvme_directive_cmd { __u32 rsvd16[3]; }; =20 +enum { + NVME_CDQ_SEL_CREATE_CDQ =3D 0x0, + NVME_CDQ_SEL_DELETE_CDQ =3D 0x1 +}; + +enum { + NVME_CDQ_CFG_PC_DISCONT =3D 0x0, + NVME_CDQ_CFG_PC_CONT =3D 0x1 +}; + +union nvme_cdq_dw11 { + struct { + __le16 flags; + __le16 cqs; + }; + struct { + __le16 cdqid; + __le16 rsvd; + }; +}; + +struct nvme_cdq { + __u8 opcode; + __u8 flags; + __u16 command_id; + __u32 rsvd1[5]; + __le64 prp1; + __le32 rsvd8[2]; + __u8 sel; + __u8 rsvd10; + __le16 mos; + union nvme_cdq_dw11 dw11; + __le32 cdqsize; + __u32 rsvd13[3]; +}; + /* * Fabrics subcommands. */ @@ -2000,6 +2042,7 @@ struct nvme_command { struct nvme_dbbuf dbbuf; struct nvme_directive_cmd directive; struct nvme_io_mgmt_recv_cmd imr; + struct nvme_cdq cdq; }; }; =20 --=20 2.50.1 From nobody Fri Jun 19 09:06:06 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id D67F93BE17B for ; Fri, 24 Apr 2026 11:38:21 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1777030701; cv=none; b=TQw3+IDQEI6yhoGRz9aeAZJ9bqCajCLSXu/BNw4OSz1OlLwc+Gn0/YLfXdNMS/3wcT9fDNQzh1QNMxnuqStV6wk10WAJOKDC57UJe5vzPcI7KpsJyh10NmJgG+NslkfQPFPKjt5Gqm9JgB/rPfijU4TMnUM6XzcLppBFfnqMTLE= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1777030701; c=relaxed/simple; bh=DyeHMsiA53Hg5qFneyAbch7hM4sTqy1Q2kOzjNNoSVs=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=IGDJ8H8qI+Cqh3I/ajhtrJYWFok8vPjflHZZO0sQhofrdxtyQ5nRmtLL4cwSvx/g6VUjVPewafLKOtNgUqAuOkr+GvQOOd9OwIX8y1icc2FXIIwYwRMQEDZQMcqU4PvBqJPkbxNML1uAkte5Jth9v0VelNEL8XwThqMfU8vUfnk= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=AcULKuxX; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="AcULKuxX" Received: by smtp.kernel.org (Postfix) with ESMTPS id AA2B1C2BCB8; Fri, 24 Apr 2026 11:38:21 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1777030701; bh=DyeHMsiA53Hg5qFneyAbch7hM4sTqy1Q2kOzjNNoSVs=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=AcULKuxXO0kW4nxweg42tbqzWYh8+yhBTx9zf3EslgfCYZ0LZ43Xpju/ysY7K1tT1 H+5WKyfz8yzwNChuIZ8yuDY+AYMQ6BzA/8rJPGfYIogmrfF2dIfRrd8CAtnj0HWokT ZwrGf1Ih2oC5DzHxWPa29gxhtoJapLRUzZcJq51slqq/UWfm6R1i4RlKRJ8F9ZJLps YrxJZ2rkn+vXh2abRiamYltZhxNS5car04inYiXtKyYQzTR8RLndkLVfFiXAvcKm1j 5P4zOzbnYuEl7uEUh4FusR2CHI9hZA/v9dGp2mnm5a8aKiW3VC44567iQLWSUvSZzM B+X0UrTRlXB2A== Received: from aws-us-west-2-korg-lkml-1.web.codeaurora.org (localhost.localdomain [127.0.0.1]) by smtp.lore.kernel.org (Postfix) with ESMTP id 9C314FE5209; Fri, 24 Apr 2026 11:38:21 +0000 (UTC) From: Joel Granados Date: Fri, 24 Apr 2026 13:37:52 +0200 Subject: [PATCH RFC 2/5] nvme: Add CDQ data structures to host driver Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260424-jag-cdq-lkml-v1-2-d773343a717c@kernel.org> References: <20260424-jag-cdq-lkml-v1-0-d773343a717c@kernel.org> In-Reply-To: <20260424-jag-cdq-lkml-v1-0-d773343a717c@kernel.org> To: Keith Busch , Jens Axboe , Christoph Hellwig , Sagi Grimberg , Chaitanya Kulkarni , Jason Gunthorpe Cc: linux-nvme@lists.infradead.org, linux-kernel@vger.kernel.org, Joel Granados X-Mailer: b4 0.14.2 X-Developer-Signature: v=1; a=openpgp-sha256; l=1538; i=joel.granados@kernel.org; h=from:subject:message-id; bh=DyeHMsiA53Hg5qFneyAbch7hM4sTqy1Q2kOzjNNoSVs=; b=owJ4nAHtARL+kA0DAAoBupfNUreWQU8ByyZiAGnrVikL1ufBNaxO3jg3y3Fffg+8zf+zzw/B0 P4HbfBBQDTamokBswQAAQoAHRYhBK5HCVcl5jElzssnkLqXzVK3lkFPBQJp61YpAAoJELqXzVK3 lkFPV4kL/0d5y27c0jUzAL+8oyMRSaia0vmNA+oFoLsBT8frQWdmpj2QI0FNzwgs5iW2L+PxQoy uLAlgCpABgAtn+4ya4fqJV3c/sZW14Fgvg6rKfU2NevWJftYVqiRiIfm61a4zwwCr+qhby2WhFN 0GHodx3+LUgRCa/NVVGB5SoE1sYevG/IO8T9zpw10aUJ2x6CuO+b9Q/JScvqUAxq7gCx6y6YJ6x hoiLk5oXsP7USr164PHKFhntwcIPlYCFcI+7QiU8MIMu+z3JGxxaNbavNPJbAkulfKhCBaa4L7S FSZ0V1ikIBLK3gy0LwfYz7EI6nzDdP8gTQ0e0NZ9ZsCGc7R73xiUwZyz0Y32JYoPuOSPJqUSZvp lSBtM3Svfhk7r6IoL5/+KiV8IBctEvH63Jg6f/+8wEdCJXx81IA4GRpyYif4z80eyjgV/fNMuma +Amx+WANJbExznXr5EPSB6NzOFV7EmQv3hu9jy6nShqDzvtMe5Zf7/LE9uPIgZKOTj1lOip9a27 m0= X-Developer-Key: i=joel.granados@kernel.org; a=openpgp; fpr=F1F8E46D30F0F6C4A45FF4465895FAAC338C6E77 X-Endpoint-Received: by B4 Relay for joel.granados@kernel.org/default with auth_id=239 Add host-side Controller Data Queue (CDQ) data structures and function declarations to drivers/nvme/host/nvme.h: - Add cdqs xarray to nvme_ctrl for managing CDQ instances - Add cdq_nvme_queue structure containing: - DMA mapping state - PRP list management - eventfd context for tail pointer event notifications Signed-off-by: Joel Granados --- drivers/nvme/host/nvme.h | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/drivers/nvme/host/nvme.h b/drivers/nvme/host/nvme.h index 9971045dbc05e9bb9d7fa32ad540fd107d8c8b83..30d5052c7728c0d5c5e8772ff53= 1bc672e96940f 100644 --- a/drivers/nvme/host/nvme.h +++ b/drivers/nvme/host/nvme.h @@ -466,6 +466,7 @@ struct nvme_ctrl { enum nvme_dctype dctype; =20 u16 awupf; /* 0's based value. */ + struct xarray cdqs; /* Controller Data Queue */ }; =20 static inline enum nvme_ctrl_state nvme_ctrl_state(struct nvme_ctrl *ctrl) @@ -619,6 +620,20 @@ static inline unsigned long nvme_get_virt_boundary(str= uct nvme_ctrl *ctrl, return NVME_CTRL_PAGE_SIZE - 1; } =20 +#define MAX_NR_CDQ_PRPS 20 +struct cdq_nvme_queue { + struct nvme_ctrl *ctrl; + __u32 size_nbyte; + u16 cdq_id; + struct eventfd_ctx *tpt_efd_ctx; + struct sg_table sgt; + struct page **pages; + unsigned long nr_pages; + void *prp_lists[MAX_NR_CDQ_PRPS]; + dma_addr_t prp_lists_dma[MAX_NR_CDQ_PRPS]; + u32 nr_prp_lists; /*number of PRP lists*/ +}; + struct nvme_ctrl_ops { const char *name; struct module *module; --=20 2.50.1 From nobody Fri Jun 19 09:06:06 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id DBA3A3BE638 for ; Fri, 24 Apr 2026 11:38:21 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1777030701; cv=none; b=e6kjKylpAwepLfmVxIXggVqGEy360RZvuQFi65FnzSjMdSLBiE30aI8IinKSx2B+3gq0cCT5uRH5PrdHtQqyJwNOyQep7TmoaxDaD4aM4hczMqJpMqPQAIcggbio05sNsTs7isPntuV9JPbaIoy86FHhy2WdM5ZS9nU9MiIgAVk= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1777030701; c=relaxed/simple; bh=hVV/r0xgERPhDudR4npmn1JJFr+BsWKu5X3JBCDiLsA=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=idXoymVLszFRHKMRn7MKfWmivC+Rz/HWPWF4qclPKSplS7UOnhApEYEYssFhpWtYm4lJpuUykUZ1tp5Kog5RRY3iixOV3xvNkG3fOUQEZMSmEKqv3Gguk/3HirH/RNawK6GZktkD5TJcNL5tK9tSAAUMinGJl5PbZbcVpedikGA= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=c57hvKoK; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="c57hvKoK" Received: by smtp.kernel.org (Postfix) with ESMTPS id B5F52C2BCB5; Fri, 24 Apr 2026 11:38:21 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1777030701; bh=hVV/r0xgERPhDudR4npmn1JJFr+BsWKu5X3JBCDiLsA=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=c57hvKoKvpgWlGQZxM41IUVmk7LhTtDmh+7hBvyJujslnePrY+ieDBqHphld9NxjD MS6teCX31+rS3uRjeXYe4iZtL8AaB5IW3w68+r4O07LnZXHUr12uK43fihfwS6J1kn f7XBXxjxwz2YPZ6be6SYfF8dVvOwqpdVRB1nFxqrdy5ltIs/iAl5RaPu+/HTbSErz3 9u4TtnIP/EkS9jmNV6vpiQ4f3yoc6wzgCxny78P3/vO7m2beGN7zSQJG+/sV7e0BaA 3Nmnok8P/kbZYQgPcOTCvyOPCWqXxTAVvivss+WAG3YXJqcfyuCT+LzOGtFLI2AlEW WcPRE8Wem+akA== Received: from aws-us-west-2-korg-lkml-1.web.codeaurora.org (localhost.localdomain [127.0.0.1]) by smtp.lore.kernel.org (Postfix) with ESMTP id AC340FE5210; Fri, 24 Apr 2026 11:38:21 +0000 (UTC) From: Joel Granados Date: Fri, 24 Apr 2026 13:37:53 +0200 Subject: [PATCH RFC 3/5] nvme: Add NVME_AER_ONE_SHOT callback handler Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260424-jag-cdq-lkml-v1-3-d773343a717c@kernel.org> References: <20260424-jag-cdq-lkml-v1-0-d773343a717c@kernel.org> In-Reply-To: <20260424-jag-cdq-lkml-v1-0-d773343a717c@kernel.org> To: Keith Busch , Jens Axboe , Christoph Hellwig , Sagi Grimberg , Chaitanya Kulkarni , Jason Gunthorpe Cc: linux-nvme@lists.infradead.org, linux-kernel@vger.kernel.org, Joel Granados X-Mailer: b4 0.14.2 X-Developer-Signature: v=1; a=openpgp-sha256; l=3053; i=joel.granados@kernel.org; h=from:subject:message-id; bh=hVV/r0xgERPhDudR4npmn1JJFr+BsWKu5X3JBCDiLsA=; b=owJ4nAHtARL+kA0DAAoBupfNUreWQU8ByyZiAGnrVirLacrNUYell8Uv8VBior6/IA2XFUPih BGJqO+aidEjHokBswQAAQoAHRYhBK5HCVcl5jElzssnkLqXzVK3lkFPBQJp61YqAAoJELqXzVK3 lkFP0dYMAJOxBxsTbTSwPIJXXJ6Emu0lE9y9Uqyx844qHLIhXVuoEmvRbw1lpyfm1XIkx+GRXK7 ZK6Y7XzQnDmEsIqgkeBFAwNpHQlomGLAqjkr9GcsV+jtovlagXBzKrOFSW/OvT4cm92p5HvlU6b 1j99YLbeVxVBfK0D0ymWYXey7xw7NpnopLGm/HSZJEkL5wGl7Ei6sbarbR2Xwn6u9qXbLmHb6bv 1aMVbMMYbDPkYBMq68r6mytD3ZIhwI5/cdRr/IkZz/CA0bFl+ydkv/o6PK/NY8651jHnXcK5HPQ OYMLu8KQuVV005PyvL94n+0iv7Ug+gyx2xdqbaaf/UIMzifQRK0tuXnaH0udjnkS+qUPKcMBjhW EhMBz/m5NJlrGoYaNNM/sWHjZC0kf8+A9iIFwJ2kHo+/f/nx4M8FLnmZJ25eNOdIjj6ovNwdKqL CHyBaR4q9JK/J4IHAnbDGNOan/llKvKh1N8xpM17Lx83U8gkApa+FoaPWjr16DzAJ9gJVq+t4E6 sI= X-Developer-Key: i=joel.granados@kernel.org; a=openpgp; fpr=F1F8E46D30F0F6C4A45FF4465895FAAC338C6E77 X-Endpoint-Received: by B4 Relay for joel.granados@kernel.org/default with auth_id=239 Add support for handling NVME_AER_ONE_SHOT asynchronous event notifications. One-shot events, unlike traditional AERs, are not requeued and include additional event parameters in the upper 32 bits of the result. Add nvme_handle_aen_oneshot() stub to dispatch one-shot events based on subtype. This will be extended by subsequent patches to handle specific one-shot event types like CDQ tail pointer events. Extend nvme_complete_async_event() to handle the NVME_AER_ONE_SHOT case, extracting the event parameter from the 64-bit result and passing it to the handler. Signed-off-by: Joel Granados --- drivers/nvme/host/core.c | 20 ++++++++++++++++++++ include/linux/nvme.h | 5 +++++ 2 files changed, 25 insertions(+) diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c index 766e9cc4ffca5e269c5e85dd4a0323dc99e5658c..be4807591d2d80d228c10e3c78b= 6b7dc371b3865 100644 --- a/drivers/nvme/host/core.c +++ b/drivers/nvme/host/core.c @@ -4747,6 +4747,16 @@ static u32 nvme_aer_subtype(u32 result) return (result & 0xff00) >> 8; } =20 +static bool nvme_handle_aen_oneshot(struct nvme_ctrl *ctrl, u32 result, u3= 2 event_param) +{ + u32 aer_subtype =3D nvme_aer_subtype(result); + + /* Will be extended to handle specific one-shot event types */ + if (aer_subtype =3D=3D NVME_AER_ONE_SHOT_CDQ_TAIL_PTR) + return -ENOSYS; + return false; +} + static bool nvme_handle_aen_notice(struct nvme_ctrl *ctrl, u32 result) { u32 aer_notice_type =3D nvme_aer_subtype(result); @@ -4795,6 +4805,7 @@ void nvme_complete_async_event(struct nvme_ctrl *ctrl= , __le16 status, volatile union nvme_result *res) { u32 result =3D le32_to_cpu(res->u32); + u32 event_param =3D 0; u32 aer_type =3D nvme_aer_type(result); u32 aer_subtype =3D nvme_aer_subtype(result); bool requeue =3D true; @@ -4807,6 +4818,15 @@ void nvme_complete_async_event(struct nvme_ctrl *ctr= l, __le16 status, case NVME_AER_NOTICE: requeue =3D nvme_handle_aen_notice(ctrl, result); break; + case NVME_AER_ONE_SHOT: + /* + * One-shot events like CDQ tail pointer events. + * Extract event parameter from upper 32 bits. + */ + event_param =3D le64_to_cpu(res->u64) >> 32; + requeue =3D nvme_handle_aen_oneshot(ctrl, result, event_param); + trace_nvme_async_event(ctrl, result); + break; case NVME_AER_ERROR: /* * For a persistent internal error, don't run async_event_work diff --git a/include/linux/nvme.h b/include/linux/nvme.h index 4a42f1614de962b9d448193193f68fe1968dfb6f..6948e39842d48dc9974579ea1f9= c4d5330238275 100644 --- a/include/linux/nvme.h +++ b/include/linux/nvme.h @@ -840,6 +840,7 @@ enum { NVME_AER_ERROR =3D 0, NVME_AER_SMART =3D 1, NVME_AER_NOTICE =3D 2, + NVME_AER_ONE_SHOT =3D 4, NVME_AER_CSS =3D 6, NVME_AER_VS =3D 7, }; @@ -855,6 +856,10 @@ enum { NVME_AER_NOTICE_DISC_CHANGED =3D 0xf0, }; =20 +enum { + NVME_AER_ONE_SHOT_CDQ_TAIL_PTR =3D 0x00, +}; + enum { NVME_AEN_BIT_NS_ATTR =3D 8, NVME_AEN_BIT_FW_ACT =3D 9, --=20 2.50.1 From nobody Fri Jun 19 09:06:06 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id EA3503BE63F for ; Fri, 24 Apr 2026 11:38:21 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1777030702; cv=none; b=rx+Z0u2pW/0WlMHKzF3WVXeGY0WLaAdBm+8UuaJIaH/AJyofM1KC7eH5NrgBBJVgXzrZHzFkDv1Ck44ZmK7klekW3gfM7KYFGcjJt521NWOhbOLe/UPPqJxQpFlJBNrcJZ1/byxrkI6IllM8BWWWkwoWE/rJZAWgBhNYAb7Er6s= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1777030702; c=relaxed/simple; bh=03dIhM6pDJ5/ddT82ZomuEoboyghm3luwc7xkzLLs88=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=tBDut8z6ZXKp/QIT3P40n6tG57i10PBUSdSpAaDjpF+VqJqnBGt54WuGA9zjYYuGLpIqudXnkO9S8ZWkQ5xF104Qs2PTlRNPYPldLqiItRkPv/GMIlNEeLAXqXm3XhLZ7+epMI47nx2pSy0gLiCP1lMRe+qFnmWtZrcI1Wum+PU= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=GoAHDJBo; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="GoAHDJBo" Received: by smtp.kernel.org (Postfix) with ESMTPS id C2983C2BCB9; Fri, 24 Apr 2026 11:38:21 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1777030701; bh=03dIhM6pDJ5/ddT82ZomuEoboyghm3luwc7xkzLLs88=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=GoAHDJBocJCSilbHiUXr07URbFr2YbEOt7WKD6E0MQPET8yAOLO2OpGW3RCr7mwlt tHMDDsjy5hTcn6vX0JDKjN2lsCGfBJkHpaPAPeY2qbTFhxeuwFnkcaj6hJ3LEprcjo oI48q4EslC4SIccLQkeRUHnPuWeKvzxL/KA7XJVWa15UuiRxoy6/v2cJUaGA1jXqQL +yxEke8aWyut5uecZM+6E9x5IkIMft2FK7cfN8JfO/cJlN2pJGjIdQq9/91imtlDa4 Srvz8UgjjO9YOCrgmx7dDrToo3XD6pG/gO8PPwgubdAfJPz/Gy8M/ZlcpRyi3O5Ezz AwQclZNA1ZPhQ== Received: from aws-us-west-2-korg-lkml-1.web.codeaurora.org (localhost.localdomain [127.0.0.1]) by smtp.lore.kernel.org (Postfix) with ESMTP id BAD33FE520E; Fri, 24 Apr 2026 11:38:21 +0000 (UTC) From: Joel Granados Date: Fri, 24 Apr 2026 13:37:54 +0200 Subject: [PATCH RFC 4/5] nvme: Implement CDQ core functionality Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260424-jag-cdq-lkml-v1-4-d773343a717c@kernel.org> References: <20260424-jag-cdq-lkml-v1-0-d773343a717c@kernel.org> In-Reply-To: <20260424-jag-cdq-lkml-v1-0-d773343a717c@kernel.org> To: Keith Busch , Jens Axboe , Christoph Hellwig , Sagi Grimberg , Chaitanya Kulkarni , Jason Gunthorpe Cc: linux-nvme@lists.infradead.org, linux-kernel@vger.kernel.org, Joel Granados X-Mailer: b4 0.14.2 X-Developer-Signature: v=1; a=openpgp-sha256; l=11713; i=joel.granados@kernel.org; h=from:subject:message-id; bh=03dIhM6pDJ5/ddT82ZomuEoboyghm3luwc7xkzLLs88=; b=owJ4nAHtARL+kA0DAAoBupfNUreWQU8ByyZiAGnrVivxNLZQykSGg3CE/47xTNKxYrOEd9nZf vOda17oyKYwHIkBswQAAQoAHRYhBK5HCVcl5jElzssnkLqXzVK3lkFPBQJp61YrAAoJELqXzVK3 lkFP2rgMAJbWG0HCVpWSQ6yt2fAL2UfZYcpGbZAEeROPC/XSdN4bs9E3Ex6WXAsb94amuofT2hs EPJuiG1pRPneAJoiIe6Qo6/Qss/rOhyZNtzaZEh3ljWWEuFxnB0an6KlloMlCPRwZxhPl5XtLL8 E7Cr3gQnoQmmoxc+jNrYwBQCD6/8fUuTe+vweaO4Fteys4meuuxVc3RiQqS0YlXkQNXXcRP45fd 4vhA6A1ldF1XJBO7f/DlX9gF2UJdxl8ruE1awQXrvQWt8wohZa+CsuGSmuH1XBmS+gT9fyAD/nk nb78UEpqT+Cbv5O7YoOysw1X74mOMhVEg9AXni0pWdDS8HBEJzZLMWumFNXFDI4Tt4RmQAEL/0R fMMukadKvTNK8U5XJ0SzNuxD8Uu4JrQhA5DyptiCMqUzrvEwTadNb9NNfWuY6U0vw6rVNRXdOr/ 7FEVQAasLkGgfnEL/tDGHIkuVAjAzw8CmBd9gJKUkGb6owM5xMsFUEoUc9pGk0xlUF4JFt/86g5 bg= X-Developer-Key: i=joel.granados@kernel.org; a=openpgp; fpr=F1F8E46D30F0F6C4A45FF4465895FAAC338C6E77 X-Endpoint-Received: by B4 Relay for joel.granados@kernel.org/default with auth_id=239 Add Controller Data Queue (CDQ) support to the NVMe driver. CDQs enable efficient device-to-host data transfer through dedicated queues with DMA-mapped user memory. This patch implements: - DMA mapping with user page pinning (nvme_cdq_map_dma_usr) - PRP list allocation for discontiguous memory (nvme_cdq_alloc_prp_list) - CDQ create/delete commands (nvme_cdq_create, nvme_cdq_delete) - Tail pointer event notification via eventfd (nvme_cdq_set_tpt) - Async event notification handling for CDQ events - xarray-based CDQ instance management - Integration into controller init/free paths - Add function declarations for CDQ lifecycle management: nvme_cdq_create(), nvme_cdq_delete(), nvme_cdq_set_tpt() Signed-off-by: Joel Granados --- drivers/nvme/host/core.c | 306 +++++++++++++++++++++++++++++++++++++++++++= ++-- drivers/nvme/host/nvme.h | 5 + 2 files changed, 304 insertions(+), 7 deletions(-) diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c index be4807591d2d80d228c10e3c78b6b7dc371b3865..1bcdf328b0edf0ede7a799a965f= d0b539404e3c6 100644 --- a/drivers/nvme/host/core.c +++ b/drivers/nvme/host/core.c @@ -23,6 +23,7 @@ #include #include #include +#include =20 #include "nvme.h" #include "fabrics.h" @@ -1252,6 +1253,298 @@ u32 nvme_passthru_start(struct nvme_ctrl *ctrl, str= uct nvme_ns *ns, u8 opcode) } EXPORT_SYMBOL_NS_GPL(nvme_passthru_start, "NVME_TARGET_PASSTHRU"); =20 +static void nvme_cdq_unmap_dma_usr(struct nvme_ctrl *ctrl, struct cdq_nvme= _queue *cdq) +{ + dma_unmap_sgtable(ctrl->dev, &cdq->sgt, DMA_BIDIRECTIONAL, 0); + sg_free_table(&cdq->sgt); + unpin_user_pages(cdq->pages, cdq->nr_pages); + kfree(cdq->pages); +} + +/* nvme_cdq_alloc_from_usr - Make user virtual memory DMAable */ +static int nvme_cdq_map_dma_usr(struct nvme_ctrl *ctrl, struct cdq_nvme_qu= eue *cdq, + const u32 size_nbytes, unsigned long uaddr) +{ + int ret =3D -ENOMEM; + struct page **pages; + + if (!PAGE_ALIGN(uaddr)) + return -EINVAL; + + cdq->nr_pages =3D (size_nbytes + PAGE_SIZE - 1) >> PAGE_SHIFT; + pages =3D kvmalloc_array(cdq->nr_pages, sizeof(struct page *), GFP_KERNEL= ); + if (!pages) + return -ENOMEM; + + mmap_read_lock(current->mm); + ret =3D pin_user_pages(uaddr, cdq->nr_pages, FOLL_WRITE | FOLL_LONGTERM, = pages); + if (ret !=3D cdq->nr_pages) { + if (ret > 0) + unpin_user_pages(pages, ret); + ret =3D -EFAULT; + mmap_read_unlock(current->mm); + goto free_pages; + } + mmap_read_unlock(current->mm); + + ret =3D sg_alloc_table_from_pages_segment(&cdq->sgt, pages, cdq->nr_pages, + 0, size_nbytes, PAGE_SIZE, GFP_KERNEL); + if (ret) + goto unpin_pages; + + ret =3D dma_map_sgtable(ctrl->dev, &cdq->sgt, DMA_BIDIRECTIONAL, 0); + if (ret) + goto free_sgt; + + cdq->pages =3D pages; + + return 0; + +free_sgt: + sg_free_table(&cdq->sgt); + +unpin_pages: + unpin_user_pages(pages, cdq->nr_pages); + +free_pages: + kvfree(pages); + + return ret; +} + +static void nvme_cdq_free_prp_lists(struct nvme_ctrl *ctrl, + struct cdq_nvme_queue *cdq) +{ + for (int i =3D 0; i < cdq->nr_prp_lists; ++i) { + if (cdq->prp_lists[i]) + dma_free_coherent(ctrl->dev, PAGE_SIZE, + cdq->prp_lists[i], + cdq->prp_lists_dma[i]); + } +} +static int nvme_cdq_alloc_prp_single(struct nvme_ctrl *ctrl, struct cdq_nv= me_queue *cdq) +{ + cdq->nr_prp_lists =3D 0; + memset(cdq->prp_lists, 0, sizeof(cdq->prp_lists)); + cdq->prp_lists_dma[0] =3D sg_dma_address(cdq->sgt.sgl); + cdq->prp_lists_dma[1] =3D 0; + return 0; +} + +static int nvme_cdq_alloc_prp_list(struct nvme_ctrl *ctrl, struct cdq_nvme= _queue *cdq) +{ + unsigned int i, prp_list_idx =3D 0; + struct scatterlist *sg; + u64 *prp_list, *prp_list_tmp; + dma_addr_t prp_list_tmp_dma; + + prp_list =3D dma_alloc_coherent(ctrl->dev, PAGE_SIZE, &prp_list_tmp_dma, = GFP_KERNEL); + if (!prp_list) + return -ENOMEM; + + cdq->prp_lists[0] =3D prp_list; + cdq->prp_lists_dma[0] =3D prp_list_tmp_dma; + cdq->nr_prp_lists =3D 1; + + for_each_sgtable_dma_sg(&cdq->sgt, sg, i) { + if (prp_list_idx =3D=3D PAGE_SIZE >> 3) { + if (cdq->nr_prp_lists =3D=3D MAX_NR_CDQ_PRPS) + goto prps_err; + + prp_list_tmp =3D dma_alloc_coherent(ctrl->dev, + PAGE_SIZE, &prp_list_tmp_dma, GFP_KERNEL); + if (!prp_list_tmp) + goto prps_err; + + cdq->prp_lists_dma[cdq->nr_prp_lists] =3D prp_list_tmp_dma; + cdq->prp_lists[cdq->nr_prp_lists++] =3D prp_list_tmp; + + prp_list =3D prp_list_tmp; + prp_list_idx =3D 0; + } + prp_list[prp_list_idx++] =3D sg_dma_address(sg); + } + + return 0; + +prps_err: + nvme_cdq_free_prp_lists(ctrl, cdq); + + return -EFAULT; +} + +static int nvme_cdq_cmd_delete(struct nvme_ctrl *ctrl, const u16 cdq_id) +{ + struct nvme_command c =3D { + .cdq.opcode =3D nvme_admin_cdq, + .cdq.sel =3D NVME_CDQ_SEL_DELETE_CDQ, + .cdq.dw11.cdqid =3D cdq_id + }; + + return __nvme_submit_sync_cmd(ctrl->admin_q, &c, NULL, NULL, 0, NVME_QID_= ANY, 0); +} + +static int nvme_cdq_cmd_create(struct cdq_nvme_queue *cdq, const u16 mos, = const u16 cqs, + const u16 dw11_flags) +{ + int ret; + union nvme_result result =3D { }; + struct nvme_command c =3D { + .cdq.opcode =3D nvme_admin_cdq, + .cdq.sel =3D NVME_CDQ_SEL_CREATE_CDQ, + .cdq.mos =3D cpu_to_le16(mos), + .cdq.dw11.cqs =3D cpu_to_le16(cqs), + .cdq.cdqsize =3D cdq->size_nbyte >> 2, // >>2: size is in dwords + .cdq.dw11.flags =3D cpu_to_le16(dw11_flags), + .cdq.prp1 =3D cdq->prp_lists_dma[0] + }; + + ret =3D __nvme_submit_sync_cmd(cdq->ctrl->admin_q, &c, &result, NULL, 0, = NVME_QID_ANY, 0); + if (ret) + return ret; + + cdq->cdq_id =3D le16_to_cpu(result.u16); + + return ret; +} + +int nvme_cdq_set_tpt(struct nvme_ctrl *ctrl, u16 cdq_id, const int tpt_fd) +{ + + struct cdq_nvme_queue *cdq; + + if (tpt_fd < 0) + return -EINVAL; + + cdq =3D xa_load(&ctrl->cdqs, cdq_id); + if (xa_is_err(cdq)) + return -EINVAL; + + if (cdq->tpt_efd_ctx) + eventfd_ctx_put(cdq->tpt_efd_ctx); + + cdq->tpt_efd_ctx =3D eventfd_ctx_fdget(tpt_fd); + if (IS_ERR(cdq->tpt_efd_ctx)) + return -EINVAL; + + return 0; +} +EXPORT_SYMBOL_GPL(nvme_cdq_set_tpt); + +int nvme_cdq_create(struct nvme_ctrl *ctrl, const u16 mos, const u16 cqs, + unsigned long uaddr, const u32 size_nbyte, u16 *cdq_id) +{ + int ret; + u16 d11_flags; + struct cdq_nvme_queue *cdq, *xa_ret; + + cdq =3D kzalloc(sizeof(*cdq), GFP_KERNEL); + if (!cdq) + return -ENOMEM; + + cdq->ctrl =3D ctrl; + cdq->size_nbyte =3D size_nbyte; + + ret =3D nvme_cdq_map_dma_usr(ctrl, cdq, size_nbyte, uaddr); + if (ret) + goto err_cdq_free; + + if (cdq->sgt.nents > 1) { + d11_flags =3D NVME_CDQ_CFG_PC_DISCONT; + ret =3D nvme_cdq_alloc_prp_list(ctrl, cdq); + } else { + d11_flags =3D NVME_CDQ_CFG_PC_CONT; + ret =3D nvme_cdq_alloc_prp_single(ctrl, cdq); + } + + if (ret) + goto err_cdq_unmap_dma; + + ret =3D nvme_cdq_cmd_create(cdq, mos, cqs, d11_flags); + if (ret) + goto err_cdq_free_prp; + + xa_ret =3D xa_store(&ctrl->cdqs, cdq->cdq_id, cdq, GFP_KERNEL); + if (xa_is_err(xa_ret)) { + ret =3D xa_err(xa_ret); + goto err_cmd_del; + } + + *cdq_id =3D cdq->cdq_id; + + return 0; + +err_cmd_del: + nvme_cdq_cmd_delete(ctrl, cdq->cdq_id); + +err_cdq_free_prp: + nvme_cdq_free_prp_lists(ctrl, cdq); + +err_cdq_unmap_dma: + cdq_id =3D NULL; + nvme_cdq_unmap_dma_usr(ctrl, cdq); + +err_cdq_free: + kfree(cdq); + + return ret; +} +EXPORT_SYMBOL_GPL(nvme_cdq_create); + +int nvme_cdq_delete(struct nvme_ctrl *ctrl, const u16 cdq_id) +{ + int ret; + struct cdq_nvme_queue *cdq; + + cdq =3D xa_load(&ctrl->cdqs, cdq_id); + if (xa_is_err(cdq)) + return -EINVAL; + + if (cdq->tpt_efd_ctx) + eventfd_ctx_put(cdq->tpt_efd_ctx); + + ret =3D nvme_cdq_cmd_delete(ctrl, cdq_id); + if (ret) + return ret; + + cdq =3D xa_erase(&ctrl->cdqs, cdq_id); + if (!cdq) + return -EINVAL; + + nvme_cdq_free_prp_lists(ctrl, cdq); + nvme_cdq_unmap_dma_usr(ctrl, cdq); + + kfree(cdq); + + return 0; +} +EXPORT_SYMBOL_GPL(nvme_cdq_delete); + +static int nvme_cdq_handle_aen_tpevent(struct nvme_ctrl *ctrl, u32 event_p= aram) +{ + u16 cdq_id =3D event_param & NVME_FEAT_CDQ_ID_MASK; + struct cdq_nvme_queue *cdq; + + cdq =3D xa_load(&ctrl->cdqs, cdq_id); + if (!cdq || xa_is_err(cdq) || !cdq->tpt_efd_ctx) + return false; + + eventfd_signal(cdq->tpt_efd_ctx); + + return true; +} + +static void nvme_free_cdqs(struct nvme_ctrl *ctrl) +{ + struct cdq_nvme_queue *cdq; + unsigned long i; + + xa_for_each(&ctrl->cdqs, i, cdq) + nvme_cdq_delete(ctrl, i); + + xa_destroy(&ctrl->cdqs); +} + void nvme_passthru_end(struct nvme_ctrl *ctrl, struct nvme_ns *ns, u32 eff= ects, struct nvme_command *cmd, int status) { @@ -4751,9 +5044,9 @@ static bool nvme_handle_aen_oneshot(struct nvme_ctrl = *ctrl, u32 result, u32 even { u32 aer_subtype =3D nvme_aer_subtype(result); =20 - /* Will be extended to handle specific one-shot event types */ if (aer_subtype =3D=3D NVME_AER_ONE_SHOT_CDQ_TAIL_PTR) - return -ENOSYS; + return nvme_cdq_handle_aen_tpevent(ctrl, event_param); + return false; } =20 @@ -4819,13 +5112,9 @@ void nvme_complete_async_event(struct nvme_ctrl *ctr= l, __le16 status, requeue =3D nvme_handle_aen_notice(ctrl, result); break; case NVME_AER_ONE_SHOT: - /* - * One-shot events like CDQ tail pointer events. - * Extract event parameter from upper 32 bits. - */ + /* One-shot events like CDQ tail pointer events. */ event_param =3D le64_to_cpu(res->u64) >> 32; requeue =3D nvme_handle_aen_oneshot(ctrl, result, event_param); - trace_nvme_async_event(ctrl, result); break; case NVME_AER_ERROR: /* @@ -5064,6 +5353,7 @@ static void nvme_free_ctrl(struct device *dev) if (!subsys || ctrl->instance !=3D subsys->instance) ida_free(&nvme_instance_ida, ctrl->instance); nvme_free_cels(ctrl); + nvme_free_cdqs(ctrl); nvme_mpath_uninit(ctrl); cleanup_srcu_struct(&ctrl->srcu); nvme_auth_stop(ctrl); @@ -5110,6 +5400,7 @@ int nvme_init_ctrl(struct nvme_ctrl *ctrl, struct dev= ice *dev, mutex_init(&ctrl->scan_lock); INIT_LIST_HEAD(&ctrl->namespaces); xa_init(&ctrl->cels); + xa_init(&ctrl->cdqs); ctrl->dev =3D dev; ctrl->ops =3D ops; ctrl->quirks =3D quirks; @@ -5375,6 +5666,7 @@ static inline void _nvme_check_size(void) BUILD_BUG_ON(sizeof(struct nvme_rotational_media_log) !=3D 512); BUILD_BUG_ON(sizeof(struct nvme_dbbuf) !=3D 64); BUILD_BUG_ON(sizeof(struct nvme_directive_cmd) !=3D 64); + BUILD_BUG_ON(sizeof(struct nvme_cdq) !=3D 64); BUILD_BUG_ON(sizeof(struct nvme_feat_host_behavior) !=3D 512); } =20 diff --git a/drivers/nvme/host/nvme.h b/drivers/nvme/host/nvme.h index 30d5052c7728c0d5c5e8772ff531bc672e96940f..2e8bbd3a7394303f6c803b0d5a4= 57abb6d1b485d 100644 --- a/drivers/nvme/host/nvme.h +++ b/drivers/nvme/host/nvme.h @@ -1285,6 +1285,11 @@ u32 nvme_passthru_start(struct nvme_ctrl *ctrl, stru= ct nvme_ns *ns, u8 opcode); int nvme_execute_rq(struct request *rq, bool at_head); void nvme_passthru_end(struct nvme_ctrl *ctrl, struct nvme_ns *ns, u32 eff= ects, struct nvme_command *cmd, int status); +int nvme_cdq_create(struct nvme_ctrl *ctrl, const u16 mos, const u16 cqs, + unsigned long uaddr, const u32 size_nbyte, + u16 *cdq_id); +int nvme_cdq_delete(struct nvme_ctrl *ctrl, const u16 cdq_id); +int nvme_cdq_set_tpt(struct nvme_ctrl *ctrl, u16 cdq_id, const int tpt_fd); struct nvme_ctrl *nvme_ctrl_from_file(struct file *file); struct nvme_ns *nvme_find_get_ns(struct nvme_ctrl *ctrl, unsigned nsid); bool nvme_get_ns(struct nvme_ns *ns); --=20 2.50.1 From nobody Fri Jun 19 09:06:06 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id EBE0A3BE642 for ; Fri, 24 Apr 2026 11:38:21 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1777030702; cv=none; b=jjBKiTtYEr+zjf/+2ShZJneuUSQo3OuFQjLISn7jIUh4Nql83WjJC7znx3wm2kRCUp7HHW04Kx+NN5e5uh71P8VANzh9hpE7klYsdEVZxyALgJrYDiguF43bTRNufHl94cFsUeCdEzHmIrfqAxbJCdtO+YPZCBxRjODUWwUB7WA= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1777030702; c=relaxed/simple; bh=4sHaCCccq5eLSKvrkGZ7ST8L13vQIeDmpX57uViLJyE=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=atob5Gm0+hUvyByWaP0wOMMMd5JymtZvtaqXdFVl77qScLEqGlKIpfwU8bAyRreNnsYKA2JjdMxryNTBx++cxx/iEF25p2vJ5/G/Lw1E73zM+jXR5yYkeLMq2D09JjQ4Lu5oqadbdjTTfd8BxgHc6eoO86Hdq5EZ0dDlMgDV8ng= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=JcGpPcSI; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="JcGpPcSI" Received: by smtp.kernel.org (Postfix) with ESMTPS id D004BC2BCF4; Fri, 24 Apr 2026 11:38:21 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1777030701; bh=4sHaCCccq5eLSKvrkGZ7ST8L13vQIeDmpX57uViLJyE=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=JcGpPcSI5b13rPFwzkSKXCLKBIcvbna9OTeH9u3anPRIfmkbmlN3xXw5gCuczG36z /VvAxkfQWHckMMZkMJEi+buYxtLqCLLDHhSdgZykf6Cl+I4FbmBgkiBVM3NTzjaZUU oXJwr0UgnBeeE8tnVT8zObxbfgGdLISZ/gx7SSaBY4IcQO1AvO/Iy9y9K2GJls7cHV T4bkMlMMKr3f94zA4kD8FnoNqMFU7oODTrnR0kAGJLh5k8TREbg3XL3fDVViliacxm 06rTHG0NEDROem3SP7fetLH7x4ievs/zeD0BVimXHsAAtw4BItvhZdia1cXXhm/K6c ShzjP37OqBuSg== Received: from aws-us-west-2-korg-lkml-1.web.codeaurora.org (localhost.localdomain [127.0.0.1]) by smtp.lore.kernel.org (Postfix) with ESMTP id C8AFAFE51FE; Fri, 24 Apr 2026 11:38:21 +0000 (UTC) From: Joel Granados Date: Fri, 24 Apr 2026 13:37:55 +0200 Subject: [PATCH RFC 5/5] nvme: Add CDQ ioctl interface Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260424-jag-cdq-lkml-v1-5-d773343a717c@kernel.org> References: <20260424-jag-cdq-lkml-v1-0-d773343a717c@kernel.org> In-Reply-To: <20260424-jag-cdq-lkml-v1-0-d773343a717c@kernel.org> To: Keith Busch , Jens Axboe , Christoph Hellwig , Sagi Grimberg , Chaitanya Kulkarni , Jason Gunthorpe Cc: linux-nvme@lists.infradead.org, linux-kernel@vger.kernel.org, Joel Granados X-Mailer: b4 0.14.2 X-Developer-Signature: v=1; a=openpgp-sha256; l=4647; i=joel.granados@kernel.org; h=from:subject:message-id; bh=4sHaCCccq5eLSKvrkGZ7ST8L13vQIeDmpX57uViLJyE=; b=owJ4nAHtARL+kA0DAAoBupfNUreWQU8ByyZiAGnrVis0PgumY0ewTsOM/34h4kUkJuD+/2+4f PTJZqQVf1j6dYkBswQAAQoAHRYhBK5HCVcl5jElzssnkLqXzVK3lkFPBQJp61YrAAoJELqXzVK3 lkFPn3wL/jKdR3jvoJ0nVQYDcX4EEO2SLnTzID0qaLwYRqAPiJmn/jBYhrYUsNL4fXi6a+E2tJ1 IEETlT35XxhtJdlxAfL0aWZ/6GcemL5+6hFMT60dajXJvGyaCYXW2Ew5lgzYlEZ9uFOgkMKyEYK IItpm8sLMG8XnAlI8re4VwZBU0xXSmfUG+A6ePP0S/y1kKqS8RbBBv5JeNqOGUfkFKJ5MiqO2D2 LW67cNFUGY8fUI2/UmatG8XQITi1qUlTISBcNs/ET/B/S5efz4ulMpgIi/MwiHmO6U05stXYty5 tVdmNtWcBqe8E81ADtOHdBCPSh2ljFQORv1Dne9Nhgk6Py/wSMw88jQ+in3hqgCoGv2ygpHjWR7 /b7HW8k0h4tq1QjObs9Xa3VGV89vIxyLYulDE6QyRjsdiDDrpubK1LX3MgeMailp96i6ZiK3+7v SLHJQlEf/NJoniwSD6kiJ8PSWLB9XV/wiuk1s0+KZIlEf7Ou/MpWNIsk1NugFnxoA8aVrg8+m26 Gk= X-Developer-Key: i=joel.granados@kernel.org; a=openpgp; fpr=F1F8E46D30F0F6C4A45FF4465895FAAC338C6E77 X-Endpoint-Received: by B4 Relay for joel.granados@kernel.org/default with auth_id=239 Add userspace ioctl interface for CDQ (Controller Data Queue) management. This allows userspace applications to create, configure, and delete CDQs. The interface includes: - struct nvme_cdq_cmd for passing CDQ parameters - NVME_IOCTL_CDQ ioctl command (0x50) - Support for both controller and device ioctls Signed-off-by: Joel Granados --- drivers/nvme/host/ioctl.c | 53 +++++++++++++++++++++++++++++++++++++= +++- include/uapi/linux/nvme_ioctl.h | 29 ++++++++++++++++++++++ 2 files changed, 81 insertions(+), 1 deletion(-) diff --git a/drivers/nvme/host/ioctl.c b/drivers/nvme/host/ioctl.c index 8844bbd395159e544218db413e066cae6c24b2f1..98441439bd6be67e20717fed4ff= c4d32c9b37725 100644 --- a/drivers/nvme/host/ioctl.c +++ b/drivers/nvme/host/ioctl.c @@ -8,6 +8,7 @@ #include #include #include "nvme.h" +#include "trace.h" =20 enum { NVME_IOCTL_VEC =3D (1 << 0), @@ -373,6 +374,51 @@ static int nvme_user_cmd64(struct nvme_ctrl *ctrl, str= uct nvme_ns *ns, return status; } =20 +static int nvme_user_cdq(struct nvme_ctrl *ctrl, struct nvme_ns *ns, + struct nvme_cdq_cmd __user *ucmd, unsigned int flags, + bool open_for_write) +{ + int status; + u16 cdq_id =3D 0; + struct nvme_cdq_cmd cmd =3D {}; + + if (copy_from_user(&cmd, ucmd, sizeof(cmd))) + return -EFAULT; + + /* 21 =3D 12 (PAGE_SHIFT) + 9 (PAGE_SHIFT / sizeof(u64)) */ + if (cmd.size_nbyte > MAX_NR_CDQ_PRPS << 21) + return -EINVAL; + + if (cmd.size_nbyte =3D=3D 0) { + status =3D nvme_cdq_delete(ctrl, cmd.id); + } else { + status =3D nvme_cdq_create(ctrl, cmd.mos, cmd.cqs, cmd.entries, + cmd.size_nbyte, &cdq_id); + if (status) + return status; + + if (cmd.tpt_fd > 0) { + status =3D nvme_cdq_set_tpt(ctrl, cdq_id, cmd.tpt_fd); + if (status) + goto del_cdq; + } + + cmd.id =3D cdq_id; + + if (copy_to_user(ucmd, &cmd, sizeof(cmd))) { + status =3D -EINVAL; + goto del_cdq; + } + } + + return status; + +del_cdq: + // Ignore return; already in error + nvme_cdq_delete(ctrl, cdq_id); + return status; +} + struct nvme_uring_data { __u64 metadata; __u64 addr; @@ -540,7 +586,8 @@ static int nvme_uring_cmd_io(struct nvme_ctrl *ctrl, st= ruct nvme_ns *ns, =20 static bool is_ctrl_ioctl(unsigned int cmd) { - if (cmd =3D=3D NVME_IOCTL_ADMIN_CMD || cmd =3D=3D NVME_IOCTL_ADMIN64_CMD) + if (cmd =3D=3D NVME_IOCTL_ADMIN_CMD || cmd =3D=3D NVME_IOCTL_ADMIN64_CMD = || + cmd =3D=3D NVME_IOCTL_CDQ) return true; if (is_sed_ioctl(cmd)) return true; @@ -555,6 +602,8 @@ static int nvme_ctrl_ioctl(struct nvme_ctrl *ctrl, unsi= gned int cmd, return nvme_user_cmd(ctrl, NULL, argp, 0, open_for_write); case NVME_IOCTL_ADMIN64_CMD: return nvme_user_cmd64(ctrl, NULL, argp, 0, open_for_write); + case NVME_IOCTL_CDQ: + return nvme_user_cdq(ctrl, NULL, argp, 0, open_for_write); default: return sed_ioctl(ctrl->opal_dev, cmd, argp); } @@ -873,6 +922,8 @@ long nvme_dev_ioctl(struct file *file, unsigned int cmd, return -EACCES; nvme_queue_scan(ctrl); return 0; + case NVME_IOCTL_CDQ: + return nvme_user_cdq(ctrl, NULL, argp, 0, open_for_write); default: return -ENOTTY; } diff --git a/include/uapi/linux/nvme_ioctl.h b/include/uapi/linux/nvme_ioct= l.h index 2f76cba6716637baff53e167a6141b68420d75c3..8d220c276d959dbd45f224d8ed3= 00fe02dea2f20 100644 --- a/include/uapi/linux/nvme_ioctl.h +++ b/include/uapi/linux/nvme_ioctl.h @@ -92,6 +92,34 @@ struct nvme_uring_cmd { __u32 rsvd2; }; =20 +struct nvme_cdq_cmd { + /* + * CDQ size in bytes: + * (Number of entries) * (entry size in bytes) + */ + __u32 size_nbyte; + + /* + * Virtual mem (returned by mmap). Start of the entries buf in virtual me= m. + */ + __u64 entries; + + /* + * Tail Pointer Trigger eventfd File Descriptor + * Passed when creating the cdq. + * -1 means that there is no FD and AER should not be forwarded. + */ + int tpt_fd; + + /* + * Returned by controller; CDQ ID + */ + __u16 id; + + __u16 cqs; + __u16 mos; +}; + #define nvme_admin_cmd nvme_passthru_cmd =20 #define NVME_IOCTL_ID _IO('N', 0x40) @@ -104,6 +132,7 @@ struct nvme_uring_cmd { #define NVME_IOCTL_ADMIN64_CMD _IOWR('N', 0x47, struct nvme_passthru_cmd64) #define NVME_IOCTL_IO64_CMD _IOWR('N', 0x48, struct nvme_passthru_cmd64) #define NVME_IOCTL_IO64_CMD_VEC _IOWR('N', 0x49, struct nvme_passthru_cmd6= 4) +#define NVME_IOCTL_CDQ _IOR('N', 0x50, struct nvme_cdq_cmd) =20 /* io_uring async commands: */ #define NVME_URING_CMD_IO _IOWR('N', 0x80, struct nvme_uring_cmd) --=20 2.50.1