Commit cc0331e2 authored by Jens Axboe's avatar Jens Axboe
Browse files

Merge tag 'nvme-6.13-2024-12-31' of git://git.infradead.org/nvme into block-6.13

Pull NVMe fixes from Keith:

"nvme fixes for Linux 6.13

 - Fix device specific quirk for PRP list alignment (Robert)
 - Fix target name overflow (Leo)
 - Fix target write granularity (Luis)
 - Fix target sleeping in atomic context (Nilay)
 - Remove unnecessary tcp queue teardown (Chunguang)"

* tag 'nvme-6.13-2024-12-31' of git://git.infradead.org/nvme:
  nvme-tcp: remove nvme_tcp_destroy_io_queues()
  nvmet-loop: avoid using mutex in IO hotpath
  nvmet: propagate npwg topology
  nvmet: Don't overflow subsysnqn
  nvme-pci: 512 byte aligned dma pool segment quirk
parents de30d74f 36e3b1f9
Loading
Loading
Loading
Loading
+5 −0
Original line number Diff line number Diff line
@@ -173,6 +173,11 @@ enum nvme_quirks {
	 * MSI (but not MSI-X) interrupts are broken and never fire.
	 */
	NVME_QUIRK_BROKEN_MSI			= (1 << 21),

	/*
	 * Align dma pool segment size to 512 bytes
	 */
	NVME_QUIRK_DMAPOOL_ALIGN_512		= (1 << 22),
};

/*
+7 −2
Original line number Diff line number Diff line
@@ -2834,15 +2834,20 @@ static int nvme_disable_prepare_reset(struct nvme_dev *dev, bool shutdown)

static int nvme_setup_prp_pools(struct nvme_dev *dev)
{
	size_t small_align = 256;

	dev->prp_page_pool = dma_pool_create("prp list page", dev->dev,
						NVME_CTRL_PAGE_SIZE,
						NVME_CTRL_PAGE_SIZE, 0);
	if (!dev->prp_page_pool)
		return -ENOMEM;

	if (dev->ctrl.quirks & NVME_QUIRK_DMAPOOL_ALIGN_512)
		small_align = 512;

	/* Optimisation for I/Os between 4k and 128k */
	dev->prp_small_pool = dma_pool_create("prp list 256", dev->dev,
						256, 256, 0);
						256, small_align, 0);
	if (!dev->prp_small_pool) {
		dma_pool_destroy(dev->prp_page_pool);
		return -ENOMEM;
@@ -3607,7 +3612,7 @@ static const struct pci_device_id nvme_id_table[] = {
	{ PCI_VDEVICE(REDHAT, 0x0010),	/* Qemu emulated controller */
		.driver_data = NVME_QUIRK_BOGUS_NID, },
	{ PCI_DEVICE(0x1217, 0x8760), /* O2 Micro 64GB Steam Deck */
		.driver_data = NVME_QUIRK_QDEPTH_ONE },
		.driver_data = NVME_QUIRK_DMAPOOL_ALIGN_512, },
	{ PCI_DEVICE(0x126f, 0x2262),	/* Silicon Motion generic */
		.driver_data = NVME_QUIRK_NO_DEEPEST_PS |
				NVME_QUIRK_BOGUS_NID, },
+7 −11
Original line number Diff line number Diff line
@@ -2024,14 +2024,6 @@ static int nvme_tcp_alloc_io_queues(struct nvme_ctrl *ctrl)
	return __nvme_tcp_alloc_io_queues(ctrl);
}

static void nvme_tcp_destroy_io_queues(struct nvme_ctrl *ctrl, bool remove)
{
	nvme_tcp_stop_io_queues(ctrl);
	if (remove)
		nvme_remove_io_tag_set(ctrl);
	nvme_tcp_free_io_queues(ctrl);
}

static int nvme_tcp_configure_io_queues(struct nvme_ctrl *ctrl, bool new)
{
	int ret, nr_queues;
@@ -2176,9 +2168,11 @@ static void nvme_tcp_teardown_io_queues(struct nvme_ctrl *ctrl,
	nvme_sync_io_queues(ctrl);
	nvme_tcp_stop_io_queues(ctrl);
	nvme_cancel_tagset(ctrl);
	if (remove)
	if (remove) {
		nvme_unquiesce_io_queues(ctrl);
	nvme_tcp_destroy_io_queues(ctrl, remove);
		nvme_remove_io_tag_set(ctrl);
	}
	nvme_tcp_free_io_queues(ctrl);
}

static void nvme_tcp_reconnect_or_remove(struct nvme_ctrl *ctrl,
@@ -2267,7 +2261,9 @@ static int nvme_tcp_setup_ctrl(struct nvme_ctrl *ctrl, bool new)
		nvme_sync_io_queues(ctrl);
		nvme_tcp_stop_io_queues(ctrl);
		nvme_cancel_tagset(ctrl);
		nvme_tcp_destroy_io_queues(ctrl, new);
		if (new)
			nvme_remove_io_tag_set(ctrl);
		nvme_tcp_free_io_queues(ctrl);
	}
destroy_admin:
	nvme_stop_keep_alive(ctrl);
+5 −4
Original line number Diff line number Diff line
@@ -139,7 +139,7 @@ static u16 nvmet_get_smart_log_all(struct nvmet_req *req,
	unsigned long idx;

	ctrl = req->sq->ctrl;
	xa_for_each(&ctrl->subsys->namespaces, idx, ns) {
	nvmet_for_each_enabled_ns(&ctrl->subsys->namespaces, idx, ns) {
		/* we don't have the right data for file backed ns */
		if (!ns->bdev)
			continue;
@@ -331,10 +331,11 @@ static u32 nvmet_format_ana_group(struct nvmet_req *req, u32 grpid,
	u32 count = 0;

	if (!(req->cmd->get_log_page.lsp & NVME_ANA_LOG_RGO)) {
		xa_for_each(&ctrl->subsys->namespaces, idx, ns)
		nvmet_for_each_enabled_ns(&ctrl->subsys->namespaces, idx, ns) {
			if (ns->anagrpid == grpid)
				desc->nsids[count++] = cpu_to_le32(ns->nsid);
		}
	}

	desc->grpid = cpu_to_le32(grpid);
	desc->nnsids = cpu_to_le32(count);
@@ -772,7 +773,7 @@ static void nvmet_execute_identify_endgrp_list(struct nvmet_req *req)
		goto out;
	}

	xa_for_each(&ctrl->subsys->namespaces, idx, ns) {
	nvmet_for_each_enabled_ns(&ctrl->subsys->namespaces, idx, ns) {
		if (ns->nsid <= min_endgid)
			continue;

@@ -815,7 +816,7 @@ static void nvmet_execute_identify_nslist(struct nvmet_req *req, bool match_css)
		goto out;
	}

	xa_for_each(&ctrl->subsys->namespaces, idx, ns) {
	nvmet_for_each_enabled_ns(&ctrl->subsys->namespaces, idx, ns) {
		if (ns->nsid <= min_nsid)
			continue;
		if (match_css && req->ns->csi != req->cmd->identify.csi)
+9 −14
Original line number Diff line number Diff line
@@ -810,18 +810,6 @@ static struct configfs_attribute *nvmet_ns_attrs[] = {
	NULL,
};

bool nvmet_subsys_nsid_exists(struct nvmet_subsys *subsys, u32 nsid)
{
	struct config_item *ns_item;
	char name[12];

	snprintf(name, sizeof(name), "%u", nsid);
	mutex_lock(&subsys->namespaces_group.cg_subsys->su_mutex);
	ns_item = config_group_find_item(&subsys->namespaces_group, name);
	mutex_unlock(&subsys->namespaces_group.cg_subsys->su_mutex);
	return ns_item != NULL;
}

static void nvmet_ns_release(struct config_item *item)
{
	struct nvmet_ns *ns = to_nvmet_ns(item);
@@ -2254,12 +2242,17 @@ static ssize_t nvmet_root_discovery_nqn_store(struct config_item *item,
		const char *page, size_t count)
{
	struct list_head *entry;
	char *old_nqn, *new_nqn;
	size_t len;

	len = strcspn(page, "\n");
	if (!len || len > NVMF_NQN_FIELD_LEN - 1)
		return -EINVAL;

	new_nqn = kstrndup(page, len, GFP_KERNEL);
	if (!new_nqn)
		return -ENOMEM;

	down_write(&nvmet_config_sem);
	list_for_each(entry, &nvmet_subsystems_group.cg_children) {
		struct config_item *item =
@@ -2268,13 +2261,15 @@ static ssize_t nvmet_root_discovery_nqn_store(struct config_item *item,
		if (!strncmp(config_item_name(item), page, len)) {
			pr_err("duplicate NQN %s\n", config_item_name(item));
			up_write(&nvmet_config_sem);
			kfree(new_nqn);
			return -EINVAL;
		}
	}
	memset(nvmet_disc_subsys->subsysnqn, 0, NVMF_NQN_FIELD_LEN);
	memcpy(nvmet_disc_subsys->subsysnqn, page, len);
	old_nqn = nvmet_disc_subsys->subsysnqn;
	nvmet_disc_subsys->subsysnqn = new_nqn;
	up_write(&nvmet_config_sem);

	kfree(old_nqn);
	return len;
}

Loading