nvme: simplify transport specific device attribute handling
authorChristoph Hellwig <hch@lst.de>
Thu, 27 Oct 2022 09:34:13 +0000 (02:34 -0700)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 1 Feb 2023 07:34:43 +0000 (08:34 +0100)
[ Upstream commit 86adbf0cdb9ec6533234696c3e243184d4d0d040 ]

Allow the transport driver to override the attribute groups for the
control device, so that the PCIe driver doesn't manually have to add a
group after device creation and keep track of it.

Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Keith Busch <kbusch@kernel.org>
Reviewed-by: Sagi Grimberg <sagi@grimberg.me>
Reviewed-by: Chaitanya Kulkarni <kch@nvidia.com>
Tested-by Gerd Bayer <gbayer@linxu.ibm.com>
Stable-dep-of: 98e3528012cd ("nvme-fc: fix initialization order")
Signed-off-by: Sasha Levin <sashal@kernel.org>
drivers/nvme/host/core.c
drivers/nvme/host/nvme.h
drivers/nvme/host/pci.c

index 1ded96d..badc698 100644 (file)
@@ -3903,10 +3903,11 @@ static umode_t nvme_dev_attrs_are_visible(struct kobject *kobj,
        return a->mode;
 }
 
-static const struct attribute_group nvme_dev_attrs_group = {
+const struct attribute_group nvme_dev_attrs_group = {
        .attrs          = nvme_dev_attrs,
        .is_visible     = nvme_dev_attrs_are_visible,
 };
+EXPORT_SYMBOL_GPL(nvme_dev_attrs_group);
 
 static const struct attribute_group *nvme_dev_attr_groups[] = {
        &nvme_dev_attrs_group,
@@ -5080,7 +5081,10 @@ int nvme_init_ctrl(struct nvme_ctrl *ctrl, struct device *dev,
                        ctrl->instance);
        ctrl->device->class = nvme_class;
        ctrl->device->parent = ctrl->dev;
-       ctrl->device->groups = nvme_dev_attr_groups;
+       if (ops->dev_attr_groups)
+               ctrl->device->groups = ops->dev_attr_groups;
+       else
+               ctrl->device->groups = nvme_dev_attr_groups;
        ctrl->device->release = nvme_free_ctrl;
        dev_set_drvdata(ctrl->device, ctrl);
        ret = dev_set_name(ctrl->device, "nvme%d", ctrl->instance);
index cbda8a1..aef3693 100644 (file)
@@ -508,6 +508,7 @@ struct nvme_ctrl_ops {
        unsigned int flags;
 #define NVME_F_FABRICS                 (1 << 0)
 #define NVME_F_METADATA_SUPPORTED      (1 << 1)
+       const struct attribute_group **dev_attr_groups;
        int (*reg_read32)(struct nvme_ctrl *ctrl, u32 off, u32 *val);
        int (*reg_write32)(struct nvme_ctrl *ctrl, u32 off, u32 val);
        int (*reg_read64)(struct nvme_ctrl *ctrl, u32 off, u64 *val);
@@ -857,6 +858,7 @@ int nvme_dev_uring_cmd(struct io_uring_cmd *ioucmd, unsigned int issue_flags);
 extern const struct attribute_group *nvme_ns_id_attr_groups[];
 extern const struct pr_ops nvme_pr_ops;
 extern const struct block_device_operations nvme_ns_head_ops;
+extern const struct attribute_group nvme_dev_attrs_group;
 
 struct nvme_ns *nvme_find_path(struct nvme_ns_head *head);
 #ifdef CONFIG_NVME_MULTIPATH
index e2de5d0..d839689 100644 (file)
@@ -158,8 +158,6 @@ struct nvme_dev {
        unsigned int nr_allocated_queues;
        unsigned int nr_write_queues;
        unsigned int nr_poll_queues;
-
-       bool attrs_added;
 };
 
 static int io_queue_depth_set(const char *val, const struct kernel_param *kp)
@@ -2241,11 +2239,17 @@ static struct attribute *nvme_pci_attrs[] = {
        NULL,
 };
 
-static const struct attribute_group nvme_pci_attr_group = {
+static const struct attribute_group nvme_pci_dev_attrs_group = {
        .attrs          = nvme_pci_attrs,
        .is_visible     = nvme_pci_attrs_are_visible,
 };
 
+static const struct attribute_group *nvme_pci_dev_attr_groups[] = {
+       &nvme_dev_attrs_group,
+       &nvme_pci_dev_attrs_group,
+       NULL,
+};
+
 /*
  * nirqs is the number of interrupts available for write and read
  * queues. The core already reserved an interrupt for the admin queue.
@@ -2935,10 +2939,6 @@ static void nvme_reset_work(struct work_struct *work)
                goto out;
        }
 
-       if (!dev->attrs_added && !sysfs_create_group(&dev->ctrl.device->kobj,
-                       &nvme_pci_attr_group))
-               dev->attrs_added = true;
-
        nvme_start_ctrl(&dev->ctrl);
        return;
 
@@ -3011,6 +3011,7 @@ static const struct nvme_ctrl_ops nvme_pci_ctrl_ops = {
        .name                   = "pcie",
        .module                 = THIS_MODULE,
        .flags                  = NVME_F_METADATA_SUPPORTED,
+       .dev_attr_groups        = nvme_pci_dev_attr_groups,
        .reg_read32             = nvme_pci_reg_read32,
        .reg_write32            = nvme_pci_reg_write32,
        .reg_read64             = nvme_pci_reg_read64,
@@ -3209,13 +3210,6 @@ static void nvme_shutdown(struct pci_dev *pdev)
        nvme_disable_prepare_reset(dev, true);
 }
 
-static void nvme_remove_attrs(struct nvme_dev *dev)
-{
-       if (dev->attrs_added)
-               sysfs_remove_group(&dev->ctrl.device->kobj,
-                                  &nvme_pci_attr_group);
-}
-
 /*
  * The driver's remove may be called on a device in a partially initialized
  * state. This function must not have any dependencies on the device state in
@@ -3237,7 +3231,6 @@ static void nvme_remove(struct pci_dev *pdev)
        nvme_stop_ctrl(&dev->ctrl);
        nvme_remove_namespaces(&dev->ctrl);
        nvme_dev_disable(dev, true);
-       nvme_remove_attrs(dev);
        nvme_free_host_mem(dev);
        nvme_dev_remove_admin(dev);
        nvme_free_queues(dev, 0);