* [PATCH 1/6] blk-mq: introduce blk_mq_unquiesce_queue
2017-05-26 3:07 [PATCH 0/6] blk-mq: fix & improve queue quiescing Ming Lei
@ 2017-05-26 3:07 ` Ming Lei
2017-05-26 3:07 ` [PATCH 2/6] blk-mq: use the introduced blk_mq_unquiesce_queue() Ming Lei
` (5 subsequent siblings)
6 siblings, 0 replies; 10+ messages in thread
From: Ming Lei @ 2017-05-26 3:07 UTC (permalink / raw)
To: Jens Axboe, linux-block, Christoph Hellwig
Cc: Bart Van Assche, linux-nvme, linux-scsi, dm-devel
Now we use blk_mq_start_stopped_hw_queues() implictely
as pair of blk_mq_quiesce_queue(), now we introduce
blk_mq_unquiesce_queue() explictely.
Also this function is introduced for fixing
current quiescing mechanism, which will be done
in the following patches.
Signed-off-by: Ming Lei <ming.lei@redhat.com>
---
block/blk-mq.c | 13 +++++++++++++
include/linux/blkdev.h | 1 +
2 files changed, 14 insertions(+)
diff --git a/block/blk-mq.c b/block/blk-mq.c
index f2224ffd225d..a26fee3fb389 100644
--- a/block/blk-mq.c
+++ b/block/blk-mq.c
@@ -181,6 +181,19 @@ void blk_mq_quiesce_queue(struct request_queue *q)
}
EXPORT_SYMBOL_GPL(blk_mq_quiesce_queue);
+/**
+ * blk_mq_unquiesce_queue() - pair of blk_mq_quiesce_queue()
+ * @q: request queue.
+ *
+ * This function recovers queue into the state before quiescing
+ * done by blk_mq_quiesce_queue
+ */
+void blk_mq_unquiesce_queue(struct request_queue *q)
+{
+ blk_mq_start_stopped_hw_queues(q, true);
+}
+EXPORT_SYMBOL_GPL(blk_mq_unquiesce_queue);
+
void blk_mq_wake_waiters(struct request_queue *q)
{
struct blk_mq_hw_ctx *hctx;
diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h
index ab92c4ea138b..41291be82ac4 100644
--- a/include/linux/blkdev.h
+++ b/include/linux/blkdev.h
@@ -964,6 +964,7 @@ extern void __blk_run_queue_uncond(struct request_queue *q);
extern void blk_run_queue(struct request_queue *);
extern void blk_run_queue_async(struct request_queue *q);
extern void blk_mq_quiesce_queue(struct request_queue *q);
+extern void blk_mq_unquiesce_queue(struct request_queue *q);
extern int blk_rq_map_user(struct request_queue *, struct request *,
struct rq_map_data *, void __user *, unsigned long,
gfp_t);
--
2.9.4
^ permalink raw reply related [flat|nested] 10+ messages in thread* [PATCH 2/6] blk-mq: use the introduced blk_mq_unquiesce_queue()
2017-05-26 3:07 [PATCH 0/6] blk-mq: fix & improve queue quiescing Ming Lei
2017-05-26 3:07 ` [PATCH 1/6] blk-mq: introduce blk_mq_unquiesce_queue Ming Lei
@ 2017-05-26 3:07 ` Ming Lei
2017-05-26 7:46 ` kbuild test robot
2017-05-26 3:07 ` [PATCH 3/6] blk-mq: fix blk_mq_quiesce_queue Ming Lei
` (4 subsequent siblings)
6 siblings, 1 reply; 10+ messages in thread
From: Ming Lei @ 2017-05-26 3:07 UTC (permalink / raw)
To: Jens Axboe, linux-block, Christoph Hellwig
Cc: Bart Van Assche, linux-nvme, linux-scsi, dm-devel
blk_mq_unquiesce_queue() is used for unquiescing the queue.
Signed-off-by: Ming Lei <ming.lei@redhat.com>
---
drivers/md/dm-rq.c | 2 +-
drivers/nvme/host/core.c | 2 +-
drivers/scsi/scsi_lib.c | 5 ++++-
3 files changed, 6 insertions(+), 3 deletions(-)
diff --git a/drivers/md/dm-rq.c b/drivers/md/dm-rq.c
index 2af27026aa2e..673fcf075077 100644
--- a/drivers/md/dm-rq.c
+++ b/drivers/md/dm-rq.c
@@ -71,7 +71,7 @@ static void dm_old_start_queue(struct request_queue *q)
static void dm_mq_start_queue(struct request_queue *q)
{
- blk_mq_start_stopped_hw_queues(q, true);
+ blk_mq_unquiesce_queue(q);
blk_mq_kick_requeue_list(q);
}
diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c
index 04e115834702..231d36028afc 100644
--- a/drivers/nvme/host/core.c
+++ b/drivers/nvme/host/core.c
@@ -2514,7 +2514,7 @@ void nvme_start_queues(struct nvme_ctrl *ctrl)
mutex_lock(&ctrl->namespaces_mutex);
list_for_each_entry(ns, &ctrl->namespaces, list) {
- blk_mq_start_stopped_hw_queues(ns->queue, true);
+ blk_mq_unquiesce_queue(ns->queue);
blk_mq_kick_requeue_list(ns->queue);
}
mutex_unlock(&ctrl->namespaces_mutex);
diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c
index 814a4bd8405d..72b11f75719c 100644
--- a/drivers/scsi/scsi_lib.c
+++ b/drivers/scsi/scsi_lib.c
@@ -3030,7 +3030,10 @@ scsi_internal_device_unblock(struct scsi_device *sdev,
return -EINVAL;
if (q->mq_ops) {
- blk_mq_start_stopped_hw_queues(q, false);
+ if (blk_queue_quiesced(q))
+ blk_mq_unquiesce_queue(q);
+ else
+ blk_mq_start_stopped_hw_queues(q, false);
} else {
spin_lock_irqsave(q->queue_lock, flags);
blk_start_queue(q);
--
2.9.4
^ permalink raw reply related [flat|nested] 10+ messages in thread* Re: [PATCH 2/6] blk-mq: use the introduced blk_mq_unquiesce_queue()
2017-05-26 3:07 ` [PATCH 2/6] blk-mq: use the introduced blk_mq_unquiesce_queue() Ming Lei
@ 2017-05-26 7:46 ` kbuild test robot
2017-05-26 8:24 ` Ming Lei
0 siblings, 1 reply; 10+ messages in thread
From: kbuild test robot @ 2017-05-26 7:46 UTC (permalink / raw)
To: Ming Lei
Cc: linux-block, linux-scsi, Christoph Hellwig, linux-nvme,
Jens Axboe, dm-devel, kbuild-all, Bart Van Assche
[-- Attachment #1: Type: text/plain, Size: 8463 bytes --]
Hi Ming,
[auto build test ERROR on block/for-next]
[also build test ERROR on v4.12-rc2 next-20170525]
[if your patch is applied to the wrong git tree, please drop us a note to help improve the system]
url: https://github.com/0day-ci/linux/commits/Ming-Lei/blk-mq-introduce-blk_mq_unquiesce_queue/20170526-140138
base: https://git.kernel.org/pub/scm/linux/kernel/git/axboe/linux-block.git for-next
config: x86_64-randconfig-x019-201721 (attached as .config)
compiler: gcc-6 (Debian 6.2.0-3) 6.2.0 20160901
reproduce:
# save the attached .config to linux build tree
make ARCH=x86_64
Note: the linux-review/Ming-Lei/blk-mq-introduce-blk_mq_unquiesce_queue/20170526-140138 HEAD 470e70e5203ed8f76bb7c1a86db58023098bfc21 builds fine.
It only hurts bisectibility.
All errors (new ones prefixed by >>):
drivers/scsi/scsi_lib.c: In function 'scsi_internal_device_unblock':
>> drivers/scsi/scsi_lib.c:3033:7: error: implicit declaration of function 'blk_queue_quiesced' [-Werror=implicit-function-declaration]
if (blk_queue_quiesced(q))
^~~~~~~~~~~~~~~~~~
Cyclomatic Complexity 5 include/linux/compiler.h:__read_once_size
Cyclomatic Complexity 5 include/linux/compiler.h:__write_once_size
Cyclomatic Complexity 1 arch/x86/include/asm/bitops.h:test_and_clear_bit
Cyclomatic Complexity 1 arch/x86/include/asm/bitops.h:constant_test_bit
Cyclomatic Complexity 1 arch/x86/include/asm/bitops.h:variable_test_bit
Cyclomatic Complexity 1 arch/x86/include/asm/bitops.h:fls64
Cyclomatic Complexity 1 include/uapi/linux/swab.h:__swab16p
Cyclomatic Complexity 1 include/uapi/linux/byteorder/little_endian.h:__be16_to_cpup
Cyclomatic Complexity 1 include/linux/log2.h:__ilog2_u64
Cyclomatic Complexity 1 include/linux/list.h:INIT_LIST_HEAD
Cyclomatic Complexity 1 include/linux/list.h:__list_add_valid
Cyclomatic Complexity 1 include/linux/list.h:__list_del_entry_valid
Cyclomatic Complexity 2 include/linux/list.h:__list_add
Cyclomatic Complexity 1 include/linux/list.h:list_add_tail
Cyclomatic Complexity 1 include/linux/list.h:__list_del
Cyclomatic Complexity 2 include/linux/list.h:__list_del_entry
Cyclomatic Complexity 1 include/linux/list.h:list_del
Cyclomatic Complexity 1 include/linux/list.h:list_del_init
Cyclomatic Complexity 1 include/linux/list.h:list_move_tail
Cyclomatic Complexity 1 include/linux/list.h:list_empty
Cyclomatic Complexity 1 include/linux/list.h:__list_splice
Cyclomatic Complexity 2 include/linux/list.h:list_splice
Cyclomatic Complexity 2 include/linux/list.h:list_splice_init
Cyclomatic Complexity 1 arch/x86/include/asm/current.h:get_current
Cyclomatic Complexity 1 include/asm-generic/getorder.h:__get_order
Cyclomatic Complexity 1 arch/x86/include/asm/atomic.h:atomic_read
Cyclomatic Complexity 1 arch/x86/include/asm/atomic.h:atomic_set
Cyclomatic Complexity 1 arch/x86/include/asm/atomic.h:atomic_inc
Cyclomatic Complexity 1 arch/x86/include/asm/atomic.h:atomic_dec
Cyclomatic Complexity 1 arch/x86/include/asm/atomic.h:atomic_add_return
Cyclomatic Complexity 1 arch/x86/include/asm/atomic.h:atomic_sub_return
Cyclomatic Complexity 1 include/linux/jump_label.h:static_key_count
Cyclomatic Complexity 2 include/linux/jump_label.h:static_key_false
Cyclomatic Complexity 1 arch/x86/include/asm/paravirt.h:arch_local_save_flags
Cyclomatic Complexity 1 arch/x86/include/asm/irqflags.h:arch_irqs_disabled_flags
Cyclomatic Complexity 5 arch/x86/include/asm/preempt.h:__preempt_count_add
Cyclomatic Complexity 1 arch/x86/include/asm/preempt.h:__preempt_count_dec_and_test
Cyclomatic Complexity 1 include/linux/spinlock.h:spinlock_check
Cyclomatic Complexity 1 include/linux/spinlock.h:spin_lock_irq
Cyclomatic Complexity 1 include/linux/spinlock.h:spin_unlock_irq
Cyclomatic Complexity 1 include/linux/spinlock.h:spin_unlock_irqrestore
Cyclomatic Complexity 1 include/linux/rcupdate.h:rcu_read_lock_sched_notrace
Cyclomatic Complexity 1 include/linux/mm.h:lowmem_page_address
Cyclomatic Complexity 1 include/linux/uaccess.h:pagefault_disabled_inc
Cyclomatic Complexity 1 include/linux/uaccess.h:pagefault_disabled_dec
Cyclomatic Complexity 1 include/linux/uaccess.h:pagefault_disable
Cyclomatic Complexity 1 include/linux/uaccess.h:pagefault_enable
Cyclomatic Complexity 1 include/linux/highmem.h:kmap_atomic
Cyclomatic Complexity 1 include/linux/blk_types.h:op_is_write
Cyclomatic Complexity 1 include/linux/slab.h:kmem_cache_alloc_node
Cyclomatic Complexity 68 include/linux/slab.h:kmalloc_large
Cyclomatic Complexity 3 include/linux/slab.h:kmalloc
Cyclomatic Complexity 1 include/linux/slab.h:kzalloc
Cyclomatic Complexity 1 include/linux/blkdev.h:blk_rq_is_scsi
Cyclomatic Complexity 1 include/linux/blkdev.h:blk_rq_is_private
Cyclomatic Complexity 3 include/linux/blkdev.h:blk_rq_is_passthrough
Cyclomatic Complexity 1 include/linux/blkdev.h:blk_rq_bytes
Cyclomatic Complexity 2 include/linux/blkdev.h:blk_rq_payload_bytes
Cyclomatic Complexity 2 include/linux/blkdev.h:blk_rq_nr_phys_segments
Cyclomatic Complexity 1 include/linux/blkdev.h:blk_integrity_rq
Cyclomatic Complexity 1 include/linux/blkdev.h:blk_rq_count_integrity_sg
Cyclomatic Complexity 1 include/linux/blkdev.h:blk_rq_map_integrity_sg
Cyclomatic Complexity 1 include/linux/blkdev.h:blk_queue_max_integrity_segments
Cyclomatic Complexity 1 include/linux/blkdev.h:queue_max_integrity_segments
Cyclomatic Complexity 3 include/linux/dma-mapping.h:dma_get_max_seg_size
Cyclomatic Complexity 2 include/linux/dma-mapping.h:dma_set_seg_boundary
Cyclomatic Complexity 1 include/linux/dma-mapping.h:dma_max_pfn
Cyclomatic Complexity 1 include/linux/blk-mq.h:blk_mq_rq_to_pdu
Cyclomatic Complexity 1 include/linux/unaligned/access_ok.h:get_unaligned_be16
Cyclomatic Complexity 1 include/scsi/scsi_common.h:scsi_varlen_cdb_length
Cyclomatic Complexity 2 include/scsi/scsi_common.h:scsi_command_size
Cyclomatic Complexity 2 include/scsi/scsi_common.h:scsi_sense_valid
Cyclomatic Complexity 3 include/scsi/scsi.h:scsi_status_is_good
Cyclomatic Complexity 1 include/scsi/scsi_device.h:scsi_target
Cyclomatic Complexity 1 include/scsi/scsi_device.h:scsi_device_online
Cyclomatic Complexity 1 include/scsi/scsi_device.h:scsi_device_blocked
Cyclomatic Complexity 1 include/scsi/scsi_request.h:scsi_req
Cyclomatic Complexity 1 include/scsi/scsi_cmnd.h:scsi_cmd_to_driver
Cyclomatic Complexity 1 include/scsi/scsi_cmnd.h:scsi_set_resid
Cyclomatic Complexity 1 include/scsi/scsi_cmnd.h:scsi_get_resid
Cyclomatic Complexity 3 include/scsi/scsi_cmnd.h:scsi_bidi_cmnd
Cyclomatic Complexity 2 include/scsi/scsi_cmnd.h:scsi_in
Cyclomatic Complexity 2 include/scsi/scsi_cmnd.h:scsi_prot_sg_count
Cyclomatic Complexity 1 include/scsi/scsi_cmnd.h:set_host_byte
Cyclomatic Complexity 3 include/scsi/scsi_eh.h:scsi_sense_is_deferred
Cyclomatic Complexity 3 include/scsi/scsi_host.h:scsi_host_in_recovery
Cyclomatic Complexity 1 include/scsi/scsi_host.h:scsi_get_device
Cyclomatic Complexity 1 include/scsi/scsi_host.h:scsi_host_get_prot
Cyclomatic Complexity 1 include/scsi/scsi_host.h:scsi_host_prot_dma
Cyclomatic Complexity 1 drivers/scsi/scsi_priv.h:scsi_log_send
Cyclomatic Complexity 1 drivers/scsi/scsi_priv.h:scsi_log_completion
Cyclomatic Complexity 2 drivers/scsi/scsi_lib.c:scsi_select_sense_cache
Cyclomatic Complexity 1 drivers/scsi/scsi_lib.c:scsi_alloc_sense_buffer
Cyclomatic Complexity 4 drivers/scsi/scsi_lib.c:scsi_set_blocked
Cyclomatic Complexity 3 drivers/scsi/scsi_lib.c:scsi_device_is_busy
Cyclomatic Complexity 4 drivers/scsi/scsi_lib.c:scsi_target_is_busy
Cyclomatic Complexity 5 drivers/scsi/scsi_lib.c:scsi_host_is_busy
Cyclomatic Complexity 3 drivers/scsi/scsi_lib.c:scsi_uninit_cmd
vim +/blk_queue_quiesced +3033 drivers/scsi/scsi_lib.c
3027 sdev->sdev_state = SDEV_CREATED;
3028 } else if (sdev->sdev_state != SDEV_CANCEL &&
3029 sdev->sdev_state != SDEV_OFFLINE)
3030 return -EINVAL;
3031
3032 if (q->mq_ops) {
> 3033 if (blk_queue_quiesced(q))
3034 blk_mq_unquiesce_queue(q);
3035 else
3036 blk_mq_start_stopped_hw_queues(q, false);
---
0-DAY kernel test infrastructure Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all Intel Corporation
[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 28792 bytes --]
[-- Attachment #3: Type: text/plain, Size: 0 bytes --]
^ permalink raw reply [flat|nested] 10+ messages in thread* Re: [PATCH 2/6] blk-mq: use the introduced blk_mq_unquiesce_queue()
2017-05-26 7:46 ` kbuild test robot
@ 2017-05-26 8:24 ` Ming Lei
0 siblings, 0 replies; 10+ messages in thread
From: Ming Lei @ 2017-05-26 8:24 UTC (permalink / raw)
To: kbuild test robot
Cc: kbuild-all, Jens Axboe, linux-block, Christoph Hellwig,
Bart Van Assche, linux-nvme, linux-scsi, dm-devel
On Fri, May 26, 2017 at 03:46:51PM +0800, kbuild test robot wrote:
> Hi Ming,
>
> [auto build test ERROR on block/for-next]
> [also build test ERROR on v4.12-rc2 next-20170525]
> [if your patch is applied to the wrong git tree, please drop us a note to help improve the system]
>
> url: https://github.com/0day-ci/linux/commits/Ming-Lei/blk-mq-introduce-blk_mq_unquiesce_queue/20170526-140138
> base: https://git.kernel.org/pub/scm/linux/kernel/git/axboe/linux-block.git for-next
> config: x86_64-randconfig-x019-201721 (attached as .config)
> compiler: gcc-6 (Debian 6.2.0-3) 6.2.0 20160901
> reproduce:
> # save the attached .config to linux build tree
> make ARCH=x86_64
>
> Note: the linux-review/Ming-Lei/blk-mq-introduce-blk_mq_unquiesce_queue/20170526-140138 HEAD 470e70e5203ed8f76bb7c1a86db58023098bfc21 builds fine.
> It only hurts bisectibility.
>
> All errors (new ones prefixed by >>):
>
> drivers/scsi/scsi_lib.c: In function 'scsi_internal_device_unblock':
> >> drivers/scsi/scsi_lib.c:3033:7: error: implicit declaration of function 'blk_queue_quiesced' [-Werror=implicit-function-declaration]
> if (blk_queue_quiesced(q))
> ^~~~~~~~~~~~~~~~~~
> Cyclomatic Complexity 5 include/linux/compiler.h:__read_once_size
> Cyclomatic Complexity 5 include/linux/compiler.h:__write_once_size
> Cyclomatic Complexity 1 arch/x86/include/asm/bitops.h:test_and_clear_bit
> Cyclomatic Complexity 1 arch/x86/include/asm/bitops.h:constant_test_bit
> Cyclomatic Complexity 1 arch/x86/include/asm/bitops.h:variable_test_bit
> Cyclomatic Complexity 1 arch/x86/include/asm/bitops.h:fls64
> Cyclomatic Complexity 1 include/uapi/linux/swab.h:__swab16p
> Cyclomatic Complexity 1 include/uapi/linux/byteorder/little_endian.h:__be16_to_cpup
> Cyclomatic Complexity 1 include/linux/log2.h:__ilog2_u64
> Cyclomatic Complexity 1 include/linux/list.h:INIT_LIST_HEAD
> Cyclomatic Complexity 1 include/linux/list.h:__list_add_valid
> Cyclomatic Complexity 1 include/linux/list.h:__list_del_entry_valid
> Cyclomatic Complexity 2 include/linux/list.h:__list_add
> Cyclomatic Complexity 1 include/linux/list.h:list_add_tail
> Cyclomatic Complexity 1 include/linux/list.h:__list_del
> Cyclomatic Complexity 2 include/linux/list.h:__list_del_entry
> Cyclomatic Complexity 1 include/linux/list.h:list_del
> Cyclomatic Complexity 1 include/linux/list.h:list_del_init
> Cyclomatic Complexity 1 include/linux/list.h:list_move_tail
> Cyclomatic Complexity 1 include/linux/list.h:list_empty
> Cyclomatic Complexity 1 include/linux/list.h:__list_splice
> Cyclomatic Complexity 2 include/linux/list.h:list_splice
> Cyclomatic Complexity 2 include/linux/list.h:list_splice_init
> Cyclomatic Complexity 1 arch/x86/include/asm/current.h:get_current
> Cyclomatic Complexity 1 include/asm-generic/getorder.h:__get_order
> Cyclomatic Complexity 1 arch/x86/include/asm/atomic.h:atomic_read
> Cyclomatic Complexity 1 arch/x86/include/asm/atomic.h:atomic_set
> Cyclomatic Complexity 1 arch/x86/include/asm/atomic.h:atomic_inc
> Cyclomatic Complexity 1 arch/x86/include/asm/atomic.h:atomic_dec
> Cyclomatic Complexity 1 arch/x86/include/asm/atomic.h:atomic_add_return
> Cyclomatic Complexity 1 arch/x86/include/asm/atomic.h:atomic_sub_return
> Cyclomatic Complexity 1 include/linux/jump_label.h:static_key_count
> Cyclomatic Complexity 2 include/linux/jump_label.h:static_key_false
> Cyclomatic Complexity 1 arch/x86/include/asm/paravirt.h:arch_local_save_flags
> Cyclomatic Complexity 1 arch/x86/include/asm/irqflags.h:arch_irqs_disabled_flags
> Cyclomatic Complexity 5 arch/x86/include/asm/preempt.h:__preempt_count_add
> Cyclomatic Complexity 1 arch/x86/include/asm/preempt.h:__preempt_count_dec_and_test
> Cyclomatic Complexity 1 include/linux/spinlock.h:spinlock_check
> Cyclomatic Complexity 1 include/linux/spinlock.h:spin_lock_irq
> Cyclomatic Complexity 1 include/linux/spinlock.h:spin_unlock_irq
> Cyclomatic Complexity 1 include/linux/spinlock.h:spin_unlock_irqrestore
> Cyclomatic Complexity 1 include/linux/rcupdate.h:rcu_read_lock_sched_notrace
> Cyclomatic Complexity 1 include/linux/mm.h:lowmem_page_address
> Cyclomatic Complexity 1 include/linux/uaccess.h:pagefault_disabled_inc
> Cyclomatic Complexity 1 include/linux/uaccess.h:pagefault_disabled_dec
> Cyclomatic Complexity 1 include/linux/uaccess.h:pagefault_disable
> Cyclomatic Complexity 1 include/linux/uaccess.h:pagefault_enable
> Cyclomatic Complexity 1 include/linux/highmem.h:kmap_atomic
> Cyclomatic Complexity 1 include/linux/blk_types.h:op_is_write
> Cyclomatic Complexity 1 include/linux/slab.h:kmem_cache_alloc_node
> Cyclomatic Complexity 68 include/linux/slab.h:kmalloc_large
> Cyclomatic Complexity 3 include/linux/slab.h:kmalloc
> Cyclomatic Complexity 1 include/linux/slab.h:kzalloc
> Cyclomatic Complexity 1 include/linux/blkdev.h:blk_rq_is_scsi
> Cyclomatic Complexity 1 include/linux/blkdev.h:blk_rq_is_private
> Cyclomatic Complexity 3 include/linux/blkdev.h:blk_rq_is_passthrough
> Cyclomatic Complexity 1 include/linux/blkdev.h:blk_rq_bytes
> Cyclomatic Complexity 2 include/linux/blkdev.h:blk_rq_payload_bytes
> Cyclomatic Complexity 2 include/linux/blkdev.h:blk_rq_nr_phys_segments
> Cyclomatic Complexity 1 include/linux/blkdev.h:blk_integrity_rq
> Cyclomatic Complexity 1 include/linux/blkdev.h:blk_rq_count_integrity_sg
> Cyclomatic Complexity 1 include/linux/blkdev.h:blk_rq_map_integrity_sg
> Cyclomatic Complexity 1 include/linux/blkdev.h:blk_queue_max_integrity_segments
> Cyclomatic Complexity 1 include/linux/blkdev.h:queue_max_integrity_segments
> Cyclomatic Complexity 3 include/linux/dma-mapping.h:dma_get_max_seg_size
> Cyclomatic Complexity 2 include/linux/dma-mapping.h:dma_set_seg_boundary
> Cyclomatic Complexity 1 include/linux/dma-mapping.h:dma_max_pfn
> Cyclomatic Complexity 1 include/linux/blk-mq.h:blk_mq_rq_to_pdu
> Cyclomatic Complexity 1 include/linux/unaligned/access_ok.h:get_unaligned_be16
> Cyclomatic Complexity 1 include/scsi/scsi_common.h:scsi_varlen_cdb_length
> Cyclomatic Complexity 2 include/scsi/scsi_common.h:scsi_command_size
> Cyclomatic Complexity 2 include/scsi/scsi_common.h:scsi_sense_valid
> Cyclomatic Complexity 3 include/scsi/scsi.h:scsi_status_is_good
> Cyclomatic Complexity 1 include/scsi/scsi_device.h:scsi_target
> Cyclomatic Complexity 1 include/scsi/scsi_device.h:scsi_device_online
> Cyclomatic Complexity 1 include/scsi/scsi_device.h:scsi_device_blocked
> Cyclomatic Complexity 1 include/scsi/scsi_request.h:scsi_req
> Cyclomatic Complexity 1 include/scsi/scsi_cmnd.h:scsi_cmd_to_driver
> Cyclomatic Complexity 1 include/scsi/scsi_cmnd.h:scsi_set_resid
> Cyclomatic Complexity 1 include/scsi/scsi_cmnd.h:scsi_get_resid
> Cyclomatic Complexity 3 include/scsi/scsi_cmnd.h:scsi_bidi_cmnd
> Cyclomatic Complexity 2 include/scsi/scsi_cmnd.h:scsi_in
> Cyclomatic Complexity 2 include/scsi/scsi_cmnd.h:scsi_prot_sg_count
> Cyclomatic Complexity 1 include/scsi/scsi_cmnd.h:set_host_byte
> Cyclomatic Complexity 3 include/scsi/scsi_eh.h:scsi_sense_is_deferred
> Cyclomatic Complexity 3 include/scsi/scsi_host.h:scsi_host_in_recovery
> Cyclomatic Complexity 1 include/scsi/scsi_host.h:scsi_get_device
> Cyclomatic Complexity 1 include/scsi/scsi_host.h:scsi_host_get_prot
> Cyclomatic Complexity 1 include/scsi/scsi_host.h:scsi_host_prot_dma
> Cyclomatic Complexity 1 drivers/scsi/scsi_priv.h:scsi_log_send
> Cyclomatic Complexity 1 drivers/scsi/scsi_priv.h:scsi_log_completion
> Cyclomatic Complexity 2 drivers/scsi/scsi_lib.c:scsi_select_sense_cache
> Cyclomatic Complexity 1 drivers/scsi/scsi_lib.c:scsi_alloc_sense_buffer
> Cyclomatic Complexity 4 drivers/scsi/scsi_lib.c:scsi_set_blocked
> Cyclomatic Complexity 3 drivers/scsi/scsi_lib.c:scsi_device_is_busy
> Cyclomatic Complexity 4 drivers/scsi/scsi_lib.c:scsi_target_is_busy
> Cyclomatic Complexity 5 drivers/scsi/scsi_lib.c:scsi_host_is_busy
> Cyclomatic Complexity 3 drivers/scsi/scsi_lib.c:scsi_uninit_cmd
>
> vim +/blk_queue_quiesced +3033 drivers/scsi/scsi_lib.c
>
> 3027 sdev->sdev_state = SDEV_CREATED;
> 3028 } else if (sdev->sdev_state != SDEV_CANCEL &&
> 3029 sdev->sdev_state != SDEV_OFFLINE)
> 3030 return -EINVAL;
> 3031
> 3032 if (q->mq_ops) {
> > 3033 if (blk_queue_quiesced(q))
> 3034 blk_mq_unquiesce_queue(q);
> 3035 else
> 3036 blk_mq_start_stopped_hw_queues(q, false);
My fault, I shouldn't have merged blk_queue_quiesced()
into patch 03, will fix it in V2.
Thanks,
Ming
^ permalink raw reply [flat|nested] 10+ messages in thread
* [PATCH 3/6] blk-mq: fix blk_mq_quiesce_queue
2017-05-26 3:07 [PATCH 0/6] blk-mq: fix & improve queue quiescing Ming Lei
2017-05-26 3:07 ` [PATCH 1/6] blk-mq: introduce blk_mq_unquiesce_queue Ming Lei
2017-05-26 3:07 ` [PATCH 2/6] blk-mq: use the introduced blk_mq_unquiesce_queue() Ming Lei
@ 2017-05-26 3:07 ` Ming Lei
2017-05-26 3:07 ` [PATCH 4/6] blk-mq: update comments on blk_mq_quiesce_queue() Ming Lei
` (3 subsequent siblings)
6 siblings, 0 replies; 10+ messages in thread
From: Ming Lei @ 2017-05-26 3:07 UTC (permalink / raw)
To: Jens Axboe, linux-block, Christoph Hellwig
Cc: Bart Van Assche, linux-nvme, linux-scsi, dm-devel
blk_mq_quiesce_queue() can not block dispatch in the following
two cases:
- direct issue or BLK_MQ_S_START_ON_RUN
- in theory, new RCU read-side critical sections may begin while
synchronize_rcu() was waiting, and end after returning of
synchronize_rcu().
so a new flag of QUEUE_FLAG_QUIESCED is introduced and evaluated
inside RCU read-side critical sections for fixing the above issues.
This patch fixes request use-after-free during canceling requets
of NVMe in nvme_dev_disable().
Signed-off-by: Ming Lei <ming.lei@redhat.com>
---
block/blk-mq.c | 33 ++++++++++++++++++++++++++++-----
include/linux/blkdev.h | 2 ++
2 files changed, 30 insertions(+), 5 deletions(-)
diff --git a/block/blk-mq.c b/block/blk-mq.c
index a26fee3fb389..864709453c90 100644
--- a/block/blk-mq.c
+++ b/block/blk-mq.c
@@ -170,6 +170,10 @@ void blk_mq_quiesce_queue(struct request_queue *q)
__blk_mq_stop_hw_queues(q, true);
+ spin_lock_irq(q->queue_lock);
+ queue_flag_set(QUEUE_FLAG_QUIESCED, q);
+ spin_unlock_irq(q->queue_lock);
+
queue_for_each_hw_ctx(q, hctx, i) {
if (hctx->flags & BLK_MQ_F_BLOCKING)
synchronize_srcu(&hctx->queue_rq_srcu);
@@ -190,6 +194,10 @@ EXPORT_SYMBOL_GPL(blk_mq_quiesce_queue);
*/
void blk_mq_unquiesce_queue(struct request_queue *q)
{
+ spin_lock_irq(q->queue_lock);
+ queue_flag_clear(QUEUE_FLAG_QUIESCED, q);
+ spin_unlock_irq(q->queue_lock);
+
blk_mq_start_stopped_hw_queues(q, true);
}
EXPORT_SYMBOL_GPL(blk_mq_unquiesce_queue);
@@ -209,6 +217,9 @@ void blk_mq_wake_waiters(struct request_queue *q)
* the queue are notified as well.
*/
wake_up_all(&q->mq_freeze_wq);
+
+ /* Forcibly unquiesce the queue to avoid having stuck requests */
+ blk_mq_unquiesce_queue(q);
}
bool blk_mq_can_queue(struct blk_mq_hw_ctx *hctx)
@@ -1108,13 +1119,15 @@ static void __blk_mq_run_hw_queue(struct blk_mq_hw_ctx *hctx)
if (!(hctx->flags & BLK_MQ_F_BLOCKING)) {
rcu_read_lock();
- blk_mq_sched_dispatch_requests(hctx);
+ if (!blk_queue_quiesced(hctx->queue))
+ blk_mq_sched_dispatch_requests(hctx);
rcu_read_unlock();
} else {
might_sleep();
srcu_idx = srcu_read_lock(&hctx->queue_rq_srcu);
- blk_mq_sched_dispatch_requests(hctx);
+ if (!blk_queue_quiesced(hctx->queue))
+ blk_mq_sched_dispatch_requests(hctx);
srcu_read_unlock(&hctx->queue_rq_srcu, srcu_idx);
}
}
@@ -1519,9 +1532,14 @@ static void __blk_mq_try_issue_directly(struct request *rq, blk_qc_t *cookie,
static void blk_mq_try_issue_directly(struct blk_mq_hw_ctx *hctx,
struct request *rq, blk_qc_t *cookie)
{
- if (!(hctx->flags & BLK_MQ_F_BLOCKING)) {
+ bool blocking = hctx->flags & BLK_MQ_F_BLOCKING;
+ bool quiesced;
+
+ if (!blocking) {
rcu_read_lock();
- __blk_mq_try_issue_directly(rq, cookie, false);
+ quiesced = blk_queue_quiesced(rq->q);
+ if (!quiesced)
+ __blk_mq_try_issue_directly(rq, cookie, false);
rcu_read_unlock();
} else {
unsigned int srcu_idx;
@@ -1529,9 +1547,14 @@ static void blk_mq_try_issue_directly(struct blk_mq_hw_ctx *hctx,
might_sleep();
srcu_idx = srcu_read_lock(&hctx->queue_rq_srcu);
- __blk_mq_try_issue_directly(rq, cookie, true);
+ quiesced = blk_queue_quiesced(rq->q);
+ if (!quiesced)
+ __blk_mq_try_issue_directly(rq, cookie, true);
srcu_read_unlock(&hctx->queue_rq_srcu, srcu_idx);
}
+
+ if (quiesced)
+ blk_mq_sched_insert_request(rq, false, false, false, blocking);
}
static blk_qc_t blk_mq_make_request(struct request_queue *q, struct bio *bio)
diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h
index 41291be82ac4..60967797f4f6 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_QUIESCED 30 /* queue has been quiesced */
#define QUEUE_FLAG_DEFAULT ((1 << QUEUE_FLAG_IO_STAT) | \
(1 << QUEUE_FLAG_STACKABLE) | \
@@ -712,6 +713,7 @@ static inline void queue_flag_clear(unsigned int flag, struct request_queue *q)
#define blk_noretry_request(rq) \
((rq)->cmd_flags & (REQ_FAILFAST_DEV|REQ_FAILFAST_TRANSPORT| \
REQ_FAILFAST_DRIVER))
+#define blk_queue_quiesced(q) test_bit(QUEUE_FLAG_QUIESCED, &(q)->queue_flags)
static inline bool blk_account_rq(struct request *rq)
{
--
2.9.4
^ permalink raw reply related [flat|nested] 10+ messages in thread* [PATCH 4/6] blk-mq: update comments on blk_mq_quiesce_queue()
2017-05-26 3:07 [PATCH 0/6] blk-mq: fix & improve queue quiescing Ming Lei
` (2 preceding siblings ...)
2017-05-26 3:07 ` [PATCH 3/6] blk-mq: fix blk_mq_quiesce_queue Ming Lei
@ 2017-05-26 3:07 ` Ming Lei
2017-05-26 3:07 ` [PATCH 5/6] blk-mq: don't stop queue for quiescing Ming Lei
` (2 subsequent siblings)
6 siblings, 0 replies; 10+ messages in thread
From: Ming Lei @ 2017-05-26 3:07 UTC (permalink / raw)
To: Jens Axboe, linux-block, Christoph Hellwig
Cc: Bart Van Assche, linux-nvme, linux-scsi, dm-devel
Actually what we want to get from blk_mq_quiesce_queue()
isn't only to wait for completion of all ongooing .queue_rq().
In the typical context of canceling requests, we need to
make sure that the following is done in the dispatch path
before starting to cancel requests:
- failed dispatched request is freeed
- busy dispatched request is requeued, and the STARTED
flag is cleared
Signed-off-by: Ming Lei <ming.lei@redhat.com>
---
block/blk-mq.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/block/blk-mq.c b/block/blk-mq.c
index 864709453c90..e1fc9ab50c87 100644
--- a/block/blk-mq.c
+++ b/block/blk-mq.c
@@ -155,12 +155,12 @@ 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() - wait until all ongoing dispatching have finished
* @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. Once this function is returned, we make
+ * sure no dispatching can happen.
*/
void blk_mq_quiesce_queue(struct request_queue *q)
{
--
2.9.4
^ permalink raw reply related [flat|nested] 10+ messages in thread* [PATCH 5/6] blk-mq: don't stop queue for quiescing
2017-05-26 3:07 [PATCH 0/6] blk-mq: fix & improve queue quiescing Ming Lei
` (3 preceding siblings ...)
2017-05-26 3:07 ` [PATCH 4/6] blk-mq: update comments on blk_mq_quiesce_queue() Ming Lei
@ 2017-05-26 3:07 ` Ming Lei
2017-05-26 3:07 ` [PATCH 6/6] blk-mq: clarify dispatching may not be drained/blocked by stopping queue Ming Lei
2017-05-26 3:07 ` [PATCH 6/6] blk-mq: clarify dispatching won't be blocked " Ming Lei
6 siblings, 0 replies; 10+ messages in thread
From: Ming Lei @ 2017-05-26 3:07 UTC (permalink / raw)
To: Jens Axboe, linux-block, Christoph Hellwig
Cc: Bart Van Assche, linux-nvme, linux-scsi, dm-devel
Now we use the QUIESCED flag to drain & block dispatching,
not necessary to stop queue any more.
Also queue can be started by other blk-mq APIs, this limits
uses of blk_mq_quiesce_queue().
Now blk_mq_quiesce_queue() can be used safely and users won't
worry about queue restart during quiescing.
Signed-off-by: Ming Lei <ming.lei@redhat.com>
---
block/blk-mq.c | 9 ++++++---
1 file changed, 6 insertions(+), 3 deletions(-)
diff --git a/block/blk-mq.c b/block/blk-mq.c
index e1fc9ab50c87..900eb91e0ece 100644
--- a/block/blk-mq.c
+++ b/block/blk-mq.c
@@ -168,8 +168,6 @@ void blk_mq_quiesce_queue(struct request_queue *q)
unsigned int i;
bool rcu = false;
- __blk_mq_stop_hw_queues(q, true);
-
spin_lock_irq(q->queue_lock);
queue_flag_set(QUEUE_FLAG_QUIESCED, q);
spin_unlock_irq(q->queue_lock);
@@ -198,7 +196,12 @@ void blk_mq_unquiesce_queue(struct request_queue *q)
queue_flag_clear(QUEUE_FLAG_QUIESCED, q);
spin_unlock_irq(q->queue_lock);
- blk_mq_start_stopped_hw_queues(q, true);
+ /*
+ * During quiescing, requests can be inserted
+ * to scheduler queue or sw queue, so we run
+ * queues for dispatching these requests.
+ */
+ blk_mq_start_hw_queues(q);
}
EXPORT_SYMBOL_GPL(blk_mq_unquiesce_queue);
--
2.9.4
^ permalink raw reply related [flat|nested] 10+ messages in thread* [PATCH 6/6] blk-mq: clarify dispatching may not be drained/blocked by stopping queue
2017-05-26 3:07 [PATCH 0/6] blk-mq: fix & improve queue quiescing Ming Lei
` (4 preceding siblings ...)
2017-05-26 3:07 ` [PATCH 5/6] blk-mq: don't stop queue for quiescing Ming Lei
@ 2017-05-26 3:07 ` Ming Lei
2017-05-26 3:07 ` [PATCH 6/6] blk-mq: clarify dispatching won't be blocked " Ming Lei
6 siblings, 0 replies; 10+ messages in thread
From: Ming Lei @ 2017-05-26 3:07 UTC (permalink / raw)
To: Jens Axboe, linux-block, Christoph Hellwig
Cc: Bart Van Assche, linux-nvme, linux-scsi, dm-devel
BLK_MQ_S_STOPPED may be not observed in other concurrent I/O paths,
we can't guarantee that dispatching won't happen after queue
is stopped.
So clarify the fact and avoid potential misuse.
Signed-off-by: Ming Lei <ming.lei@redhat.com>
---
block/blk-mq.c | 10 ++++++++++
1 file changed, 10 insertions(+)
diff --git a/block/blk-mq.c b/block/blk-mq.c
index 900eb91e0ece..32bed5bac7da 100644
--- a/block/blk-mq.c
+++ b/block/blk-mq.c
@@ -1240,6 +1240,11 @@ static void __blk_mq_stop_hw_queue(struct blk_mq_hw_ctx *hctx, bool sync)
set_bit(BLK_MQ_S_STOPPED, &hctx->state);
}
+/*
+ * Do not expect that dispatching or .queue_rq() can be blocked
+ * after blk_mq_stop_hw_queue() returns. Please use
+ * blk_mq_quiesce_queue() for that requirement.
+ */
void blk_mq_stop_hw_queue(struct blk_mq_hw_ctx *hctx)
{
__blk_mq_stop_hw_queue(hctx, false);
@@ -1255,6 +1260,11 @@ static void __blk_mq_stop_hw_queues(struct request_queue *q, bool sync)
__blk_mq_stop_hw_queue(hctx, sync);
}
+/*
+ * Do not expect that dispatching or .queue_rq() can be blocked
+ * after blk_mq_stop_hw_queues() returns. Please use
+ * blk_mq_quiesce_queue() for that requirement.
+ */
void blk_mq_stop_hw_queues(struct request_queue *q)
{
__blk_mq_stop_hw_queues(q, false);
--
2.9.4
^ permalink raw reply related [flat|nested] 10+ messages in thread* [PATCH 6/6] blk-mq: clarify dispatching won't be blocked by stopping queue
2017-05-26 3:07 [PATCH 0/6] blk-mq: fix & improve queue quiescing Ming Lei
` (5 preceding siblings ...)
2017-05-26 3:07 ` [PATCH 6/6] blk-mq: clarify dispatching may not be drained/blocked by stopping queue Ming Lei
@ 2017-05-26 3:07 ` Ming Lei
6 siblings, 0 replies; 10+ messages in thread
From: Ming Lei @ 2017-05-26 3:07 UTC (permalink / raw)
To: Jens Axboe, linux-block, Christoph Hellwig
Cc: Bart Van Assche, linux-nvme, linux-scsi, dm-devel
BLK_MQ_S_STOPPED may be not observed in other concurrent I/O paths,
we can't guarantee that dispatching won't happen after queue
is stopped.
So clarify the fact and avoid potential misuse.
Signed-off-by: Ming Lei <ming.lei@redhat.com>
---
block/blk-mq.c | 10 ++++++++++
1 file changed, 10 insertions(+)
diff --git a/block/blk-mq.c b/block/blk-mq.c
index 900eb91e0ece..32bed5bac7da 100644
--- a/block/blk-mq.c
+++ b/block/blk-mq.c
@@ -1240,6 +1240,11 @@ static void __blk_mq_stop_hw_queue(struct blk_mq_hw_ctx *hctx, bool sync)
set_bit(BLK_MQ_S_STOPPED, &hctx->state);
}
+/*
+ * Do not expect that dispatching or .queue_rq() can be blocked
+ * after blk_mq_stop_hw_queue() returns. Please use
+ * blk_mq_quiesce_queue() for that requirement.
+ */
void blk_mq_stop_hw_queue(struct blk_mq_hw_ctx *hctx)
{
__blk_mq_stop_hw_queue(hctx, false);
@@ -1255,6 +1260,11 @@ static void __blk_mq_stop_hw_queues(struct request_queue *q, bool sync)
__blk_mq_stop_hw_queue(hctx, sync);
}
+/*
+ * Do not expect that dispatching or .queue_rq() can be blocked
+ * after blk_mq_stop_hw_queues() returns. Please use
+ * blk_mq_quiesce_queue() for that requirement.
+ */
void blk_mq_stop_hw_queues(struct request_queue *q)
{
__blk_mq_stop_hw_queues(q, false);
--
2.9.4
^ permalink raw reply related [flat|nested] 10+ messages in thread