aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDan Williams <dan.j.williams@intel.com>2017-07-12 20:58:21 -0400
committerDan Williams <dan.j.williams@intel.com>2019-01-07 00:24:46 -0500
commit51cf784c42d07fbd62cb604836a9270cf3361509 (patch)
tree808f5603d9f6f71f7727b33224d1a79cd958e99c
parent753a0850e707e9a8c5861356222f9b9e4eba7945 (diff)
device-dax: Start defining a dax bus model
Towards eliminating the dax_class, move the dax-device-attribute enabling to a new bus.c file in the core. The amount of code thrash of sub-sequent patches is reduced as no logic changes are made, just pure code movement. A temporary export of unregister_dex_dax() and dax_attribute_groups is needed to preserve compilation, but those symbols become static again in a follow-on patch. Signed-off-by: Dan Williams <dan.j.williams@intel.com>
-rw-r--r--drivers/dax/Makefile1
-rw-r--r--drivers/dax/bus.c174
-rw-r--r--drivers/dax/bus.h15
-rw-r--r--drivers/dax/dax-private.h14
-rw-r--r--drivers/dax/dax.h18
-rw-r--r--drivers/dax/device-dax.h23
-rw-r--r--drivers/dax/device.c185
-rw-r--r--drivers/dax/pmem.c2
-rw-r--r--drivers/dax/super.c1
-rw-r--r--tools/testing/nvdimm/Kbuild1
10 files changed, 210 insertions, 224 deletions
diff --git a/drivers/dax/Makefile b/drivers/dax/Makefile
index 574286fac87c..658e6b9b1d74 100644
--- a/drivers/dax/Makefile
+++ b/drivers/dax/Makefile
@@ -4,5 +4,6 @@ obj-$(CONFIG_DEV_DAX) += device_dax.o
4obj-$(CONFIG_DEV_DAX_PMEM) += dax_pmem.o 4obj-$(CONFIG_DEV_DAX_PMEM) += dax_pmem.o
5 5
6dax-y := super.o 6dax-y := super.o
7dax-y += bus.o
7dax_pmem-y := pmem.o 8dax_pmem-y := pmem.o
8device_dax-y := device.o 9device_dax-y := device.o
diff --git a/drivers/dax/bus.c b/drivers/dax/bus.c
new file mode 100644
index 000000000000..8a398e8e1956
--- /dev/null
+++ b/drivers/dax/bus.c
@@ -0,0 +1,174 @@
1// SPDX-License-Identifier: GPL-2.0
2/* Copyright(c) 2017-2018 Intel Corporation. All rights reserved. */
3#include <linux/device.h>
4#include <linux/slab.h>
5#include <linux/dax.h>
6#include "dax-private.h"
7#include "bus.h"
8
9/*
10 * Rely on the fact that drvdata is set before the attributes are
11 * registered, and that the attributes are unregistered before drvdata
12 * is cleared to assume that drvdata is always valid.
13 */
14static ssize_t id_show(struct device *dev,
15 struct device_attribute *attr, char *buf)
16{
17 struct dax_region *dax_region = dev_get_drvdata(dev);
18
19 return sprintf(buf, "%d\n", dax_region->id);
20}
21static DEVICE_ATTR_RO(id);
22
23static ssize_t region_size_show(struct device *dev,
24 struct device_attribute *attr, char *buf)
25{
26 struct dax_region *dax_region = dev_get_drvdata(dev);
27
28 return sprintf(buf, "%llu\n", (unsigned long long)
29 resource_size(&dax_region->res));
30}
31static struct device_attribute dev_attr_region_size = __ATTR(size, 0444,
32 region_size_show, NULL);
33
34static ssize_t align_show(struct device *dev,
35 struct device_attribute *attr, char *buf)
36{
37 struct dax_region *dax_region = dev_get_drvdata(dev);
38
39 return sprintf(buf, "%u\n", dax_region->align);
40}
41static DEVICE_ATTR_RO(align);
42
43static struct attribute *dax_region_attributes[] = {
44 &dev_attr_region_size.attr,
45 &dev_attr_align.attr,
46 &dev_attr_id.attr,
47 NULL,
48};
49
50static const struct attribute_group dax_region_attribute_group = {
51 .name = "dax_region",
52 .attrs = dax_region_attributes,
53};
54
55static const struct attribute_group *dax_region_attribute_groups[] = {
56 &dax_region_attribute_group,
57 NULL,
58};
59
60static void dax_region_free(struct kref *kref)
61{
62 struct dax_region *dax_region;
63
64 dax_region = container_of(kref, struct dax_region, kref);
65 kfree(dax_region);
66}
67
68void dax_region_put(struct dax_region *dax_region)
69{
70 kref_put(&dax_region->kref, dax_region_free);
71}
72EXPORT_SYMBOL_GPL(dax_region_put);
73
74static void dax_region_unregister(void *region)
75{
76 struct dax_region *dax_region = region;
77
78 sysfs_remove_groups(&dax_region->dev->kobj,
79 dax_region_attribute_groups);
80 dax_region_put(dax_region);
81}
82
83struct dax_region *alloc_dax_region(struct device *parent, int region_id,
84 struct resource *res, unsigned int align,
85 unsigned long pfn_flags)
86{
87 struct dax_region *dax_region;
88
89 /*
90 * The DAX core assumes that it can store its private data in
91 * parent->driver_data. This WARN is a reminder / safeguard for
92 * developers of device-dax drivers.
93 */
94 if (dev_get_drvdata(parent)) {
95 dev_WARN(parent, "dax core failed to setup private data\n");
96 return NULL;
97 }
98
99 if (!IS_ALIGNED(res->start, align)
100 || !IS_ALIGNED(resource_size(res), align))
101 return NULL;
102
103 dax_region = kzalloc(sizeof(*dax_region), GFP_KERNEL);
104 if (!dax_region)
105 return NULL;
106
107 dev_set_drvdata(parent, dax_region);
108 memcpy(&dax_region->res, res, sizeof(*res));
109 dax_region->pfn_flags = pfn_flags;
110 kref_init(&dax_region->kref);
111 dax_region->id = region_id;
112 dax_region->align = align;
113 dax_region->dev = parent;
114 if (sysfs_create_groups(&parent->kobj, dax_region_attribute_groups)) {
115 kfree(dax_region);
116 return NULL;
117 }
118
119 kref_get(&dax_region->kref);
120 if (devm_add_action_or_reset(parent, dax_region_unregister, dax_region))
121 return NULL;
122 return dax_region;
123}
124EXPORT_SYMBOL_GPL(alloc_dax_region);
125
126static ssize_t size_show(struct device *dev,
127 struct device_attribute *attr, char *buf)
128{
129 struct dev_dax *dev_dax = to_dev_dax(dev);
130 unsigned long long size = resource_size(&dev_dax->region->res);
131
132 return sprintf(buf, "%llu\n", size);
133}
134static DEVICE_ATTR_RO(size);
135
136static struct attribute *dev_dax_attributes[] = {
137 &dev_attr_size.attr,
138 NULL,
139};
140
141static const struct attribute_group dev_dax_attribute_group = {
142 .attrs = dev_dax_attributes,
143};
144
145const struct attribute_group *dax_attribute_groups[] = {
146 &dev_dax_attribute_group,
147 NULL,
148};
149EXPORT_SYMBOL_GPL(dax_attribute_groups);
150
151void kill_dev_dax(struct dev_dax *dev_dax)
152{
153 struct dax_device *dax_dev = dev_dax->dax_dev;
154 struct inode *inode = dax_inode(dax_dev);
155
156 kill_dax(dax_dev);
157 unmap_mapping_range(inode->i_mapping, 0, 0, 1);
158}
159EXPORT_SYMBOL_GPL(kill_dev_dax);
160
161void unregister_dev_dax(void *dev)
162{
163 struct dev_dax *dev_dax = to_dev_dax(dev);
164 struct dax_device *dax_dev = dev_dax->dax_dev;
165 struct inode *inode = dax_inode(dax_dev);
166 struct cdev *cdev = inode->i_cdev;
167
168 dev_dbg(dev, "trace\n");
169
170 kill_dev_dax(dev_dax);
171 cdev_device_del(cdev, dev);
172 put_device(dev);
173}
174EXPORT_SYMBOL_GPL(unregister_dev_dax);
diff --git a/drivers/dax/bus.h b/drivers/dax/bus.h
new file mode 100644
index 000000000000..840865aa69e8
--- /dev/null
+++ b/drivers/dax/bus.h
@@ -0,0 +1,15 @@
1// SPDX-License-Identifier: GPL-2.0
2/* Copyright(c) 2016 - 2018 Intel Corporation. All rights reserved. */
3#ifndef __DAX_BUS_H__
4#define __DAX_BUS_H__
5struct device;
6struct dev_dax;
7struct resource;
8struct dax_device;
9struct dax_region;
10void dax_region_put(struct dax_region *dax_region);
11struct dax_region *alloc_dax_region(struct device *parent, int region_id,
12 struct resource *res, unsigned int align, unsigned long flags);
13struct dev_dax *devm_create_dev_dax(struct dax_region *dax_region, int id);
14void kill_dev_dax(struct dev_dax *dev_dax);
15#endif /* __DAX_BUS_H__ */
diff --git a/drivers/dax/dax-private.h b/drivers/dax/dax-private.h
index dbd077653b5c..620c3f4eefe7 100644
--- a/drivers/dax/dax-private.h
+++ b/drivers/dax/dax-private.h
@@ -16,6 +16,15 @@
16#include <linux/device.h> 16#include <linux/device.h>
17#include <linux/cdev.h> 17#include <linux/cdev.h>
18 18
19/* private routines between core files */
20struct dax_device;
21struct dax_device *inode_dax(struct inode *inode);
22struct inode *dax_inode(struct dax_device *dax_dev);
23
24/* temporary until devm_create_dax_dev moves to bus.c */
25extern const struct attribute_group *dax_attribute_groups[];
26void unregister_dev_dax(void *dev);
27
19/** 28/**
20 * struct dax_region - mapping infrastructure for dax devices 29 * struct dax_region - mapping infrastructure for dax devices
21 * @id: kernel-wide unique region for a memory range 30 * @id: kernel-wide unique region for a memory range
@@ -45,4 +54,9 @@ struct dev_dax {
45 struct dax_device *dax_dev; 54 struct dax_device *dax_dev;
46 struct device dev; 55 struct device dev;
47}; 56};
57
58static inline struct dev_dax *to_dev_dax(struct device *dev)
59{
60 return container_of(dev, struct dev_dax, dev);
61}
48#endif 62#endif
diff --git a/drivers/dax/dax.h b/drivers/dax/dax.h
deleted file mode 100644
index f9e5feea742c..000000000000
--- a/drivers/dax/dax.h
+++ /dev/null
@@ -1,18 +0,0 @@
1/*
2 * Copyright(c) 2016 - 2017 Intel Corporation. All rights reserved.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of version 2 of the GNU General Public License as
6 * published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful, but
9 * WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 * General Public License for more details.
12 */
13#ifndef __DAX_H__
14#define __DAX_H__
15struct dax_device;
16struct dax_device *inode_dax(struct inode *inode);
17struct inode *dax_inode(struct dax_device *dax_dev);
18#endif /* __DAX_H__ */
diff --git a/drivers/dax/device-dax.h b/drivers/dax/device-dax.h
deleted file mode 100644
index e9be99584b92..000000000000
--- a/drivers/dax/device-dax.h
+++ /dev/null
@@ -1,23 +0,0 @@
1/*
2 * Copyright(c) 2016 Intel Corporation. All rights reserved.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of version 2 of the GNU General Public License as
6 * published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful, but
9 * WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 * General Public License for more details.
12 */
13#ifndef __DEVICE_DAX_H__
14#define __DEVICE_DAX_H__
15struct device;
16struct dev_dax;
17struct resource;
18struct dax_region;
19void dax_region_put(struct dax_region *dax_region);
20struct dax_region *alloc_dax_region(struct device *parent, int region_id,
21 struct resource *res, unsigned int align, unsigned long flags);
22struct dev_dax *devm_create_dev_dax(struct dax_region *dax_region, int id);
23#endif /* __DEVICE_DAX_H__ */
diff --git a/drivers/dax/device.c b/drivers/dax/device.c
index db12e24b8005..1fc375783e0b 100644
--- a/drivers/dax/device.c
+++ b/drivers/dax/device.c
@@ -1,15 +1,5 @@
1/* 1// SPDX-License-Identifier: GPL-2.0
2 * Copyright(c) 2016 - 2017 Intel Corporation. All rights reserved. 2/* Copyright(c) 2016-2018 Intel Corporation. All rights reserved. */
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of version 2 of the GNU General Public License as
6 * published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful, but
9 * WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 * General Public License for more details.
12 */
13#include <linux/pagemap.h> 3#include <linux/pagemap.h>
14#include <linux/module.h> 4#include <linux/module.h>
15#include <linux/device.h> 5#include <linux/device.h>
@@ -21,156 +11,10 @@
21#include <linux/mm.h> 11#include <linux/mm.h>
22#include <linux/mman.h> 12#include <linux/mman.h>
23#include "dax-private.h" 13#include "dax-private.h"
24#include "dax.h" 14#include "bus.h"
25 15
26static struct class *dax_class; 16static struct class *dax_class;
27 17
28/*
29 * Rely on the fact that drvdata is set before the attributes are
30 * registered, and that the attributes are unregistered before drvdata
31 * is cleared to assume that drvdata is always valid.
32 */
33static ssize_t id_show(struct device *dev,
34 struct device_attribute *attr, char *buf)
35{
36 struct dax_region *dax_region = dev_get_drvdata(dev);
37
38 return sprintf(buf, "%d\n", dax_region->id);
39}
40static DEVICE_ATTR_RO(id);
41
42static ssize_t region_size_show(struct device *dev,
43 struct device_attribute *attr, char *buf)
44{
45 struct dax_region *dax_region = dev_get_drvdata(dev);
46
47 return sprintf(buf, "%llu\n", (unsigned long long)
48 resource_size(&dax_region->res));
49}
50static struct device_attribute dev_attr_region_size = __ATTR(size, 0444,
51 region_size_show, NULL);
52
53static ssize_t align_show(struct device *dev,
54 struct device_attribute *attr, char *buf)
55{
56 struct dax_region *dax_region = dev_get_drvdata(dev);
57
58 return sprintf(buf, "%u\n", dax_region->align);
59}
60static DEVICE_ATTR_RO(align);
61
62static struct attribute *dax_region_attributes[] = {
63 &dev_attr_region_size.attr,
64 &dev_attr_align.attr,
65 &dev_attr_id.attr,
66 NULL,
67};
68
69static const struct attribute_group dax_region_attribute_group = {
70 .name = "dax_region",
71 .attrs = dax_region_attributes,
72};
73
74static const struct attribute_group *dax_region_attribute_groups[] = {
75 &dax_region_attribute_group,
76 NULL,
77};
78
79static void dax_region_free(struct kref *kref)
80{
81 struct dax_region *dax_region;
82
83 dax_region = container_of(kref, struct dax_region, kref);
84 kfree(dax_region);
85}
86
87void dax_region_put(struct dax_region *dax_region)
88{
89 kref_put(&dax_region->kref, dax_region_free);
90}
91EXPORT_SYMBOL_GPL(dax_region_put);
92
93static void dax_region_unregister(void *region)
94{
95 struct dax_region *dax_region = region;
96
97 sysfs_remove_groups(&dax_region->dev->kobj,
98 dax_region_attribute_groups);
99 dax_region_put(dax_region);
100}
101
102struct dax_region *alloc_dax_region(struct device *parent, int region_id,
103 struct resource *res, unsigned int align,
104 unsigned long pfn_flags)
105{
106 struct dax_region *dax_region;
107
108 /*
109 * The DAX core assumes that it can store its private data in
110 * parent->driver_data. This WARN is a reminder / safeguard for
111 * developers of device-dax drivers.
112 */
113 if (dev_get_drvdata(parent)) {
114 dev_WARN(parent, "dax core failed to setup private data\n");
115 return NULL;
116 }
117
118 if (!IS_ALIGNED(res->start, align)
119 || !IS_ALIGNED(resource_size(res), align))
120 return NULL;
121
122 dax_region = kzalloc(sizeof(*dax_region), GFP_KERNEL);
123 if (!dax_region)
124 return NULL;
125
126 dev_set_drvdata(parent, dax_region);
127 memcpy(&dax_region->res, res, sizeof(*res));
128 dax_region->pfn_flags = pfn_flags;
129 kref_init(&dax_region->kref);
130 dax_region->id = region_id;
131 dax_region->align = align;
132 dax_region->dev = parent;
133 if (sysfs_create_groups(&parent->kobj, dax_region_attribute_groups)) {
134 kfree(dax_region);
135 return NULL;
136 }
137
138 kref_get(&dax_region->kref);
139 if (devm_add_action_or_reset(parent, dax_region_unregister, dax_region))
140 return NULL;
141 return dax_region;
142}
143EXPORT_SYMBOL_GPL(alloc_dax_region);
144
145static struct dev_dax *to_dev_dax(struct device *dev)
146{
147 return container_of(dev, struct dev_dax, dev);
148}
149
150static ssize_t size_show(struct device *dev,
151 struct device_attribute *attr, char *buf)
152{
153 struct dev_dax *dev_dax = to_dev_dax(dev);
154 unsigned long long size = resource_size(&dev_dax->region->res);
155
156 return sprintf(buf, "%llu\n", size);
157}
158static DEVICE_ATTR_RO(size);
159
160static struct attribute *dev_dax_attributes[] = {
161 &dev_attr_size.attr,
162 NULL,
163};
164
165static const struct attribute_group dev_dax_attribute_group = {
166 .attrs = dev_dax_attributes,
167};
168
169static const struct attribute_group *dax_attribute_groups[] = {
170 &dev_dax_attribute_group,
171 NULL,
172};
173
174static int check_vma(struct dev_dax *dev_dax, struct vm_area_struct *vma, 18static int check_vma(struct dev_dax *dev_dax, struct vm_area_struct *vma,
175 const char *func) 19 const char *func)
176{ 20{
@@ -571,29 +415,6 @@ static void dev_dax_release(struct device *dev)
571 kfree(dev_dax); 415 kfree(dev_dax);
572} 416}
573 417
574static void kill_dev_dax(struct dev_dax *dev_dax)
575{
576 struct dax_device *dax_dev = dev_dax->dax_dev;
577 struct inode *inode = dax_inode(dax_dev);
578
579 kill_dax(dax_dev);
580 unmap_mapping_range(inode->i_mapping, 0, 0, 1);
581}
582
583static void unregister_dev_dax(void *dev)
584{
585 struct dev_dax *dev_dax = to_dev_dax(dev);
586 struct dax_device *dax_dev = dev_dax->dax_dev;
587 struct inode *inode = dax_inode(dax_dev);
588 struct cdev *cdev = inode->i_cdev;
589
590 dev_dbg(dev, "trace\n");
591
592 kill_dev_dax(dev_dax);
593 cdev_device_del(cdev, dev);
594 put_device(dev);
595}
596
597struct dev_dax *devm_create_dev_dax(struct dax_region *dax_region, int id) 418struct dev_dax *devm_create_dev_dax(struct dax_region *dax_region, int id)
598{ 419{
599 struct device *parent = dax_region->dev; 420 struct device *parent = dax_region->dev;
diff --git a/drivers/dax/pmem.c b/drivers/dax/pmem.c
index 6c61a019f997..e1b50d8fd1f8 100644
--- a/drivers/dax/pmem.c
+++ b/drivers/dax/pmem.c
@@ -16,7 +16,7 @@
16#include <linux/pfn_t.h> 16#include <linux/pfn_t.h>
17#include "../nvdimm/pfn.h" 17#include "../nvdimm/pfn.h"
18#include "../nvdimm/nd.h" 18#include "../nvdimm/nd.h"
19#include "device-dax.h" 19#include "bus.h"
20 20
21struct dax_pmem { 21struct dax_pmem {
22 struct device *dev; 22 struct device *dev;
diff --git a/drivers/dax/super.c b/drivers/dax/super.c
index 6e928f37d084..0ecc1a2cf1cc 100644
--- a/drivers/dax/super.c
+++ b/drivers/dax/super.c
@@ -22,6 +22,7 @@
22#include <linux/uio.h> 22#include <linux/uio.h>
23#include <linux/dax.h> 23#include <linux/dax.h>
24#include <linux/fs.h> 24#include <linux/fs.h>
25#include "dax-private.h"
25 26
26static dev_t dax_devt; 27static dev_t dax_devt;
27DEFINE_STATIC_SRCU(dax_srcu); 28DEFINE_STATIC_SRCU(dax_srcu);
diff --git a/tools/testing/nvdimm/Kbuild b/tools/testing/nvdimm/Kbuild
index 10ddf223055b..c9b500a652d5 100644
--- a/tools/testing/nvdimm/Kbuild
+++ b/tools/testing/nvdimm/Kbuild
@@ -57,6 +57,7 @@ nd_e820-y := $(NVDIMM_SRC)/e820.o
57nd_e820-y += config_check.o 57nd_e820-y += config_check.o
58 58
59dax-y := $(DAX_SRC)/super.o 59dax-y := $(DAX_SRC)/super.o
60dax-y += $(DAX_SRC)/bus.o
60dax-y += config_check.o 61dax-y += config_check.o
61 62
62device_dax-y := $(DAX_SRC)/device.o 63device_dax-y := $(DAX_SRC)/device.o