linux-block.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [for-4.16 PATCH 0/2] block: cope with gendisk's 'queue' being added later
@ 2018-01-09 22:10 Mike Snitzer
  2018-01-09 22:10 ` [for-4.16 PATCH 1/2] " Mike Snitzer
  2018-01-09 22:10 ` [for-4.16 PATCH 2/2] dm: fix awkward request_queue initialization Mike Snitzer
  0 siblings, 2 replies; 6+ messages in thread
From: Mike Snitzer @ 2018-01-09 22:10 UTC (permalink / raw)
  To: axboe; +Cc: dm-devel, linux-block

Hi Jens,

Please consider PATCH 1/2 for 4.16 inclusion.  I've included PATCH 2/2
to show the DM changes needed in order to make use of the block
changes.

I think, all things considered, this moves DM's interface with block
core in a better direction for the long-term but I obviously welcome
any critical feedback.

Thanks!
Mike

Mike Snitzer (2):
  block: cope with gendisk's 'queue' being added later
  dm: fix awkward request_queue initialization

 block/blk-sysfs.c     | 12 ++++++++++
 block/genhd.c         | 28 +++++++---------------
 drivers/md/dm-core.h  |  2 --
 drivers/md/dm-ioctl.c |  7 ++----
 drivers/md/dm-rq.c    | 13 +---------
 drivers/md/dm-table.c |  2 +-
 drivers/md/dm.c       | 66 +++++++++++++++++++++++++++++++--------------------
 7 files changed, 64 insertions(+), 66 deletions(-)

-- 
2.15.0

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

* [for-4.16 PATCH 1/2] block: cope with gendisk's 'queue' being added later
  2018-01-09 22:10 [for-4.16 PATCH 0/2] block: cope with gendisk's 'queue' being added later Mike Snitzer
@ 2018-01-09 22:10 ` Mike Snitzer
  2018-01-09 23:04   ` Bart Van Assche
  2018-01-09 22:10 ` [for-4.16 PATCH 2/2] dm: fix awkward request_queue initialization Mike Snitzer
  1 sibling, 1 reply; 6+ messages in thread
From: Mike Snitzer @ 2018-01-09 22:10 UTC (permalink / raw)
  To: axboe; +Cc: dm-devel, linux-block

Since I can remember DM has forced the block layer to allow the
allocation and initialization of the request_queue to be distinct
operations.  Reason for this was block/genhd.c:add_disk() has required
that the request_queue (and associated bdi) be tied to the gendisk
before add_disk() is called -- because add_disk() also deals with
exposing the request_queue via blk_register_queue().

DM's dynamic creation of arbitrary device types (and associated
request_queue types) requires the DM device's gendisk be available so
that DM table loads can establish a master/slave relationship with
subordinate devices that are referenced by loaded DM tables -- using
bd_link_disk_holder().  But until these DM tables, and their associated
subordinate devices, are known DM cannot know what type of request_queue
it needs -- nor what its queue_limits should be.

This chicken and egg scenario has created all manner of problems for DM
and, at times, the block layer.

Summary of changes:

- Adjust device_add_disk() so that that it can cope with the gendisk _not_
  having its 'queue' established yet.

- Remove del_gendisk()'s WARN_ON() if disk->queue is NULL

- Move "bdi" symlink creation from register_disk() to the end of
  blk_register_queue() -- it is more logical in that the bdi is part of
  the request_queue.

- Move extra request_queue reference count (on behalf of gendisk) from
  device_add_disk() to end of blk_register_queue().

- Make device_add_disk()'s calls to bdi_register_owner() and
  blk_register_queue() conditional on disk->queue not being NULL.

- Export blk_register_queue()

These changes allow DM to use device_add_disk() to anchor its gendisk as
the "master" for master/slave relationships DM must establish with
subordinate devices referenced in DM tables that get loaded.  Once all
"slave" devices for a DM device are known a request_queue can be
properly initialized and then advertised via sysfs -- important
improvement being that no request_queue resource initialization is
missed.

These changes have been tested to work without any IO races because the
request_queue and associated bdi don't even exist at the time that the
gendisk's "struct device"s are established by device_add_disk().  I've
been mindful of historic bugs, and haven't experienced them with DM,
e.g.: https://bugzilla.kernel.org/show_bug.cgi?id=16312 (fixed by commit
01ea5063 "block: Fix race during disk initialization")

Signed-off-by: Mike Snitzer <snitzer@redhat.com>
---
 block/blk-sysfs.c | 12 ++++++++++++
 block/genhd.c     | 28 ++++++++--------------------
 2 files changed, 20 insertions(+), 20 deletions(-)

diff --git a/block/blk-sysfs.c b/block/blk-sysfs.c
index 870484eaed1f..0b0dda8e2420 100644
--- a/block/blk-sysfs.c
+++ b/block/blk-sysfs.c
@@ -919,8 +919,20 @@ int blk_register_queue(struct gendisk *disk)
 	ret = 0;
 unlock:
 	mutex_unlock(&q->sysfs_lock);
+
+	/*
+	 * Take an extra ref on queue which will be put on disk_release()
+	 * so that it sticks around as long as @disk is there.
+	 */
+	WARN_ON_ONCE(!blk_get_queue(q));
+
+	WARN_ON(sysfs_create_link(&dev->kobj,
+				  &q->backing_dev_info->dev->kobj,
+				  "bdi"));
+
 	return ret;
 }
+EXPORT_SYMBOL_GPL(blk_register_queue);
 
 void blk_unregister_queue(struct gendisk *disk)
 {
diff --git a/block/genhd.c b/block/genhd.c
index 96a66f671720..13aa80319b3b 100644
--- a/block/genhd.c
+++ b/block/genhd.c
@@ -621,11 +621,6 @@ static void register_disk(struct device *parent, struct gendisk *disk)
 	while ((part = disk_part_iter_next(&piter)))
 		kobject_uevent(&part_to_dev(part)->kobj, KOBJ_ADD);
 	disk_part_iter_exit(&piter);
-
-	err = sysfs_create_link(&ddev->kobj,
-				&disk->queue->backing_dev_info->dev->kobj,
-				"bdi");
-	WARN_ON(err);
 }
 
 /**
@@ -671,24 +666,19 @@ void device_add_disk(struct device *parent, struct gendisk *disk)
 		disk->flags |= GENHD_FL_SUPPRESS_PARTITION_INFO;
 		disk->flags |= GENHD_FL_NO_PART_SCAN;
 	} else {
-		int ret;
-
-		/* Register BDI before referencing it from bdev */
 		disk_to_dev(disk)->devt = devt;
-		ret = bdi_register_owner(disk->queue->backing_dev_info,
-						disk_to_dev(disk));
-		WARN_ON(ret);
+		/* Register BDI before referencing it from bdev */
+		if (disk->queue) {
+			retval = bdi_register_owner(disk->queue->backing_dev_info,
+						    disk_to_dev(disk));
+			WARN_ON(retval);
+		}
 		blk_register_region(disk_devt(disk), disk->minors, NULL,
 				    exact_match, exact_lock, disk);
 	}
 	register_disk(parent, disk);
-	blk_register_queue(disk);
-
-	/*
-	 * Take an extra ref on queue which will be put on disk_release()
-	 * so that it sticks around as long as @disk is there.
-	 */
-	WARN_ON_ONCE(!blk_get_queue(disk->queue));
+	if (disk->queue)
+		blk_register_queue(disk);
 
 	disk_add_events(disk);
 	blk_integrity_add(disk);
@@ -727,8 +717,6 @@ void del_gendisk(struct gendisk *disk)
 		 */
 		bdi_unregister(disk->queue->backing_dev_info);
 		blk_unregister_queue(disk);
-	} else {
-		WARN_ON(1);
 	}
 
 	if (!(disk->flags & GENHD_FL_HIDDEN))
-- 
2.15.0

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

* [for-4.16 PATCH 2/2] dm: fix awkward request_queue initialization
  2018-01-09 22:10 [for-4.16 PATCH 0/2] block: cope with gendisk's 'queue' being added later Mike Snitzer
  2018-01-09 22:10 ` [for-4.16 PATCH 1/2] " Mike Snitzer
@ 2018-01-09 22:10 ` Mike Snitzer
  1 sibling, 0 replies; 6+ messages in thread
From: Mike Snitzer @ 2018-01-09 22:10 UTC (permalink / raw)
  To: axboe; +Cc: dm-devel, linux-block

Fix DM so that it no longer creates a place-holder request_queue that
doesn't reflect the actual way the request_queue will ulimately be used,
only to have to backfill proper queue and queue_limits initialization.
Instead, DM creates a gendisk that initially doesn't have a
request_queue at all.  This serves to allow DM table loads to own
subordinate devices without first needing to know the aggregated
capabilities that will be needed of the DM device's request_queue.  Once
all DM tables are loaded the request_queue is allocated and DM then
backfills its gendisk's ->queue member and associated sysfs and bdi
initialization via blk_register_queue().

DM is now no longer prone to having its request_queue be improperly
initialized.

Summary of changes:

- alloc_dev() doesn't pre-allocate a place-holder request_queue, and now
  sets md->disk->queue to NULL before calling add_disk().

- dm_setup_md_queue() is updated to allocate and initialize the
  DM's request_queue (_after_ all table loads have occurred and
  request_queue type and features and limits are known).

- dm_setup_md_queue() must call bdi_register_owner() and
  blk_register_queue() because they were not possible at
  add_disk()-time (due to disk->queue being NULL).

Any future "why is disk->queue NULL!?" awkwardness is DM's to own and
shouldn't put more burden on block core (famous last words).  So
potential issues related to disk->queue NULL pointer dereferences should
be for DM maintainer(s) to triage and address.

A very welcome side-effect of these changes is DM no longer needs to:
1) backfill the "mq" sysfs entry (because historically DM didn't
initialize the request_queue to use blk-mq until _after_
register_queue() was called via add_disk()).
2) call elv_register_queue() to get .request_fn request-based DM
device's "queue" exposed in syfs.

These changes also stave off the need to introduce new DM-specific
workarounds in block core, e.g. this proposal:
https://patchwork.kernel.org/patch/10067961/

In the end DM devices should be less unicorn in nature (relative to
initialization and availability of block core infrastructure).

Signed-off-by: Mike Snitzer <snitzer@redhat.com>
---
 drivers/md/dm-core.h  |  2 --
 drivers/md/dm-ioctl.c |  7 ++----
 drivers/md/dm-rq.c    | 13 +---------
 drivers/md/dm-table.c |  2 +-
 drivers/md/dm.c       | 66 +++++++++++++++++++++++++++++++--------------------
 5 files changed, 44 insertions(+), 46 deletions(-)

diff --git a/drivers/md/dm-core.h b/drivers/md/dm-core.h
index 124ffa2d6b9a..3222e21cbbf8 100644
--- a/drivers/md/dm-core.h
+++ b/drivers/md/dm-core.h
@@ -129,8 +129,6 @@ struct mapped_device {
 	struct srcu_struct io_barrier;
 };
 
-void dm_init_md_queue(struct mapped_device *md);
-void dm_init_normal_md_queue(struct mapped_device *md);
 int md_in_flight(struct mapped_device *md);
 void disable_write_same(struct mapped_device *md);
 void disable_write_zeroes(struct mapped_device *md);
diff --git a/drivers/md/dm-ioctl.c b/drivers/md/dm-ioctl.c
index e52676fa9832..cf8908a6fcc9 100644
--- a/drivers/md/dm-ioctl.c
+++ b/drivers/md/dm-ioctl.c
@@ -1334,13 +1334,10 @@ static int table_load(struct file *filp, struct dm_ioctl *param, size_t param_si
 	}
 
 	if (dm_get_md_type(md) == DM_TYPE_NONE) {
-		/* Initial table load: acquire type of table. */
-		dm_set_md_type(md, dm_table_get_type(t));
-
-		/* setup md->queue to reflect md's type (may block) */
+		/* setup md->type and md->queue to reflect table's type (may block) */
 		r = dm_setup_md_queue(md, t);
 		if (r) {
-			DMWARN("unable to set up device queue for new table.");
+			DMWARN("unable to setup queue for device.");
 			goto err_unlock_md_type;
 		}
 	} else if (!is_valid_type(dm_get_md_type(md), dm_table_get_type(t))) {
diff --git a/drivers/md/dm-rq.c b/drivers/md/dm-rq.c
index 9d32f25489c2..ab95cc3f2f29 100644
--- a/drivers/md/dm-rq.c
+++ b/drivers/md/dm-rq.c
@@ -56,7 +56,7 @@ static unsigned dm_get_blk_mq_queue_depth(void)
 
 int dm_request_based(struct mapped_device *md)
 {
-	return queue_is_rq_based(md->queue);
+	return md->queue && queue_is_rq_based(md->queue);
 }
 
 static void dm_old_start_queue(struct request_queue *q)
@@ -700,7 +700,6 @@ int dm_old_init_request_queue(struct mapped_device *md, struct dm_table *t)
 	/* disable dm_old_request_fn's merge heuristic by default */
 	md->seq_rq_merge_deadline_usecs = 0;
 
-	dm_init_normal_md_queue(md);
 	blk_queue_softirq_done(md->queue, dm_softirq_done);
 
 	/* Initialize the request-based DM worker thread */
@@ -713,8 +712,6 @@ int dm_old_init_request_queue(struct mapped_device *md, struct dm_table *t)
 		return error;
 	}
 
-	elv_register_queue(md->queue);
-
 	return 0;
 }
 
@@ -810,17 +807,9 @@ int dm_mq_init_request_queue(struct mapped_device *md, struct dm_table *t)
 		err = PTR_ERR(q);
 		goto out_tag_set;
 	}
-	dm_init_md_queue(md);
-
-	/* backfill 'mq' sysfs registration normally done in blk_register_queue */
-	err = blk_mq_register_dev(disk_to_dev(md->disk), q);
-	if (err)
-		goto out_cleanup_queue;
 
 	return 0;
 
-out_cleanup_queue:
-	blk_cleanup_queue(q);
 out_tag_set:
 	blk_mq_free_tag_set(md->tag_set);
 out_kfree_tag_set:
diff --git a/drivers/md/dm-table.c b/drivers/md/dm-table.c
index ad4ac294dd57..905e0947325a 100644
--- a/drivers/md/dm-table.c
+++ b/drivers/md/dm-table.c
@@ -1192,7 +1192,7 @@ static int dm_table_build_index(struct dm_table *t)
 
 static bool integrity_profile_exists(struct gendisk *disk)
 {
-	return !!blk_get_integrity(disk);
+	return disk->queue && !!blk_get_integrity(disk);
 }
 
 /*
diff --git a/drivers/md/dm.c b/drivers/md/dm.c
index 67bf11610e4d..bf8e86087489 100644
--- a/drivers/md/dm.c
+++ b/drivers/md/dm.c
@@ -1733,20 +1733,9 @@ static const struct dax_operations dm_dax_ops;
 
 static void dm_wq_work(struct work_struct *work);
 
-void dm_init_md_queue(struct mapped_device *md)
-{
-	/*
-	 * Initialize data that will only be used by a non-blk-mq DM queue
-	 * - must do so here (in alloc_dev callchain) before queue is used
-	 */
-	md->queue->queuedata = md;
-	md->queue->backing_dev_info->congested_data = md;
-}
-
-void dm_init_normal_md_queue(struct mapped_device *md)
+static void dm_init_normal_md_queue(struct mapped_device *md)
 {
 	md->use_blk_mq = false;
-	dm_init_md_queue(md);
 
 	/*
 	 * Initialize aspects of queue that aren't relevant for blk-mq
@@ -1843,13 +1832,7 @@ static struct mapped_device *alloc_dev(int minor)
 	INIT_LIST_HEAD(&md->table_devices);
 	spin_lock_init(&md->uevent_lock);
 
-	md->queue = blk_alloc_queue_node(GFP_KERNEL, numa_node_id);
-	if (!md->queue)
-		goto bad;
-
-	dm_init_md_queue(md);
-
-	md->disk = alloc_disk_node(1, numa_node_id);
+	md->disk = alloc_disk_node(1, md->numa_node_id);
 	if (!md->disk)
 		goto bad;
 
@@ -1864,7 +1847,7 @@ static struct mapped_device *alloc_dev(int minor)
 	md->disk->major = _major;
 	md->disk->first_minor = minor;
 	md->disk->fops = &dm_blk_dops;
-	md->disk->queue = md->queue;
+	md->disk->queue = NULL;
 	md->disk->private_data = md;
 	sprintf(md->disk->disk_name, "dm-%d", minor);
 
@@ -2082,13 +2065,18 @@ static struct dm_table *__unbind(struct mapped_device *md)
  */
 int dm_create(int minor, struct mapped_device **result)
 {
+	int r;
 	struct mapped_device *md;
 
 	md = alloc_dev(minor);
 	if (!md)
 		return -ENXIO;
 
-	dm_sysfs_init(md);
+	r = dm_sysfs_init(md);
+	if (r) {
+		free_dev(md);
+		return r;
+	}
 
 	*result = md;
 	return 0;
@@ -2141,21 +2129,31 @@ EXPORT_SYMBOL_GPL(dm_get_queue_limits);
 int dm_setup_md_queue(struct mapped_device *md, struct dm_table *t)
 {
 	int r;
-	enum dm_queue_mode type = dm_get_md_type(md);
+	struct queue_limits limits;
+	enum dm_queue_mode type = dm_table_get_type(t);
+
+	md->queue = blk_alloc_queue_node(GFP_KERNEL, md->numa_node_id);
+	if (!md->queue) {
+		DMERR("Cannot allocate queue for mapped device");
+		return -ENOMEM;
+	}
+	md->queue->queuedata = md;
+	md->queue->backing_dev_info->congested_data = md;
 
 	switch (type) {
 	case DM_TYPE_REQUEST_BASED:
+		dm_init_normal_md_queue(md);
 		r = dm_old_init_request_queue(md, t);
 		if (r) {
 			DMERR("Cannot initialize queue for request-based mapped device");
-			return r;
+			goto bad;
 		}
 		break;
 	case DM_TYPE_MQ_REQUEST_BASED:
 		r = dm_mq_init_request_queue(md, t);
 		if (r) {
 			DMERR("Cannot initialize queue for request-based dm-mq mapped device");
-			return r;
+			goto bad;
 		}
 		break;
 	case DM_TYPE_BIO_BASED:
@@ -2172,7 +2170,23 @@ int dm_setup_md_queue(struct mapped_device *md, struct dm_table *t)
 		break;
 	}
 
+	r = dm_calculate_queue_limits(t, &limits);
+	if (r) {
+		DMERR("Cannot calculate initial queue limits");
+		goto bad;
+	}
+	dm_table_set_restrictions(t, md->queue, &limits);
+
+	md->disk->queue = md->queue;
+	WARN_ON(bdi_register_owner(md->queue->backing_dev_info,
+				   disk_to_dev(md->disk)));
+	blk_register_queue(md->disk);
+
+	dm_set_md_type(md, type);
 	return 0;
+bad:
+	blk_cleanup_queue(md->queue);
+	return r;
 }
 
 struct mapped_device *dm_get_md(dev_t dev)
@@ -2236,7 +2250,6 @@ EXPORT_SYMBOL_GPL(dm_device_name);
 
 static void __dm_destroy(struct mapped_device *md, bool wait)
 {
-	struct request_queue *q = dm_get_md_queue(md);
 	struct dm_table *map;
 	int srcu_idx;
 
@@ -2247,7 +2260,8 @@ static void __dm_destroy(struct mapped_device *md, bool wait)
 	set_bit(DMF_FREEING, &md->flags);
 	spin_unlock(&_minor_lock);
 
-	blk_set_queue_dying(q);
+	if (md->queue)
+		blk_set_queue_dying(md->queue);
 
 	if (dm_request_based(md) && md->kworker_task)
 		kthread_flush_worker(&md->kworker);
-- 
2.15.0

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

* Re: [for-4.16 PATCH 1/2] block: cope with gendisk's 'queue' being added later
  2018-01-09 22:10 ` [for-4.16 PATCH 1/2] " Mike Snitzer
@ 2018-01-09 23:04   ` Bart Van Assche
  2018-01-09 23:41     ` Mike Snitzer
  0 siblings, 1 reply; 6+ messages in thread
From: Bart Van Assche @ 2018-01-09 23:04 UTC (permalink / raw)
  To: snitzer@redhat.com, axboe@kernel.dk
  Cc: dm-devel@redhat.com, linux-block@vger.kernel.org

T24gVHVlLCAyMDE4LTAxLTA5IGF0IDE3OjEwIC0wNTAwLCBNaWtlIFNuaXR6ZXIgd3JvdGU6DQo+
IGRpZmYgLS1naXQgYS9ibG9jay9ibGstc3lzZnMuYyBiL2Jsb2NrL2Jsay1zeXNmcy5jDQo+IGlu
ZGV4IDg3MDQ4NGVhZWQxZi4uMGIwZGRhOGUyNDIwIDEwMDY0NA0KPiAtLS0gYS9ibG9jay9ibGst
c3lzZnMuYw0KPiArKysgYi9ibG9jay9ibGstc3lzZnMuYw0KPiBAQCAtOTE5LDggKzkxOSwyMCBA
QCBpbnQgYmxrX3JlZ2lzdGVyX3F1ZXVlKHN0cnVjdCBnZW5kaXNrICpkaXNrKQ0KPiAgCXJldCA9
IDA7DQo+ICB1bmxvY2s6DQo+ICAJbXV0ZXhfdW5sb2NrKCZxLT5zeXNmc19sb2NrKTsNCj4gKw0K
PiArCS8qDQo+ICsJICogVGFrZSBhbiBleHRyYSByZWYgb24gcXVldWUgd2hpY2ggd2lsbCBiZSBw
dXQgb24gZGlza19yZWxlYXNlKCkNCj4gKwkgKiBzbyB0aGF0IGl0IHN0aWNrcyBhcm91bmQgYXMg
bG9uZyBhcyBAZGlzayBpcyB0aGVyZS4NCj4gKwkgKi8NCj4gKwlXQVJOX09OX09OQ0UoIWJsa19n
ZXRfcXVldWUocSkpOw0KPiArDQo+ICsJV0FSTl9PTihzeXNmc19jcmVhdGVfbGluaygmZGV2LT5r
b2JqLA0KPiArCQkJCSAgJnEtPmJhY2tpbmdfZGV2X2luZm8tPmRldi0+a29iaiwNCj4gKwkJCQkg
ICJiZGkiKSk7DQo+ICsNCj4gIAlyZXR1cm4gcmV0Ow0KPiAgfQ0KPiArRVhQT1JUX1NZTUJPTF9H
UEwoYmxrX3JlZ2lzdGVyX3F1ZXVlKTsNCg0KSGVsbG8gTWlrZSwNCg0KU28gdGhlIHN5c2ZzX2Ny
ZWF0ZV9saW5rKCkgY2FsbCBpcyBtb3ZlZCBmcm9tIHJlZ2lzdGVyX2Rpc2soKSBpbnRvDQpibGtf
cmVnaXN0ZXJfcXVldWUoKSBidXQgdGhlIHN5c2ZzX3JlbW92ZV9saW5rKCkgY2FsbCBzdGF5cyBp
biBkZWxfZ2VuZGlzaygpPw0KQXJlIHlvdSBzdXJlIHRoYXQgeW91IHdhbnQgdGhpcyBhc3ltbWV0
cnk/DQoNClRoYW5rcywNCg0KQmFydC4=

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

* Re: [for-4.16 PATCH 1/2] block: cope with gendisk's 'queue' being added later
  2018-01-09 23:04   ` Bart Van Assche
@ 2018-01-09 23:41     ` Mike Snitzer
  2018-01-10  0:33       ` Mike Snitzer
  0 siblings, 1 reply; 6+ messages in thread
From: Mike Snitzer @ 2018-01-09 23:41 UTC (permalink / raw)
  To: Bart Van Assche
  Cc: axboe@kernel.dk, dm-devel@redhat.com, linux-block@vger.kernel.org

On Tue, Jan 09 2018 at  6:04pm -0500,
Bart Van Assche <Bart.VanAssche@wdc.com> wrote:

> On Tue, 2018-01-09 at 17:10 -0500, Mike Snitzer wrote:
> > diff --git a/block/blk-sysfs.c b/block/blk-sysfs.c
> > index 870484eaed1f..0b0dda8e2420 100644
> > --- a/block/blk-sysfs.c
> > +++ b/block/blk-sysfs.c
> > @@ -919,8 +919,20 @@ int blk_register_queue(struct gendisk *disk)
> >  	ret = 0;
> >  unlock:
> >  	mutex_unlock(&q->sysfs_lock);
> > +
> > +	/*
> > +	 * Take an extra ref on queue which will be put on disk_release()
> > +	 * so that it sticks around as long as @disk is there.
> > +	 */
> > +	WARN_ON_ONCE(!blk_get_queue(q));
> > +
> > +	WARN_ON(sysfs_create_link(&dev->kobj,
> > +				  &q->backing_dev_info->dev->kobj,
> > +				  "bdi"));
> > +
> >  	return ret;
> >  }
> > +EXPORT_SYMBOL_GPL(blk_register_queue);
> 
> Hello Mike,
> 
> So the sysfs_create_link() call is moved from register_disk() into
> blk_register_queue() but the sysfs_remove_link() call stays in del_gendisk()?
> Are you sure that you want this asymmetry?

My focus was on the add_disk() side of things, due to disk->queue
possibly being NULL on add.  But on remove all was basically left
unmodified (aside from removing the WARN_ON).

I dont think the asymmetry is a big deal but I can fix it.  I'll wait
for more feedback before sending out a v2 though.

Thanks,
Mike

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

* Re: [for-4.16 PATCH 1/2] block: cope with gendisk's 'queue' being added later
  2018-01-09 23:41     ` Mike Snitzer
@ 2018-01-10  0:33       ` Mike Snitzer
  0 siblings, 0 replies; 6+ messages in thread
From: Mike Snitzer @ 2018-01-10  0:33 UTC (permalink / raw)
  To: Bart Van Assche, hch
  Cc: axboe@kernel.dk, dm-devel@redhat.com, linux-block@vger.kernel.org

On Tue, Jan 09 2018 at  6:41pm -0500,
Mike Snitzer <snitzer@redhat.com> wrote:

> On Tue, Jan 09 2018 at  6:04pm -0500,
> Bart Van Assche <Bart.VanAssche@wdc.com> wrote:
> 
> > On Tue, 2018-01-09 at 17:10 -0500, Mike Snitzer wrote:
> > > diff --git a/block/blk-sysfs.c b/block/blk-sysfs.c
> > > index 870484eaed1f..0b0dda8e2420 100644
> > > --- a/block/blk-sysfs.c
> > > +++ b/block/blk-sysfs.c
> > > @@ -919,8 +919,20 @@ int blk_register_queue(struct gendisk *disk)
> > >  	ret = 0;
> > >  unlock:
> > >  	mutex_unlock(&q->sysfs_lock);
> > > +
> > > +	/*
> > > +	 * Take an extra ref on queue which will be put on disk_release()
> > > +	 * so that it sticks around as long as @disk is there.
> > > +	 */
> > > +	WARN_ON_ONCE(!blk_get_queue(q));
> > > +
> > > +	WARN_ON(sysfs_create_link(&dev->kobj,
> > > +				  &q->backing_dev_info->dev->kobj,
> > > +				  "bdi"));
> > > +
> > >  	return ret;
> > >  }
> > > +EXPORT_SYMBOL_GPL(blk_register_queue);
> > 
> > Hello Mike,
> > 
> > So the sysfs_create_link() call is moved from register_disk() into
> > blk_register_queue() but the sysfs_remove_link() call stays in del_gendisk()?
> > Are you sure that you want this asymmetry?
> 
> My focus was on the add_disk() side of things, due to disk->queue
> possibly being NULL on add.  But on remove all was basically left
> unmodified (aside from removing the WARN_ON).
> 
> I dont think the asymmetry is a big deal but I can fix it.  I'll wait
> for more feedback before sending out a v2 though.

But while reviewing this asymetry I found that the sysfs_create_link()
that I moved to blk_register_queue() needs to be guarded against
GENHD_FL_HIDDEN -- I didn't notice the GENHD_FL_HIDDEN early return in
register_disk().  I'll get that fixed up.

But unrelated to my patch: I think I found another curious imbalance, in
current upstream code, relative to GENHD_FL_HIDDEN.
bdi_register_owner() is only called if !GENHD_FL_HIDDEN but
bdi_unregister() is called unconditionally.  Not sure what is needed to
address that issue because I'd have thought that the bdi would be needed
regardless of GENHD_FL_HIDDEN.  Christoph?

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

end of thread, other threads:[~2018-01-10  0:33 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2018-01-09 22:10 [for-4.16 PATCH 0/2] block: cope with gendisk's 'queue' being added later Mike Snitzer
2018-01-09 22:10 ` [for-4.16 PATCH 1/2] " Mike Snitzer
2018-01-09 23:04   ` Bart Van Assche
2018-01-09 23:41     ` Mike Snitzer
2018-01-10  0:33       ` Mike Snitzer
2018-01-09 22:10 ` [for-4.16 PATCH 2/2] dm: fix awkward request_queue initialization Mike Snitzer

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).