From f4bd3139933da65c2daa402b2a4d5fe469133aec Mon Sep 17 00:00:00 2001 From: Jinjie Ruan Date: Thu, 22 Aug 2024 15:19:16 +0800 Subject: [PATCH 1/7] nvmet: Make nvmet_debugfs static The sparse tool complains as follows: drivers/nvme/target/debugfs.c:16:15: warning: symbol 'nvmet_debugfs' was not declared. Should it be static? This symbol is not used outside debugfs.c, so marks it static. Signed-off-by: Jinjie Ruan Reviewed-by: Chaitanya Kulkarni Reviewed-by: Christoph Hellwig Signed-off-by: Keith Busch --- drivers/nvme/target/debugfs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/nvme/target/debugfs.c b/drivers/nvme/target/debugfs.c index cb2befc8619e..220c7391fc19 100644 --- a/drivers/nvme/target/debugfs.c +++ b/drivers/nvme/target/debugfs.c @@ -13,7 +13,7 @@ #include "nvmet.h" #include "debugfs.h" -struct dentry *nvmet_debugfs; +static struct dentry *nvmet_debugfs; #define NVMET_DEBUGFS_ATTR(field) \ static int field##_open(struct inode *inode, struct file *file) \ From 5a6d3a638c93881b7a7c13df870238b91399578a Mon Sep 17 00:00:00 2001 From: Keith Busch Date: Thu, 22 Aug 2024 08:18:08 -0700 Subject: [PATCH 2/7] nvme: use better description for async reset reason The NVMe AER notification of a persistent internal error triggers a reset. The existing warning message just says "due to AER", which can be confused with the unrelated PCIe AER condition. Just say what the event was instead of the generic overloaded acronym. Reviewed-by: Christoph Hellwig Reviewed-by: Chaitanya Kulkarni Signed-off-by: Keith Busch --- drivers/nvme/host/core.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c index 0dc8bcc664f2..983909a600ad 100644 --- a/drivers/nvme/host/core.c +++ b/drivers/nvme/host/core.c @@ -4437,7 +4437,8 @@ static bool nvme_handle_aen_notice(struct nvme_ctrl *ctrl, u32 result) static void nvme_handle_aer_persistent_error(struct nvme_ctrl *ctrl) { - dev_warn(ctrl->device, "resetting controller due to AER\n"); + dev_warn(ctrl->device, + "resetting controller due to persistent internal error\n"); nvme_reset_ctrl(ctrl); } From 5572a55a6f830ee3f3a994b6b962a5c327d28cb3 Mon Sep 17 00:00:00 2001 From: Maurizio Lombardi Date: Wed, 21 Aug 2024 16:28:26 +0200 Subject: [PATCH 3/7] nvmet-tcp: fix kernel crash if commands allocation fails If the commands allocation fails in nvmet_tcp_alloc_cmds() the kernel crashes in nvmet_tcp_release_queue_work() because of a NULL pointer dereference. nvmet: failed to install queue 0 cntlid 1 ret 6 Unable to handle kernel NULL pointer dereference at virtual address 0000000000000008 Fix the bug by setting queue->nr_cmds to zero in case nvmet_tcp_alloc_cmd() fails. Fixes: 872d26a391da ("nvmet-tcp: add NVMe over TCP target driver") Signed-off-by: Maurizio Lombardi Reviewed-by: Christoph Hellwig Signed-off-by: Keith Busch --- drivers/nvme/target/tcp.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/nvme/target/tcp.c b/drivers/nvme/target/tcp.c index 5bff0d5464d1..7c51c2a8c109 100644 --- a/drivers/nvme/target/tcp.c +++ b/drivers/nvme/target/tcp.c @@ -2146,8 +2146,10 @@ static u16 nvmet_tcp_install_queue(struct nvmet_sq *sq) } queue->nr_cmds = sq->size * 2; - if (nvmet_tcp_alloc_cmds(queue)) + if (nvmet_tcp_alloc_cmds(queue)) { + queue->nr_cmds = 0; return NVME_SC_INTERNAL; + } return 0; } From 6f01bdbfef3b62955cf6503a8425d527b3a5cf94 Mon Sep 17 00:00:00 2001 From: Keith Busch Date: Mon, 26 Aug 2024 11:20:57 -0700 Subject: [PATCH 4/7] nvme-pci: allocate tagset on reset if necessary If a drive is unable to create IO queues on the initial probe, a subsequent reset will need to allocate the tagset if IO queue creation is successful. Without this, blk_mq_update_nr_hw_queues will crash on a bad pointer due to the invalid tagset. Fixes: eac3ef262941f62 ("nvme-pci: split the initial probe from the rest path") Reviewed-by: Sagi Grimberg Reviewed-by: Christoph Hellwig Signed-off-by: Keith Busch --- drivers/nvme/host/pci.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/drivers/nvme/host/pci.c b/drivers/nvme/host/pci.c index 6cd9395ba9ec..9026a730d5ed 100644 --- a/drivers/nvme/host/pci.c +++ b/drivers/nvme/host/pci.c @@ -2508,6 +2508,12 @@ static unsigned int nvme_pci_nr_maps(struct nvme_dev *dev) static void nvme_pci_update_nr_queues(struct nvme_dev *dev) { + if (!dev->ctrl.tagset) { + nvme_alloc_io_tag_set(&dev->ctrl, &dev->tagset, &nvme_mq_ops, + nvme_pci_nr_maps(dev), sizeof(struct nvme_iod)); + return; + } + blk_mq_update_nr_hw_queues(&dev->tagset, dev->online_queues - 1); /* free previously allocated queues that are no longer usable */ nvme_free_queues(dev, dev->online_queues); From 61aa894e7a2fda4ee026523b01d07e83ce2abb72 Mon Sep 17 00:00:00 2001 From: Georg Gottleuber Date: Tue, 27 Aug 2024 12:41:33 +0200 Subject: [PATCH 5/7] nvme-pci: Add sleep quirk for Samsung 990 Evo On some TUXEDO platforms, a Samsung 990 Evo NVMe leads to a high power consumption in s2idle sleep (2-3 watts). This patch applies 'Force No Simple Suspend' quirk to achieve a sleep with a lower power consumption, typically around 0.5 watts. Signed-off-by: Georg Gottleuber Signed-off-by: Werner Sembach Cc: Signed-off-by: Keith Busch --- drivers/nvme/host/pci.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/drivers/nvme/host/pci.c b/drivers/nvme/host/pci.c index 9026a730d5ed..c0533f3f64cb 100644 --- a/drivers/nvme/host/pci.c +++ b/drivers/nvme/host/pci.c @@ -2973,6 +2973,17 @@ static unsigned long check_vendor_combination_bug(struct pci_dev *pdev) dmi_match(DMI_BOARD_NAME, "NS5x_7xPU") || dmi_match(DMI_BOARD_NAME, "PH4PRX1_PH6PRX1")) return NVME_QUIRK_FORCE_NO_SIMPLE_SUSPEND; + } else if (pdev->vendor == 0x144d && pdev->device == 0xa80d) { + /* + * Exclude Samsung 990 Evo from NVME_QUIRK_SIMPLE_SUSPEND + * because of high power consumption (> 2 Watt) in s2idle + * sleep. Only some boards with Intel CPU are affected. + */ + if (dmi_match(DMI_BOARD_NAME, "GMxPXxx") || + dmi_match(DMI_BOARD_NAME, "PH4PG31") || + dmi_match(DMI_BOARD_NAME, "PH4PRX1_PH6PRX1") || + dmi_match(DMI_BOARD_NAME, "PH6PG01_PH6PG71")) + return NVME_QUIRK_FORCE_NO_SIMPLE_SUSPEND; } /* From 28982ad73d6a9605708631dc49a0c763cc398aa2 Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Thu, 29 Aug 2024 09:24:37 +0300 Subject: [PATCH 6/7] nvme: set BLK_FEAT_ZONED for ZNS multipath disks The new stricter limits validation doesn't like a max_append_sectors value to be set without BLK_FEAT_ZONED. Set it before allocation the disk to fix this instead of just inheriting it later. Fixes: d690cb8ae14b ("block: add an API to atomically update queue limits") Signed-off-by: Christoph Hellwig Signed-off-by: Keith Busch --- drivers/nvme/host/multipath.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/nvme/host/multipath.c b/drivers/nvme/host/multipath.c index 91d9eb3c22ef..518e22dd4f9b 100644 --- a/drivers/nvme/host/multipath.c +++ b/drivers/nvme/host/multipath.c @@ -616,7 +616,9 @@ int nvme_mpath_alloc_disk(struct nvme_ctrl *ctrl, struct nvme_ns_head *head) blk_set_stacking_limits(&lim); lim.dma_alignment = 3; lim.features |= BLK_FEAT_IO_STAT | BLK_FEAT_NOWAIT | BLK_FEAT_POLL; - if (head->ids.csi != NVME_CSI_ZNS) + if (head->ids.csi == NVME_CSI_ZNS) + lim.features |= BLK_FEAT_ZONED; + else lim.max_zone_append_sectors = 0; head->disk = blk_alloc_disk(&lim, ctrl->numa_node); From 899d2e5a4e3d36689e8938e152f4b69a4bcc6b4d Mon Sep 17 00:00:00 2001 From: Maurizio Lombardi Date: Thu, 29 Aug 2024 11:52:14 +0200 Subject: [PATCH 7/7] nvmet: Identify-Active Namespace ID List command should reject invalid nsid nsid values of 0xFFFFFFFE and 0XFFFFFFFF should be rejected with a status code of "Invalid Namespace or Format". See NVMe Base Specification, Active Namespace ID list (CNS 02h). Fixes: a07b4970f464 ("nvmet: add a generic NVMe target") Signed-off-by: Maurizio Lombardi Reviewed-by: Sagi Grimberg Signed-off-by: Keith Busch --- drivers/nvme/target/admin-cmd.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/drivers/nvme/target/admin-cmd.c b/drivers/nvme/target/admin-cmd.c index f7e1156ac7ec..85006b2df8ae 100644 --- a/drivers/nvme/target/admin-cmd.c +++ b/drivers/nvme/target/admin-cmd.c @@ -587,6 +587,16 @@ static void nvmet_execute_identify_nslist(struct nvmet_req *req) u16 status = 0; int i = 0; + /* + * NSID values 0xFFFFFFFE and NVME_NSID_ALL are invalid + * See NVMe Base Specification, Active Namespace ID list (CNS 02h). + */ + if (min_nsid == 0xFFFFFFFE || min_nsid == NVME_NSID_ALL) { + req->error_loc = offsetof(struct nvme_identify, nsid); + status = NVME_SC_INVALID_NS | NVME_STATUS_DNR; + goto out; + } + list = kzalloc(buf_size, GFP_KERNEL); if (!list) { status = NVME_SC_INTERNAL;