linux-nvme.lists.infradead.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 0/6] enable sysfs for lightnvm
@ 2016-06-29 14:51 Matias Bjørling
  2016-06-29 14:51 ` [PATCH 1/6] nvme: refactor namespaces to support non-gendisk devices Matias Bjørling
                   ` (5 more replies)
  0 siblings, 6 replies; 10+ messages in thread
From: Matias Bjørling @ 2016-06-29 14:51 UTC (permalink / raw)


The common way to expose a storage device is to export it through the
gendisk structure, which takes care of handling the visibility lifetime
of the device to user-space and carries device driver and block layer
specific sysfs entries.

For LightNVM, no gendisk is exposed, which hides these entries.

This patchset enables LightNVM to expose a subset of the gendisk entries
by implementing a new non-gendisk device that only exposes the sysfs
entries that are relevant to the device driver and LightNVM. For example
/mq and the NVMe sysfs entries.

The new non-gendisk exposes itself in place of the original gendisk.
Thus, a gendisk device exposed through /sys/class/nvme/nvme0n1, will
still be exposed through the same directory, although only with the /mq,
lightnvm, and nvme specific entries.

The LightNVM storage device can be found through sysfs by searching
for devices that has the "lightnvm" dev type.

The patches require the just posted patches before they can be applied.
They can also be found in the for-4.8/sysfs branch at:

  https://github.com/OpenChannelSSD/linux.git

v3:
 - Fixed missing divising by nvme block nr.
v2:
 - Updated "expose gennvm target type" to expose its own kobject, which
   pblk and others can hook into.
 - Fixed missing disk_name in null_blk patch on lightnvm device

Matias Bj?rling (4):
  nvme: refactor namespaces to support non-gendisk devices
  null_blk: refactor to support non-gendisk devices
  blk-mq: register device instead of disk
  lightnvm: let drivers control the lifetime of nvm_dev

Simon A. F. Lund (2):
  lightnvm: expose device geometry through sysfs
  lightnvm: expose gennvm target type through sysfs

 block/blk-mq-sysfs.c         |  13 ++-
 block/blk-sysfs.c            |   4 +-
 drivers/block/null_blk.c     | 128 +++++++++++++++++-----------
 drivers/lightnvm/Makefile    |   2 +-
 drivers/lightnvm/core.c      |  54 +++++-------
 drivers/lightnvm/gennvm.c    | 112 +++++++++++++++++++++----
 drivers/lightnvm/lightnvm.h  |  35 ++++++++
 drivers/lightnvm/sysfs.c     | 195 +++++++++++++++++++++++++++++++++++++++++++
 drivers/md/dm.c              |   2 +-
 drivers/nvme/host/core.c     | 165 ++++++++++++++++++++----------------
 drivers/nvme/host/lightnvm.c |  34 ++++++--
 drivers/nvme/host/nvme.h     |  26 ++++--
 include/linux/blk-mq.h       |   4 +-
 include/linux/lightnvm.h     |  28 +++++--
 14 files changed, 603 insertions(+), 199 deletions(-)
 create mode 100644 drivers/lightnvm/lightnvm.h
 create mode 100644 drivers/lightnvm/sysfs.c

-- 
2.1.4

^ permalink raw reply	[flat|nested] 10+ messages in thread
* [PATCH 6/6] lightnvm: expose gennvm target type through sysfs
@ 2016-06-10 12:22 Matias Bjørling
  0 siblings, 0 replies; 10+ messages in thread
From: Matias Bjørling @ 2016-06-10 12:22 UTC (permalink / raw)


From: "Simon A. F. Lund" <slund@cnexlabs.com>

Create a sysfs directory for targets to expose their internal statistics
and knobs. The entries is exposed through the
/sys/block/<disk>/lightnvm/* directory.

It currently holds a single sysfs entry "type", which exports the target
type name.

Signed-off-by: Simon A. F. Lund <slund at cnexlabs.com>
Signed-off-by: Matias Bj?rling <m at bjorling.me>
---
 drivers/lightnvm/gennvm.c | 112 ++++++++++++++++++++++++++++++++++++++--------
 include/linux/lightnvm.h  |  10 +++++
 2 files changed, 104 insertions(+), 18 deletions(-)

diff --git a/drivers/lightnvm/gennvm.c b/drivers/lightnvm/gennvm.c
index b74174c..bfdad3c 100644
--- a/drivers/lightnvm/gennvm.c
+++ b/drivers/lightnvm/gennvm.c
@@ -20,6 +20,87 @@
 
 #include "gennvm.h"
 
+static struct attribute gen_type_attr = {
+	.name = "type",
+	.mode = S_IRUGO
+};
+
+static struct attribute *gen_target_attrs[] = {
+	&gen_type_attr,
+	NULL,
+};
+
+static ssize_t gen_target_attr_show(struct kobject *kobj,
+				struct attribute *attr,
+				char *page)
+{
+	struct nvm_target *t = container_of(kobj, struct nvm_target, kobj);
+
+	if (strcmp(attr->name, "type") == 0)
+		return scnprintf(page, PAGE_SIZE, "%s\n", t->type->name);
+
+	if (t->type->sysfs_show)
+		return t->type->sysfs_show(t, attr, page);
+
+	return scnprintf(page, PAGE_SIZE,
+			"Unhandled attr(%s) in `nvm_target_attr_show`\n",
+			attr->name);
+}
+
+static const struct sysfs_ops target_sysfs_ops = {
+	.show = gen_target_attr_show,
+};
+
+static void gen_target_release(struct kobject *kobj)
+{
+	struct nvm_target *t = container_of(kobj, struct nvm_target, kobj);
+	struct nvm_tgt_type *tt = t->type;
+	struct gendisk *tdisk = t->disk;
+	struct request_queue *q = tdisk->queue;
+
+	pr_debug("gen: `gen_target_release`\n");
+
+	del_gendisk(tdisk);
+	blk_cleanup_queue(q);
+	put_disk(tdisk);
+
+	if (tt->exit)
+		tt->exit(tdisk->private_data);
+
+	kfree(t);
+}
+
+static struct kobj_type nvm_target_type = {
+	.sysfs_ops	= &target_sysfs_ops,
+	.default_attrs	= gen_target_attrs,
+	.release	= gen_target_release
+};
+
+void gen_unregister_target(struct nvm_target *t)
+{
+	kobject_uevent(&t->kobj, KOBJ_REMOVE);
+	kobject_del(&t->kobj);
+	kobject_put(&t->kobj);
+}
+
+int gen_register_target(struct nvm_target *t)
+{
+	struct gendisk *disk = t->disk;
+	struct device *dev = disk_to_dev(disk);
+	int ret;
+
+	ret = kobject_init_and_add(&t->kobj, &nvm_target_type,
+				   kobject_get(&dev->kobj), "%s", "lightnvm");
+	if (ret < 0) {
+		pr_err("gen: `_register_target` failed.\n");
+		kobject_put(&t->kobj);
+		return ret;
+	}
+
+	kobject_uevent(&t->kobj, KOBJ_ADD);
+	return 0;
+}
+
 static struct nvm_target *gen_find_target(struct gen_dev *gn, const char *name)
 {
 	struct nvm_target *tgt;
@@ -60,7 +141,7 @@ static int gen_create_tgt(struct nvm_dev *dev, struct nvm_ioctl_create *create)
 	}
 	mutex_unlock(&gn->lock);
 
-	t = kmalloc(sizeof(struct nvm_target), GFP_KERNEL);
+	t = kzalloc(sizeof(struct nvm_target), GFP_KERNEL);
 	if (!t)
 		return -ENOMEM;
 
@@ -89,13 +170,19 @@ static int gen_create_tgt(struct nvm_dev *dev, struct nvm_ioctl_create *create)
 
 	blk_queue_max_hw_sectors(tqueue, 8 * dev->ops->max_phys_sect);
 
-	set_capacity(tdisk, tt->capacity(targetdata));
-	add_disk(tdisk);
-
 	t->type = tt;
 	t->disk = tdisk;
 	t->dev = dev;
 
+	set_capacity(tdisk, tt->capacity(targetdata));
+	add_disk(tdisk);
+
+	if (gen_register_target(t))
+		goto err_init;
+
+	if (tt->sysfs_init)
+		tt->sysfs_init(t);
+
 	mutex_lock(&gn->lock);
 	list_add_tail(&t->list, &gn->targets);
 	mutex_unlock(&gn->lock);
@@ -112,20 +199,10 @@ err_t:
 
 static void __gen_remove_target(struct nvm_target *t)
 {
-	struct nvm_tgt_type *tt = t->type;
-	struct gendisk *tdisk = t->disk;
-	struct request_queue *q = tdisk->queue;
-
-	del_gendisk(tdisk);
-	blk_cleanup_queue(q);
-
-	if (tt->exit)
-		tt->exit(tdisk->private_data);
-
-	put_disk(tdisk);
-
 	list_del(&t->list);
-	kfree(t);
+	if (t->type->sysfs_exit)
+		t->type->sysfs_exit(t);
+	gen_unregister_target(t);
 }
 
 /**
@@ -627,7 +704,6 @@ static void gen_lun_info_print(struct nvm_dev *dev)
 	struct gen_lun *lun;
 	unsigned int i;
 
-
 	gen_for_each_lun(gn, lun, i) {
 		spin_lock(&lun->vlun.lock);
 
diff --git a/include/linux/lightnvm.h b/include/linux/lightnvm.h
index d190786..3823891 100644
--- a/include/linux/lightnvm.h
+++ b/include/linux/lightnvm.h
@@ -211,6 +211,8 @@ struct nvm_target {
 	struct nvm_dev *dev;
 	struct nvm_tgt_type *type;
 	struct gendisk *disk;
+
+	struct kobject kobj;
 };
 
 struct nvm_tgt_instance {
@@ -434,6 +436,10 @@ typedef blk_qc_t (nvm_tgt_make_rq_fn)(struct request_queue *, struct bio *);
 typedef sector_t (nvm_tgt_capacity_fn)(void *);
 typedef void *(nvm_tgt_init_fn)(struct nvm_dev *, struct gendisk *, int, int);
 typedef void (nvm_tgt_exit_fn)(void *);
+typedef void (nvm_tgt_sysfs_init_fn)(struct nvm_target *);
+typedef void (nvm_tgt_sysfs_exit_fn)(struct nvm_target *);
+typedef ssize_t(nvm_tgt_sysfs_show_fn)(struct nvm_target *,
+				     struct attribute *, char *);
 
 struct nvm_tgt_type {
 	const char *name;
@@ -448,6 +454,10 @@ struct nvm_tgt_type {
 	nvm_tgt_init_fn *init;
 	nvm_tgt_exit_fn *exit;
 
+	nvm_tgt_sysfs_init_fn *sysfs_init;
+	nvm_tgt_sysfs_exit_fn *sysfs_exit;
+	nvm_tgt_sysfs_show_fn *sysfs_show;
+
 	/* For internal use */
 	struct list_head list;
 };
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 10+ messages in thread

end of thread, other threads:[~2016-07-01  7:20 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2016-06-29 14:51 [PATCH 0/6] enable sysfs for lightnvm Matias Bjørling
2016-06-29 14:51 ` [PATCH 1/6] nvme: refactor namespaces to support non-gendisk devices Matias Bjørling
2016-06-29 14:51 ` [PATCH 2/6] null_blk: refactor " Matias Bjørling
2016-06-29 14:51 ` [PATCH 3/6] blk-mq: register device instead of disk Matias Bjørling
2016-06-29 14:51 ` [PATCH 4/6] lightnvm: let drivers control the lifetime of nvm_dev Matias Bjørling
2016-06-29 14:51 ` [PATCH 5/6] lightnvm: expose device geometry through sysfs Matias Bjørling
2016-06-30 20:01   ` J Freyensee
2016-07-01  7:20     ` Matias Bjørling
2016-06-29 14:51 ` [PATCH 6/6] lightnvm: expose gennvm target type " Matias Bjørling
  -- strict thread matches above, loose matches on Subject: below --
2016-06-10 12:22 Matias Bjørling

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).