summaryrefslogtreecommitdiff
path: root/drivers/nvme
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2018-06-08 23:36:19 +0300
committerLinus Torvalds <torvalds@linux-foundation.org>2018-06-08 23:36:19 +0300
commita3818841bd5e9b4a7e0e732c19cf3a632fcb525e (patch)
tree6eb1c6e80a5ab382601aa2d06d488900e267e231 /drivers/nvme
parent68cc38ff33f38424d0456f9a1ecfec4683226a7e (diff)
parent77016199f11eacd7b23e2faeb4d0f36166e3530b (diff)
downloadlinux-a3818841bd5e9b4a7e0e732c19cf3a632fcb525e.tar.xz
Merge tag 'for-linus-20180608' of git://git.kernel.dk/linux-block
Pull block fixes from Jens Axboe: "A few fixes for this merge window, where some of them should go in sooner rather than later, hence a new pull this week. This pull request contains: - Set of NVMe fixes, mostly follow up cleanups/fixes to the queue changes, but also teardown/removal and misc changes (Christop/Dan/ Johannes/Sagi/Steve). - Two lightnvm fixes for issues that showed up in this window (Colin/Wei). - Failfast/driver flags inheritance for flush requests (Hannes). - The md device put sanitization and fix (Kent). - dm bio_set inheritance fix (me). - nbd discard granularity fix (Josef). - nbd consistency in command printing (Kevin). - Loop recursion validation fix (Ted). - Partition overlap check (Wang)" [ .. and now my build is warning-free again thanks to the md fix - Linus ] * tag 'for-linus-20180608' of git://git.kernel.dk/linux-block: (22 commits) nvme: cleanup double shift issue nvme-pci: make CMB SQ mod-param read-only nvme-pci: unquiesce dead controller queues nvme-pci: remove HMB teardown on reset nvme-pci: queue creation fixes nvme-pci: remove unnecessary completion doorbell check nvme-pci: remove unnecessary nested locking nvmet: filter newlines from user input nvme-rdma: correctly check for target keyed sgl support nvme: don't hold nvmf_transports_rwsem for more than transport lookups nvmet: return all zeroed buffer when we can't find an active namespace md: Unify mddev destruction paths dm: use bioset_init_from_src() to copy bio_set block: add bioset_init_from_src() helper block: always set partition number to '0' in blk_partition_remap() block: pass failfast and driver-specific flags to flush requests nbd: set discard_alignment to the granularity nbd: Consistently use request pointer in debug messages. block: add verifier for cmdline partition lightnvm: pblk: fix resource leak of invalid_bitmap ...
Diffstat (limited to 'drivers/nvme')
-rw-r--r--drivers/nvme/host/core.c4
-rw-r--r--drivers/nvme/host/fabrics.c3
-rw-r--r--drivers/nvme/host/fabrics.h3
-rw-r--r--drivers/nvme/host/nvme.h1
-rw-r--r--drivers/nvme/host/pci.c35
-rw-r--r--drivers/nvme/host/rdma.c5
-rw-r--r--drivers/nvme/target/admin-cmd.c15
-rw-r--r--drivers/nvme/target/configfs.c14
8 files changed, 38 insertions, 42 deletions
diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c
index c8b30067b6ae..effb1309682e 100644
--- a/drivers/nvme/host/core.c
+++ b/drivers/nvme/host/core.c
@@ -3245,7 +3245,7 @@ static void nvme_scan_work(struct work_struct *work)
WARN_ON_ONCE(!ctrl->tagset);
- if (test_and_clear_bit(EVENT_NS_CHANGED, &ctrl->events)) {
+ if (test_and_clear_bit(NVME_AER_NOTICE_NS_CHANGED, &ctrl->events)) {
if (nvme_scan_changed_ns_log(ctrl))
goto out_sort_namespaces;
dev_info(ctrl->device, "rescanning namespaces.\n");
@@ -3386,7 +3386,7 @@ static void nvme_handle_aen_notice(struct nvme_ctrl *ctrl, u32 result)
{
switch ((result & 0xff00) >> 8) {
case NVME_AER_NOTICE_NS_CHANGED:
- set_bit(EVENT_NS_CHANGED, &ctrl->events);
+ set_bit(NVME_AER_NOTICE_NS_CHANGED, &ctrl->events);
nvme_queue_scan(ctrl);
break;
case NVME_AER_NOTICE_FW_ACT_STARTING:
diff --git a/drivers/nvme/host/fabrics.c b/drivers/nvme/host/fabrics.c
index 5f5f7067c41d..fa32c1216409 100644
--- a/drivers/nvme/host/fabrics.c
+++ b/drivers/nvme/host/fabrics.c
@@ -952,6 +952,7 @@ nvmf_create_ctrl(struct device *dev, const char *buf, size_t count)
ret = -EBUSY;
goto out_unlock;
}
+ up_read(&nvmf_transports_rwsem);
ret = nvmf_check_required_opts(opts, ops->required_opts);
if (ret)
@@ -968,11 +969,11 @@ nvmf_create_ctrl(struct device *dev, const char *buf, size_t count)
}
module_put(ops->module);
- up_read(&nvmf_transports_rwsem);
return ctrl;
out_module_put:
module_put(ops->module);
+ goto out_free_opts;
out_unlock:
up_read(&nvmf_transports_rwsem);
out_free_opts:
diff --git a/drivers/nvme/host/fabrics.h b/drivers/nvme/host/fabrics.h
index 0cf0460a5c92..7491a0bbf711 100644
--- a/drivers/nvme/host/fabrics.h
+++ b/drivers/nvme/host/fabrics.h
@@ -124,6 +124,9 @@ struct nvmf_ctrl_options {
* 1. At minimum, 'required_opts' and 'allowed_opts' should
* be set to the same enum parsing options defined earlier.
* 2. create_ctrl() must be defined (even if it does nothing)
+ * 3. struct nvmf_transport_ops must be statically allocated in the
+ * modules .bss section so that a pure module_get on @module
+ * prevents the memory from beeing freed.
*/
struct nvmf_transport_ops {
struct list_head entry;
diff --git a/drivers/nvme/host/nvme.h b/drivers/nvme/host/nvme.h
index de24fe77c80b..34df07d44f80 100644
--- a/drivers/nvme/host/nvme.h
+++ b/drivers/nvme/host/nvme.h
@@ -194,7 +194,6 @@ struct nvme_ctrl {
struct delayed_work ka_work;
struct nvme_command ka_cmd;
struct work_struct fw_act_work;
-#define EVENT_NS_CHANGED (1 << 0)
unsigned long events;
/* Power saving configuration */
diff --git a/drivers/nvme/host/pci.c b/drivers/nvme/host/pci.c
index d234de5505ea..fc33804662e7 100644
--- a/drivers/nvme/host/pci.c
+++ b/drivers/nvme/host/pci.c
@@ -42,7 +42,7 @@ static int use_threaded_interrupts;
module_param(use_threaded_interrupts, int, 0);
static bool use_cmb_sqes = true;
-module_param(use_cmb_sqes, bool, 0644);
+module_param(use_cmb_sqes, bool, 0444);
MODULE_PARM_DESC(use_cmb_sqes, "use controller's memory buffer for I/O SQes");
static unsigned int max_host_mem_size_mb = 128;
@@ -920,11 +920,9 @@ static inline void nvme_ring_cq_doorbell(struct nvme_queue *nvmeq)
{
u16 head = nvmeq->cq_head;
- if (likely(nvmeq->cq_vector >= 0)) {
- if (nvme_dbbuf_update_and_check_event(head, nvmeq->dbbuf_cq_db,
- nvmeq->dbbuf_cq_ei))
- writel(head, nvmeq->q_db + nvmeq->dev->db_stride);
- }
+ if (nvme_dbbuf_update_and_check_event(head, nvmeq->dbbuf_cq_db,
+ nvmeq->dbbuf_cq_ei))
+ writel(head, nvmeq->q_db + nvmeq->dev->db_stride);
}
static inline void nvme_handle_cqe(struct nvme_queue *nvmeq, u16 idx)
@@ -1477,11 +1475,13 @@ static int nvme_create_queue(struct nvme_queue *nvmeq, int qid)
*/
vector = dev->num_vecs == 1 ? 0 : qid;
result = adapter_alloc_cq(dev, qid, nvmeq, vector);
- if (result < 0)
- goto out;
+ if (result)
+ return result;
result = adapter_alloc_sq(dev, qid, nvmeq);
if (result < 0)
+ return result;
+ else if (result)
goto release_cq;
/*
@@ -1503,7 +1503,6 @@ release_sq:
adapter_delete_sq(dev, qid);
release_cq:
adapter_delete_cq(dev, qid);
-out:
return result;
}
@@ -2012,13 +2011,7 @@ static void nvme_del_cq_end(struct request *req, blk_status_t error)
if (!error) {
unsigned long flags;
- /*
- * We might be called with the AQ cq_lock held
- * and the I/O queue cq_lock should always
- * nest inside the AQ one.
- */
- spin_lock_irqsave_nested(&nvmeq->cq_lock, flags,
- SINGLE_DEPTH_NESTING);
+ spin_lock_irqsave(&nvmeq->cq_lock, flags);
nvme_process_cq(nvmeq, &start, &end, -1);
spin_unlock_irqrestore(&nvmeq->cq_lock, flags);
@@ -2231,14 +2224,6 @@ static void nvme_dev_disable(struct nvme_dev *dev, bool shutdown)
nvme_stop_queues(&dev->ctrl);
if (!dead && dev->ctrl.queue_count > 0) {
- /*
- * If the controller is still alive tell it to stop using the
- * host memory buffer. In theory the shutdown / reset should
- * make sure that it doesn't access the host memoery anymore,
- * but I'd rather be safe than sorry..
- */
- if (dev->host_mem_descs)
- nvme_set_host_mem(dev, 0);
nvme_disable_io_queues(dev);
nvme_disable_admin_queue(dev, shutdown);
}
@@ -2614,7 +2599,7 @@ static void nvme_remove(struct pci_dev *pdev)
if (!pci_device_is_present(pdev)) {
nvme_change_ctrl_state(&dev->ctrl, NVME_CTRL_DEAD);
- nvme_dev_disable(dev, false);
+ nvme_dev_disable(dev, true);
}
flush_work(&dev->ctrl.reset_work);
diff --git a/drivers/nvme/host/rdma.c b/drivers/nvme/host/rdma.c
index 7b3f08410430..2aba03876d84 100644
--- a/drivers/nvme/host/rdma.c
+++ b/drivers/nvme/host/rdma.c
@@ -1951,8 +1951,9 @@ static struct nvme_ctrl *nvme_rdma_create_ctrl(struct device *dev,
}
/* sanity check keyed sgls */
- if (!(ctrl->ctrl.sgls & (1 << 20))) {
- dev_err(ctrl->ctrl.device, "Mandatory keyed sgls are not support\n");
+ if (!(ctrl->ctrl.sgls & (1 << 2))) {
+ dev_err(ctrl->ctrl.device,
+ "Mandatory keyed sgls are not supported!\n");
ret = -EINVAL;
goto out_remove_admin_queue;
}
diff --git a/drivers/nvme/target/admin-cmd.c b/drivers/nvme/target/admin-cmd.c
index ead8fbe6922e..962532842769 100644
--- a/drivers/nvme/target/admin-cmd.c
+++ b/drivers/nvme/target/admin-cmd.c
@@ -270,8 +270,7 @@ static void nvmet_execute_identify_ns(struct nvmet_req *req)
struct nvme_id_ns *id;
u16 status = 0;
- ns = nvmet_find_namespace(req->sq->ctrl, req->cmd->identify.nsid);
- if (!ns) {
+ if (le32_to_cpu(req->cmd->identify.nsid) == NVME_NSID_ALL) {
status = NVME_SC_INVALID_NS | NVME_SC_DNR;
goto out;
}
@@ -279,9 +278,14 @@ static void nvmet_execute_identify_ns(struct nvmet_req *req)
id = kzalloc(sizeof(*id), GFP_KERNEL);
if (!id) {
status = NVME_SC_INTERNAL;
- goto out_put_ns;
+ goto out;
}
+ /* return an all zeroed buffer if we can't find an active namespace */
+ ns = nvmet_find_namespace(req->sq->ctrl, req->cmd->identify.nsid);
+ if (!ns)
+ goto done;
+
/*
* nuse = ncap = nsze isn't always true, but we have no way to find
* that out from the underlying device.
@@ -306,11 +310,10 @@ static void nvmet_execute_identify_ns(struct nvmet_req *req)
id->lbaf[0].ds = ns->blksize_shift;
+ nvmet_put_namespace(ns);
+done:
status = nvmet_copy_to_sgl(req, 0, id, sizeof(*id));
-
kfree(id);
-out_put_ns:
- nvmet_put_namespace(ns);
out:
nvmet_req_complete(req, status);
}
diff --git a/drivers/nvme/target/configfs.c b/drivers/nvme/target/configfs.c
index ad9ff27234b5..d3f3b3ec4d1a 100644
--- a/drivers/nvme/target/configfs.c
+++ b/drivers/nvme/target/configfs.c
@@ -137,8 +137,10 @@ static ssize_t nvmet_addr_traddr_store(struct config_item *item,
pr_err("Disable the address before modifying\n");
return -EACCES;
}
- return snprintf(port->disc_addr.traddr,
- sizeof(port->disc_addr.traddr), "%s", page);
+
+ if (sscanf(page, "%s\n", port->disc_addr.traddr) != 1)
+ return -EINVAL;
+ return count;
}
CONFIGFS_ATTR(nvmet_, addr_traddr);
@@ -208,8 +210,10 @@ static ssize_t nvmet_addr_trsvcid_store(struct config_item *item,
pr_err("Disable the address before modifying\n");
return -EACCES;
}
- return snprintf(port->disc_addr.trsvcid,
- sizeof(port->disc_addr.trsvcid), "%s", page);
+
+ if (sscanf(page, "%s\n", port->disc_addr.trsvcid) != 1)
+ return -EINVAL;
+ return count;
}
CONFIGFS_ATTR(nvmet_, addr_trsvcid);
@@ -288,7 +292,7 @@ static ssize_t nvmet_ns_device_path_store(struct config_item *item,
kfree(ns->device_path);
ret = -ENOMEM;
- ns->device_path = kstrdup(page, GFP_KERNEL);
+ ns->device_path = kstrndup(page, strcspn(page, "\n"), GFP_KERNEL);
if (!ns->device_path)
goto out_unlock;