All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 00/19] Block layer patches for kernel v4.13
@ 2017-05-25 18:43 Bart Van Assche
  2017-05-25 18:43 ` [PATCH 01/19] block: Avoid that blk_exit_rl() triggers a use-after-free Bart Van Assche
                   ` (18 more replies)
  0 siblings, 19 replies; 48+ messages in thread
From: Bart Van Assche @ 2017-05-25 18:43 UTC (permalink / raw)
  To: Jens Axboe; +Cc: linux-block, Christoph Hellwig, Bart Van Assche

Hello Jens,

The patches in this series are:
* A repost of the block layer patches I had sent to Martin earlier
  this week but now sent to you.
* Two patches to reduce the size of struct blk_mq_hw_ctx.
* A series of documentation patches I prepared about two months ago
  but for which I had not yet had the time to post these.

Please consider these patches for kernel v4.13.

Thanks,

Bart.

Bart Van Assche (19):
  block: Avoid that blk_exit_rl() triggers a use-after-free
  block: Introduce queue flag QUEUE_FLAG_SCSI_PDU
  bsg: Check queue type before attaching to a queue
  pktcdvd: Check queue type before attaching to a queue
  cdrom: Check private request size before attaching to a queue
  nfsd: Check private request size before submitting a SCSI request
  scsi: Make scsi_ioctl_reset() pass the request queue pointer to
    blk_rq_init()
  block: Introduce request_queue.initialize_rq_fn()
  block: Make scsi_req_init() calls implicit
  blk-mq: Change blk_mq_hw_ctx.queue_rq_srcu into an array
  blk-mq: Reduce blk_mq_hw_ctx size
  blk-mq: Initialize a request before assigning a tag
  blk-mq: Fix the comment above blk_mq_quiesce_queue()
  block: Add a comment above queue_lockdep_assert_held()
  block: Check locking assumptions at runtime
  block: Document what queue type each function is intended for
  blk-mq: Document locking assumptions
  block: Constify disk_type
  block: Make request operation type argument declarations consistent

 block/blk-cgroup.c                 |   2 +-
 block/blk-core.c                   | 129 ++++++++++++++++++++++++++++---------
 block/blk-flush.c                  |   8 ++-
 block/blk-merge.c                  |   2 +
 block/blk-mq.c                     |  68 ++++++++++++-------
 block/blk-sysfs.c                  |   2 +-
 block/blk-tag.c                    |  15 ++---
 block/blk-timeout.c                |   4 +-
 block/blk.h                        |   2 +-
 block/bsg-lib.c                    |   1 +
 block/bsg.c                        |   7 +-
 block/genhd.c                      |   4 +-
 block/scsi_ioctl.c                 |   3 -
 drivers/block/cciss.c              |   1 +
 drivers/block/pktcdvd.c            |   6 +-
 drivers/cdrom/cdrom.c              |   5 +-
 drivers/ide/ide-atapi.c            |   2 -
 drivers/ide/ide-cd.c               |   1 -
 drivers/ide/ide-cd_ioctl.c         |   1 -
 drivers/ide/ide-devsets.c          |   1 -
 drivers/ide/ide-disk.c             |   1 -
 drivers/ide/ide-ioctls.c           |   2 -
 drivers/ide/ide-park.c             |   2 -
 drivers/ide/ide-pm.c               |   2 -
 drivers/ide/ide-probe.c            |   7 +-
 drivers/ide/ide-tape.c             |   1 -
 drivers/ide/ide-taskfile.c         |   1 -
 drivers/scsi/osd/osd_initiator.c   |   2 -
 drivers/scsi/osst.c                |   1 -
 drivers/scsi/scsi_error.c          |   8 ++-
 drivers/scsi/scsi_lib.c            |  12 +++-
 drivers/scsi/scsi_transport_sas.c  |   7 ++
 drivers/scsi/sg.c                  |   2 -
 drivers/scsi/st.c                  |   1 -
 drivers/target/target_core_pscsi.c |   2 -
 fs/nfsd/blocklayout.c              |   4 +-
 include/linux/blk-mq.h             |  11 ++--
 include/linux/blkdev.h             |  16 ++++-
 38 files changed, 232 insertions(+), 114 deletions(-)

-- 
2.12.2

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

* [PATCH 01/19] block: Avoid that blk_exit_rl() triggers a use-after-free
  2017-05-25 18:43 [PATCH 00/19] Block layer patches for kernel v4.13 Bart Van Assche
@ 2017-05-25 18:43 ` Bart Van Assche
  2017-05-26  6:01   ` Christoph Hellwig
  2017-05-25 18:43 ` [PATCH 02/19] block: Introduce queue flag QUEUE_FLAG_SCSI_PDU Bart Van Assche
                   ` (17 subsequent siblings)
  18 siblings, 1 reply; 48+ messages in thread
From: Bart Van Assche @ 2017-05-25 18:43 UTC (permalink / raw)
  To: Jens Axboe
  Cc: linux-block, Christoph Hellwig, Bart Van Assche, Jens Axboe,
	Jan Kara, stable

Since the introduction of the .init_rq_fn() and .exit_rq_fn() it
is essential that the memory allocated for struct request_queue
stays around until all blk_exit_rl() calls have finished. Hence
make blk_init_rl() take a reference on struct request_queue.

This patch fixes the following crash:

general protection fault: 0000 [#2] SMP
CPU: 3 PID: 28 Comm: ksoftirqd/3 Tainted: G      D         4.12.0-rc2-dbg+ #2
Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.0.0-prebuilt.qemu-project.org 04/01/2014
task: ffff88013a108040 task.stack: ffffc9000071c000
RIP: 0010:free_request_size+0x1a/0x30
RSP: 0018:ffffc9000071fd38 EFLAGS: 00010202
RAX: 6b6b6b6b6b6b6b6b RBX: ffff880067362a88 RCX: 0000000000000003
RDX: ffff880067464178 RSI: ffff880067362a88 RDI: ffff880135ea4418
RBP: ffffc9000071fd40 R08: 0000000000000000 R09: 0000000100180009
R10: ffffc9000071fd38 R11: ffffffff81110800 R12: ffff88006752d3d8
R13: ffff88006752d3d8 R14: ffff88013a108040 R15: 000000000000000a
FS:  0000000000000000(0000) GS:ffff88013fd80000(0000) knlGS:0000000000000000
CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
CR2: 00007fa8ec1edb00 CR3: 0000000138ee8000 CR4: 00000000001406e0
Call Trace:
 mempool_destroy.part.10+0x21/0x40
 mempool_destroy+0xe/0x10
 blk_exit_rl+0x12/0x20
 blkg_free+0x4d/0xa0
 __blkg_release_rcu+0x59/0x170
 rcu_process_callbacks+0x260/0x4e0
 __do_softirq+0x116/0x250
 smpboot_thread_fn+0x123/0x1e0
 kthread+0x109/0x140
 ret_from_fork+0x31/0x40

Fixes: commit e9c787e65c0c ("scsi: allocate scsi_cmnd structures as part of struct request")
Signed-off-by: Bart Van Assche <bart.vanassche@sandisk.com>
Acked-by: Tejun Heo <tj@kernel.org>
Reviewed-by: Hannes Reinecke <hare@suse.com>
Cc: Jens Axboe <axboe@fb.com>
Cc: Christoph Hellwig <hch@lst.de>
Cc: Jan Kara <jack@suse.cz>
Cc: <stable@vger.kernel.org> # v4.11+
---
 block/blk-cgroup.c |  2 +-
 block/blk-core.c   | 10 ++++++++--
 block/blk-sysfs.c  |  2 +-
 block/blk.h        |  2 +-
 4 files changed, 11 insertions(+), 5 deletions(-)

diff --git a/block/blk-cgroup.c b/block/blk-cgroup.c
index 7c2947128f58..0480892e97e5 100644
--- a/block/blk-cgroup.c
+++ b/block/blk-cgroup.c
@@ -74,7 +74,7 @@ static void blkg_free(struct blkcg_gq *blkg)
 			blkcg_policy[i]->pd_free_fn(blkg->pd[i]);
 
 	if (blkg->blkcg != &blkcg_root)
-		blk_exit_rl(&blkg->rl);
+		blk_exit_rl(blkg->q, &blkg->rl);
 
 	blkg_rwstat_exit(&blkg->stat_ios);
 	blkg_rwstat_exit(&blkg->stat_bytes);
diff --git a/block/blk-core.c b/block/blk-core.c
index c580b0138a7f..9416f6f495d4 100644
--- a/block/blk-core.c
+++ b/block/blk-core.c
@@ -648,13 +648,19 @@ int blk_init_rl(struct request_list *rl, struct request_queue *q,
 	if (!rl->rq_pool)
 		return -ENOMEM;
 
+	if (rl != &q->root_rl)
+		WARN_ON_ONCE(!blk_get_queue(q));
+
 	return 0;
 }
 
-void blk_exit_rl(struct request_list *rl)
+void blk_exit_rl(struct request_queue *q, struct request_list *rl)
 {
-	if (rl->rq_pool)
+	if (rl->rq_pool) {
 		mempool_destroy(rl->rq_pool);
+		if (rl != &q->root_rl)
+			blk_put_queue(q);
+	}
 }
 
 struct request_queue *blk_alloc_queue(gfp_t gfp_mask)
diff --git a/block/blk-sysfs.c b/block/blk-sysfs.c
index 504fee940052..2ff8842f0dc1 100644
--- a/block/blk-sysfs.c
+++ b/block/blk-sysfs.c
@@ -809,7 +809,7 @@ static void blk_release_queue(struct kobject *kobj)
 
 	blk_free_queue_stats(q->stats);
 
-	blk_exit_rl(&q->root_rl);
+	blk_exit_rl(q, &q->root_rl);
 
 	if (q->queue_tags)
 		__blk_queue_free_tags(q);
diff --git a/block/blk.h b/block/blk.h
index 2ed70228e44f..83c8e1100525 100644
--- a/block/blk.h
+++ b/block/blk.h
@@ -59,7 +59,7 @@ void blk_free_flush_queue(struct blk_flush_queue *q);
 
 int blk_init_rl(struct request_list *rl, struct request_queue *q,
 		gfp_t gfp_mask);
-void blk_exit_rl(struct request_list *rl);
+void blk_exit_rl(struct request_queue *q, struct request_list *rl);
 void blk_rq_bio_prep(struct request_queue *q, struct request *rq,
 			struct bio *bio);
 void blk_queue_bypass_start(struct request_queue *q);
-- 
2.12.2

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

* [PATCH 02/19] block: Introduce queue flag QUEUE_FLAG_SCSI_PDU
  2017-05-25 18:43 [PATCH 00/19] Block layer patches for kernel v4.13 Bart Van Assche
  2017-05-25 18:43 ` [PATCH 01/19] block: Avoid that blk_exit_rl() triggers a use-after-free Bart Van Assche
@ 2017-05-25 18:43 ` Bart Van Assche
  2017-05-26  6:02   ` Christoph Hellwig
  2017-05-25 18:43 ` [PATCH 03/19] bsg: Check queue type before attaching to a queue Bart Van Assche
                   ` (16 subsequent siblings)
  18 siblings, 1 reply; 48+ messages in thread
From: Bart Van Assche @ 2017-05-25 18:43 UTC (permalink / raw)
  To: Jens Axboe
  Cc: linux-block, Christoph Hellwig, Bart Van Assche, Jens Axboe,
	Omar Sandoval

>From the context where a SCSI command is submitted it is not always
possible to figure out whether or not the queue the command is
submitted to has struct scsi_request as the first member of its
private data. Hence introduce the flag QUEUE_FLAG_SCSI_PDU.

Signed-off-by: Bart Van Assche <bart.vanassche@sandisk.com>
Reviewed-by: Hannes Reinecke <hare@suse.com>
Cc: Jens Axboe <axboe@fb.com>
Cc: Christoph Hellwig <hch@lst.de>
Cc: Omar Sandoval <osandov@fb.com>
---
 block/bsg-lib.c                   | 1 +
 drivers/block/cciss.c             | 1 +
 drivers/ide/ide-probe.c           | 1 +
 drivers/scsi/scsi_lib.c           | 2 ++
 drivers/scsi/scsi_transport_sas.c | 1 +
 include/linux/blkdev.h            | 2 ++
 6 files changed, 8 insertions(+)

diff --git a/block/bsg-lib.c b/block/bsg-lib.c
index 0a23dbba2d30..298710aa65a3 100644
--- a/block/bsg-lib.c
+++ b/block/bsg-lib.c
@@ -246,6 +246,7 @@ struct request_queue *bsg_setup_queue(struct device *dev, char *name,
 	q->bsg_job_size = dd_job_size;
 	q->bsg_job_fn = job_fn;
 	queue_flag_set_unlocked(QUEUE_FLAG_BIDI, q);
+	queue_flag_set_unlocked(QUEUE_FLAG_SCSI_PDU, q);
 	blk_queue_softirq_done(q, bsg_softirq_done);
 	blk_queue_rq_timeout(q, BLK_DEFAULT_SG_TIMEOUT);
 
diff --git a/drivers/block/cciss.c b/drivers/block/cciss.c
index cd375503f7b0..453d420a96dd 100644
--- a/drivers/block/cciss.c
+++ b/drivers/block/cciss.c
@@ -1956,6 +1956,7 @@ static int cciss_add_disk(ctlr_info_t *h, struct gendisk *disk,
 	disk->queue->cmd_size = sizeof(struct scsi_request);
 	disk->queue->request_fn = do_cciss_request;
 	disk->queue->queue_lock = &h->lock;
+	queue_flag_set_unlocked(QUEUE_FLAG_SCSI_PDU, disk->queue);
 	if (blk_init_allocated_queue(disk->queue) < 0)
 		goto cleanup_queue;
 
diff --git a/drivers/ide/ide-probe.c b/drivers/ide/ide-probe.c
index 023562565d11..a7cead2fd9ff 100644
--- a/drivers/ide/ide-probe.c
+++ b/drivers/ide/ide-probe.c
@@ -773,6 +773,7 @@ static int ide_init_queue(ide_drive_t *drive)
 	q->request_fn = do_ide_request;
 	q->init_rq_fn = ide_init_rq;
 	q->cmd_size = sizeof(struct ide_request);
+	queue_flag_set_unlocked(QUEUE_FLAG_SCSI_PDU, q);
 	if (blk_init_allocated_queue(q) < 0) {
 		blk_cleanup_queue(q);
 		return 1;
diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c
index 814a4bd8405d..48dd47e6bdf4 100644
--- a/drivers/scsi/scsi_lib.c
+++ b/drivers/scsi/scsi_lib.c
@@ -2056,6 +2056,8 @@ void __scsi_init_queue(struct Scsi_Host *shost, struct request_queue *q)
 {
 	struct device *dev = shost->dma_dev;
 
+	queue_flag_set_unlocked(QUEUE_FLAG_SCSI_PDU, q);
+
 	/*
 	 * this limit is imposed by hardware restrictions
 	 */
diff --git a/drivers/scsi/scsi_transport_sas.c b/drivers/scsi/scsi_transport_sas.c
index 0ebe2f1bb908..f903004f3cad 100644
--- a/drivers/scsi/scsi_transport_sas.c
+++ b/drivers/scsi/scsi_transport_sas.c
@@ -264,6 +264,7 @@ static int sas_bsg_initialize(struct Scsi_Host *shost, struct sas_rphy *rphy)
 		q->queuedata = shost;
 
 	queue_flag_set_unlocked(QUEUE_FLAG_BIDI, q);
+	queue_flag_set_unlocked(QUEUE_FLAG_SCSI_PDU, q);
 	return 0;
 
 out_cleanup_queue:
diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h
index b5d1e27631ee..94fd2600584d 100644
--- a/include/linux/blkdev.h
+++ b/include/linux/blkdev.h
@@ -618,6 +618,7 @@ struct request_queue {
 #define QUEUE_FLAG_STATS       27	/* track rq completion times */
 #define QUEUE_FLAG_POLL_STATS  28	/* collecting stats for hybrid polling */
 #define QUEUE_FLAG_REGISTERED  29	/* queue has been registered to a disk */
+#define QUEUE_FLAG_SCSI_PDU    30	/* queue supports SCSI commands */
 
 #define QUEUE_FLAG_DEFAULT	((1 << QUEUE_FLAG_IO_STAT) |		\
 				 (1 << QUEUE_FLAG_STACKABLE)	|	\
@@ -708,6 +709,7 @@ static inline void queue_flag_clear(unsigned int flag, struct request_queue *q)
 #define blk_queue_secure_erase(q) \
 	(test_bit(QUEUE_FLAG_SECERASE, &(q)->queue_flags))
 #define blk_queue_dax(q)	test_bit(QUEUE_FLAG_DAX, &(q)->queue_flags)
+#define blk_queue_scsi_pdu(q)	test_bit(QUEUE_FLAG_SCSI_PDU, &(q)->queue_flags)
 
 #define blk_noretry_request(rq) \
 	((rq)->cmd_flags & (REQ_FAILFAST_DEV|REQ_FAILFAST_TRANSPORT| \
-- 
2.12.2

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

* [PATCH 03/19] bsg: Check queue type before attaching to a queue
  2017-05-25 18:43 [PATCH 00/19] Block layer patches for kernel v4.13 Bart Van Assche
  2017-05-25 18:43 ` [PATCH 01/19] block: Avoid that blk_exit_rl() triggers a use-after-free Bart Van Assche
  2017-05-25 18:43 ` [PATCH 02/19] block: Introduce queue flag QUEUE_FLAG_SCSI_PDU Bart Van Assche
@ 2017-05-25 18:43 ` Bart Van Assche
  2017-05-26  6:02   ` Christoph Hellwig
  2017-05-25 18:43 ` [PATCH 04/19] pktcdvd: " Bart Van Assche
                   ` (15 subsequent siblings)
  18 siblings, 1 reply; 48+ messages in thread
From: Bart Van Assche @ 2017-05-25 18:43 UTC (permalink / raw)
  To: Jens Axboe; +Cc: linux-block, Christoph Hellwig, Bart Van Assche, Omar Sandoval

Since BSG only supports request queues for which struct scsi_request
is the first member of their private request data, refuse to register
block layer queues for which struct scsi_request is not the first
member of their private data.

References: commit bd1599d931ca ("scsi_transport_sas: fix BSG ioctl memory corruption")
References: commit 82ed4db499b8 ("block: split scsi_request out of struct request")
Signed-off-by: Bart Van Assche <bart.vanassche@sandisk.com>
Reviewed-by: Hannes Reinecke <hare@suse.com>
Cc: Christoph Hellwig <hch@lst.de>
Cc: Omar Sandoval <osandov@fb.com>
Cc: linux-block@vger.kernel.org
---
 block/bsg.c | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/block/bsg.c b/block/bsg.c
index 6fd08544d77e..5871bbe70ccd 100644
--- a/block/bsg.c
+++ b/block/bsg.c
@@ -750,6 +750,12 @@ static struct bsg_device *bsg_add_device(struct inode *inode,
 #ifdef BSG_DEBUG
 	unsigned char buf[32];
 #endif
+
+	if (!blk_queue_scsi_pdu(rq)) {
+		WARN_ONCE(true, "Attempt to register a non-SCSI queue\n");
+		return ERR_PTR(-EINVAL);
+	}
+
 	if (!blk_get_queue(rq))
 		return ERR_PTR(-ENXIO);
 
-- 
2.12.2

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

* [PATCH 04/19] pktcdvd: Check queue type before attaching to a queue
  2017-05-25 18:43 [PATCH 00/19] Block layer patches for kernel v4.13 Bart Van Assche
                   ` (2 preceding siblings ...)
  2017-05-25 18:43 ` [PATCH 03/19] bsg: Check queue type before attaching to a queue Bart Van Assche
@ 2017-05-25 18:43 ` Bart Van Assche
  2017-05-26  6:03   ` Christoph Hellwig
  2017-05-25 18:43 ` [PATCH 05/19] cdrom: Check private request size " Bart Van Assche
                   ` (14 subsequent siblings)
  18 siblings, 1 reply; 48+ messages in thread
From: Bart Van Assche @ 2017-05-25 18:43 UTC (permalink / raw)
  To: Jens Axboe
  Cc: linux-block, Christoph Hellwig, Bart Van Assche, Jens Axboe,
	Omar Sandoval

Since the pktcdvd driver only supports request queues for which
struct scsi_request is the first member of their private request
data, refuse to register block layer queues for which struct
scsi_request is not the first member of the private data.

References: commit 82ed4db499b8 ("block: split scsi_request out of struct request")
Signed-off-by: Bart Van Assche <bart.vanassche@sandisk.com>
Reviewed-by: Hannes Reinecke <hare@suse.com>
Cc: Jens Axboe <axboe@fb.com>
Cc: Christoph Hellwig <hch@lst.de>
Cc: Omar Sandoval <osandov@fb.com>
Cc: linux-block@vger.kernel.org
---
 drivers/block/pktcdvd.c | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/drivers/block/pktcdvd.c b/drivers/block/pktcdvd.c
index 205b865ebeb9..1404c1c01fd0 100644
--- a/drivers/block/pktcdvd.c
+++ b/drivers/block/pktcdvd.c
@@ -2583,6 +2583,11 @@ static int pkt_new_dev(struct pktcdvd_device *pd, dev_t dev)
 	bdev = bdget(dev);
 	if (!bdev)
 		return -ENOMEM;
+	if (!blk_queue_scsi_pdu(bdev_get_queue(bdev))) {
+		WARN_ONCE(true, "Attempt to register a non-SCSI queue\n");
+		bdput(bdev);
+		return -EINVAL;
+	}
 	ret = blkdev_get(bdev, FMODE_READ | FMODE_NDELAY, NULL);
 	if (ret)
 		return ret;
-- 
2.12.2

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

* [PATCH 05/19] cdrom: Check private request size before attaching to a queue
  2017-05-25 18:43 [PATCH 00/19] Block layer patches for kernel v4.13 Bart Van Assche
                   ` (3 preceding siblings ...)
  2017-05-25 18:43 ` [PATCH 04/19] pktcdvd: " Bart Van Assche
@ 2017-05-25 18:43 ` Bart Van Assche
  2017-05-26  6:08   ` Christoph Hellwig
  2017-05-25 18:43 ` [PATCH 06/19] nfsd: Check private request size before submitting a SCSI request Bart Van Assche
                   ` (13 subsequent siblings)
  18 siblings, 1 reply; 48+ messages in thread
From: Bart Van Assche @ 2017-05-25 18:43 UTC (permalink / raw)
  To: Jens Axboe; +Cc: linux-block, Christoph Hellwig, Bart Van Assche, Omar Sandoval

Since the cdrom driver only supports request queues for which
struct scsi_request is the first member of their private request
data, refuse to register block layer queues for which this is
not the case.

References: commit 82ed4db499b8 ("block: split scsi_request out of struct request")
Signed-off-by: Bart Van Assche <bart.vanassche@sandisk.com>
Reviewed-by: Hannes Reinecke <hare@suse.com>
Cc: Christoph Hellwig <hch@lst.de>
Cc: Omar Sandoval <osandov@fb.com>
Cc: linux-block@vger.kernel.org
---
 drivers/cdrom/cdrom.c | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/drivers/cdrom/cdrom.c b/drivers/cdrom/cdrom.c
index 76c952fd9ab9..5c1fec31b7ef 100644
--- a/drivers/cdrom/cdrom.c
+++ b/drivers/cdrom/cdrom.c
@@ -594,6 +594,10 @@ int register_cdrom(struct cdrom_device_info *cdi)
 
 	if (cdo->open == NULL || cdo->release == NULL)
 		return -EINVAL;
+	if (!blk_queue_scsi_pdu(cdi->disk->queue)) {
+		WARN_ONCE(true, "Attempt to register a non-SCSI queue\n");
+		return -EINVAL;
+	}
 	if (!banner_printed) {
 		pr_info("Uniform CD-ROM driver " REVISION "\n");
 		banner_printed = 1;
-- 
2.12.2

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

* [PATCH 06/19] nfsd: Check private request size before submitting a SCSI request
  2017-05-25 18:43 [PATCH 00/19] Block layer patches for kernel v4.13 Bart Van Assche
                   ` (4 preceding siblings ...)
  2017-05-25 18:43 ` [PATCH 05/19] cdrom: Check private request size " Bart Van Assche
@ 2017-05-25 18:43 ` Bart Van Assche
  2017-05-25 18:48   ` J . Bruce Fields
  2017-05-26  6:10   ` Christoph Hellwig
  2017-05-25 18:43 ` [PATCH 07/19] scsi: Make scsi_ioctl_reset() pass the request queue pointer to blk_rq_init() Bart Van Assche
                   ` (12 subsequent siblings)
  18 siblings, 2 replies; 48+ messages in thread
From: Bart Van Assche @ 2017-05-25 18:43 UTC (permalink / raw)
  To: Jens Axboe
  Cc: linux-block, Christoph Hellwig, Bart Van Assche,
	J . Bruce Fields, Jeff Layton, Jens Axboe, Omar Sandoval,
	linux-nfs

Since using scsi_req() is only allowed against request queues for
which struct scsi_request is the first member of their private
request data, refuse to submit SCSI commands against a queue for
which this is not the case.

References: commit 82ed4db499b8 ("block: split scsi_request out of struct request")
Signed-off-by: Bart Van Assche <bart.vanassche@sandisk.com>
Reviewed-by: Hannes Reinecke <hare@suse.com>
Cc: J. Bruce Fields <bfields@fieldses.org>
Cc: Jeff Layton <jlayton@poochiereds.net>
Cc: Jens Axboe <axboe@fb.com>
Cc: Christoph Hellwig <hch@lst.de>
Cc: Omar Sandoval <osandov@fb.com>
Cc: linux-nfs@vger.kernel.org
Cc: linux-block@vger.kernel.org
---
 fs/nfsd/blocklayout.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/fs/nfsd/blocklayout.c b/fs/nfsd/blocklayout.c
index fb5213afc854..38e14cf7e74a 100644
--- a/fs/nfsd/blocklayout.c
+++ b/fs/nfsd/blocklayout.c
@@ -219,6 +219,9 @@ static int nfsd4_scsi_identify_device(struct block_device *bdev,
 	u8 *buf, *d, type, assoc;
 	int error;
 
+	if (WARN_ON_ONCE(!blk_queue_scsi_pdu(q)))
+		return -EINVAL;
+
 	buf = kzalloc(bufflen, GFP_KERNEL);
 	if (!buf)
 		return -ENOMEM;
-- 
2.12.2

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

* [PATCH 07/19] scsi: Make scsi_ioctl_reset() pass the request queue pointer to blk_rq_init()
  2017-05-25 18:43 [PATCH 00/19] Block layer patches for kernel v4.13 Bart Van Assche
                   ` (5 preceding siblings ...)
  2017-05-25 18:43 ` [PATCH 06/19] nfsd: Check private request size before submitting a SCSI request Bart Van Assche
@ 2017-05-25 18:43 ` Bart Van Assche
  2017-05-25 18:43 ` [PATCH 08/19] block: Introduce request_queue.initialize_rq_fn() Bart Van Assche
                   ` (11 subsequent siblings)
  18 siblings, 0 replies; 48+ messages in thread
From: Bart Van Assche @ 2017-05-25 18:43 UTC (permalink / raw)
  To: Jens Axboe
  Cc: linux-block, Christoph Hellwig, Bart Van Assche,
	Martin K . Petersen, James Bottomley

A later patch will add a call to a request initialization function
into blk_rq_init(). Hence make sure that all blk_rq_init() calls
specify the request queue pointer. Since TMF callback functions in
SCSI LLD drivers do not use request.q, this patch does not change
the behavior of any SCSI driver.

Signed-off-by: Bart Van Assche <bart.vanassche@sandisk.com>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Hannes Reinecke <hare@suse.com>
Cc: Martin K. Petersen <martin.petersen@oracle.com>
Cc: James Bottomley <James.Bottomley@HansenPartnership.com>
---
 drivers/scsi/scsi_error.c | 7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/drivers/scsi/scsi_error.c b/drivers/scsi/scsi_error.c
index ecc07dab893d..97d5a0bb7061 100644
--- a/drivers/scsi/scsi_error.c
+++ b/drivers/scsi/scsi_error.c
@@ -2274,7 +2274,12 @@ scsi_ioctl_reset(struct scsi_device *dev, int __user *arg)
 			shost->hostt->cmd_size, GFP_KERNEL);
 	if (!rq)
 		goto out_put_autopm_host;
-	blk_rq_init(NULL, rq);
+	/*
+	 * Although blk_rq_init() is intended for single queue block
+	 * drivers, this code path even uses blk_rq_init() when @dev is
+	 * a scsi-mq device.
+	 */
+	blk_rq_init(dev->request_queue, rq);
 
 	scmd = (struct scsi_cmnd *)(rq + 1);
 	scsi_init_command(dev, scmd);
-- 
2.12.2

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

* [PATCH 08/19] block: Introduce request_queue.initialize_rq_fn()
  2017-05-25 18:43 [PATCH 00/19] Block layer patches for kernel v4.13 Bart Van Assche
                   ` (6 preceding siblings ...)
  2017-05-25 18:43 ` [PATCH 07/19] scsi: Make scsi_ioctl_reset() pass the request queue pointer to blk_rq_init() Bart Van Assche
@ 2017-05-25 18:43 ` Bart Van Assche
  2017-05-26  6:34   ` Christoph Hellwig
  2017-05-28  8:37   ` Christoph Hellwig
  2017-05-25 18:43 ` [PATCH 09/19] block: Make scsi_req_init() calls implicit Bart Van Assche
                   ` (10 subsequent siblings)
  18 siblings, 2 replies; 48+ messages in thread
From: Bart Van Assche @ 2017-05-25 18:43 UTC (permalink / raw)
  To: Jens Axboe
  Cc: linux-block, Christoph Hellwig, Bart Van Assche, Jens Axboe,
	Omar Sandoval

Several block drivers need to initialize the driver-private data
after having called blk_get_request() and before .prep_rq_fn() is
called, e.g. when submitting a REQ_OP_SCSI_* request. Avoid that
that initialization code has to be repeated after every
blk_get_request() call by adding a new callback function to struct
request_queue.

Signed-off-by: Bart Van Assche <bart.vanassche@sandisk.com>
Reviewed-by: Hannes Reinecke <hare@suse.com>
Cc: Jens Axboe <axboe@fb.com>
Cc: Christoph Hellwig <hch@lst.de>
Cc: Omar Sandoval <osandov@fb.com>
Cc: linux-block@vger.kernel.org
---
 block/blk-core.c       | 3 +++
 block/blk-mq.c         | 3 +++
 include/linux/blkdev.h | 4 ++++
 3 files changed, 10 insertions(+)

diff --git a/block/blk-core.c b/block/blk-core.c
index 9416f6f495d4..fa453ed95973 100644
--- a/block/blk-core.c
+++ b/block/blk-core.c
@@ -126,6 +126,9 @@ void blk_rq_init(struct request_queue *q, struct request *rq)
 	rq->start_time = jiffies;
 	set_start_time_ns(rq);
 	rq->part = NULL;
+
+	if (q->initialize_rq_fn)
+		q->initialize_rq_fn(rq);
 }
 EXPORT_SYMBOL(blk_rq_init);
 
diff --git a/block/blk-mq.c b/block/blk-mq.c
index 9ae1d9ccf4df..a1620b36b95c 100644
--- a/block/blk-mq.c
+++ b/block/blk-mq.c
@@ -241,6 +241,9 @@ void blk_mq_rq_ctx_init(struct request_queue *q, struct blk_mq_ctx *ctx,
 	rq->end_io_data = NULL;
 	rq->next_rq = NULL;
 
+	if (q->initialize_rq_fn)
+		q->initialize_rq_fn(rq);
+
 	ctx->rq_dispatched[op_is_sync(op)]++;
 }
 EXPORT_SYMBOL_GPL(blk_mq_rq_ctx_init);
diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h
index 94fd2600584d..8a223a0c95d5 100644
--- a/include/linux/blkdev.h
+++ b/include/linux/blkdev.h
@@ -410,8 +410,12 @@ struct request_queue {
 	rq_timed_out_fn		*rq_timed_out_fn;
 	dma_drain_needed_fn	*dma_drain_needed;
 	lld_busy_fn		*lld_busy_fn;
+	/* Called just after a request is allocated */
 	init_rq_fn		*init_rq_fn;
+	/* Called just before a request is freed */
 	exit_rq_fn		*exit_rq_fn;
+	/* Called from inside blk_get_request() */
+	void (*initialize_rq_fn)(struct request *rq);
 
 	const struct blk_mq_ops	*mq_ops;
 
-- 
2.12.2

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

* [PATCH 09/19] block: Make scsi_req_init() calls implicit
  2017-05-25 18:43 [PATCH 00/19] Block layer patches for kernel v4.13 Bart Van Assche
                   ` (7 preceding siblings ...)
  2017-05-25 18:43 ` [PATCH 08/19] block: Introduce request_queue.initialize_rq_fn() Bart Van Assche
@ 2017-05-25 18:43 ` Bart Van Assche
  2017-05-28  8:38   ` Christoph Hellwig
  2017-05-25 18:43 ` [PATCH 10/19] blk-mq: Change blk_mq_hw_ctx.queue_rq_srcu into an array Bart Van Assche
                   ` (9 subsequent siblings)
  18 siblings, 1 reply; 48+ messages in thread
From: Bart Van Assche @ 2017-05-25 18:43 UTC (permalink / raw)
  To: Jens Axboe
  Cc: linux-block, Christoph Hellwig, Bart Van Assche, Jens Axboe,
	Omar Sandoval

Instead of explicitly calling scsi_req_init(), let
blk_get_request() call that function from inside blk_rq_init().
Add an .initialize_rq_fn() callback function to the block drivers
that need it. Merge the IDE .init_rq_fn() function into
.initialize_rq_fn() because it is too small to keep it as a
separate function.

References: commit 82ed4db499b8 ("block: split scsi_request out of struct request")
Signed-off-by: Bart Van Assche <bart.vanassche@sandisk.com>
Reviewed-by: Hannes Reinecke <hare@suse.com>
Cc: Jens Axboe <axboe@fb.com>
Cc: Christoph Hellwig <hch@lst.de>
Cc: Omar Sandoval <osandov@fb.com>
Cc: linux-block@vger.kernel.org
---
 block/bsg.c                        |  1 -
 block/scsi_ioctl.c                 |  3 ---
 drivers/block/pktcdvd.c            |  1 -
 drivers/cdrom/cdrom.c              |  1 -
 drivers/ide/ide-atapi.c            |  2 --
 drivers/ide/ide-cd.c               |  1 -
 drivers/ide/ide-cd_ioctl.c         |  1 -
 drivers/ide/ide-devsets.c          |  1 -
 drivers/ide/ide-disk.c             |  1 -
 drivers/ide/ide-ioctls.c           |  2 --
 drivers/ide/ide-park.c             |  2 --
 drivers/ide/ide-pm.c               |  2 --
 drivers/ide/ide-probe.c            |  6 +++---
 drivers/ide/ide-tape.c             |  1 -
 drivers/ide/ide-taskfile.c         |  1 -
 drivers/scsi/osd/osd_initiator.c   |  2 --
 drivers/scsi/osst.c                |  1 -
 drivers/scsi/scsi_error.c          |  1 -
 drivers/scsi/scsi_lib.c            | 10 +++++++++-
 drivers/scsi/scsi_transport_sas.c  |  6 ++++++
 drivers/scsi/sg.c                  |  2 --
 drivers/scsi/st.c                  |  1 -
 drivers/target/target_core_pscsi.c |  2 --
 fs/nfsd/blocklayout.c              |  1 -
 24 files changed, 18 insertions(+), 34 deletions(-)

diff --git a/block/bsg.c b/block/bsg.c
index 5871bbe70ccd..dd9fcb163326 100644
--- a/block/bsg.c
+++ b/block/bsg.c
@@ -236,7 +236,6 @@ bsg_map_hdr(struct bsg_device *bd, struct sg_io_v4 *hdr, fmode_t has_write_perm)
 	rq = blk_get_request(q, op, GFP_KERNEL);
 	if (IS_ERR(rq))
 		return rq;
-	scsi_req_init(rq);
 
 	ret = blk_fill_sgv4_hdr_rq(q, rq, hdr, bd, has_write_perm);
 	if (ret)
diff --git a/block/scsi_ioctl.c b/block/scsi_ioctl.c
index 4a294a5f7fab..f96c51f5df40 100644
--- a/block/scsi_ioctl.c
+++ b/block/scsi_ioctl.c
@@ -326,7 +326,6 @@ static int sg_io(struct request_queue *q, struct gendisk *bd_disk,
 	if (IS_ERR(rq))
 		return PTR_ERR(rq);
 	req = scsi_req(rq);
-	scsi_req_init(rq);
 
 	if (hdr->cmd_len > BLK_MAX_CDB) {
 		req->cmd = kzalloc(hdr->cmd_len, GFP_KERNEL);
@@ -456,7 +455,6 @@ int sg_scsi_ioctl(struct request_queue *q, struct gendisk *disk, fmode_t mode,
 		goto error_free_buffer;
 	}
 	req = scsi_req(rq);
-	scsi_req_init(rq);
 
 	cmdlen = COMMAND_SIZE(opcode);
 
@@ -542,7 +540,6 @@ static int __blk_send_generic(struct request_queue *q, struct gendisk *bd_disk,
 	rq = blk_get_request(q, REQ_OP_SCSI_OUT, __GFP_RECLAIM);
 	if (IS_ERR(rq))
 		return PTR_ERR(rq);
-	scsi_req_init(rq);
 	rq->timeout = BLK_DEFAULT_SG_TIMEOUT;
 	scsi_req(rq)->cmd[0] = cmd;
 	scsi_req(rq)->cmd[4] = data;
diff --git a/drivers/block/pktcdvd.c b/drivers/block/pktcdvd.c
index 1404c1c01fd0..c3704baff1d6 100644
--- a/drivers/block/pktcdvd.c
+++ b/drivers/block/pktcdvd.c
@@ -707,7 +707,6 @@ static int pkt_generic_packet(struct pktcdvd_device *pd, struct packet_command *
 			     REQ_OP_SCSI_OUT : REQ_OP_SCSI_IN, __GFP_RECLAIM);
 	if (IS_ERR(rq))
 		return PTR_ERR(rq);
-	scsi_req_init(rq);
 
 	if (cgc->buflen) {
 		ret = blk_rq_map_kern(q, rq, cgc->buffer, cgc->buflen,
diff --git a/drivers/cdrom/cdrom.c b/drivers/cdrom/cdrom.c
index 5c1fec31b7ef..05b8a4d30ed0 100644
--- a/drivers/cdrom/cdrom.c
+++ b/drivers/cdrom/cdrom.c
@@ -2199,7 +2199,6 @@ static int cdrom_read_cdda_bpc(struct cdrom_device_info *cdi, __u8 __user *ubuf,
 			break;
 		}
 		req = scsi_req(rq);
-		scsi_req_init(rq);
 
 		ret = blk_rq_map_user(q, rq, NULL, ubuf, len, GFP_KERNEL);
 		if (ret) {
diff --git a/drivers/ide/ide-atapi.c b/drivers/ide/ide-atapi.c
index 5901937284e7..7edebe0fb1eb 100644
--- a/drivers/ide/ide-atapi.c
+++ b/drivers/ide/ide-atapi.c
@@ -93,7 +93,6 @@ int ide_queue_pc_tail(ide_drive_t *drive, struct gendisk *disk,
 	int error;
 
 	rq = blk_get_request(drive->queue, REQ_OP_DRV_IN, __GFP_RECLAIM);
-	scsi_req_init(rq);
 	ide_req(rq)->type = ATA_PRIV_MISC;
 	rq->special = (char *)pc;
 
@@ -200,7 +199,6 @@ void ide_prep_sense(ide_drive_t *drive, struct request *rq)
 	memset(sense, 0, sizeof(*sense));
 
 	blk_rq_init(rq->q, sense_rq);
-	scsi_req_init(sense_rq);
 
 	err = blk_rq_map_kern(drive->queue, sense_rq, sense, sense_len,
 			      GFP_NOIO);
diff --git a/drivers/ide/ide-cd.c b/drivers/ide/ide-cd.c
index 07e5ff3a64c3..a14ccb34c923 100644
--- a/drivers/ide/ide-cd.c
+++ b/drivers/ide/ide-cd.c
@@ -438,7 +438,6 @@ int ide_cd_queue_pc(ide_drive_t *drive, const unsigned char *cmd,
 
 		rq = blk_get_request(drive->queue,
 			write ? REQ_OP_DRV_OUT : REQ_OP_DRV_IN,  __GFP_RECLAIM);
-		scsi_req_init(rq);
 		memcpy(scsi_req(rq)->cmd, cmd, BLK_MAX_CDB);
 		ide_req(rq)->type = ATA_PRIV_PC;
 		rq->rq_flags |= rq_flags;
diff --git a/drivers/ide/ide-cd_ioctl.c b/drivers/ide/ide-cd_ioctl.c
index 55cd736c39c6..9d26c9737e21 100644
--- a/drivers/ide/ide-cd_ioctl.c
+++ b/drivers/ide/ide-cd_ioctl.c
@@ -304,7 +304,6 @@ int ide_cdrom_reset(struct cdrom_device_info *cdi)
 	int ret;
 
 	rq = blk_get_request(drive->queue, REQ_OP_DRV_IN, __GFP_RECLAIM);
-	scsi_req_init(rq);
 	ide_req(rq)->type = ATA_PRIV_MISC;
 	rq->rq_flags = RQF_QUIET;
 	blk_execute_rq(drive->queue, cd->disk, rq, 0);
diff --git a/drivers/ide/ide-devsets.c b/drivers/ide/ide-devsets.c
index 9b69c32ee560..ef7c8c43a380 100644
--- a/drivers/ide/ide-devsets.c
+++ b/drivers/ide/ide-devsets.c
@@ -166,7 +166,6 @@ int ide_devset_execute(ide_drive_t *drive, const struct ide_devset *setting,
 		return setting->set(drive, arg);
 
 	rq = blk_get_request(q, REQ_OP_DRV_IN, __GFP_RECLAIM);
-	scsi_req_init(rq);
 	ide_req(rq)->type = ATA_PRIV_MISC;
 	scsi_req(rq)->cmd_len = 5;
 	scsi_req(rq)->cmd[0] = REQ_DEVSET_EXEC;
diff --git a/drivers/ide/ide-disk.c b/drivers/ide/ide-disk.c
index 7c06237f3479..241983da5fc4 100644
--- a/drivers/ide/ide-disk.c
+++ b/drivers/ide/ide-disk.c
@@ -478,7 +478,6 @@ static int set_multcount(ide_drive_t *drive, int arg)
 		return -EBUSY;
 
 	rq = blk_get_request(drive->queue, REQ_OP_DRV_IN, __GFP_RECLAIM);
-	scsi_req_init(rq);
 	ide_req(rq)->type = ATA_PRIV_TASKFILE;
 
 	drive->mult_req = arg;
diff --git a/drivers/ide/ide-ioctls.c b/drivers/ide/ide-ioctls.c
index 8c0d17297a7a..3661abb16a5f 100644
--- a/drivers/ide/ide-ioctls.c
+++ b/drivers/ide/ide-ioctls.c
@@ -126,7 +126,6 @@ static int ide_cmd_ioctl(ide_drive_t *drive, unsigned long arg)
 		struct request *rq;
 
 		rq = blk_get_request(drive->queue, REQ_OP_DRV_IN, __GFP_RECLAIM);
-		scsi_req_init(rq);
 		ide_req(rq)->type = ATA_PRIV_TASKFILE;
 		blk_execute_rq(drive->queue, NULL, rq, 0);
 		err = scsi_req(rq)->result ? -EIO : 0;
@@ -224,7 +223,6 @@ static int generic_drive_reset(ide_drive_t *drive)
 	int ret = 0;
 
 	rq = blk_get_request(drive->queue, REQ_OP_DRV_IN, __GFP_RECLAIM);
-	scsi_req_init(rq);
 	ide_req(rq)->type = ATA_PRIV_MISC;
 	scsi_req(rq)->cmd_len = 1;
 	scsi_req(rq)->cmd[0] = REQ_DRIVE_RESET;
diff --git a/drivers/ide/ide-park.c b/drivers/ide/ide-park.c
index 94e3107f59b9..1f264d5d3f3f 100644
--- a/drivers/ide/ide-park.c
+++ b/drivers/ide/ide-park.c
@@ -32,7 +32,6 @@ static void issue_park_cmd(ide_drive_t *drive, unsigned long timeout)
 	spin_unlock_irq(&hwif->lock);
 
 	rq = blk_get_request(q, REQ_OP_DRV_IN, __GFP_RECLAIM);
-	scsi_req_init(rq);
 	scsi_req(rq)->cmd[0] = REQ_PARK_HEADS;
 	scsi_req(rq)->cmd_len = 1;
 	ide_req(rq)->type = ATA_PRIV_MISC;
@@ -48,7 +47,6 @@ static void issue_park_cmd(ide_drive_t *drive, unsigned long timeout)
 	 * timeout has expired, so power management will be reenabled.
 	 */
 	rq = blk_get_request(q, REQ_OP_DRV_IN, GFP_NOWAIT);
-	scsi_req_init(rq);
 	if (IS_ERR(rq))
 		goto out;
 
diff --git a/drivers/ide/ide-pm.c b/drivers/ide/ide-pm.c
index 0977fc1f40ce..cfe3c2d7db7f 100644
--- a/drivers/ide/ide-pm.c
+++ b/drivers/ide/ide-pm.c
@@ -19,7 +19,6 @@ int generic_ide_suspend(struct device *dev, pm_message_t mesg)
 
 	memset(&rqpm, 0, sizeof(rqpm));
 	rq = blk_get_request(drive->queue, REQ_OP_DRV_IN, __GFP_RECLAIM);
-	scsi_req_init(rq);
 	ide_req(rq)->type = ATA_PRIV_PM_SUSPEND;
 	rq->special = &rqpm;
 	rqpm.pm_step = IDE_PM_START_SUSPEND;
@@ -91,7 +90,6 @@ int generic_ide_resume(struct device *dev)
 
 	memset(&rqpm, 0, sizeof(rqpm));
 	rq = blk_get_request(drive->queue, REQ_OP_DRV_IN, __GFP_RECLAIM);
-	scsi_req_init(rq);
 	ide_req(rq)->type = ATA_PRIV_PM_RESUME;
 	rq->rq_flags |= RQF_PREEMPT;
 	rq->special = &rqpm;
diff --git a/drivers/ide/ide-probe.c b/drivers/ide/ide-probe.c
index a7cead2fd9ff..a539733da12c 100644
--- a/drivers/ide/ide-probe.c
+++ b/drivers/ide/ide-probe.c
@@ -741,12 +741,12 @@ static void ide_port_tune_devices(ide_hwif_t *hwif)
 	}
 }
 
-static int ide_init_rq(struct request_queue *q, struct request *rq, gfp_t gfp)
+static void ide_initialize_rq(struct request *rq)
 {
 	struct ide_request *req = blk_mq_rq_to_pdu(rq);
 
+	scsi_req_init(rq);
 	req->sreq.sense = req->sense;
-	return 0;
 }
 
 /*
@@ -771,7 +771,7 @@ static int ide_init_queue(ide_drive_t *drive)
 		return 1;
 
 	q->request_fn = do_ide_request;
-	q->init_rq_fn = ide_init_rq;
+	q->initialize_rq_fn = ide_initialize_rq;
 	q->cmd_size = sizeof(struct ide_request);
 	queue_flag_set_unlocked(QUEUE_FLAG_SCSI_PDU, q);
 	if (blk_init_allocated_queue(q) < 0) {
diff --git a/drivers/ide/ide-tape.c b/drivers/ide/ide-tape.c
index a0651f948b76..370fd39dce94 100644
--- a/drivers/ide/ide-tape.c
+++ b/drivers/ide/ide-tape.c
@@ -855,7 +855,6 @@ static int idetape_queue_rw_tail(ide_drive_t *drive, int cmd, int size)
 	BUG_ON(size < 0 || size % tape->blk_size);
 
 	rq = blk_get_request(drive->queue, REQ_OP_DRV_IN, __GFP_RECLAIM);
-	scsi_req_init(rq);
 	ide_req(rq)->type = ATA_PRIV_MISC;
 	scsi_req(rq)->cmd[13] = cmd;
 	rq->rq_disk = tape->disk;
diff --git a/drivers/ide/ide-taskfile.c b/drivers/ide/ide-taskfile.c
index d71199d23c9e..d915a8eba557 100644
--- a/drivers/ide/ide-taskfile.c
+++ b/drivers/ide/ide-taskfile.c
@@ -433,7 +433,6 @@ int ide_raw_taskfile(ide_drive_t *drive, struct ide_cmd *cmd, u8 *buf,
 	rq = blk_get_request(drive->queue,
 		(cmd->tf_flags & IDE_TFLAG_WRITE) ?
 			REQ_OP_DRV_OUT : REQ_OP_DRV_IN, __GFP_RECLAIM);
-	scsi_req_init(rq);
 	ide_req(rq)->type = ATA_PRIV_TASKFILE;
 
 	/*
diff --git a/drivers/scsi/osd/osd_initiator.c b/drivers/scsi/osd/osd_initiator.c
index 8a1b94816419..d974e7f1d2f1 100644
--- a/drivers/scsi/osd/osd_initiator.c
+++ b/drivers/scsi/osd/osd_initiator.c
@@ -1572,7 +1572,6 @@ static struct request *_make_request(struct request_queue *q, bool has_write,
 			flags);
 	if (IS_ERR(req))
 		return req;
-	scsi_req_init(req);
 
 	for_each_bio(bio) {
 		struct bio *bounce_bio = bio;
@@ -1617,7 +1616,6 @@ static int _init_blk_request(struct osd_request *or,
 				ret = PTR_ERR(req);
 				goto out;
 			}
-			scsi_req_init(req);
 			or->in.req = or->request->next_rq = req;
 		}
 	} else if (has_in)
diff --git a/drivers/scsi/osst.c b/drivers/scsi/osst.c
index 67cbed92f07d..22080148c6a8 100644
--- a/drivers/scsi/osst.c
+++ b/drivers/scsi/osst.c
@@ -373,7 +373,6 @@ static int osst_execute(struct osst_request *SRpnt, const unsigned char *cmd,
 		return DRIVER_ERROR << 24;
 
 	rq = scsi_req(req);
-	scsi_req_init(req);
 	req->rq_flags |= RQF_QUIET;
 
 	SRpnt->bio = NULL;
diff --git a/drivers/scsi/scsi_error.c b/drivers/scsi/scsi_error.c
index 97d5a0bb7061..07fba6208554 100644
--- a/drivers/scsi/scsi_error.c
+++ b/drivers/scsi/scsi_error.c
@@ -1903,7 +1903,6 @@ static void scsi_eh_lock_door(struct scsi_device *sdev)
 	if (IS_ERR(req))
 		return;
 	rq = scsi_req(req);
-	scsi_req_init(req);
 
 	rq->cmd[0] = ALLOW_MEDIUM_REMOVAL;
 	rq->cmd[1] = 0;
diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c
index 48dd47e6bdf4..79a05bc341f2 100644
--- a/drivers/scsi/scsi_lib.c
+++ b/drivers/scsi/scsi_lib.c
@@ -249,7 +249,6 @@ int scsi_execute(struct scsi_device *sdev, const unsigned char *cmd,
 	if (IS_ERR(req))
 		return ret;
 	rq = scsi_req(req);
-	scsi_req_init(req);
 
 	if (bufflen &&	blk_rq_map_kern(sdev->request_queue, req,
 					buffer, bufflen, __GFP_RECLAIM))
@@ -1133,6 +1132,13 @@ int scsi_init_io(struct scsi_cmnd *cmd)
 }
 EXPORT_SYMBOL(scsi_init_io);
 
+/* Called from inside blk_get_request() */
+static void scsi_initialize_rq(struct request *rq)
+{
+	scsi_req_init(rq);
+}
+
+/* Called after a request has been started. */
 void scsi_init_command(struct scsi_device *dev, struct scsi_cmnd *cmd)
 {
 	void *buf = cmd->sense_buffer;
@@ -2088,6 +2094,8 @@ void __scsi_init_queue(struct Scsi_Host *shost, struct request_queue *q)
 	 * blk_queue_update_dma_alignment() later.
 	 */
 	blk_queue_dma_alignment(q, 0x03);
+
+	q->initialize_rq_fn = scsi_initialize_rq;
 }
 EXPORT_SYMBOL_GPL(__scsi_init_queue);
 
diff --git a/drivers/scsi/scsi_transport_sas.c b/drivers/scsi/scsi_transport_sas.c
index f903004f3cad..f4d3bfeccf2c 100644
--- a/drivers/scsi/scsi_transport_sas.c
+++ b/drivers/scsi/scsi_transport_sas.c
@@ -213,6 +213,11 @@ static void sas_host_release(struct device *dev)
 		blk_cleanup_queue(q);
 }
 
+static void sas_initialize_rq(struct request *rq)
+{
+	scsi_req_init(rq);
+}
+
 static int sas_bsg_initialize(struct Scsi_Host *shost, struct sas_rphy *rphy)
 {
 	struct request_queue *q;
@@ -230,6 +235,7 @@ static int sas_bsg_initialize(struct Scsi_Host *shost, struct sas_rphy *rphy)
 	q = blk_alloc_queue(GFP_KERNEL);
 	if (!q)
 		return -ENOMEM;
+	q->initialize_rq_fn = sas_initialize_rq;
 	q->cmd_size = sizeof(struct scsi_request);
 
 	if (rphy) {
diff --git a/drivers/scsi/sg.c b/drivers/scsi/sg.c
index 0a38ba01b7b4..071a7fe27c11 100644
--- a/drivers/scsi/sg.c
+++ b/drivers/scsi/sg.c
@@ -1732,8 +1732,6 @@ sg_start_req(Sg_request *srp, unsigned char *cmd)
 	}
 	req = scsi_req(rq);
 
-	scsi_req_init(rq);
-
 	if (hp->cmd_len > BLK_MAX_CDB)
 		req->cmd = long_cmdp;
 	memcpy(req->cmd, cmd, hp->cmd_len);
diff --git a/drivers/scsi/st.c b/drivers/scsi/st.c
index 1ea34d6f5437..dc4d2b9e15a0 100644
--- a/drivers/scsi/st.c
+++ b/drivers/scsi/st.c
@@ -549,7 +549,6 @@ static int st_scsi_execute(struct st_request *SRpnt, const unsigned char *cmd,
 	if (IS_ERR(req))
 		return DRIVER_ERROR << 24;
 	rq = scsi_req(req);
-	scsi_req_init(req);
 	req->rq_flags |= RQF_QUIET;
 
 	mdata->null_mapped = 1;
diff --git a/drivers/target/target_core_pscsi.c b/drivers/target/target_core_pscsi.c
index a93d94e68ab5..4df4fd5783c3 100644
--- a/drivers/target/target_core_pscsi.c
+++ b/drivers/target/target_core_pscsi.c
@@ -992,8 +992,6 @@ pscsi_execute_cmd(struct se_cmd *cmd)
 		goto fail;
 	}
 
-	scsi_req_init(req);
-
 	if (sgl) {
 		ret = pscsi_map_sg(cmd, sgl, sgl_nents, req);
 		if (ret)
diff --git a/fs/nfsd/blocklayout.c b/fs/nfsd/blocklayout.c
index 38e14cf7e74a..4874426a20b3 100644
--- a/fs/nfsd/blocklayout.c
+++ b/fs/nfsd/blocklayout.c
@@ -232,7 +232,6 @@ static int nfsd4_scsi_identify_device(struct block_device *bdev,
 		goto out_free_buf;
 	}
 	req = scsi_req(rq);
-	scsi_req_init(rq);
 
 	error = blk_rq_map_kern(q, rq, buf, bufflen, GFP_KERNEL);
 	if (error)
-- 
2.12.2

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

* [PATCH 10/19] blk-mq: Change blk_mq_hw_ctx.queue_rq_srcu into an array
  2017-05-25 18:43 [PATCH 00/19] Block layer patches for kernel v4.13 Bart Van Assche
                   ` (8 preceding siblings ...)
  2017-05-25 18:43 ` [PATCH 09/19] block: Make scsi_req_init() calls implicit Bart Van Assche
@ 2017-05-25 18:43 ` Bart Van Assche
  2017-05-28  8:39   ` Christoph Hellwig
  2017-05-25 18:43 ` [PATCH 11/19] blk-mq: Reduce blk_mq_hw_ctx size Bart Van Assche
                   ` (8 subsequent siblings)
  18 siblings, 1 reply; 48+ messages in thread
From: Bart Van Assche @ 2017-05-25 18:43 UTC (permalink / raw)
  To: Jens Axboe
  Cc: linux-block, Christoph Hellwig, Bart Van Assche, Hannes Reinecke,
	Omar Sandoval, Ming Lei

This patch does not change any functionality but makes the next
patch easier to read.

Signed-off-by: Bart Van Assche <bart.vanassche@sandisk.com>
Cc: Christoph Hellwig <hch@lst.de>
Cc: Hannes Reinecke <hare@suse.com>
Cc: Omar Sandoval <osandov@fb.com>
Cc: Ming Lei <ming.lei@redhat.com>
---
 block/blk-mq.c         | 14 +++++++-------
 include/linux/blk-mq.h |  2 +-
 2 files changed, 8 insertions(+), 8 deletions(-)

diff --git a/block/blk-mq.c b/block/blk-mq.c
index a1620b36b95c..bc96e6007e53 100644
--- a/block/blk-mq.c
+++ b/block/blk-mq.c
@@ -172,7 +172,7 @@ void blk_mq_quiesce_queue(struct request_queue *q)
 
 	queue_for_each_hw_ctx(q, hctx, i) {
 		if (hctx->flags & BLK_MQ_F_BLOCKING)
-			synchronize_srcu(&hctx->queue_rq_srcu);
+			synchronize_srcu(hctx->queue_rq_srcu);
 		else
 			rcu = true;
 	}
@@ -1122,9 +1122,9 @@ static void __blk_mq_run_hw_queue(struct blk_mq_hw_ctx *hctx)
 	} else {
 		might_sleep();
 
-		srcu_idx = srcu_read_lock(&hctx->queue_rq_srcu);
+		srcu_idx = srcu_read_lock(hctx->queue_rq_srcu);
 		blk_mq_sched_dispatch_requests(hctx);
-		srcu_read_unlock(&hctx->queue_rq_srcu, srcu_idx);
+		srcu_read_unlock(hctx->queue_rq_srcu, srcu_idx);
 	}
 }
 
@@ -1537,9 +1537,9 @@ static void blk_mq_try_issue_directly(struct blk_mq_hw_ctx *hctx,
 
 		might_sleep();
 
-		srcu_idx = srcu_read_lock(&hctx->queue_rq_srcu);
+		srcu_idx = srcu_read_lock(hctx->queue_rq_srcu);
 		__blk_mq_try_issue_directly(rq, cookie, true);
-		srcu_read_unlock(&hctx->queue_rq_srcu, srcu_idx);
+		srcu_read_unlock(hctx->queue_rq_srcu, srcu_idx);
 	}
 }
 
@@ -1879,7 +1879,7 @@ static void blk_mq_exit_hctx(struct request_queue *q,
 		set->ops->exit_hctx(hctx, hctx_idx);
 
 	if (hctx->flags & BLK_MQ_F_BLOCKING)
-		cleanup_srcu_struct(&hctx->queue_rq_srcu);
+		cleanup_srcu_struct(hctx->queue_rq_srcu);
 
 	blk_mq_remove_cpuhp(hctx);
 	blk_free_flush_queue(hctx->fq);
@@ -1952,7 +1952,7 @@ static int blk_mq_init_hctx(struct request_queue *q,
 		goto free_fq;
 
 	if (hctx->flags & BLK_MQ_F_BLOCKING)
-		init_srcu_struct(&hctx->queue_rq_srcu);
+		init_srcu_struct(hctx->queue_rq_srcu);
 
 	blk_mq_debugfs_register_hctx(q, hctx);
 
diff --git a/include/linux/blk-mq.h b/include/linux/blk-mq.h
index c47aa248c640..c63d1d98404a 100644
--- a/include/linux/blk-mq.h
+++ b/include/linux/blk-mq.h
@@ -39,7 +39,7 @@ struct blk_mq_hw_ctx {
 	struct blk_mq_tags	*tags;
 	struct blk_mq_tags	*sched_tags;
 
-	struct srcu_struct	queue_rq_srcu;
+	struct srcu_struct	queue_rq_srcu[1];
 
 	unsigned long		queued;
 	unsigned long		run;
-- 
2.12.2

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

* [PATCH 11/19] blk-mq: Reduce blk_mq_hw_ctx size
  2017-05-25 18:43 [PATCH 00/19] Block layer patches for kernel v4.13 Bart Van Assche
                   ` (9 preceding siblings ...)
  2017-05-25 18:43 ` [PATCH 10/19] blk-mq: Change blk_mq_hw_ctx.queue_rq_srcu into an array Bart Van Assche
@ 2017-05-25 18:43 ` Bart Van Assche
  2017-05-28  8:40   ` Christoph Hellwig
  2017-05-25 18:43 ` [PATCH 12/19] blk-mq: Initialize a request before assigning a tag Bart Van Assche
                   ` (7 subsequent siblings)
  18 siblings, 1 reply; 48+ messages in thread
From: Bart Van Assche @ 2017-05-25 18:43 UTC (permalink / raw)
  To: Jens Axboe
  Cc: linux-block, Christoph Hellwig, Bart Van Assche, Hannes Reinecke,
	Omar Sandoval, Ming Lei

Since the srcu structure is rather large (184 bytes on an x86-64
system), only allocate it if needed.

Reported-by: Ming Lei <ming.lei@redhat.com>
Signed-off-by: Bart Van Assche <bart.vanassche@sandisk.com>
Cc: Christoph Hellwig <hch@lst.de>
Cc: Hannes Reinecke <hare@suse.com>
Cc: Omar Sandoval <osandov@fb.com>
Cc: Ming Lei <ming.lei@redhat.com>
---
 block/blk-mq.c         | 16 +++++++++++++++-
 include/linux/blk-mq.h |  5 +++--
 2 files changed, 18 insertions(+), 3 deletions(-)

diff --git a/block/blk-mq.c b/block/blk-mq.c
index bc96e6007e53..b8092786d42f 100644
--- a/block/blk-mq.c
+++ b/block/blk-mq.c
@@ -2227,6 +2227,20 @@ struct request_queue *blk_mq_init_queue(struct blk_mq_tag_set *set)
 }
 EXPORT_SYMBOL(blk_mq_init_queue);
 
+static int blk_mq_hw_ctx_size(struct request_queue *q)
+{
+	int hw_ctx_size = sizeof(struct blk_mq_hw_ctx);
+
+	BUILD_BUG_ON(ALIGN(offsetof(struct blk_mq_hw_ctx, queue_rq_srcu),
+			   __alignof__(struct blk_mq_hw_ctx)) !=
+		     sizeof(struct blk_mq_hw_ctx));
+
+	if (tag_set->flags & BLK_MQ_F_BLOCKING)
+		hw_ctx_size += sizeof(struct srcu_struct);
+
+	return hw_ctx_size;
+}
+
 static void blk_mq_realloc_hw_ctxs(struct blk_mq_tag_set *set,
 						struct request_queue *q)
 {
@@ -2241,7 +2255,7 @@ static void blk_mq_realloc_hw_ctxs(struct blk_mq_tag_set *set,
 			continue;
 
 		node = blk_mq_hw_queue_to_node(q->mq_map, i);
-		hctxs[i] = kzalloc_node(sizeof(struct blk_mq_hw_ctx),
+		hctxs[i] = kzalloc_node(blk_mq_hw_ctx_size(q),
 					GFP_KERNEL, node);
 		if (!hctxs[i])
 			break;
diff --git a/include/linux/blk-mq.h b/include/linux/blk-mq.h
index c63d1d98404a..c589b81be491 100644
--- a/include/linux/blk-mq.h
+++ b/include/linux/blk-mq.h
@@ -39,8 +39,6 @@ struct blk_mq_hw_ctx {
 	struct blk_mq_tags	*tags;
 	struct blk_mq_tags	*sched_tags;
 
-	struct srcu_struct	queue_rq_srcu[1];
-
 	unsigned long		queued;
 	unsigned long		run;
 #define BLK_MQ_MAX_DISPATCH_ORDER	7
@@ -62,6 +60,9 @@ struct blk_mq_hw_ctx {
 	struct dentry		*debugfs_dir;
 	struct dentry		*sched_debugfs_dir;
 #endif
+
+	/* Must be the last member - see also blk_mq_hw_ctx_size(). */
+	struct srcu_struct	queue_rq_srcu[0];
 };
 
 struct blk_mq_tag_set {
-- 
2.12.2

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

* [PATCH 12/19] blk-mq: Initialize a request before assigning a tag
  2017-05-25 18:43 [PATCH 00/19] Block layer patches for kernel v4.13 Bart Van Assche
                   ` (10 preceding siblings ...)
  2017-05-25 18:43 ` [PATCH 11/19] blk-mq: Reduce blk_mq_hw_ctx size Bart Van Assche
@ 2017-05-25 18:43 ` Bart Van Assche
  2017-05-28  8:42   ` Christoph Hellwig
  2017-05-25 18:43 ` [PATCH 13/19] blk-mq: Fix the comment above blk_mq_quiesce_queue() Bart Van Assche
                   ` (6 subsequent siblings)
  18 siblings, 1 reply; 48+ messages in thread
From: Bart Van Assche @ 2017-05-25 18:43 UTC (permalink / raw)
  To: Jens Axboe
  Cc: linux-block, Christoph Hellwig, Bart Van Assche, Hannes Reinecke,
	Omar Sandoval, Ming Lei

Initialization of blk-mq requests is a bit weird: blk_mq_rq_ctx_init()
is called after a tag has been assigned and .rq_flags is initialized
in __blk_mq_finish_request(). Call blk_mq_rq_ctx_init() before
modifying any struct request members. Initialize .rq_flags in
blk_mq_rq_ctx_init() instead of in __blk_mq_finish_request(). This
patch does not change the behavior of the block layer.

Signed-off-by: Bart Van Assche <bart.vanassche@sandisk.com>
Cc: Christoph Hellwig <hch@lst.de>
Cc: Hannes Reinecke <hare@suse.com>
Cc: Omar Sandoval <osandov@fb.com>
Cc: Ming Lei <ming.lei@redhat.com>
---
 block/blk-mq.c | 14 +++++++-------
 1 file changed, 7 insertions(+), 7 deletions(-)

diff --git a/block/blk-mq.c b/block/blk-mq.c
index b8092786d42f..1fcc20df1a4e 100644
--- a/block/blk-mq.c
+++ b/block/blk-mq.c
@@ -212,6 +212,7 @@ void blk_mq_rq_ctx_init(struct request_queue *q, struct blk_mq_ctx *ctx,
 	rq->q = q;
 	rq->mq_ctx = ctx;
 	rq->cmd_flags = op;
+	rq->rq_flags = 0;
 	if (blk_queue_io_stat(q))
 		rq->rq_flags |= RQF_IO_STAT;
 	/* do not touch atomic flags, it needs atomic ops against the timer */
@@ -231,7 +232,8 @@ void blk_mq_rq_ctx_init(struct request_queue *q, struct blk_mq_ctx *ctx,
 	rq->nr_integrity_segments = 0;
 #endif
 	rq->special = NULL;
-	/* tag was already set */
+	rq->tag = -1;
+	rq->internal_tag = -1;
 	rq->extra_len = 0;
 
 	INIT_LIST_HEAD(&rq->timeout_list);
@@ -260,20 +262,19 @@ struct request *__blk_mq_alloc_request(struct blk_mq_alloc_data *data,
 
 		rq = tags->static_rqs[tag];
 
+		blk_mq_rq_ctx_init(data->q, data->ctx, rq, op);
+
 		if (data->flags & BLK_MQ_REQ_INTERNAL) {
-			rq->tag = -1;
 			rq->internal_tag = tag;
 		} else {
 			if (blk_mq_tag_busy(data->hctx)) {
-				rq->rq_flags = RQF_MQ_INFLIGHT;
+				rq->rq_flags |= RQF_MQ_INFLIGHT;
 				atomic_inc(&data->hctx->nr_active);
 			}
 			rq->tag = tag;
-			rq->internal_tag = -1;
-			data->hctx->tags->rqs[rq->tag] = rq;
+			data->hctx->tags->rqs[tag] = rq;
 		}
 
-		blk_mq_rq_ctx_init(data->q, data->ctx, rq, op);
 		return rq;
 	}
 
@@ -364,7 +365,6 @@ void __blk_mq_finish_request(struct blk_mq_hw_ctx *hctx, struct blk_mq_ctx *ctx,
 		atomic_dec(&hctx->nr_active);
 
 	wbt_done(q->rq_wb, &rq->issue_stat);
-	rq->rq_flags = 0;
 
 	clear_bit(REQ_ATOM_STARTED, &rq->atomic_flags);
 	clear_bit(REQ_ATOM_POLL_SLEPT, &rq->atomic_flags);
-- 
2.12.2

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

* [PATCH 13/19] blk-mq: Fix the comment above blk_mq_quiesce_queue()
  2017-05-25 18:43 [PATCH 00/19] Block layer patches for kernel v4.13 Bart Van Assche
                   ` (11 preceding siblings ...)
  2017-05-25 18:43 ` [PATCH 12/19] blk-mq: Initialize a request before assigning a tag Bart Van Assche
@ 2017-05-25 18:43 ` Bart Van Assche
  2017-05-28  8:42   ` Christoph Hellwig
  2017-05-25 18:43 ` [PATCH 14/19] block: Add a comment above queue_lockdep_assert_held() Bart Van Assche
                   ` (5 subsequent siblings)
  18 siblings, 1 reply; 48+ messages in thread
From: Bart Van Assche @ 2017-05-25 18:43 UTC (permalink / raw)
  To: Jens Axboe
  Cc: linux-block, Christoph Hellwig, Bart Van Assche, Hannes Reinecke,
	Omar Sandoval, Ming Lei

The first version of blk_mq_quiesce_queue() that was posted on
the linux-block mailing list waited for ongoing .queue_rq()
calls but did not stop the request queue. The current version
however stops the request queue. Since the comment above that
function still reflects the old behavior, update that comment.

Signed-off-by: Bart Van Assche <bart.vanassche@sandisk.com>
Cc: Christoph Hellwig <hch@lst.de>
Cc: Hannes Reinecke <hare@suse.com>
Cc: Omar Sandoval <osandov@fb.com>
Cc: Ming Lei <ming.lei@redhat.com>
---
 block/blk-mq.c | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/block/blk-mq.c b/block/blk-mq.c
index 1fcc20df1a4e..b230038eba1d 100644
--- a/block/blk-mq.c
+++ b/block/blk-mq.c
@@ -155,12 +155,11 @@ void blk_mq_unfreeze_queue(struct request_queue *q)
 EXPORT_SYMBOL_GPL(blk_mq_unfreeze_queue);
 
 /**
- * blk_mq_quiesce_queue() - wait until all ongoing queue_rq calls have finished
+ * blk_mq_quiesce_queue() - stop a queue and wait for ongoing queue_rq calls
  * @q: request queue.
  *
  * Note: this function does not prevent that the struct request end_io()
- * callback function is invoked. Additionally, it is not prevented that
- * new queue_rq() calls occur unless the queue has been stopped first.
+ * callback function is invoked.
  */
 void blk_mq_quiesce_queue(struct request_queue *q)
 {
-- 
2.12.2

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

* [PATCH 14/19] block: Add a comment above queue_lockdep_assert_held()
  2017-05-25 18:43 [PATCH 00/19] Block layer patches for kernel v4.13 Bart Van Assche
                   ` (12 preceding siblings ...)
  2017-05-25 18:43 ` [PATCH 13/19] blk-mq: Fix the comment above blk_mq_quiesce_queue() Bart Van Assche
@ 2017-05-25 18:43 ` Bart Van Assche
  2017-05-28  8:42   ` Christoph Hellwig
  2017-05-25 18:43 ` [PATCH 15/19] block: Check locking assumptions at runtime Bart Van Assche
                   ` (4 subsequent siblings)
  18 siblings, 1 reply; 48+ messages in thread
From: Bart Van Assche @ 2017-05-25 18:43 UTC (permalink / raw)
  To: Jens Axboe
  Cc: linux-block, Christoph Hellwig, Bart Van Assche, Hannes Reinecke,
	Omar Sandoval, Ming Lei

Add a comment above the queue_lockdep_assert_held() macro that
explains the purpose of the q->queue_lock test.

Signed-off-by: Bart Van Assche <bart.vanassche@sandisk.com>
Cc: Christoph Hellwig <hch@lst.de>
Cc: Hannes Reinecke <hare@suse.com>
Cc: Omar Sandoval <osandov@fb.com>
Cc: Ming Lei <ming.lei@redhat.com>
---
 include/linux/blkdev.h | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h
index 8a223a0c95d5..293067a2726e 100644
--- a/include/linux/blkdev.h
+++ b/include/linux/blkdev.h
@@ -634,6 +634,13 @@ struct request_queue {
 				 (1 << QUEUE_FLAG_SAME_COMP)	|	\
 				 (1 << QUEUE_FLAG_POLL))
 
+/*
+ * @q->queue_lock is set while a queue is being initialized. Since we know
+ * that no other threads access the queue object before @q->queue_lock has
+ * been set, it is safe to manipulate queue flags without holding the
+ * queue_lock if @q->queue_lock == NULL. See also blk_alloc_queue_node() and
+ * blk_init_allocated_queue().
+ */
 static inline void queue_lockdep_assert_held(struct request_queue *q)
 {
 	if (q->queue_lock)
-- 
2.12.2

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

* [PATCH 15/19] block: Check locking assumptions at runtime
  2017-05-25 18:43 [PATCH 00/19] Block layer patches for kernel v4.13 Bart Van Assche
                   ` (13 preceding siblings ...)
  2017-05-25 18:43 ` [PATCH 14/19] block: Add a comment above queue_lockdep_assert_held() Bart Van Assche
@ 2017-05-25 18:43 ` Bart Van Assche
  2017-05-25 18:43 ` [PATCH 16/19] block: Document what queue type each function is intended for Bart Van Assche
                   ` (3 subsequent siblings)
  18 siblings, 0 replies; 48+ messages in thread
From: Bart Van Assche @ 2017-05-25 18:43 UTC (permalink / raw)
  To: Jens Axboe
  Cc: linux-block, Christoph Hellwig, Bart Van Assche, Hannes Reinecke,
	Omar Sandoval, Ming Lei

Instead of documenting the locking assumptions of most block layer
functions as a comment, use lockdep_assert_held() to verify locking
assumptions at runtime.

Signed-off-by: Bart Van Assche <bart.vanassche@sandisk.com>
Cc: Christoph Hellwig <hch@lst.de>
Cc: Hannes Reinecke <hare@suse.com>
Cc: Omar Sandoval <osandov@fb.com>
Cc: Ming Lei <ming.lei@redhat.com>
---
 block/blk-core.c    | 71 +++++++++++++++++++++++++++++++++++------------------
 block/blk-flush.c   |  8 +++---
 block/blk-merge.c   |  2 ++
 block/blk-tag.c     | 15 +++++------
 block/blk-timeout.c |  4 ++-
 5 files changed, 63 insertions(+), 37 deletions(-)

diff --git a/block/blk-core.c b/block/blk-core.c
index fa453ed95973..418236b68fb6 100644
--- a/block/blk-core.c
+++ b/block/blk-core.c
@@ -180,10 +180,12 @@ static void blk_delay_work(struct work_struct *work)
  * Description:
  *   Sometimes queueing needs to be postponed for a little while, to allow
  *   resources to come back. This function will make sure that queueing is
- *   restarted around the specified time. Queue lock must be held.
+ *   restarted around the specified time.
  */
 void blk_delay_queue(struct request_queue *q, unsigned long msecs)
 {
+	lockdep_assert_held(q->queue_lock);
+
 	if (likely(!blk_queue_dead(q)))
 		queue_delayed_work(kblockd_workqueue, &q->delay_work,
 				   msecs_to_jiffies(msecs));
@@ -201,6 +203,8 @@ EXPORT_SYMBOL(blk_delay_queue);
  **/
 void blk_start_queue_async(struct request_queue *q)
 {
+	lockdep_assert_held(q->queue_lock);
+
 	queue_flag_clear(QUEUE_FLAG_STOPPED, q);
 	blk_run_queue_async(q);
 }
@@ -213,10 +217,11 @@ EXPORT_SYMBOL(blk_start_queue_async);
  * Description:
  *   blk_start_queue() will clear the stop flag on the queue, and call
  *   the request_fn for the queue if it was in a stopped state when
- *   entered. Also see blk_stop_queue(). Queue lock must be held.
+ *   entered. Also see blk_stop_queue().
  **/
 void blk_start_queue(struct request_queue *q)
 {
+	lockdep_assert_held(q->queue_lock);
 	WARN_ON(!irqs_disabled());
 
 	queue_flag_clear(QUEUE_FLAG_STOPPED, q);
@@ -236,10 +241,12 @@ EXPORT_SYMBOL(blk_start_queue);
  *   or if it simply chooses not to queue more I/O at one point, it can
  *   call this function to prevent the request_fn from being called until
  *   the driver has signalled it's ready to go again. This happens by calling
- *   blk_start_queue() to restart queue operations. Queue lock must be held.
+ *   blk_start_queue() to restart queue operations.
  **/
 void blk_stop_queue(struct request_queue *q)
 {
+	lockdep_assert_held(q->queue_lock);
+
 	cancel_delayed_work(&q->delay_work);
 	queue_flag_set(QUEUE_FLAG_STOPPED, q);
 }
@@ -292,6 +299,8 @@ EXPORT_SYMBOL(blk_sync_queue);
  */
 inline void __blk_run_queue_uncond(struct request_queue *q)
 {
+	lockdep_assert_held(q->queue_lock);
+
 	if (unlikely(blk_queue_dead(q)))
 		return;
 
@@ -313,11 +322,12 @@ EXPORT_SYMBOL_GPL(__blk_run_queue_uncond);
  * @q:	The queue to run
  *
  * Description:
- *    See @blk_run_queue. This variant must be called with the queue lock
- *    held and interrupts disabled.
+ *    See @blk_run_queue.
  */
 void __blk_run_queue(struct request_queue *q)
 {
+	lockdep_assert_held(q->queue_lock);
+
 	if (unlikely(blk_queue_stopped(q)))
 		return;
 
@@ -331,10 +341,17 @@ EXPORT_SYMBOL(__blk_run_queue);
  *
  * Description:
  *    Tells kblockd to perform the equivalent of @blk_run_queue on behalf
- *    of us. The caller must hold the queue lock.
+ *    of us.
+ *
+ * Note:
+ *    Since it is not allowed to run q->delay_work after blk_cleanup_queue()
+ *    has canceled q->delay_work, callers must hold the queue lock to avoid
+ *    race conditions between blk_cleanup_queue() and blk_run_queue_async().
  */
 void blk_run_queue_async(struct request_queue *q)
 {
+	lockdep_assert_held(q->queue_lock);
+
 	if (likely(!blk_queue_stopped(q) && !blk_queue_dead(q)))
 		mod_delayed_work(kblockd_workqueue, &q->delay_work, 0);
 }
@@ -1080,6 +1097,8 @@ static struct request *__get_request(struct request_list *rl, unsigned int op,
 	int may_queue;
 	req_flags_t rq_flags = RQF_ALLOCED;
 
+	lockdep_assert_held(q->queue_lock);
+
 	if (unlikely(blk_queue_dying(q)))
 		return ERR_PTR(-ENODEV);
 
@@ -1253,6 +1272,8 @@ static struct request *get_request(struct request_queue *q, unsigned int op,
 	struct request_list *rl;
 	struct request *rq;
 
+	lockdep_assert_held(q->queue_lock);
+
 	rl = blk_get_rl(q, bio);	/* transferred to @rq on success */
 retry:
 	rq = __get_request(rl, op, bio, gfp_mask);
@@ -1331,6 +1352,8 @@ EXPORT_SYMBOL(blk_get_request);
  */
 void blk_requeue_request(struct request_queue *q, struct request *rq)
 {
+	lockdep_assert_held(q->queue_lock);
+
 	blk_delete_timer(rq);
 	blk_clear_rq_complete(rq);
 	trace_block_rq_requeue(q, rq);
@@ -1405,9 +1428,6 @@ static void blk_pm_put_request(struct request *rq)
 static inline void blk_pm_put_request(struct request *rq) {}
 #endif
 
-/*
- * queue lock must be held
- */
 void __blk_put_request(struct request_queue *q, struct request *req)
 {
 	req_flags_t rq_flags = req->rq_flags;
@@ -1420,6 +1440,8 @@ void __blk_put_request(struct request_queue *q, struct request *req)
 		return;
 	}
 
+	lockdep_assert_held(q->queue_lock);
+
 	blk_pm_put_request(req);
 
 	elv_completed_request(q, req);
@@ -2241,9 +2263,6 @@ EXPORT_SYMBOL_GPL(blk_insert_cloned_request);
  *
  * Return:
  *     The number of bytes to fail.
- *
- * Context:
- *     queue_lock must be held.
  */
 unsigned int blk_rq_err_bytes(const struct request *rq)
 {
@@ -2383,15 +2402,14 @@ void blk_account_io_start(struct request *rq, bool new_io)
  * Return:
  *     Pointer to the request at the top of @q if available.  Null
  *     otherwise.
- *
- * Context:
- *     queue_lock must be held.
  */
 struct request *blk_peek_request(struct request_queue *q)
 {
 	struct request *rq;
 	int ret;
 
+	lockdep_assert_held(q->queue_lock);
+
 	while ((rq = __elv_next_request(q)) != NULL) {
 
 		rq = blk_pm_peek_request(q, rq);
@@ -2508,12 +2526,11 @@ void blk_dequeue_request(struct request *rq)
  *
  *     Block internal functions which don't want to start timer should
  *     call blk_dequeue_request().
- *
- * Context:
- *     queue_lock must be held.
  */
 void blk_start_request(struct request *req)
 {
+	lockdep_assert_held(req->q->queue_lock);
+
 	blk_dequeue_request(req);
 
 	if (test_bit(QUEUE_FLAG_STATS, &req->q->queue_flags)) {
@@ -2538,14 +2555,13 @@ EXPORT_SYMBOL(blk_start_request);
  * Return:
  *     Pointer to the request at the top of @q if available.  Null
  *     otherwise.
- *
- * Context:
- *     queue_lock must be held.
  */
 struct request *blk_fetch_request(struct request_queue *q)
 {
 	struct request *rq;
 
+	lockdep_assert_held(q->queue_lock);
+
 	rq = blk_peek_request(q);
 	if (rq)
 		blk_start_request(rq);
@@ -2721,13 +2737,12 @@ void blk_unprep_request(struct request *req)
 }
 EXPORT_SYMBOL_GPL(blk_unprep_request);
 
-/*
- * queue lock must be held
- */
 void blk_finish_request(struct request *req, int error)
 {
 	struct request_queue *q = req->q;
 
+	lockdep_assert_held(req->q->queue_lock);
+	
 	if (req->rq_flags & RQF_STATS)
 		blk_stat_add(req);
 
@@ -2809,6 +2824,8 @@ static bool blk_end_bidi_request(struct request *rq, int error,
 static bool __blk_end_bidi_request(struct request *rq, int error,
 				   unsigned int nr_bytes, unsigned int bidi_bytes)
 {
+	lockdep_assert_held(rq->q->queue_lock);
+
 	if (blk_update_bidi_request(rq, error, nr_bytes, bidi_bytes))
 		return true;
 
@@ -2873,6 +2890,8 @@ EXPORT_SYMBOL(blk_end_request_all);
  **/
 bool __blk_end_request(struct request *rq, int error, unsigned int nr_bytes)
 {
+	lockdep_assert_held(rq->q->queue_lock);
+
 	return __blk_end_bidi_request(rq, error, nr_bytes, 0);
 }
 EXPORT_SYMBOL(__blk_end_request);
@@ -2890,6 +2909,8 @@ void __blk_end_request_all(struct request *rq, int error)
 	bool pending;
 	unsigned int bidi_bytes = 0;
 
+	lockdep_assert_held(rq->q->queue_lock);
+
 	if (unlikely(blk_bidi_rq(rq)))
 		bidi_bytes = blk_rq_bytes(rq->next_rq);
 
@@ -3154,6 +3175,8 @@ static void queue_unplugged(struct request_queue *q, unsigned int depth,
 			    bool from_schedule)
 	__releases(q->queue_lock)
 {
+	lockdep_assert_held(q->queue_lock);
+
 	trace_block_unplug(q, depth, !from_schedule);
 
 	if (from_schedule)
diff --git a/block/blk-flush.c b/block/blk-flush.c
index c4e0880b54bb..610c35bd9eeb 100644
--- a/block/blk-flush.c
+++ b/block/blk-flush.c
@@ -346,6 +346,8 @@ static void flush_data_end_io(struct request *rq, int error)
 	struct request_queue *q = rq->q;
 	struct blk_flush_queue *fq = blk_get_flush_queue(q, NULL);
 
+	lockdep_assert_held(q->queue_lock);
+
 	/*
 	 * Updating q->in_flight[] here for making this tag usable
 	 * early. Because in blk_queue_start_tag(),
@@ -411,9 +413,6 @@ static void mq_flush_data_end_io(struct request *rq, int error)
  * or __blk_mq_run_hw_queue() to dispatch request.
  * @rq is being submitted.  Analyze what needs to be done and put it on the
  * right queue.
- *
- * CONTEXT:
- * spin_lock_irq(q->queue_lock) in !mq case
  */
 void blk_insert_flush(struct request *rq)
 {
@@ -422,6 +421,9 @@ void blk_insert_flush(struct request *rq)
 	unsigned int policy = blk_flush_policy(fflags, rq);
 	struct blk_flush_queue *fq = blk_get_flush_queue(q, rq->mq_ctx);
 
+	if (!q->mq_ops)
+		lockdep_assert_held(q->queue_lock);
+
 	/*
 	 * @policy now records what operations need to be done.  Adjust
 	 * REQ_PREFLUSH and FUA for the driver.
diff --git a/block/blk-merge.c b/block/blk-merge.c
index 3990ae406341..61206eeeaaad 100644
--- a/block/blk-merge.c
+++ b/block/blk-merge.c
@@ -671,6 +671,8 @@ static void blk_account_io_merge(struct request *req)
 static struct request *attempt_merge(struct request_queue *q,
 				     struct request *req, struct request *next)
 {
+	lockdep_assert_held(q->queue_lock);
+
 	if (!rq_mergeable(req) || !rq_mergeable(next))
 		return NULL;
 
diff --git a/block/blk-tag.c b/block/blk-tag.c
index 07cc329fa4b0..2290f65b9d73 100644
--- a/block/blk-tag.c
+++ b/block/blk-tag.c
@@ -258,15 +258,14 @@ EXPORT_SYMBOL(blk_queue_resize_tags);
  *    all transfers have been done for a request. It's important to call
  *    this function before end_that_request_last(), as that will put the
  *    request back on the free list thus corrupting the internal tag list.
- *
- *  Notes:
- *   queue lock must be held.
  **/
 void blk_queue_end_tag(struct request_queue *q, struct request *rq)
 {
 	struct blk_queue_tag *bqt = q->queue_tags;
 	unsigned tag = rq->tag; /* negative tags invalid */
 
+	lockdep_assert_held(q->queue_lock);
+
 	BUG_ON(tag >= bqt->real_max_depth);
 
 	list_del_init(&rq->queuelist);
@@ -307,9 +306,6 @@ EXPORT_SYMBOL(blk_queue_end_tag);
  *    calling this function.  The request will also be removed from
  *    the request queue, so it's the drivers responsibility to readd
  *    it if it should need to be restarted for some reason.
- *
- *  Notes:
- *   queue lock must be held.
  **/
 int blk_queue_start_tag(struct request_queue *q, struct request *rq)
 {
@@ -317,6 +313,8 @@ int blk_queue_start_tag(struct request_queue *q, struct request *rq)
 	unsigned max_depth;
 	int tag;
 
+	lockdep_assert_held(q->queue_lock);
+
 	if (unlikely((rq->rq_flags & RQF_QUEUED))) {
 		printk(KERN_ERR
 		       "%s: request %p for device [%s] already tagged %d",
@@ -389,14 +387,13 @@ EXPORT_SYMBOL(blk_queue_start_tag);
  *   Hardware conditions may dictate a need to stop all pending requests.
  *   In this case, we will safely clear the block side of the tag queue and
  *   readd all requests to the request queue in the right order.
- *
- *  Notes:
- *   queue lock must be held.
  **/
 void blk_queue_invalidate_tags(struct request_queue *q)
 {
 	struct list_head *tmp, *n;
 
+	lockdep_assert_held(q->queue_lock);
+
 	list_for_each_safe(tmp, n, &q->tag_busy_list)
 		blk_requeue_request(q, list_entry_rq(tmp));
 }
diff --git a/block/blk-timeout.c b/block/blk-timeout.c
index cbff183f3d9f..17ec83bb0900 100644
--- a/block/blk-timeout.c
+++ b/block/blk-timeout.c
@@ -189,13 +189,15 @@ unsigned long blk_rq_timeout(unsigned long timeout)
  * Notes:
  *    Each request has its own timer, and as it is added to the queue, we
  *    set up the timer. When the request completes, we cancel the timer.
- *    Queue lock must be held for the non-mq case, mq case doesn't care.
  */
 void blk_add_timer(struct request *req)
 {
 	struct request_queue *q = req->q;
 	unsigned long expiry;
 
+	if (!q->mq_ops)
+		lockdep_assert_held(q->queue_lock);
+
 	/* blk-mq has its own handler, so we don't need ->rq_timed_out_fn */
 	if (!q->mq_ops && !q->rq_timed_out_fn)
 		return;
-- 
2.12.2

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

* [PATCH 16/19] block: Document what queue type each function is intended for
  2017-05-25 18:43 [PATCH 00/19] Block layer patches for kernel v4.13 Bart Van Assche
                   ` (14 preceding siblings ...)
  2017-05-25 18:43 ` [PATCH 15/19] block: Check locking assumptions at runtime Bart Van Assche
@ 2017-05-25 18:43 ` Bart Van Assche
  2017-05-25 18:43 ` [PATCH 17/19] blk-mq: Document locking assumptions Bart Van Assche
                   ` (2 subsequent siblings)
  18 siblings, 0 replies; 48+ messages in thread
From: Bart Van Assche @ 2017-05-25 18:43 UTC (permalink / raw)
  To: Jens Axboe
  Cc: linux-block, Christoph Hellwig, Bart Van Assche, Hannes Reinecke,
	Omar Sandoval, Ming Lei

Some functions in block/blk-core.c must only be used on blk-sq queues
while others are safe to use against any queue type. Document which
functions are intended for blk-sq queues and issue a warning if the
blk-sq API is misused.

Signed-off-by: Bart Van Assche <bart.vanassche@sandisk.com>
Cc: Christoph Hellwig <hch@lst.de>
Cc: Hannes Reinecke <hare@suse.com>
Cc: Omar Sandoval <osandov@fb.com>
Cc: Ming Lei <ming.lei@redhat.com>
---
 block/blk-core.c | 32 ++++++++++++++++++++++++++++++++
 1 file changed, 32 insertions(+)

diff --git a/block/blk-core.c b/block/blk-core.c
index 418236b68fb6..82e0dbfc593b 100644
--- a/block/blk-core.c
+++ b/block/blk-core.c
@@ -185,6 +185,7 @@ static void blk_delay_work(struct work_struct *work)
 void blk_delay_queue(struct request_queue *q, unsigned long msecs)
 {
 	lockdep_assert_held(q->queue_lock);
+	WARN_ON_ONCE(q->mq_ops);
 
 	if (likely(!blk_queue_dead(q)))
 		queue_delayed_work(kblockd_workqueue, &q->delay_work,
@@ -204,6 +205,7 @@ EXPORT_SYMBOL(blk_delay_queue);
 void blk_start_queue_async(struct request_queue *q)
 {
 	lockdep_assert_held(q->queue_lock);
+	WARN_ON_ONCE(q->mq_ops);
 
 	queue_flag_clear(QUEUE_FLAG_STOPPED, q);
 	blk_run_queue_async(q);
@@ -223,6 +225,7 @@ void blk_start_queue(struct request_queue *q)
 {
 	lockdep_assert_held(q->queue_lock);
 	WARN_ON(!irqs_disabled());
+	WARN_ON_ONCE(q->mq_ops);
 
 	queue_flag_clear(QUEUE_FLAG_STOPPED, q);
 	__blk_run_queue(q);
@@ -246,6 +249,7 @@ EXPORT_SYMBOL(blk_start_queue);
 void blk_stop_queue(struct request_queue *q)
 {
 	lockdep_assert_held(q->queue_lock);
+	WARN_ON_ONCE(q->mq_ops);
 
 	cancel_delayed_work(&q->delay_work);
 	queue_flag_set(QUEUE_FLAG_STOPPED, q);
@@ -300,6 +304,7 @@ EXPORT_SYMBOL(blk_sync_queue);
 inline void __blk_run_queue_uncond(struct request_queue *q)
 {
 	lockdep_assert_held(q->queue_lock);
+	WARN_ON_ONCE(q->mq_ops);
 
 	if (unlikely(blk_queue_dead(q)))
 		return;
@@ -327,6 +332,7 @@ EXPORT_SYMBOL_GPL(__blk_run_queue_uncond);
 void __blk_run_queue(struct request_queue *q)
 {
 	lockdep_assert_held(q->queue_lock);
+	WARN_ON_ONCE(q->mq_ops);
 
 	if (unlikely(blk_queue_stopped(q)))
 		return;
@@ -351,6 +357,7 @@ EXPORT_SYMBOL(__blk_run_queue);
 void blk_run_queue_async(struct request_queue *q)
 {
 	lockdep_assert_held(q->queue_lock);
+	WARN_ON_ONCE(q->mq_ops);
 
 	if (likely(!blk_queue_stopped(q) && !blk_queue_dead(q)))
 		mod_delayed_work(kblockd_workqueue, &q->delay_work, 0);
@@ -369,6 +376,8 @@ void blk_run_queue(struct request_queue *q)
 {
 	unsigned long flags;
 
+	WARN_ON_ONCE(q->mq_ops);
+
 	spin_lock_irqsave(q->queue_lock, flags);
 	__blk_run_queue(q);
 	spin_unlock_irqrestore(q->queue_lock, flags);
@@ -397,6 +406,7 @@ static void __blk_drain_queue(struct request_queue *q, bool drain_all)
 	int i;
 
 	lockdep_assert_held(q->queue_lock);
+	WARN_ON_ONCE(q->mq_ops);
 
 	while (true) {
 		bool drain = false;
@@ -475,6 +485,8 @@ static void __blk_drain_queue(struct request_queue *q, bool drain_all)
  */
 void blk_queue_bypass_start(struct request_queue *q)
 {
+	WARN_ON_ONCE(q->mq_ops);
+
 	spin_lock_irq(q->queue_lock);
 	q->bypass_depth++;
 	queue_flag_set(QUEUE_FLAG_BYPASS, q);
@@ -504,6 +516,8 @@ EXPORT_SYMBOL_GPL(blk_queue_bypass_start);
  */
 void blk_queue_bypass_end(struct request_queue *q)
 {
+	WARN_ON_ONCE(q->mq_ops);
+
 	spin_lock_irq(q->queue_lock);
 	if (!--q->bypass_depth)
 		queue_flag_clear(QUEUE_FLAG_BYPASS, q);
@@ -898,6 +912,8 @@ static blk_qc_t blk_queue_bio(struct request_queue *q, struct bio *bio);
 
 int blk_init_allocated_queue(struct request_queue *q)
 {
+	WARN_ON_ONCE(q->mq_ops);
+
 	q->fq = blk_alloc_flush_queue(q, NUMA_NO_NODE, q->cmd_size);
 	if (!q->fq)
 		return -ENOMEM;
@@ -1035,6 +1051,8 @@ int blk_update_nr_requests(struct request_queue *q, unsigned int nr)
 	struct request_list *rl;
 	int on_thresh, off_thresh;
 
+	WARN_ON_ONCE(q->mq_ops);
+
 	spin_lock_irq(q->queue_lock);
 	q->nr_requests = nr;
 	blk_queue_congestion_threshold(q);
@@ -1273,6 +1291,7 @@ static struct request *get_request(struct request_queue *q, unsigned int op,
 	struct request *rq;
 
 	lockdep_assert_held(q->queue_lock);
+	WARN_ON_ONCE(q->mq_ops);
 
 	rl = blk_get_rl(q, bio);	/* transferred to @rq on success */
 retry:
@@ -1312,6 +1331,8 @@ static struct request *blk_old_get_request(struct request_queue *q, int rw,
 {
 	struct request *rq;
 
+	WARN_ON_ONCE(q->mq_ops);
+
 	/* create ioc upfront */
 	create_io_context(gfp_mask, q->node);
 
@@ -1353,6 +1374,7 @@ EXPORT_SYMBOL(blk_get_request);
 void blk_requeue_request(struct request_queue *q, struct request *rq)
 {
 	lockdep_assert_held(q->queue_lock);
+	WARN_ON_ONCE(q->mq_ops);
 
 	blk_delete_timer(rq);
 	blk_clear_rq_complete(rq);
@@ -2409,6 +2431,7 @@ struct request *blk_peek_request(struct request_queue *q)
 	int ret;
 
 	lockdep_assert_held(q->queue_lock);
+	WARN_ON_ONCE(q->mq_ops);
 
 	while ((rq = __elv_next_request(q)) != NULL) {
 
@@ -2530,6 +2553,7 @@ void blk_dequeue_request(struct request *rq)
 void blk_start_request(struct request *req)
 {
 	lockdep_assert_held(req->q->queue_lock);
+	WARN_ON_ONCE(req->q->mq_ops);
 
 	blk_dequeue_request(req);
 
@@ -2561,6 +2585,7 @@ struct request *blk_fetch_request(struct request_queue *q)
 	struct request *rq;
 
 	lockdep_assert_held(q->queue_lock);
+	WARN_ON_ONCE(q->mq_ops);
 
 	rq = blk_peek_request(q);
 	if (rq)
@@ -2742,6 +2767,7 @@ void blk_finish_request(struct request *req, int error)
 	struct request_queue *q = req->q;
 
 	lockdep_assert_held(req->q->queue_lock);
+	WARN_ON_ONCE(q->mq_ops);
 	
 	if (req->rq_flags & RQF_STATS)
 		blk_stat_add(req);
@@ -2796,6 +2822,8 @@ static bool blk_end_bidi_request(struct request *rq, int error,
 	struct request_queue *q = rq->q;
 	unsigned long flags;
 
+	WARN_ON_ONCE(q->mq_ops);
+
 	if (blk_update_bidi_request(rq, error, nr_bytes, bidi_bytes))
 		return true;
 
@@ -2825,6 +2853,7 @@ static bool __blk_end_bidi_request(struct request *rq, int error,
 				   unsigned int nr_bytes, unsigned int bidi_bytes)
 {
 	lockdep_assert_held(rq->q->queue_lock);
+	WARN_ON_ONCE(rq->q->mq_ops);
 
 	if (blk_update_bidi_request(rq, error, nr_bytes, bidi_bytes))
 		return true;
@@ -2850,6 +2879,7 @@ static bool __blk_end_bidi_request(struct request *rq, int error,
  **/
 bool blk_end_request(struct request *rq, int error, unsigned int nr_bytes)
 {
+	WARN_ON_ONCE(rq->q->mq_ops);
 	return blk_end_bidi_request(rq, error, nr_bytes, 0);
 }
 EXPORT_SYMBOL(blk_end_request);
@@ -2891,6 +2921,7 @@ EXPORT_SYMBOL(blk_end_request_all);
 bool __blk_end_request(struct request *rq, int error, unsigned int nr_bytes)
 {
 	lockdep_assert_held(rq->q->queue_lock);
+	WARN_ON_ONCE(rq->q->mq_ops);
 
 	return __blk_end_bidi_request(rq, error, nr_bytes, 0);
 }
@@ -2910,6 +2941,7 @@ void __blk_end_request_all(struct request *rq, int error)
 	unsigned int bidi_bytes = 0;
 
 	lockdep_assert_held(rq->q->queue_lock);
+	WARN_ON_ONCE(rq->q->mq_ops);
 
 	if (unlikely(blk_bidi_rq(rq)))
 		bidi_bytes = blk_rq_bytes(rq->next_rq);
-- 
2.12.2

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

* [PATCH 17/19] blk-mq: Document locking assumptions
  2017-05-25 18:43 [PATCH 00/19] Block layer patches for kernel v4.13 Bart Van Assche
                   ` (15 preceding siblings ...)
  2017-05-25 18:43 ` [PATCH 16/19] block: Document what queue type each function is intended for Bart Van Assche
@ 2017-05-25 18:43 ` Bart Van Assche
  2017-05-25 18:43 ` [PATCH 18/19] block: Constify disk_type Bart Van Assche
  2017-05-25 18:43 ` [PATCH 19/19] block: Make request operation type argument declarations consistent Bart Van Assche
  18 siblings, 0 replies; 48+ messages in thread
From: Bart Van Assche @ 2017-05-25 18:43 UTC (permalink / raw)
  To: Jens Axboe
  Cc: linux-block, Christoph Hellwig, Bart Van Assche, Hannes Reinecke,
	Omar Sandoval, Ming Lei

Document the locking assumptions in functions that modify
blk_mq_ctx.rq_list to make it easier for humans to verify
this code.

Signed-off-by: Bart Van Assche <bart.vanassche@sandisk.com>
Cc: Christoph Hellwig <hch@lst.de>
Cc: Hannes Reinecke <hare@suse.com>
Cc: Omar Sandoval <osandov@fb.com>
Cc: Ming Lei <ming.lei@redhat.com>
---
 block/blk-mq.c | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/block/blk-mq.c b/block/blk-mq.c
index b230038eba1d..4b1b2c7b4344 100644
--- a/block/blk-mq.c
+++ b/block/blk-mq.c
@@ -785,6 +785,8 @@ static bool blk_mq_attempt_merge(struct request_queue *q,
 	struct request *rq;
 	int checked = 8;
 
+	lockdep_assert_held(&ctx->lock);
+
 	list_for_each_entry_reverse(rq, &ctx->rq_list, queuelist) {
 		bool merged = false;
 
@@ -1338,6 +1340,8 @@ static inline void __blk_mq_insert_req_list(struct blk_mq_hw_ctx *hctx,
 {
 	struct blk_mq_ctx *ctx = rq->mq_ctx;
 
+	lockdep_assert_held(&ctx->lock);
+
 	trace_block_rq_insert(hctx->queue, rq);
 
 	if (at_head)
@@ -1351,6 +1355,8 @@ void __blk_mq_insert_request(struct blk_mq_hw_ctx *hctx, struct request *rq,
 {
 	struct blk_mq_ctx *ctx = rq->mq_ctx;
 
+	lockdep_assert_held(&ctx->lock);
+
 	__blk_mq_insert_req_list(hctx, rq, at_head);
 	blk_mq_hctx_mark_pending(hctx, ctx);
 }
-- 
2.12.2

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

* [PATCH 18/19] block: Constify disk_type
  2017-05-25 18:43 [PATCH 00/19] Block layer patches for kernel v4.13 Bart Van Assche
                   ` (16 preceding siblings ...)
  2017-05-25 18:43 ` [PATCH 17/19] blk-mq: Document locking assumptions Bart Van Assche
@ 2017-05-25 18:43 ` Bart Van Assche
  2017-05-28  8:43   ` Christoph Hellwig
  2017-05-25 18:43 ` [PATCH 19/19] block: Make request operation type argument declarations consistent Bart Van Assche
  18 siblings, 1 reply; 48+ messages in thread
From: Bart Van Assche @ 2017-05-25 18:43 UTC (permalink / raw)
  To: Jens Axboe
  Cc: linux-block, Christoph Hellwig, Bart Van Assche, Hannes Reinecke,
	Omar Sandoval, Ming Lei

The variable 'disk_type' is never modified so constify it.

Signed-off-by: Bart Van Assche <bart.vanassche@sandisk.com>
Cc: Christoph Hellwig <hch@lst.de>
Cc: Hannes Reinecke <hare@suse.com>
Cc: Omar Sandoval <osandov@fb.com>
Cc: Ming Lei <ming.lei@redhat.com>
---
 block/genhd.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/block/genhd.c b/block/genhd.c
index d252d29fe837..7f520fa25d16 100644
--- a/block/genhd.c
+++ b/block/genhd.c
@@ -36,7 +36,7 @@ struct kobject *block_depr;
 static DEFINE_SPINLOCK(ext_devt_lock);
 static DEFINE_IDR(ext_devt_idr);
 
-static struct device_type disk_type;
+static const struct device_type disk_type;
 
 static void disk_check_events(struct disk_events *ev,
 			      unsigned int *clearing_ptr);
@@ -1183,7 +1183,7 @@ static char *block_devnode(struct device *dev, umode_t *mode,
 	return NULL;
 }
 
-static struct device_type disk_type = {
+static const struct device_type disk_type = {
 	.name		= "disk",
 	.groups		= disk_attr_groups,
 	.release	= disk_release,
-- 
2.12.2

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

* [PATCH 19/19] block: Make request operation type argument declarations consistent
  2017-05-25 18:43 [PATCH 00/19] Block layer patches for kernel v4.13 Bart Van Assche
                   ` (17 preceding siblings ...)
  2017-05-25 18:43 ` [PATCH 18/19] block: Constify disk_type Bart Van Assche
@ 2017-05-25 18:43 ` Bart Van Assche
  2017-05-28  8:43   ` Christoph Hellwig
  18 siblings, 1 reply; 48+ messages in thread
From: Bart Van Assche @ 2017-05-25 18:43 UTC (permalink / raw)
  To: Jens Axboe
  Cc: linux-block, Christoph Hellwig, Bart Van Assche, Hannes Reinecke,
	Omar Sandoval, Ming Lei

Instead of declaring the second argument of blk_*_get_request()
as int and passing it to functions that expect an unsigned int,
declare that second argument as unsigned int. Also because of
consistency, rename that second argument from 'rw' into 'op'.

Signed-off-by: Bart Van Assche <bart.vanassche@sandisk.com>
Cc: Christoph Hellwig <hch@lst.de>
Cc: Hannes Reinecke <hare@suse.com>
Cc: Omar Sandoval <osandov@fb.com>
Cc: Ming Lei <ming.lei@redhat.com>
---
 block/blk-core.c       | 13 +++++++------
 block/blk-mq.c         | 10 +++++-----
 include/linux/blk-mq.h |  6 +++---
 include/linux/blkdev.h |  3 ++-
 4 files changed, 17 insertions(+), 15 deletions(-)

diff --git a/block/blk-core.c b/block/blk-core.c
index 82e0dbfc593b..02952e85c580 100644
--- a/block/blk-core.c
+++ b/block/blk-core.c
@@ -1326,8 +1326,8 @@ static struct request *get_request(struct request_queue *q, unsigned int op,
 	goto retry;
 }
 
-static struct request *blk_old_get_request(struct request_queue *q, int rw,
-		gfp_t gfp_mask)
+static struct request *blk_old_get_request(struct request_queue *q,
+					   unsigned int op, gfp_t gfp_mask)
 {
 	struct request *rq;
 
@@ -1337,7 +1337,7 @@ static struct request *blk_old_get_request(struct request_queue *q, int rw,
 	create_io_context(gfp_mask, q->node);
 
 	spin_lock_irq(q->queue_lock);
-	rq = get_request(q, rw, NULL, gfp_mask);
+	rq = get_request(q, op, NULL, gfp_mask);
 	if (IS_ERR(rq)) {
 		spin_unlock_irq(q->queue_lock);
 		return rq;
@@ -1350,14 +1350,15 @@ static struct request *blk_old_get_request(struct request_queue *q, int rw,
 	return rq;
 }
 
-struct request *blk_get_request(struct request_queue *q, int rw, gfp_t gfp_mask)
+struct request *blk_get_request(struct request_queue *q, unsigned int op,
+				gfp_t gfp_mask)
 {
 	if (q->mq_ops)
-		return blk_mq_alloc_request(q, rw,
+		return blk_mq_alloc_request(q, op,
 			(gfp_mask & __GFP_DIRECT_RECLAIM) ?
 				0 : BLK_MQ_REQ_NOWAIT);
 	else
-		return blk_old_get_request(q, rw, gfp_mask);
+		return blk_old_get_request(q, op, gfp_mask);
 }
 EXPORT_SYMBOL(blk_get_request);
 
diff --git a/block/blk-mq.c b/block/blk-mq.c
index 4b1b2c7b4344..aa2e9eb643a9 100644
--- a/block/blk-mq.c
+++ b/block/blk-mq.c
@@ -281,7 +281,7 @@ struct request *__blk_mq_alloc_request(struct blk_mq_alloc_data *data,
 }
 EXPORT_SYMBOL_GPL(__blk_mq_alloc_request);
 
-struct request *blk_mq_alloc_request(struct request_queue *q, int rw,
+struct request *blk_mq_alloc_request(struct request_queue *q, unsigned int op,
 		unsigned int flags)
 {
 	struct blk_mq_alloc_data alloc_data = { .flags = flags };
@@ -292,7 +292,7 @@ struct request *blk_mq_alloc_request(struct request_queue *q, int rw,
 	if (ret)
 		return ERR_PTR(ret);
 
-	rq = blk_mq_sched_get_request(q, NULL, rw, &alloc_data);
+	rq = blk_mq_sched_get_request(q, NULL, op, &alloc_data);
 
 	blk_mq_put_ctx(alloc_data.ctx);
 	blk_queue_exit(q);
@@ -307,8 +307,8 @@ struct request *blk_mq_alloc_request(struct request_queue *q, int rw,
 }
 EXPORT_SYMBOL(blk_mq_alloc_request);
 
-struct request *blk_mq_alloc_request_hctx(struct request_queue *q, int rw,
-		unsigned int flags, unsigned int hctx_idx)
+struct request *blk_mq_alloc_request_hctx(struct request_queue *q,
+		unsigned int op, unsigned int flags, unsigned int hctx_idx)
 {
 	struct blk_mq_alloc_data alloc_data = { .flags = flags };
 	struct request *rq;
@@ -343,7 +343,7 @@ struct request *blk_mq_alloc_request_hctx(struct request_queue *q, int rw,
 	cpu = cpumask_first(alloc_data.hctx->cpumask);
 	alloc_data.ctx = __blk_mq_get_ctx(q, cpu);
 
-	rq = blk_mq_sched_get_request(q, NULL, rw, &alloc_data);
+	rq = blk_mq_sched_get_request(q, NULL, op, &alloc_data);
 
 	blk_queue_exit(q);
 
diff --git a/include/linux/blk-mq.h b/include/linux/blk-mq.h
index c589b81be491..da892b9fd4d7 100644
--- a/include/linux/blk-mq.h
+++ b/include/linux/blk-mq.h
@@ -205,10 +205,10 @@ enum {
 	BLK_MQ_REQ_INTERNAL	= (1 << 2), /* allocate internal/sched tag */
 };
 
-struct request *blk_mq_alloc_request(struct request_queue *q, int rw,
+struct request *blk_mq_alloc_request(struct request_queue *q, unsigned int op,
 		unsigned int flags);
-struct request *blk_mq_alloc_request_hctx(struct request_queue *q, int op,
-		unsigned int flags, unsigned int hctx_idx);
+struct request *blk_mq_alloc_request_hctx(struct request_queue *q,
+		unsigned int op, unsigned int flags, unsigned int hctx_idx);
 struct request *blk_mq_tag_to_rq(struct blk_mq_tags *tags, unsigned int tag);
 
 enum {
diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h
index 293067a2726e..85230b5259da 100644
--- a/include/linux/blkdev.h
+++ b/include/linux/blkdev.h
@@ -942,7 +942,8 @@ extern void blk_rq_init(struct request_queue *q, struct request *rq);
 extern void blk_init_request_from_bio(struct request *req, struct bio *bio);
 extern void blk_put_request(struct request *);
 extern void __blk_put_request(struct request_queue *, struct request *);
-extern struct request *blk_get_request(struct request_queue *, int, gfp_t);
+extern struct request *blk_get_request(struct request_queue *, unsigned int op,
+				       gfp_t gfp_mask);
 extern void blk_requeue_request(struct request_queue *, struct request *);
 extern int blk_lld_busy(struct request_queue *q);
 extern int blk_rq_prep_clone(struct request *rq, struct request *rq_src,
-- 
2.12.2

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

* Re: [PATCH 06/19] nfsd: Check private request size before submitting a SCSI request
  2017-05-25 18:43 ` [PATCH 06/19] nfsd: Check private request size before submitting a SCSI request Bart Van Assche
@ 2017-05-25 18:48   ` J . Bruce Fields
  2017-05-25 20:19     ` Bart Van Assche
  2017-05-26  6:10   ` Christoph Hellwig
  1 sibling, 1 reply; 48+ messages in thread
From: J . Bruce Fields @ 2017-05-25 18:48 UTC (permalink / raw)
  To: Bart Van Assche
  Cc: Jens Axboe, linux-block, Christoph Hellwig, Jeff Layton,
	Jens Axboe, Omar Sandoval, linux-nfs

On Thu, May 25, 2017 at 11:43:14AM -0700, Bart Van Assche wrote:
> Since using scsi_req() is only allowed against request queues for
> which struct scsi_request is the first member of their private
> request data, refuse to submit SCSI commands against a queue for
> which this is not the case.

Is it possible we could catch this earlier and avoid giving out the
layout in the first place?

--b.

> 
> References: commit 82ed4db499b8 ("block: split scsi_request out of struct request")
> Signed-off-by: Bart Van Assche <bart.vanassche@sandisk.com>
> Reviewed-by: Hannes Reinecke <hare@suse.com>
> Cc: J. Bruce Fields <bfields@fieldses.org>
> Cc: Jeff Layton <jlayton@poochiereds.net>
> Cc: Jens Axboe <axboe@fb.com>
> Cc: Christoph Hellwig <hch@lst.de>
> Cc: Omar Sandoval <osandov@fb.com>
> Cc: linux-nfs@vger.kernel.org
> Cc: linux-block@vger.kernel.org
> ---
>  fs/nfsd/blocklayout.c | 3 +++
>  1 file changed, 3 insertions(+)
> 
> diff --git a/fs/nfsd/blocklayout.c b/fs/nfsd/blocklayout.c
> index fb5213afc854..38e14cf7e74a 100644
> --- a/fs/nfsd/blocklayout.c
> +++ b/fs/nfsd/blocklayout.c
> @@ -219,6 +219,9 @@ static int nfsd4_scsi_identify_device(struct block_device *bdev,
>  	u8 *buf, *d, type, assoc;
>  	int error;
>  
> +	if (WARN_ON_ONCE(!blk_queue_scsi_pdu(q)))
> +		return -EINVAL;
> +
>  	buf = kzalloc(bufflen, GFP_KERNEL);
>  	if (!buf)
>  		return -ENOMEM;
> -- 
> 2.12.2

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

* Re: [PATCH 06/19] nfsd: Check private request size before submitting a SCSI request
  2017-05-25 18:48   ` J . Bruce Fields
@ 2017-05-25 20:19     ` Bart Van Assche
  2017-05-26  6:10       ` hch
  0 siblings, 1 reply; 48+ messages in thread
From: Bart Van Assche @ 2017-05-25 20:19 UTC (permalink / raw)
  To: bfields; +Cc: hch, jlayton, linux-block, osandov, axboe, axboe, linux-nfs

On Thu, 2017-05-25 at 14:48 -0400, J . Bruce Fields wrote:
> On Thu, May 25, 2017 at 11:43:14AM -0700, Bart Van Assche wrote:
> > Since using scsi_req() is only allowed against request queues for
> > which struct scsi_request is the first member of their private
> > request data, refuse to submit SCSI commands against a queue for
> > which this is not the case.
>=20
> Is it possible we could catch this earlier and avoid giving out the
> layout in the first place?

Hello Christoph,

According to what I see in commit 8650b8a05850 you are the author of this
code? Can the blk_queue_scsi_pdu(q) test fail in nfsd4_scsi_identify_device=
()?
If so, can nfsd4_layout_verify() be modified in such a way that it prevents
that nfsd4_scsi_proc_getdeviceinfo() is ever called for a non-SCSI queue?
Can you recommend an approach?

Thanks,

Bart.=

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

* Re: [PATCH 01/19] block: Avoid that blk_exit_rl() triggers a use-after-free
  2017-05-25 18:43 ` [PATCH 01/19] block: Avoid that blk_exit_rl() triggers a use-after-free Bart Van Assche
@ 2017-05-26  6:01   ` Christoph Hellwig
  0 siblings, 0 replies; 48+ messages in thread
From: Christoph Hellwig @ 2017-05-26  6:01 UTC (permalink / raw)
  To: Bart Van Assche
  Cc: Jens Axboe, linux-block, Christoph Hellwig, Jens Axboe, Jan Kara, stable

Looks fine,

Reviewed-by: Christoph Hellwig <hch@lst.de>

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

* Re: [PATCH 02/19] block: Introduce queue flag QUEUE_FLAG_SCSI_PDU
  2017-05-25 18:43 ` [PATCH 02/19] block: Introduce queue flag QUEUE_FLAG_SCSI_PDU Bart Van Assche
@ 2017-05-26  6:02   ` Christoph Hellwig
  0 siblings, 0 replies; 48+ messages in thread
From: Christoph Hellwig @ 2017-05-26  6:02 UTC (permalink / raw)
  To: Bart Van Assche
  Cc: Jens Axboe, linux-block, Christoph Hellwig, Jens Axboe, Omar Sandoval

On Thu, May 25, 2017 at 11:43:10AM -0700, Bart Van Assche wrote:
> >From the context where a SCSI command is submitted it is not always
> possible to figure out whether or not the queue the command is
> submitted to has struct scsi_request as the first member of its
> private data. Hence introduce the flag QUEUE_FLAG_SCSI_PDU.

I would call it QUEUE_FLAG_SCSI_PASSTHROUGH, but except for that:

Reviewed-by: Christoph Hellwig <hch@lst.de>

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

* Re: [PATCH 03/19] bsg: Check queue type before attaching to a queue
  2017-05-25 18:43 ` [PATCH 03/19] bsg: Check queue type before attaching to a queue Bart Van Assche
@ 2017-05-26  6:02   ` Christoph Hellwig
  0 siblings, 0 replies; 48+ messages in thread
From: Christoph Hellwig @ 2017-05-26  6:02 UTC (permalink / raw)
  To: Bart Van Assche; +Cc: Jens Axboe, linux-block, Christoph Hellwig, Omar Sandoval

Looks fine,

Reviewed-by: Christoph Hellwig <hch@lst.de>

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

* Re: [PATCH 04/19] pktcdvd: Check queue type before attaching to a queue
  2017-05-25 18:43 ` [PATCH 04/19] pktcdvd: " Bart Van Assche
@ 2017-05-26  6:03   ` Christoph Hellwig
  0 siblings, 0 replies; 48+ messages in thread
From: Christoph Hellwig @ 2017-05-26  6:03 UTC (permalink / raw)
  To: Bart Van Assche
  Cc: Jens Axboe, linux-block, Christoph Hellwig, Jens Axboe, Omar Sandoval

Looks good,

Reviewed-by: Christoph Hellwig <hch@lst.de>

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

* Re: [PATCH 05/19] cdrom: Check private request size before attaching to a queue
  2017-05-25 18:43 ` [PATCH 05/19] cdrom: Check private request size " Bart Van Assche
@ 2017-05-26  6:08   ` Christoph Hellwig
  2017-05-26 15:50     ` Bart Van Assche
  0 siblings, 1 reply; 48+ messages in thread
From: Christoph Hellwig @ 2017-05-26  6:08 UTC (permalink / raw)
  To: Bart Van Assche; +Cc: Jens Axboe, linux-block, Christoph Hellwig, Omar Sandoval

On Thu, May 25, 2017 at 11:43:13AM -0700, Bart Van Assche wrote:
> Since the cdrom driver only supports request queues for which
> struct scsi_request is the first member of their private request
> data, refuse to register block layer queues for which this is
> not the case.

Hmm.  I think we have a deeper issue there.  The cdrom layer usually
sends packets commands through the cdrom ops ->generic_packet
method, but one function (cdrom_read_cdda_bpc) seems to directly
send a scsi passthrough request.  It is only used if the cdda_method
is not CDDA_OLD, which is set if the cdrom_device_info structure
does not have a gendisk pointer hanging off it.  It seems like
the legacy cdrom drivers fall into that category and would be
broken by this change.

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

* Re: [PATCH 06/19] nfsd: Check private request size before submitting a SCSI request
  2017-05-25 20:19     ` Bart Van Assche
@ 2017-05-26  6:10       ` hch
  2017-05-26 15:47         ` bfields
  0 siblings, 1 reply; 48+ messages in thread
From: hch @ 2017-05-26  6:10 UTC (permalink / raw)
  To: Bart Van Assche
  Cc: bfields, hch, jlayton, linux-block, osandov, axboe, axboe, linux-nfs

On Thu, May 25, 2017 at 08:19:47PM +0000, Bart Van Assche wrote:
> On Thu, 2017-05-25 at 14:48 -0400, J . Bruce Fields wrote:
> > On Thu, May 25, 2017 at 11:43:14AM -0700, Bart Van Assche wrote:
> > > Since using scsi_req() is only allowed against request queues for
> > > which struct scsi_request is the first member of their private
> > > request data, refuse to submit SCSI commands against a queue for
> > > which this is not the case.
> > 
> > Is it possible we could catch this earlier and avoid giving out the
> > layout in the first place?
> 
> Hello Christoph,
> 
> According to what I see in commit 8650b8a05850 you are the author of this
> code? Can the blk_queue_scsi_pdu(q) test fail in nfsd4_scsi_identify_device()?

If the user explicitly asked for a scsi layout export of a non-scsi
device it can.

> If so, can nfsd4_layout_verify() be modified in such a way that it prevents
> that nfsd4_scsi_proc_getdeviceinfo() is ever called for a non-SCSI queue?
> Can you recommend an approach?

Not easily.  The only thing we could do is an export time check, that
would refuse the scsi layout export if the device is not capable.

I can look into that, but it will take some time so for now I think we
should go ahead with your series.

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

* Re: [PATCH 06/19] nfsd: Check private request size before submitting a SCSI request
  2017-05-25 18:43 ` [PATCH 06/19] nfsd: Check private request size before submitting a SCSI request Bart Van Assche
  2017-05-25 18:48   ` J . Bruce Fields
@ 2017-05-26  6:10   ` Christoph Hellwig
  1 sibling, 0 replies; 48+ messages in thread
From: Christoph Hellwig @ 2017-05-26  6:10 UTC (permalink / raw)
  To: Bart Van Assche
  Cc: Jens Axboe, linux-block, Christoph Hellwig, J . Bruce Fields,
	Jeff Layton, Jens Axboe, Omar Sandoval, linux-nfs

Looks fine,

Reviewed-by: Christoph Hellwig <hch@lst.de>

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

* Re: [PATCH 08/19] block: Introduce request_queue.initialize_rq_fn()
  2017-05-25 18:43 ` [PATCH 08/19] block: Introduce request_queue.initialize_rq_fn() Bart Van Assche
@ 2017-05-26  6:34   ` Christoph Hellwig
  2017-05-26 23:56     ` Bart Van Assche
  2017-05-28  8:37   ` Christoph Hellwig
  1 sibling, 1 reply; 48+ messages in thread
From: Christoph Hellwig @ 2017-05-26  6:34 UTC (permalink / raw)
  To: Bart Van Assche
  Cc: Jens Axboe, linux-block, Christoph Hellwig, Jens Axboe, Omar Sandoval

On Thu, May 25, 2017 at 11:43:16AM -0700, Bart Van Assche wrote:
> Several block drivers need to initialize the driver-private data
> after having called blk_get_request() and before .prep_rq_fn() is
> called, e.g. when submitting a REQ_OP_SCSI_* request. Avoid that
> that initialization code has to be repeated after every
> blk_get_request() call by adding a new callback function to struct
> request_queue.

I still think we should do this at the end of blk_mq_alloc_request /
blk_old_get_request to exactly keep the old semantics and keep the
calls out of the hot path.

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

* Re: [PATCH 06/19] nfsd: Check private request size before submitting a SCSI request
  2017-05-26  6:10       ` hch
@ 2017-05-26 15:47         ` bfields
  0 siblings, 0 replies; 48+ messages in thread
From: bfields @ 2017-05-26 15:47 UTC (permalink / raw)
  To: hch
  Cc: Bart Van Assche, jlayton, linux-block, osandov, axboe, axboe, linux-nfs

On Fri, May 26, 2017 at 08:10:03AM +0200, hch@lst.de wrote:
> On Thu, May 25, 2017 at 08:19:47PM +0000, Bart Van Assche wrote:
> > On Thu, 2017-05-25 at 14:48 -0400, J . Bruce Fields wrote:
> > > On Thu, May 25, 2017 at 11:43:14AM -0700, Bart Van Assche wrote:
> > > > Since using scsi_req() is only allowed against request queues for
> > > > which struct scsi_request is the first member of their private
> > > > request data, refuse to submit SCSI commands against a queue for
> > > > which this is not the case.
> > > 
> > > Is it possible we could catch this earlier and avoid giving out the
> > > layout in the first place?
> > 
> > Hello Christoph,
> > 
> > According to what I see in commit 8650b8a05850 you are the author of this
> > code? Can the blk_queue_scsi_pdu(q) test fail in nfsd4_scsi_identify_device()?
> 
> If the user explicitly asked for a scsi layout export of a non-scsi
> device it can.
> 
> > If so, can nfsd4_layout_verify() be modified in such a way that it prevents
> > that nfsd4_scsi_proc_getdeviceinfo() is ever called for a non-SCSI queue?
> > Can you recommend an approach?
> 
> Not easily.  The only thing we could do is an export time check, that
> would refuse the scsi layout export if the device is not capable.
> 
> I can look into that, but it will take some time so for now I think we
> should go ahead with your series.

Fine by me.--b.

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

* Re: [PATCH 05/19] cdrom: Check private request size before attaching to a queue
  2017-05-26  6:08   ` Christoph Hellwig
@ 2017-05-26 15:50     ` Bart Van Assche
  2017-05-28  8:32       ` hch
  0 siblings, 1 reply; 48+ messages in thread
From: Bart Van Assche @ 2017-05-26 15:50 UTC (permalink / raw)
  To: hch; +Cc: linux-block, osandov, axboe

On Fri, 2017-05-26 at 08:08 +0200, Christoph Hellwig wrote:
> On Thu, May 25, 2017 at 11:43:13AM -0700, Bart Van Assche wrote:
> > Since the cdrom driver only supports request queues for which
> > struct scsi_request is the first member of their private request
> > data, refuse to register block layer queues for which this is
> > not the case.
>=20
> Hmm.  I think we have a deeper issue there.  The cdrom layer usually
> sends packets commands through the cdrom ops ->generic_packet
> method, but one function (cdrom_read_cdda_bpc) seems to directly
> send a scsi passthrough request.  It is only used if the cdda_method
> is not CDDA_OLD, which is set if the cdrom_device_info structure
> does not have a gendisk pointer hanging off it.  It seems like
> the legacy cdrom drivers fall into that category and would be
> broken by this change.

Hello Christoph,

How about moving the check into cdrom_read_cdda_bpc()? As far as I can see
that function is only called if a CDROMREADAUDIO ioctl is submitted. Althou=
gh
Documentation/cdrom/cdrom-standard.tex mentions that that ioctl is unsuppor=
ted
applications like cdparanoia use it.

Bart.=

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

* Re: [PATCH 08/19] block: Introduce request_queue.initialize_rq_fn()
  2017-05-26  6:34   ` Christoph Hellwig
@ 2017-05-26 23:56     ` Bart Van Assche
  2017-05-28  8:34       ` hch
  0 siblings, 1 reply; 48+ messages in thread
From: Bart Van Assche @ 2017-05-26 23:56 UTC (permalink / raw)
  To: hch; +Cc: linux-block, osandov, axboe, axboe

On Fri, 2017-05-26 at 08:34 +0200, Christoph Hellwig wrote:
> On Thu, May 25, 2017 at 11:43:16AM -0700, Bart Van Assche wrote:
> > Several block drivers need to initialize the driver-private data
> > after having called blk_get_request() and before .prep_rq_fn() is
> > called, e.g. when submitting a REQ_OP_SCSI_* request. Avoid that
> > that initialization code has to be repeated after every
> > blk_get_request() call by adding a new callback function to struct
> > request_queue.
>=20
> I still think we should do this at the end of blk_mq_alloc_request /
> blk_old_get_request to exactly keep the old semantics and keep the
> calls out of the hot path.

Hello Christoph,

I have tried to move that call into blk_mq_alloc_request() but that
resulted in a kernel oops during boot due to scsi_add_cmd_to_list()
dereferencing scsi_cmnd.device and due to that pointer being invalid.
I think that pointer was invalid because moving the initialize_rq_fn()
call into blk_mq_alloc_request() caused request initialization to be
skipped for the following code path:
submit_bio()
-> generic_make_request()
  -> .make_request_fn =3D=3D blk_mq_make_request()
 =A0  -> blk_mq_sched_get_request()
      -> __blk_mq_alloc_request()
 =A0 =A0 =A0  -> blk_mq_rq_ctx_init()

This is why I would like to keep the .initialize_rq_fn() call in
blk_mq_rq_ctx_init().

Bart.=

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

* Re: [PATCH 05/19] cdrom: Check private request size before attaching to a queue
  2017-05-26 15:50     ` Bart Van Assche
@ 2017-05-28  8:32       ` hch
  0 siblings, 0 replies; 48+ messages in thread
From: hch @ 2017-05-28  8:32 UTC (permalink / raw)
  To: Bart Van Assche; +Cc: hch, linux-block, osandov, axboe

On Fri, May 26, 2017 at 03:50:42PM +0000, Bart Van Assche wrote:
> On Fri, 2017-05-26 at 08:08 +0200, Christoph Hellwig wrote:
> > On Thu, May 25, 2017 at 11:43:13AM -0700, Bart Van Assche wrote:
> > > Since the cdrom driver only supports request queues for which
> > > struct scsi_request is the first member of their private request
> > > data, refuse to register block layer queues for which this is
> > > not the case.
> > 
> > Hmm.  I think we have a deeper issue there.  The cdrom layer usually
> > sends packets commands through the cdrom ops ->generic_packet
> > method, but one function (cdrom_read_cdda_bpc) seems to directly
> > send a scsi passthrough request.  It is only used if the cdda_method
> > is not CDDA_OLD, which is set if the cdrom_device_info structure
> > does not have a gendisk pointer hanging off it.  It seems like
> > the legacy cdrom drivers fall into that category and would be
> > broken by this change.
> 
> Hello Christoph,
> 
> How about moving the check into cdrom_read_cdda_bpc()? As far as I can see
> that function is only called if a CDROMREADAUDIO ioctl is submitted. Although
> Documentation/cdrom/cdrom-standard.tex mentions that that ioctl is unsupported
> applications like cdparanoia use it.

I guess that's fine for now.  In the long run we can probably replace
the current users of generic_packet method with direct scsi passthrough
requests, but that can be left for later.

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

* Re: [PATCH 08/19] block: Introduce request_queue.initialize_rq_fn()
  2017-05-26 23:56     ` Bart Van Assche
@ 2017-05-28  8:34       ` hch
  2017-05-28 16:12         ` Bart Van Assche
  0 siblings, 1 reply; 48+ messages in thread
From: hch @ 2017-05-28  8:34 UTC (permalink / raw)
  To: Bart Van Assche; +Cc: hch, linux-block, osandov, axboe, axboe

On Fri, May 26, 2017 at 11:56:30PM +0000, Bart Van Assche wrote:
> I have tried to move that call into blk_mq_alloc_request() but that
> resulted in a kernel oops during boot due to scsi_add_cmd_to_list()
> dereferencing scsi_cmnd.device and due to that pointer being invalid.
> I think that pointer was invalid because moving the initialize_rq_fn()
> call into blk_mq_alloc_request() caused request initialization to be
> skipped for the following code path:
> submit_bio()
> -> generic_make_request()
>   -> .make_request_fn == blk_mq_make_request()
>  �  -> blk_mq_sched_get_request()
>       -> __blk_mq_alloc_request()
>  � � �  -> blk_mq_rq_ctx_init()
> 
> This is why I would like to keep the .initialize_rq_fn() call in
> blk_mq_rq_ctx_init().

But we don't call scsi_req_init for this path either with the current
code.  So not having the call should be fine as long as you ensure
we still manually initialize everything for the non-passthrough path
in the later patches.  I'll keep an eye on that issue while reviewing
the remaining patches.

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

* Re: [PATCH 08/19] block: Introduce request_queue.initialize_rq_fn()
  2017-05-25 18:43 ` [PATCH 08/19] block: Introduce request_queue.initialize_rq_fn() Bart Van Assche
  2017-05-26  6:34   ` Christoph Hellwig
@ 2017-05-28  8:37   ` Christoph Hellwig
  2017-05-30 17:54     ` Bart Van Assche
  1 sibling, 1 reply; 48+ messages in thread
From: Christoph Hellwig @ 2017-05-28  8:37 UTC (permalink / raw)
  To: Bart Van Assche
  Cc: Jens Axboe, linux-block, Christoph Hellwig, Jens Axboe, Omar Sandoval

Oh, and btw - for the mq case we don't want to use the function
pointer directly in the queue, but in blk_mq_ops, so that we have
all the mq methods in one place.

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

* Re: [PATCH 09/19] block: Make scsi_req_init() calls implicit
  2017-05-25 18:43 ` [PATCH 09/19] block: Make scsi_req_init() calls implicit Bart Van Assche
@ 2017-05-28  8:38   ` Christoph Hellwig
  0 siblings, 0 replies; 48+ messages in thread
From: Christoph Hellwig @ 2017-05-28  8:38 UTC (permalink / raw)
  To: Bart Van Assche
  Cc: Jens Axboe, linux-block, Christoph Hellwig, Jens Axboe, Omar Sandoval

On Thu, May 25, 2017 at 11:43:17AM -0700, Bart Van Assche wrote:
> Instead of explicitly calling scsi_req_init(), let
> blk_get_request() call that function from inside blk_rq_init().
> Add an .initialize_rq_fn() callback function to the block drivers
> that need it. Merge the IDE .init_rq_fn() function into
> .initialize_rq_fn() because it is too small to keep it as a
> separate function.

That won't work if we don't call initialize_rq_fn from the fast path.

Except for that the idea is great and I like it.

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

* Re: [PATCH 10/19] blk-mq: Change blk_mq_hw_ctx.queue_rq_srcu into an array
  2017-05-25 18:43 ` [PATCH 10/19] blk-mq: Change blk_mq_hw_ctx.queue_rq_srcu into an array Bart Van Assche
@ 2017-05-28  8:39   ` Christoph Hellwig
  2017-05-28 16:36     ` Bart Van Assche
  0 siblings, 1 reply; 48+ messages in thread
From: Christoph Hellwig @ 2017-05-28  8:39 UTC (permalink / raw)
  To: Bart Van Assche
  Cc: Jens Axboe, linux-block, Christoph Hellwig, Hannes Reinecke,
	Omar Sandoval, Ming Lei

I think starting from here thing should be in a different series..

On Thu, May 25, 2017 at 11:43:18AM -0700, Bart Van Assche wrote:
> This patch does not change any functionality but makes the next
> patch easier to read.

I think merging the two would be better.  But except for that this
looks fine to me:

Reviewed-by: Christoph Hellwig <hch@lst.de>

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

* Re: [PATCH 11/19] blk-mq: Reduce blk_mq_hw_ctx size
  2017-05-25 18:43 ` [PATCH 11/19] blk-mq: Reduce blk_mq_hw_ctx size Bart Van Assche
@ 2017-05-28  8:40   ` Christoph Hellwig
  0 siblings, 0 replies; 48+ messages in thread
From: Christoph Hellwig @ 2017-05-28  8:40 UTC (permalink / raw)
  To: Bart Van Assche
  Cc: Jens Axboe, linux-block, Christoph Hellwig, Hannes Reinecke,
	Omar Sandoval, Ming Lei

Looks fine,

Reviewed-by: Christoph Hellwig <hch@lst.de>

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

* Re: [PATCH 12/19] blk-mq: Initialize a request before assigning a tag
  2017-05-25 18:43 ` [PATCH 12/19] blk-mq: Initialize a request before assigning a tag Bart Van Assche
@ 2017-05-28  8:42   ` Christoph Hellwig
  2017-05-28 16:17     ` Bart Van Assche
  0 siblings, 1 reply; 48+ messages in thread
From: Christoph Hellwig @ 2017-05-28  8:42 UTC (permalink / raw)
  To: Bart Van Assche
  Cc: Jens Axboe, linux-block, Christoph Hellwig, Hannes Reinecke,
	Omar Sandoval, Ming Lei

On Thu, May 25, 2017 at 11:43:20AM -0700, Bart Van Assche wrote:
> Initialization of blk-mq requests is a bit weird: blk_mq_rq_ctx_init()
> is called after a tag has been assigned and .rq_flags is initialized
> in __blk_mq_finish_request().
>
> Call blk_mq_rq_ctx_init() before
> modifying any struct request members. Initialize .rq_flags in
> blk_mq_rq_ctx_init() instead of in __blk_mq_finish_request(). This
> patch does not change the behavior of the block layer.

One things this patch does is to initialize the tag value actually
set twice.  In general this looks ok, but I can't really see the real
value.

So a very reluctant:

Reviewed-by: Christoph Hellwig <hch@lst.de>

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

* Re: [PATCH 13/19] blk-mq: Fix the comment above blk_mq_quiesce_queue()
  2017-05-25 18:43 ` [PATCH 13/19] blk-mq: Fix the comment above blk_mq_quiesce_queue() Bart Van Assche
@ 2017-05-28  8:42   ` Christoph Hellwig
  0 siblings, 0 replies; 48+ messages in thread
From: Christoph Hellwig @ 2017-05-28  8:42 UTC (permalink / raw)
  To: Bart Van Assche
  Cc: Jens Axboe, linux-block, Christoph Hellwig, Hannes Reinecke,
	Omar Sandoval, Ming Lei

Looks fine,

Reviewed-by: Christoph Hellwig <hch@lst.de>

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

* Re: [PATCH 14/19] block: Add a comment above queue_lockdep_assert_held()
  2017-05-25 18:43 ` [PATCH 14/19] block: Add a comment above queue_lockdep_assert_held() Bart Van Assche
@ 2017-05-28  8:42   ` Christoph Hellwig
  0 siblings, 0 replies; 48+ messages in thread
From: Christoph Hellwig @ 2017-05-28  8:42 UTC (permalink / raw)
  To: Bart Van Assche
  Cc: Jens Axboe, linux-block, Christoph Hellwig, Hannes Reinecke,
	Omar Sandoval, Ming Lei

Looks fine,

Reviewed-by: Christoph Hellwig <hch@lst.de>

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

* Re: [PATCH 18/19] block: Constify disk_type
  2017-05-25 18:43 ` [PATCH 18/19] block: Constify disk_type Bart Van Assche
@ 2017-05-28  8:43   ` Christoph Hellwig
  0 siblings, 0 replies; 48+ messages in thread
From: Christoph Hellwig @ 2017-05-28  8:43 UTC (permalink / raw)
  To: Bart Van Assche
  Cc: Jens Axboe, linux-block, Christoph Hellwig, Hannes Reinecke,
	Omar Sandoval, Ming Lei

Looks fine,

Reviewed-by: Christoph Hellwig <hch@lst.de>

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

* Re: [PATCH 19/19] block: Make request operation type argument declarations consistent
  2017-05-25 18:43 ` [PATCH 19/19] block: Make request operation type argument declarations consistent Bart Van Assche
@ 2017-05-28  8:43   ` Christoph Hellwig
  0 siblings, 0 replies; 48+ messages in thread
From: Christoph Hellwig @ 2017-05-28  8:43 UTC (permalink / raw)
  To: Bart Van Assche
  Cc: Jens Axboe, linux-block, Christoph Hellwig, Hannes Reinecke,
	Omar Sandoval, Ming Lei

Looks fine,

Reviewed-by: Christoph Hellwig <hch@lst.de>

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

* Re: [PATCH 08/19] block: Introduce request_queue.initialize_rq_fn()
  2017-05-28  8:34       ` hch
@ 2017-05-28 16:12         ` Bart Van Assche
  0 siblings, 0 replies; 48+ messages in thread
From: Bart Van Assche @ 2017-05-28 16:12 UTC (permalink / raw)
  To: hch; +Cc: linux-block, osandov, axboe, axboe

T24gU3VuLCAyMDE3LTA1LTI4IGF0IDEwOjM0ICswMjAwLCBoY2hAbHN0LmRlIHdyb3RlOg0KPiBP
biBGcmksIE1heSAyNiwgMjAxNyBhdCAxMTo1NjozMFBNICswMDAwLCBCYXJ0IFZhbiBBc3NjaGUg
d3JvdGU6DQo+ID4gSSBoYXZlIHRyaWVkIHRvIG1vdmUgdGhhdCBjYWxsIGludG8gYmxrX21xX2Fs
bG9jX3JlcXVlc3QoKSBidXQgdGhhdA0KPiA+IHJlc3VsdGVkIGluIGEga2VybmVsIG9vcHMgZHVy
aW5nIGJvb3QgZHVlIHRvIHNjc2lfYWRkX2NtZF90b19saXN0KCkNCj4gPiBkZXJlZmVyZW5jaW5n
IHNjc2lfY21uZC5kZXZpY2UgYW5kIGR1ZSB0byB0aGF0IHBvaW50ZXIgYmVpbmcgaW52YWxpZC4N
Cj4gPiBJIHRoaW5rIHRoYXQgcG9pbnRlciB3YXMgaW52YWxpZCBiZWNhdXNlIG1vdmluZyB0aGUg
aW5pdGlhbGl6ZV9ycV9mbigpDQo+ID4gY2FsbCBpbnRvIGJsa19tcV9hbGxvY19yZXF1ZXN0KCkg
Y2F1c2VkIHJlcXVlc3QgaW5pdGlhbGl6YXRpb24gdG8gYmUNCj4gPiBza2lwcGVkIGZvciB0aGUg
Zm9sbG93aW5nIGNvZGUgcGF0aDoNCj4gPiBzdWJtaXRfYmlvKCkNCj4gPiAtPiBnZW5lcmljX21h
a2VfcmVxdWVzdCgpDQo+ID4gICAtPiAubWFrZV9yZXF1ZXN0X2ZuID09IGJsa19tcV9tYWtlX3Jl
cXVlc3QoKQ0KPiA+ICAgICAtPiBibGtfbXFfc2NoZWRfZ2V0X3JlcXVlc3QoKQ0KPiA+ICAgICAg
IC0+IF9fYmxrX21xX2FsbG9jX3JlcXVlc3QoKQ0KPiA+ICAgICAgICAgLT4gYmxrX21xX3JxX2N0
eF9pbml0KCkNCj4gPiANCj4gPiBUaGlzIGlzIHdoeSBJIHdvdWxkIGxpa2UgdG8ga2VlcCB0aGUg
LmluaXRpYWxpemVfcnFfZm4oKSBjYWxsIGluDQo+ID4gYmxrX21xX3JxX2N0eF9pbml0KCkuDQo+
IA0KPiBCdXQgd2UgZG9uJ3QgY2FsbCBzY3NpX3JlcV9pbml0IGZvciB0aGlzIHBhdGggZWl0aGVy
IHdpdGggdGhlIGN1cnJlbnQNCj4gY29kZS4gIFNvIG5vdCBoYXZpbmcgdGhlIGNhbGwgc2hvdWxk
IGJlIGZpbmUgYXMgbG9uZyBhcyB5b3UgZW5zdXJlDQo+IHdlIHN0aWxsIG1hbnVhbGx5IGluaXRp
YWxpemUgZXZlcnl0aGluZyBmb3IgdGhlIG5vbi1wYXNzdGhyb3VnaCBwYXRoDQo+IGluIHRoZSBs
YXRlciBwYXRjaGVzLiAgSSdsbCBrZWVwIGFuIGV5ZSBvbiB0aGF0IGlzc3VlIHdoaWxlIHJldmll
d2luZw0KPiB0aGUgcmVtYWluaW5nIHBhdGNoZXMuDQoNCkhlbGxvIENocmlzdG9waCwNCg0KRG8g
eW91IHNlZSBhbiBhbHRlcm5hdGl2ZSB0byBpbnRyb2R1Y2luZyBhbiAuaW5pdGlhbGl6ZV9ycV9m
bigpIGNhbGwgaW4NCmJsa19ycV9pbml0KCkgLyBibGtfbXFfcnFfY3R4X2luaXQoKSB0byBlbnN1
cmUgdGhhdCBqaWZmaWVzX2F0X2FsbG9jIGlzDQpvbmx5IHNldCBvbmNlIGFuZCBub3QgZXZlcnkg
dGltZSBhIHJlcXVlc3QgaXMgcmVxdWV1ZWQ/DQoNClRoYW5rcywNCg0KQmFydC4=

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

* Re: [PATCH 12/19] blk-mq: Initialize a request before assigning a tag
  2017-05-28  8:42   ` Christoph Hellwig
@ 2017-05-28 16:17     ` Bart Van Assche
  0 siblings, 0 replies; 48+ messages in thread
From: Bart Van Assche @ 2017-05-28 16:17 UTC (permalink / raw)
  To: hch; +Cc: osandov, linux-block, hare, axboe, ming.lei

T24gU3VuLCAyMDE3LTA1LTI4IGF0IDEwOjQyICswMjAwLCBDaHJpc3RvcGggSGVsbHdpZyB3cm90
ZToNCj4gT24gVGh1LCBNYXkgMjUsIDIwMTcgYXQgMTE6NDM6MjBBTSAtMDcwMCwgQmFydCBWYW4g
QXNzY2hlIHdyb3RlOg0KPiA+IEluaXRpYWxpemF0aW9uIG9mIGJsay1tcSByZXF1ZXN0cyBpcyBh
IGJpdCB3ZWlyZDogYmxrX21xX3JxX2N0eF9pbml0KCkNCj4gPiBpcyBjYWxsZWQgYWZ0ZXIgYSB0
YWcgaGFzIGJlZW4gYXNzaWduZWQgYW5kIC5ycV9mbGFncyBpcyBpbml0aWFsaXplZA0KPiA+IGlu
IF9fYmxrX21xX2ZpbmlzaF9yZXF1ZXN0KCkuDQo+ID4gDQo+ID4gQ2FsbCBibGtfbXFfcnFfY3R4
X2luaXQoKSBiZWZvcmUNCj4gPiBtb2RpZnlpbmcgYW55IHN0cnVjdCByZXF1ZXN0IG1lbWJlcnMu
IEluaXRpYWxpemUgLnJxX2ZsYWdzIGluDQo+ID4gYmxrX21xX3JxX2N0eF9pbml0KCkgaW5zdGVh
ZCBvZiBpbiBfX2Jsa19tcV9maW5pc2hfcmVxdWVzdCgpLiBUaGlzDQo+ID4gcGF0Y2ggZG9lcyBu
b3QgY2hhbmdlIHRoZSBiZWhhdmlvciBvZiB0aGUgYmxvY2sgbGF5ZXIuDQo+IA0KPiBPbmUgdGhp
bmdzIHRoaXMgcGF0Y2ggZG9lcyBpcyB0byBpbml0aWFsaXplIHRoZSB0YWcgdmFsdWUgYWN0dWFs
bHkNCj4gc2V0IHR3aWNlLiAgSW4gZ2VuZXJhbCB0aGlzIGxvb2tzIG9rLCBidXQgSSBjYW4ndCBy
ZWFsbHkgc2VlIHRoZSByZWFsDQo+IHZhbHVlLg0KDQpIZWxsbyBDaHJpc3RvcGgsDQoNCklmIHlv
dSB3YW50IEkgY2FuIGxlYXZlIG91dCB0aGUgY2hhbmdlcyB0byB0aGUgLnRhZyAvIC5pbnRlcm5h
bF90YWcNCmFzc2lnbm1lbnRzIGZyb20gdGhpcyBwYXRjaC4NCg0KQmFydC4=

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

* Re: [PATCH 10/19] blk-mq: Change blk_mq_hw_ctx.queue_rq_srcu into an array
  2017-05-28  8:39   ` Christoph Hellwig
@ 2017-05-28 16:36     ` Bart Van Assche
  0 siblings, 0 replies; 48+ messages in thread
From: Bart Van Assche @ 2017-05-28 16:36 UTC (permalink / raw)
  To: hch; +Cc: osandov, linux-block, hare, axboe, ming.lei

T24gU3VuLCAyMDE3LTA1LTI4IGF0IDEwOjM5ICswMjAwLCBDaHJpc3RvcGggSGVsbHdpZyB3cm90
ZToNCj4gSSB0aGluayBzdGFydGluZyBmcm9tIGhlcmUgdGhpbmcgc2hvdWxkIGJlIGluIGEgZGlm
ZmVyZW50IHNlcmllcy4uDQoNCkhlbGxvIENocmlzdG9waCwNCg0KSSB3aWxsIHNwbGl0IHRoaXMg
c2VyaWVzLg0KDQpCYXJ0Lg==

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

* Re: [PATCH 08/19] block: Introduce request_queue.initialize_rq_fn()
  2017-05-28  8:37   ` Christoph Hellwig
@ 2017-05-30 17:54     ` Bart Van Assche
  0 siblings, 0 replies; 48+ messages in thread
From: Bart Van Assche @ 2017-05-30 17:54 UTC (permalink / raw)
  To: hch; +Cc: linux-block, osandov, axboe, axboe

On Sun, 2017-05-28 at 10:37 +0200, Christoph Hellwig wrote:
> Oh, and btw - for the mq case we don't want to use the function
> pointer directly in the queue, but in blk_mq_ops, so that we have
> all the mq methods in one place.

Hello Christoph,

Are you sure of this? All other function pointers that apply to both blk-sq
and blk-mq occur in struct request, e.g. .make_request_fn(), .init_rq_fn()
and .exit_rq_fn(). If the .initialize_rq_fn() will be added to struct reque=
st
all I have to add to blk_get_request is the following:

=A0=A0=A0=A0=A0=A0=A0 if (!IS_ERR(req) && q->initialize_rq_fn)
=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 q->initialize_rq_fn(req);

However, if for the mq case the .initialize_rq_fn() would be added to struc=
t
blk_mq_ops then that code would look as follows:

=A0=A0=A0=A0=A0=A0=A0 if (!IS_ERR(req))
                if (q->mq_ops)
=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 q->mq=
_ops->initialize_rq_fn(req);
=A0=A0=A0=A0=A0=A0=A0 =A0=A0=A0=A0=A0=A0=A0 else
=A0=A0=A0=A0=A0=A0=A0=A0 =A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0q->in=
itialize_rq_fn(req);

Personally I prefer the first alternative.

Bart.=

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

end of thread, other threads:[~2017-05-30 17:54 UTC | newest]

Thread overview: 48+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-05-25 18:43 [PATCH 00/19] Block layer patches for kernel v4.13 Bart Van Assche
2017-05-25 18:43 ` [PATCH 01/19] block: Avoid that blk_exit_rl() triggers a use-after-free Bart Van Assche
2017-05-26  6:01   ` Christoph Hellwig
2017-05-25 18:43 ` [PATCH 02/19] block: Introduce queue flag QUEUE_FLAG_SCSI_PDU Bart Van Assche
2017-05-26  6:02   ` Christoph Hellwig
2017-05-25 18:43 ` [PATCH 03/19] bsg: Check queue type before attaching to a queue Bart Van Assche
2017-05-26  6:02   ` Christoph Hellwig
2017-05-25 18:43 ` [PATCH 04/19] pktcdvd: " Bart Van Assche
2017-05-26  6:03   ` Christoph Hellwig
2017-05-25 18:43 ` [PATCH 05/19] cdrom: Check private request size " Bart Van Assche
2017-05-26  6:08   ` Christoph Hellwig
2017-05-26 15:50     ` Bart Van Assche
2017-05-28  8:32       ` hch
2017-05-25 18:43 ` [PATCH 06/19] nfsd: Check private request size before submitting a SCSI request Bart Van Assche
2017-05-25 18:48   ` J . Bruce Fields
2017-05-25 20:19     ` Bart Van Assche
2017-05-26  6:10       ` hch
2017-05-26 15:47         ` bfields
2017-05-26  6:10   ` Christoph Hellwig
2017-05-25 18:43 ` [PATCH 07/19] scsi: Make scsi_ioctl_reset() pass the request queue pointer to blk_rq_init() Bart Van Assche
2017-05-25 18:43 ` [PATCH 08/19] block: Introduce request_queue.initialize_rq_fn() Bart Van Assche
2017-05-26  6:34   ` Christoph Hellwig
2017-05-26 23:56     ` Bart Van Assche
2017-05-28  8:34       ` hch
2017-05-28 16:12         ` Bart Van Assche
2017-05-28  8:37   ` Christoph Hellwig
2017-05-30 17:54     ` Bart Van Assche
2017-05-25 18:43 ` [PATCH 09/19] block: Make scsi_req_init() calls implicit Bart Van Assche
2017-05-28  8:38   ` Christoph Hellwig
2017-05-25 18:43 ` [PATCH 10/19] blk-mq: Change blk_mq_hw_ctx.queue_rq_srcu into an array Bart Van Assche
2017-05-28  8:39   ` Christoph Hellwig
2017-05-28 16:36     ` Bart Van Assche
2017-05-25 18:43 ` [PATCH 11/19] blk-mq: Reduce blk_mq_hw_ctx size Bart Van Assche
2017-05-28  8:40   ` Christoph Hellwig
2017-05-25 18:43 ` [PATCH 12/19] blk-mq: Initialize a request before assigning a tag Bart Van Assche
2017-05-28  8:42   ` Christoph Hellwig
2017-05-28 16:17     ` Bart Van Assche
2017-05-25 18:43 ` [PATCH 13/19] blk-mq: Fix the comment above blk_mq_quiesce_queue() Bart Van Assche
2017-05-28  8:42   ` Christoph Hellwig
2017-05-25 18:43 ` [PATCH 14/19] block: Add a comment above queue_lockdep_assert_held() Bart Van Assche
2017-05-28  8:42   ` Christoph Hellwig
2017-05-25 18:43 ` [PATCH 15/19] block: Check locking assumptions at runtime Bart Van Assche
2017-05-25 18:43 ` [PATCH 16/19] block: Document what queue type each function is intended for Bart Van Assche
2017-05-25 18:43 ` [PATCH 17/19] blk-mq: Document locking assumptions Bart Van Assche
2017-05-25 18:43 ` [PATCH 18/19] block: Constify disk_type Bart Van Assche
2017-05-28  8:43   ` Christoph Hellwig
2017-05-25 18:43 ` [PATCH 19/19] block: Make request operation type argument declarations consistent Bart Van Assche
2017-05-28  8:43   ` Christoph Hellwig

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.