[PATCH 17/18] nvme: move namespace scanning to common code
J Freyensee
james_p_freyensee at linux.intel.com
Wed Oct 21 16:27:39 PDT 2015
On Fri, 2015-10-16 at 07:58 +0200, Christoph Hellwig wrote:
> The namespace scanning code has been mostly generic already, we just
> need to store a pointer to the tagset in the nvme_ctrl structure, and
> add a method to check if a controller is I/O incapable. The latter
> will hopefully be replaced by a proper controller state machine soon.
>
> Signed-off-by: Christoph Hellwig <hch at lst.de>
> ---
> drivers/nvme/host/core.c | 190
> +++++++++++++++++++++++++++++++++++++++-
> drivers/nvme/host/nvme.h | 25 +++++-
> drivers/nvme/host/pci.c | 221 +++++++------------------------------
> ----------
> 3 files changed, 239 insertions(+), 197 deletions(-)
>
> diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c
> index 3e88901..a01ab5a 100644
> --- a/drivers/nvme/host/core.c
> +++ b/drivers/nvme/host/core.c
> @@ -17,6 +17,8 @@
> #include <linux/errno.h>
> #include <linux/hdreg.h>
> #include <linux/kernel.h>
> +#include <linux/module.h>
> +#include <linux/list_sort.h>
> #include <linux/slab.h>
> #include <linux/types.h>
> #include <linux/ptrace.h>
> @@ -26,6 +28,9 @@
>
> #include "nvme.h"
>
> +static int nvme_major;
> +module_param(nvme_major, int, 0);
> +
> DEFINE_SPINLOCK(dev_list_lock);
>
> static void nvme_free_ns(struct kref *kref)
> @@ -41,7 +46,7 @@ static void nvme_free_ns(struct kref *kref)
> kfree(ns);
> }
>
> -void nvme_put_ns(struct nvme_ns *ns)
> +static void nvme_put_ns(struct nvme_ns *ns)
> {
> kref_put(&ns->kref, nvme_free_ns);
> }
> @@ -503,7 +508,7 @@ static void nvme_config_discard(struct nvme_ns
> *ns)
> queue_flag_set_unlocked(QUEUE_FLAG_DISCARD, ns->queue);
> }
>
> -int nvme_revalidate_disk(struct gendisk *disk)
> +static int nvme_revalidate_disk(struct gendisk *disk)
> {
> struct nvme_ns *ns = disk->private_data;
> struct nvme_id_ns *id;
> @@ -564,7 +569,7 @@ int nvme_revalidate_disk(struct gendisk *disk)
> return 0;
> }
>
> -const struct block_device_operations nvme_fops = {
> +static const struct block_device_operations nvme_fops = {
> .owner = THIS_MODULE,
> .ioctl = nvme_ioctl,
> .compat_ioctl = nvme_compat_ioctl,
> @@ -591,6 +596,7 @@ int nvme_init_identify(struct nvme_ctrl *ctrl)
> return ret;
> }
> page_shift = NVME_CAP_MPSMIN(cap) + 12;
> + ctrl->page_size = 1 << page_shift;
>
> ret = nvme_identify_ctrl(ctrl, &id);
> if (ret) {
> @@ -636,3 +642,181 @@ void nvme_put_ctrl(struct nvme_ctrl *ctrl)
> kref_put(&ctrl->kref, nvme_free_ctrl);
> }
>
> +static int ns_cmp(void *priv, struct list_head *a, struct list_head
> *b)
> +{
> + struct nvme_ns *nsa = container_of(a, struct nvme_ns, list);
> + struct nvme_ns *nsb = container_of(b, struct nvme_ns, list);
> +
> + return nsa->ns_id - nsb->ns_id;
> +}
> +
> +static struct nvme_ns *nvme_find_ns(struct nvme_ctrl *ctrl, unsigned
> nsid)
> +{
> + struct nvme_ns *ns;
> +
> + list_for_each_entry(ns, &ctrl->namespaces, list) {
I know this is basically just a move into core.c, but with the concept
of namespace management in the 1.2 spec, would something like
list_for_each_entry_safe() and/or a spinlock be more appropriate?
> + if (ns->ns_id == nsid)
> + return ns;
> + if (ns->ns_id > nsid)
> + break;
> + }
> + return NULL;
> +}
<snip>
> +
> static const struct nvme_ctrl_ops nvme_pci_ctrl_ops = {
> .reg_read32 = nvme_pci_reg_read32,
> .reg_read64 = nvme_pci_reg_read64,
> + .io_incapable = nvme_pci_io_incapable,
> .free_ctrl = nvme_pci_free_ctrl,
> };
>
> @@ -2645,7 +2486,7 @@ static int nvme_probe(struct pci_dev *pdev,
> const struct pci_device_id *id)
> if (!dev->queues)
> goto free;
>
> - INIT_LIST_HEAD(&dev->namespaces);
> + INIT_LIST_HEAD(&dev->ctrl.namespaces);
OK, so I'm looking at your git repo:
http://git.infradead.org/users/hch/block.git/shortlog/refs/heads/nvme
-split.5
and I see:
struct nvme_ctrl {
.
.
struct list_head namespaces;
.
.
}
So that makes more sense, and I must have missed some code or future
patch.
> INIT_WORK(&dev->reset_work, nvme_reset_work);
> dev->dev = get_device(&pdev->dev);
> pci_set_drvdata(pdev, dev);
> @@ -2664,17 +2505,17 @@ static int nvme_probe(struct pci_dev *pdev,
> const struct pci_device_id *id)
> goto release;
>
> kref_init(&dev->ctrl.kref);
> - dev->device = device_create(nvme_class, &pdev->dev,
> + dev->ctrl.device = device_create(nvme_class, &pdev->dev,
> MKDEV(nvme_char_major, dev
> ->ctrl.instance),
> dev, "nvme%d", dev->ctrl.instance);
> - if (IS_ERR(dev->device)) {
> - result = PTR_ERR(dev->device);
> + if (IS_ERR(dev->ctrl.device)) {
> + result = PTR_ERR(dev->ctrl.device);
> goto release_pools;
> }
> - get_device(dev->device);
> - dev_set_drvdata(dev->device, dev);
> + get_device(dev->ctrl.device);
> + dev_set_drvdata(dev->ctrl.device, dev);
>
> - result = device_create_file(dev->device,
> &dev_attr_reset_controller);
> + result = device_create_file(dev->ctrl.device,
> &dev_attr_reset_controller);
> if (result)
> goto put_dev;
>
> @@ -2686,7 +2527,7 @@ static int nvme_probe(struct pci_dev *pdev,
> const struct pci_device_id *id)
>
> put_dev:
> device_destroy(nvme_class, MKDEV(nvme_char_major, dev
> ->ctrl.instance));
> - put_device(dev->device);
> + put_device(dev->ctrl.device);
> release_pools:
> nvme_release_prp_pools(dev);
> release:
> @@ -2728,8 +2569,8 @@ static void nvme_remove(struct pci_dev *pdev)
> flush_work(&dev->probe_work);
> flush_work(&dev->reset_work);
> flush_work(&dev->scan_work);
> - device_remove_file(dev->device, &dev_attr_reset_controller);
> - nvme_dev_remove(dev);
> + device_remove_file(dev->ctrl.device,
> &dev_attr_reset_controller);
> + nvme_remove_namespaces(&dev->ctrl);
> nvme_dev_shutdown(dev);
> nvme_dev_remove_admin(dev);
> device_destroy(nvme_class, MKDEV(nvme_char_major, dev
> ->ctrl.instance));
> @@ -2810,11 +2651,9 @@ static int __init nvme_init(void)
> if (!nvme_workq)
> return -ENOMEM;
>
> - result = register_blkdev(nvme_major, "nvme");
> + result = nvme_core_init();
> if (result < 0)
> goto kill_workq;
> - else if (result > 0)
> - nvme_major = result;
>
> result = __register_chrdev(nvme_char_major, 0, NVME_MINORS,
> "nvme",
> &nvme_dev_fo
> ps);
> @@ -2839,7 +2678,7 @@ static int __init nvme_init(void)
> unregister_chrdev:
> __unregister_chrdev(nvme_char_major, 0, NVME_MINORS,
> "nvme");
> unregister_blkdev:
> - unregister_blkdev(nvme_major, "nvme");
> + nvme_core_exit();
> kill_workq:
> destroy_workqueue(nvme_workq);
> return result;
> @@ -2848,7 +2687,7 @@ static int __init nvme_init(void)
> static void __exit nvme_exit(void)
> {
> pci_unregister_driver(&nvme_driver);
> - unregister_blkdev(nvme_major, "nvme");
> + nvme_core_exit();
> destroy_workqueue(nvme_workq);
> class_destroy(nvme_class);
> __unregister_chrdev(nvme_char_major, 0, NVME_MINORS,
> "nvme");
More information about the Linux-nvme
mailing list