Merge tag 'for-5.8/drivers-2020-06-01' of git://git.kernel.dk/linux-block
[linux-2.6-microblaze.git] / drivers / nvme / host / pci.c
index cc46e25..d690d55 100644 (file)
@@ -68,14 +68,30 @@ 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");
 
+static int io_queue_count_set(const char *val, const struct kernel_param *kp)
+{
+       unsigned int n;
+       int ret;
+
+       ret = kstrtouint(val, 10, &n);
+       if (ret != 0 || n > num_possible_cpus())
+               return -EINVAL;
+       return param_set_uint(val, kp);
+}
+
+static const struct kernel_param_ops io_queue_count_ops = {
+       .set = io_queue_count_set,
+       .get = param_get_uint,
+};
+
 static unsigned int write_queues;
-module_param(write_queues, uint, 0644);
+module_param_cb(write_queues, &io_queue_count_ops, &write_queues, 0644);
 MODULE_PARM_DESC(write_queues,
        "Number of queues to use for writes. If not set, reads and writes "
        "will share a queue set.");
 
 static unsigned int poll_queues;
-module_param(poll_queues, uint, 0644);
+module_param_cb(poll_queues, &io_queue_count_ops, &poll_queues, 0644);
 MODULE_PARM_DESC(poll_queues, "Number of queues to use for polled IO.");
 
 struct nvme_dev;
@@ -128,6 +144,9 @@ struct nvme_dev {
        dma_addr_t host_mem_descs_dma;
        struct nvme_host_mem_buf_desc *host_mem_descs;
        void **host_mem_desc_bufs;
+       unsigned int nr_allocated_queues;
+       unsigned int nr_write_queues;
+       unsigned int nr_poll_queues;
 };
 
 static int io_queue_depth_set(const char *val, const struct kernel_param *kp)
@@ -166,14 +185,13 @@ struct nvme_queue {
        void *sq_cmds;
         /* only used for poll queues: */
        spinlock_t cq_poll_lock ____cacheline_aligned_in_smp;
-       volatile struct nvme_completion *cqes;
+       struct nvme_completion *cqes;
        dma_addr_t sq_dma_addr;
        dma_addr_t cq_dma_addr;
        u32 __iomem *q_db;
        u16 q_depth;
        u16 cq_vector;
        u16 sq_tail;
-       u16 last_sq_tail;
        u16 cq_head;
        u16 qid;
        u8 cq_phase;
@@ -209,25 +227,14 @@ struct nvme_iod {
        struct scatterlist *sg;
 };
 
-static unsigned int max_io_queues(void)
+static inline unsigned int nvme_dbbuf_size(struct nvme_dev *dev)
 {
-       return num_possible_cpus() + write_queues + poll_queues;
-}
-
-static unsigned int max_queue_count(void)
-{
-       /* IO queues + admin queue */
-       return 1 + max_io_queues();
-}
-
-static inline unsigned int nvme_dbbuf_size(u32 stride)
-{
-       return (max_queue_count() * 8 * stride);
+       return dev->nr_allocated_queues * 8 * dev->db_stride;
 }
 
 static int nvme_dbbuf_dma_alloc(struct nvme_dev *dev)
 {
-       unsigned int mem_size = nvme_dbbuf_size(dev->db_stride);
+       unsigned int mem_size = nvme_dbbuf_size(dev);
 
        if (dev->dbbuf_dbs)
                return 0;
@@ -252,7 +259,7 @@ static int nvme_dbbuf_dma_alloc(struct nvme_dev *dev)
 
 static void nvme_dbbuf_dma_free(struct nvme_dev *dev)
 {
-       unsigned int mem_size = nvme_dbbuf_size(dev->db_stride);
+       unsigned int mem_size = nvme_dbbuf_size(dev);
 
        if (dev->dbbuf_dbs) {
                dma_free_coherent(dev->dev, mem_size,
@@ -446,24 +453,11 @@ static int nvme_pci_map_queues(struct blk_mq_tag_set *set)
        return 0;
 }
 
-/*
- * Write sq tail if we are asked to, or if the next command would wrap.
- */
-static inline void nvme_write_sq_db(struct nvme_queue *nvmeq, bool write_sq)
+static inline void nvme_write_sq_db(struct nvme_queue *nvmeq)
 {
-       if (!write_sq) {
-               u16 next_tail = nvmeq->sq_tail + 1;
-
-               if (next_tail == nvmeq->q_depth)
-                       next_tail = 0;
-               if (next_tail != nvmeq->last_sq_tail)
-                       return;
-       }
-
        if (nvme_dbbuf_update_and_check_event(nvmeq->sq_tail,
                        nvmeq->dbbuf_sq_db, nvmeq->dbbuf_sq_ei))
                writel(nvmeq->sq_tail, nvmeq->q_db);
-       nvmeq->last_sq_tail = nvmeq->sq_tail;
 }
 
 /**
@@ -480,7 +474,8 @@ static void nvme_submit_cmd(struct nvme_queue *nvmeq, struct nvme_command *cmd,
               cmd, sizeof(*cmd));
        if (++nvmeq->sq_tail == nvmeq->q_depth)
                nvmeq->sq_tail = 0;
-       nvme_write_sq_db(nvmeq, write_sq);
+       if (write_sq)
+               nvme_write_sq_db(nvmeq);
        spin_unlock(&nvmeq->sq_lock);
 }
 
@@ -489,8 +484,7 @@ static void nvme_commit_rqs(struct blk_mq_hw_ctx *hctx)
        struct nvme_queue *nvmeq = hctx->driver_data;
 
        spin_lock(&nvmeq->sq_lock);
-       if (nvmeq->sq_tail != nvmeq->last_sq_tail)
-               nvme_write_sq_db(nvmeq, true);
+       nvme_write_sq_db(nvmeq);
        spin_unlock(&nvmeq->sq_lock);
 }
 
@@ -922,8 +916,9 @@ static void nvme_pci_complete_rq(struct request *req)
 /* We read the CQE phase first to check if the rest of the entry is valid */
 static inline bool nvme_cqe_pending(struct nvme_queue *nvmeq)
 {
-       return (le16_to_cpu(nvmeq->cqes[nvmeq->cq_head].status) & 1) ==
-                       nvmeq->cq_phase;
+       struct nvme_completion *hcqe = &nvmeq->cqes[nvmeq->cq_head];
+
+       return (le16_to_cpu(READ_ONCE(hcqe->status)) & 1) == nvmeq->cq_phase;
 }
 
 static inline void nvme_ring_cq_doorbell(struct nvme_queue *nvmeq)
@@ -944,7 +939,7 @@ static inline struct blk_mq_tags *nvme_queue_tagset(struct nvme_queue *nvmeq)
 
 static inline void nvme_handle_cqe(struct nvme_queue *nvmeq, u16 idx)
 {
-       volatile struct nvme_completion *cqe = &nvmeq->cqes[idx];
+       struct nvme_completion *cqe = &nvmeq->cqes[idx];
        struct request *req;
 
        if (unlikely(cqe->command_id >= nvmeq->q_depth)) {
@@ -1501,7 +1496,6 @@ static void nvme_init_queue(struct nvme_queue *nvmeq, u16 qid)
        struct nvme_dev *dev = nvmeq->dev;
 
        nvmeq->sq_tail = 0;
-       nvmeq->last_sq_tail = 0;
        nvmeq->cq_head = 0;
        nvmeq->cq_phase = 1;
        nvmeq->q_db = &dev->dbs[qid * 2 * dev->db_stride];
@@ -2003,7 +1997,7 @@ static int nvme_setup_host_mem(struct nvme_dev *dev)
 static void nvme_calc_irq_sets(struct irq_affinity *affd, unsigned int nrirqs)
 {
        struct nvme_dev *dev = affd->priv;
-       unsigned int nr_read_queues;
+       unsigned int nr_read_queues, nr_write_queues = dev->nr_write_queues;
 
        /*
         * If there is no interupt available for queues, ensure that
@@ -2019,12 +2013,12 @@ static void nvme_calc_irq_sets(struct irq_affinity *affd, unsigned int nrirqs)
        if (!nrirqs) {
                nrirqs = 1;
                nr_read_queues = 0;
-       } else if (nrirqs == 1 || !write_queues) {
+       } else if (nrirqs == 1 || !nr_write_queues) {
                nr_read_queues = 0;
-       } else if (write_queues >= nrirqs) {
+       } else if (nr_write_queues >= nrirqs) {
                nr_read_queues = 1;
        } else {
-               nr_read_queues = nrirqs - write_queues;
+               nr_read_queues = nrirqs - nr_write_queues;
        }
 
        dev->io_queues[HCTX_TYPE_DEFAULT] = nrirqs - nr_read_queues;
@@ -2048,7 +2042,7 @@ static int nvme_setup_irqs(struct nvme_dev *dev, unsigned int nr_io_queues)
         * Poll queues don't need interrupts, but we need at least one IO
         * queue left over for non-polled IO.
         */
-       this_p_queues = poll_queues;
+       this_p_queues = dev->nr_poll_queues;
        if (this_p_queues >= nr_io_queues) {
                this_p_queues = nr_io_queues - 1;
                irq_queues = 1;
@@ -2078,14 +2072,25 @@ static void nvme_disable_io_queues(struct nvme_dev *dev)
                __nvme_disable_io_queues(dev, nvme_admin_delete_cq);
 }
 
+static unsigned int nvme_max_io_queues(struct nvme_dev *dev)
+{
+       return num_possible_cpus() + dev->nr_write_queues + dev->nr_poll_queues;
+}
+
 static int nvme_setup_io_queues(struct nvme_dev *dev)
 {
        struct nvme_queue *adminq = &dev->queues[0];
        struct pci_dev *pdev = to_pci_dev(dev->dev);
-       int result, nr_io_queues;
+       unsigned int nr_io_queues;
        unsigned long size;
+       int result;
 
-       nr_io_queues = max_io_queues();
+       /*
+        * Sample the module parameters once at reset time so that we have
+        * stable values to work with.
+        */
+       dev->nr_write_queues = write_queues;
+       dev->nr_poll_queues = poll_queues;
 
        /*
         * If tags are shared with admin queue (Apple bug), then
@@ -2093,6 +2098,9 @@ static int nvme_setup_io_queues(struct nvme_dev *dev)
         */
        if (dev->ctrl.quirks & NVME_QUIRK_SHARED_TAGS)
                nr_io_queues = 1;
+       else
+               nr_io_queues = min(nvme_max_io_queues(dev),
+                                  dev->nr_allocated_queues - 1);
 
        result = nvme_set_queue_count(&dev->ctrl, &nr_io_queues);
        if (result < 0)
@@ -2565,6 +2573,12 @@ static void nvme_reset_work(struct work_struct *work)
                goto out;
        }
 
+       /*
+        * We do not support an SGL for metadata (yet), so we are limited to a
+        * single integrity segment for the separate metadata pointer.
+        */
+       dev->ctrl.max_integrity_segments = 1;
+
        result = nvme_init_identify(&dev->ctrl);
        if (result)
                goto out;
@@ -2767,8 +2781,11 @@ static int nvme_probe(struct pci_dev *pdev, const struct pci_device_id *id)
        if (!dev)
                return -ENOMEM;
 
-       dev->queues = kcalloc_node(max_queue_count(), sizeof(struct nvme_queue),
-                                       GFP_KERNEL, node);
+       dev->nr_write_queues = write_queues;
+       dev->nr_poll_queues = poll_queues;
+       dev->nr_allocated_queues = nvme_max_io_queues(dev) + 1;
+       dev->queues = kcalloc_node(dev->nr_allocated_queues,
+                       sizeof(struct nvme_queue), GFP_KERNEL, node);
        if (!dev->queues)
                goto free;
 
@@ -3131,8 +3148,6 @@ static int __init nvme_init(void)
        BUILD_BUG_ON(sizeof(struct nvme_delete_queue) != 64);
        BUILD_BUG_ON(IRQ_AFFINITY_MAX_SETS < 2);
 
-       write_queues = min(write_queues, num_possible_cpus());
-       poll_queues = min(poll_queues, num_possible_cpus());
        return pci_register_driver(&nvme_driver);
 }