Merge branch 'nvme-4.13' of git://git.infradead.org/nvme into for-linus
Pull followup NVMe (mostly) changes from Sagi: I added the quiesce/unquiesce patches in here as it's easy for me easily apply changes on top. It has accumulated reviews and includes mostly nvme anyway, please tell me if you don't want to take them with this. This includes: - quiesce/unquiesce fixes in nvme and others from me - nvme-fc add create association padding spec updates from James - some more quirking from MKP - nvmet nit cleanup from Max - Fix nvme-rdma racy RDMA completion signalling from Marta - some centralization patches from me - add tagset nr_hw_queues updates on controller resets in nvme drivers from me - nvme-rdma fix resources recycling when doing error recovery from me - minor cleanups in nvme-fc from me
This commit is contained in:
@@ -35,7 +35,6 @@
|
||||
|
||||
#include "nvme.h"
|
||||
|
||||
#define NVME_Q_DEPTH 1024
|
||||
#define SQ_SIZE(depth) (depth * sizeof(struct nvme_command))
|
||||
#define CQ_SIZE(depth) (depth * sizeof(struct nvme_completion))
|
||||
|
||||
@@ -57,6 +56,16 @@ module_param(max_host_mem_size_mb, uint, 0444);
|
||||
MODULE_PARM_DESC(max_host_mem_size_mb,
|
||||
"Maximum Host Memory Buffer (HMB) size per controller (in MiB)");
|
||||
|
||||
static int io_queue_depth_set(const char *val, const struct kernel_param *kp);
|
||||
static const struct kernel_param_ops io_queue_depth_ops = {
|
||||
.set = io_queue_depth_set,
|
||||
.get = param_get_int,
|
||||
};
|
||||
|
||||
static int io_queue_depth = 1024;
|
||||
module_param_cb(io_queue_depth, &io_queue_depth_ops, &io_queue_depth, 0644);
|
||||
MODULE_PARM_DESC(io_queue_depth, "set io queue depth, should >= 2");
|
||||
|
||||
struct nvme_dev;
|
||||
struct nvme_queue;
|
||||
|
||||
@@ -74,7 +83,6 @@ struct nvme_dev {
|
||||
struct device *dev;
|
||||
struct dma_pool *prp_page_pool;
|
||||
struct dma_pool *prp_small_pool;
|
||||
unsigned queue_count;
|
||||
unsigned online_queues;
|
||||
unsigned max_qid;
|
||||
int q_depth;
|
||||
@@ -105,6 +113,17 @@ struct nvme_dev {
|
||||
void **host_mem_desc_bufs;
|
||||
};
|
||||
|
||||
static int io_queue_depth_set(const char *val, const struct kernel_param *kp)
|
||||
{
|
||||
int n = 0, ret;
|
||||
|
||||
ret = kstrtoint(val, 10, &n);
|
||||
if (ret != 0 || n < 2)
|
||||
return -EINVAL;
|
||||
|
||||
return param_set_int(val, kp);
|
||||
}
|
||||
|
||||
static inline unsigned int sq_idx(unsigned int qid, u32 stride)
|
||||
{
|
||||
return qid * 2 * stride;
|
||||
@@ -1099,9 +1118,9 @@ static void nvme_free_queues(struct nvme_dev *dev, int lowest)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = dev->queue_count - 1; i >= lowest; i--) {
|
||||
for (i = dev->ctrl.queue_count - 1; i >= lowest; i--) {
|
||||
struct nvme_queue *nvmeq = dev->queues[i];
|
||||
dev->queue_count--;
|
||||
dev->ctrl.queue_count--;
|
||||
dev->queues[i] = NULL;
|
||||
nvme_free_queue(nvmeq);
|
||||
}
|
||||
@@ -1126,7 +1145,7 @@ static int nvme_suspend_queue(struct nvme_queue *nvmeq)
|
||||
spin_unlock_irq(&nvmeq->q_lock);
|
||||
|
||||
if (!nvmeq->qid && nvmeq->dev->ctrl.admin_q)
|
||||
blk_mq_stop_hw_queues(nvmeq->dev->ctrl.admin_q);
|
||||
blk_mq_quiesce_queue(nvmeq->dev->ctrl.admin_q);
|
||||
|
||||
pci_free_irq(to_pci_dev(nvmeq->dev->dev), vector, nvmeq);
|
||||
|
||||
@@ -1145,8 +1164,7 @@ static void nvme_disable_admin_queue(struct nvme_dev *dev, bool shutdown)
|
||||
if (shutdown)
|
||||
nvme_shutdown_ctrl(&dev->ctrl);
|
||||
else
|
||||
nvme_disable_ctrl(&dev->ctrl, lo_hi_readq(
|
||||
dev->bar + NVME_REG_CAP));
|
||||
nvme_disable_ctrl(&dev->ctrl, dev->ctrl.cap);
|
||||
|
||||
spin_lock_irq(&nvmeq->q_lock);
|
||||
nvme_process_cq(nvmeq);
|
||||
@@ -1221,7 +1239,7 @@ static struct nvme_queue *nvme_alloc_queue(struct nvme_dev *dev, int qid,
|
||||
nvmeq->qid = qid;
|
||||
nvmeq->cq_vector = -1;
|
||||
dev->queues[qid] = nvmeq;
|
||||
dev->queue_count++;
|
||||
dev->ctrl.queue_count++;
|
||||
|
||||
return nvmeq;
|
||||
|
||||
@@ -1317,7 +1335,7 @@ static void nvme_dev_remove_admin(struct nvme_dev *dev)
|
||||
* user requests may be waiting on a stopped queue. Start the
|
||||
* queue to flush these to completion.
|
||||
*/
|
||||
blk_mq_start_stopped_hw_queues(dev->ctrl.admin_q, true);
|
||||
blk_mq_unquiesce_queue(dev->ctrl.admin_q);
|
||||
blk_cleanup_queue(dev->ctrl.admin_q);
|
||||
blk_mq_free_tag_set(&dev->admin_tagset);
|
||||
}
|
||||
@@ -1354,7 +1372,7 @@ static int nvme_alloc_admin_tags(struct nvme_dev *dev)
|
||||
return -ENODEV;
|
||||
}
|
||||
} else
|
||||
blk_mq_start_stopped_hw_queues(dev->ctrl.admin_q, true);
|
||||
blk_mq_unquiesce_queue(dev->ctrl.admin_q);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -1385,11 +1403,10 @@ static int nvme_remap_bar(struct nvme_dev *dev, unsigned long size)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int nvme_configure_admin_queue(struct nvme_dev *dev)
|
||||
static int nvme_pci_configure_admin_queue(struct nvme_dev *dev)
|
||||
{
|
||||
int result;
|
||||
u32 aqa;
|
||||
u64 cap = lo_hi_readq(dev->bar + NVME_REG_CAP);
|
||||
struct nvme_queue *nvmeq;
|
||||
|
||||
result = nvme_remap_bar(dev, db_bar_size(dev, 0));
|
||||
@@ -1397,13 +1414,13 @@ static int nvme_configure_admin_queue(struct nvme_dev *dev)
|
||||
return result;
|
||||
|
||||
dev->subsystem = readl(dev->bar + NVME_REG_VS) >= NVME_VS(1, 1, 0) ?
|
||||
NVME_CAP_NSSRC(cap) : 0;
|
||||
NVME_CAP_NSSRC(dev->ctrl.cap) : 0;
|
||||
|
||||
if (dev->subsystem &&
|
||||
(readl(dev->bar + NVME_REG_CSTS) & NVME_CSTS_NSSRO))
|
||||
writel(NVME_CSTS_NSSRO, dev->bar + NVME_REG_CSTS);
|
||||
|
||||
result = nvme_disable_ctrl(&dev->ctrl, cap);
|
||||
result = nvme_disable_ctrl(&dev->ctrl, dev->ctrl.cap);
|
||||
if (result < 0)
|
||||
return result;
|
||||
|
||||
@@ -1422,7 +1439,7 @@ static int nvme_configure_admin_queue(struct nvme_dev *dev)
|
||||
lo_hi_writeq(nvmeq->sq_dma_addr, dev->bar + NVME_REG_ASQ);
|
||||
lo_hi_writeq(nvmeq->cq_dma_addr, dev->bar + NVME_REG_ACQ);
|
||||
|
||||
result = nvme_enable_ctrl(&dev->ctrl, cap);
|
||||
result = nvme_enable_ctrl(&dev->ctrl, dev->ctrl.cap);
|
||||
if (result)
|
||||
return result;
|
||||
|
||||
@@ -1441,7 +1458,7 @@ static int nvme_create_io_queues(struct nvme_dev *dev)
|
||||
unsigned i, max;
|
||||
int ret = 0;
|
||||
|
||||
for (i = dev->queue_count; i <= dev->max_qid; i++) {
|
||||
for (i = dev->ctrl.queue_count; i <= dev->max_qid; i++) {
|
||||
/* vector == qid - 1, match nvme_create_queue */
|
||||
if (!nvme_alloc_queue(dev, i, dev->q_depth,
|
||||
pci_irq_get_node(to_pci_dev(dev->dev), i - 1))) {
|
||||
@@ -1450,7 +1467,7 @@ static int nvme_create_io_queues(struct nvme_dev *dev)
|
||||
}
|
||||
}
|
||||
|
||||
max = min(dev->max_qid, dev->queue_count - 1);
|
||||
max = min(dev->max_qid, dev->ctrl.queue_count - 1);
|
||||
for (i = dev->online_queues; i <= max; i++) {
|
||||
ret = nvme_create_queue(dev->queues[i], i);
|
||||
if (ret)
|
||||
@@ -1585,9 +1602,10 @@ static void nvme_free_host_mem(struct nvme_dev *dev)
|
||||
static int nvme_alloc_host_mem(struct nvme_dev *dev, u64 min, u64 preferred)
|
||||
{
|
||||
struct nvme_host_mem_buf_desc *descs;
|
||||
u32 chunk_size, max_entries, i = 0;
|
||||
u32 chunk_size, max_entries;
|
||||
int i = 0;
|
||||
void **bufs;
|
||||
u64 size, tmp;
|
||||
u64 size = 0, tmp;
|
||||
|
||||
/* start big and work our way down */
|
||||
chunk_size = min(preferred, (u64)PAGE_SIZE << MAX_ORDER);
|
||||
@@ -1866,7 +1884,6 @@ static int nvme_dev_add(struct nvme_dev *dev)
|
||||
|
||||
static int nvme_pci_enable(struct nvme_dev *dev)
|
||||
{
|
||||
u64 cap;
|
||||
int result = -ENOMEM;
|
||||
struct pci_dev *pdev = to_pci_dev(dev->dev);
|
||||
|
||||
@@ -1893,10 +1910,11 @@ static int nvme_pci_enable(struct nvme_dev *dev)
|
||||
if (result < 0)
|
||||
return result;
|
||||
|
||||
cap = lo_hi_readq(dev->bar + NVME_REG_CAP);
|
||||
dev->ctrl.cap = lo_hi_readq(dev->bar + NVME_REG_CAP);
|
||||
|
||||
dev->q_depth = min_t(int, NVME_CAP_MQES(cap) + 1, NVME_Q_DEPTH);
|
||||
dev->db_stride = 1 << NVME_CAP_STRIDE(cap);
|
||||
dev->q_depth = min_t(int, NVME_CAP_MQES(dev->ctrl.cap) + 1,
|
||||
io_queue_depth);
|
||||
dev->db_stride = 1 << NVME_CAP_STRIDE(dev->ctrl.cap);
|
||||
dev->dbs = dev->bar + 4096;
|
||||
|
||||
/*
|
||||
@@ -1908,6 +1926,12 @@ static int nvme_pci_enable(struct nvme_dev *dev)
|
||||
dev_warn(dev->ctrl.device, "detected Apple NVMe controller, "
|
||||
"set queue depth=%u to work around controller resets\n",
|
||||
dev->q_depth);
|
||||
} else if (pdev->vendor == PCI_VENDOR_ID_SAMSUNG &&
|
||||
(pdev->device == 0xa821 || pdev->device == 0xa822) &&
|
||||
NVME_CAP_MQES(dev->ctrl.cap) == 0) {
|
||||
dev->q_depth = 64;
|
||||
dev_err(dev->ctrl.device, "detected PM1725 NVMe controller, "
|
||||
"set queue depth=%u\n", dev->q_depth);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -1996,7 +2020,7 @@ static void nvme_dev_disable(struct nvme_dev *dev, bool shutdown)
|
||||
nvme_stop_queues(&dev->ctrl);
|
||||
|
||||
queues = dev->online_queues - 1;
|
||||
for (i = dev->queue_count - 1; i > 0; i--)
|
||||
for (i = dev->ctrl.queue_count - 1; i > 0; i--)
|
||||
nvme_suspend_queue(dev->queues[i]);
|
||||
|
||||
if (dead) {
|
||||
@@ -2004,7 +2028,7 @@ static void nvme_dev_disable(struct nvme_dev *dev, bool shutdown)
|
||||
* probe, before the admin queue is configured. Thus,
|
||||
* queue_count can be 0 here.
|
||||
*/
|
||||
if (dev->queue_count)
|
||||
if (dev->ctrl.queue_count)
|
||||
nvme_suspend_queue(dev->queues[0]);
|
||||
} else {
|
||||
nvme_disable_io_queues(dev, queues);
|
||||
@@ -2094,7 +2118,7 @@ static void nvme_reset_work(struct work_struct *work)
|
||||
if (result)
|
||||
goto out;
|
||||
|
||||
result = nvme_configure_admin_queue(dev);
|
||||
result = nvme_pci_configure_admin_queue(dev);
|
||||
if (result)
|
||||
goto out;
|
||||
|
||||
@@ -2132,15 +2156,6 @@ static void nvme_reset_work(struct work_struct *work)
|
||||
if (result)
|
||||
goto out;
|
||||
|
||||
/*
|
||||
* A controller that can not execute IO typically requires user
|
||||
* intervention to correct. For such degraded controllers, the driver
|
||||
* should not submit commands the user did not request, so skip
|
||||
* registering for asynchronous event notification on this condition.
|
||||
*/
|
||||
if (dev->online_queues > 1)
|
||||
nvme_queue_async_events(&dev->ctrl);
|
||||
|
||||
/*
|
||||
* Keep the controller around but remove all namespaces if we don't have
|
||||
* any working I/O queue.
|
||||
@@ -2161,8 +2176,7 @@ static void nvme_reset_work(struct work_struct *work)
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (dev->online_queues > 1)
|
||||
nvme_queue_scan(&dev->ctrl);
|
||||
nvme_start_ctrl(&dev->ctrl);
|
||||
return;
|
||||
|
||||
out:
|
||||
@@ -2339,11 +2353,13 @@ static void nvme_remove(struct pci_dev *pdev)
|
||||
}
|
||||
|
||||
flush_work(&dev->ctrl.reset_work);
|
||||
nvme_uninit_ctrl(&dev->ctrl);
|
||||
nvme_stop_ctrl(&dev->ctrl);
|
||||
nvme_remove_namespaces(&dev->ctrl);
|
||||
nvme_dev_disable(dev, true);
|
||||
nvme_free_host_mem(dev);
|
||||
nvme_dev_remove_admin(dev);
|
||||
nvme_free_queues(dev, 0);
|
||||
nvme_uninit_ctrl(&dev->ctrl);
|
||||
nvme_release_prp_pools(dev);
|
||||
nvme_dev_unmap(dev);
|
||||
nvme_put_ctrl(&dev->ctrl);
|
||||
@@ -2455,6 +2471,10 @@ static const struct pci_device_id nvme_id_table[] = {
|
||||
.driver_data = NVME_QUIRK_DELAY_BEFORE_CHK_RDY, },
|
||||
{ PCI_DEVICE(0x1c5f, 0x0540), /* Memblaze Pblaze4 adapter */
|
||||
.driver_data = NVME_QUIRK_DELAY_BEFORE_CHK_RDY, },
|
||||
{ PCI_DEVICE(0x144d, 0xa821), /* Samsung PM1725 */
|
||||
.driver_data = NVME_QUIRK_DELAY_BEFORE_CHK_RDY, },
|
||||
{ PCI_DEVICE(0x144d, 0xa822), /* Samsung PM1725a */
|
||||
.driver_data = NVME_QUIRK_DELAY_BEFORE_CHK_RDY, },
|
||||
{ PCI_DEVICE_CLASS(PCI_CLASS_STORAGE_EXPRESS, 0xffffff) },
|
||||
{ PCI_DEVICE(PCI_VENDOR_ID_APPLE, 0x2001) },
|
||||
{ PCI_DEVICE(PCI_VENDOR_ID_APPLE, 0x2003) },
|
||||
|
Reference in New Issue
Block a user