On 2020-02-17 19:16, Ming Lei wrote: > I guess the issue can be fixed by the following change, and we do not > need to touch each queue map: > > diff --git a/block/blk-mq.c b/block/blk-mq.c > index 5f5c43ae3792..f7340afb89ec 100644 > --- a/block/blk-mq.c > +++ b/block/blk-mq.c > @@ -3046,6 +3046,7 @@ static int blk_mq_update_queue_map(struct blk_mq_tag_set *set) > return set->ops->map_queues(set); > } else { > BUG_ON(set->nr_maps > 1); > + set->map[HCTX_TYPE_DEFAULT].nr_queues = set->nr_hw_queues; > return blk_mq_map_queues(&set->map[HCTX_TYPE_DEFAULT]); > } > } Every caller of blk_mq_map_queues() needs to set the number of queues in the default queue map so I would like to make the number of queues an argument. How about the (untested) patch below? Thanks, Bart. --- block/blk-mq-cpumap.c | 5 +++-- block/blk-mq-rdma.c | 2 +- block/blk-mq-virtio.c | 2 +- block/blk-mq.c | 6 ++++-- drivers/block/virtio_blk.c | 5 +++-- drivers/nvme/host/pci.c | 2 +- drivers/nvme/host/rdma.c | 5 ++--- drivers/nvme/host/tcp.c | 11 ++++++----- drivers/scsi/qla2xxx/qla_os.c | 8 +++++--- drivers/scsi/scsi_lib.c | 3 ++- drivers/scsi/smartpqi/smartpqi_init.c | 5 +++-- drivers/scsi/virtio_scsi.c | 1 + include/linux/blk-mq.h | 2 +- 13 files changed, 33 insertions(+), 24 deletions(-) diff --git a/block/blk-mq-cpumap.c b/block/blk-mq-cpumap.c index 0157f2b3485a..4c0d5768305a 100644 --- a/block/blk-mq-cpumap.c +++ b/block/blk-mq-cpumap.c @@ -32,12 +32,13 @@ static int get_first_sibling(unsigned int cpu) return cpu; } -int blk_mq_map_queues(struct blk_mq_queue_map *qmap) +int blk_mq_map_queues(struct blk_mq_queue_map *qmap, unsigned int nr_queues) { unsigned int *map = qmap->mq_map; - unsigned int nr_queues = qmap->nr_queues; unsigned int cpu, first_sibling, q = 0; + qmap->nr_queues = nr_queues; + for_each_possible_cpu(cpu) map[cpu] = -1; diff --git a/block/blk-mq-rdma.c b/block/blk-mq-rdma.c index 14f968e58b8f..c32af1231244 100644 --- a/block/blk-mq-rdma.c +++ b/block/blk-mq-rdma.c @@ -39,6 +39,6 @@ int blk_mq_rdma_map_queues(struct blk_mq_queue_map *map, return 0; fallback: - return blk_mq_map_queues(map); + return blk_mq_map_queues(map, map->nr_queues); } EXPORT_SYMBOL_GPL(blk_mq_rdma_map_queues); diff --git a/block/blk-mq-virtio.c b/block/blk-mq-virtio.c index 488341628256..b5911cb43974 100644 --- a/block/blk-mq-virtio.c +++ b/block/blk-mq-virtio.c @@ -41,6 +41,6 @@ int blk_mq_virtio_map_queues(struct blk_mq_queue_map *qmap, return 0; fallback: - return blk_mq_map_queues(qmap); + return blk_mq_map_queues(qmap, qmap->nr_queues); } EXPORT_SYMBOL_GPL(blk_mq_virtio_map_queues); diff --git a/block/blk-mq.c b/block/blk-mq.c index f298500e6dda..bbd9edde2b6f 100644 --- a/block/blk-mq.c +++ b/block/blk-mq.c @@ -3046,7 +3046,8 @@ static int blk_mq_update_queue_map(struct blk_mq_tag_set *set) return set->ops->map_queues(set); } else { BUG_ON(set->nr_maps > 1); - return blk_mq_map_queues(&set->map[HCTX_TYPE_DEFAULT]); + return blk_mq_map_queues(&set->map[HCTX_TYPE_DEFAULT], + set->nr_hw_queues); } } @@ -3339,7 +3340,8 @@ static void __blk_mq_update_nr_hw_queues(struct blk_mq_tag_set *set, pr_warn("Increasing nr_hw_queues to %d fails, fallback to %d\n", nr_hw_queues, prev_nr_hw_queues); set->nr_hw_queues = prev_nr_hw_queues; - blk_mq_map_queues(&set->map[HCTX_TYPE_DEFAULT]); + blk_mq_map_queues(&set->map[HCTX_TYPE_DEFAULT], + set->nr_hw_queues); goto fallback; } blk_mq_map_swqueue(q); diff --git a/drivers/block/virtio_blk.c b/drivers/block/virtio_blk.c index 54158766334b..61d6482a0b9e 100644 --- a/drivers/block/virtio_blk.c +++ b/drivers/block/virtio_blk.c @@ -595,9 +595,10 @@ static int virtblk_init_request(struct blk_mq_tag_set *set, struct request *rq, static int virtblk_map_queues(struct blk_mq_tag_set *set) { struct virtio_blk *vblk = set->driver_data; + struct blk_mq_queue_map *qmap = &set->map[HCTX_TYPE_DEFAULT]; - return blk_mq_virtio_map_queues(&set->map[HCTX_TYPE_DEFAULT], - vblk->vdev, 0); + qmap->nr_queues = set->nr_hw_queues; + return blk_mq_virtio_map_queues(qmap, vblk->vdev, 0); } static const struct blk_mq_ops virtio_mq_ops = { diff --git a/drivers/nvme/host/pci.c b/drivers/nvme/host/pci.c index da392b50f73e..7531a6950736 100644 --- a/drivers/nvme/host/pci.c +++ b/drivers/nvme/host/pci.c @@ -438,7 +438,7 @@ static int nvme_pci_map_queues(struct blk_mq_tag_set *set) if (i != HCTX_TYPE_POLL && offset) blk_mq_pci_map_queues(map, to_pci_dev(dev->dev), offset); else - blk_mq_map_queues(map); + blk_mq_map_queues(map, map->nr_queues); qoff += map->nr_queues; offset += map->nr_queues; } diff --git a/drivers/nvme/host/rdma.c b/drivers/nvme/host/rdma.c index 2a47c6c5007e..27d00bc7a746 100644 --- a/drivers/nvme/host/rdma.c +++ b/drivers/nvme/host/rdma.c @@ -1844,12 +1844,11 @@ static int nvme_rdma_map_queues(struct blk_mq_tag_set *set) if (opts->nr_poll_queues && ctrl->io_queues[HCTX_TYPE_POLL]) { /* map dedicated poll queues only if we have queues left */ - set->map[HCTX_TYPE_POLL].nr_queues = - ctrl->io_queues[HCTX_TYPE_POLL]; set->map[HCTX_TYPE_POLL].queue_offset = ctrl->io_queues[HCTX_TYPE_DEFAULT] + ctrl->io_queues[HCTX_TYPE_READ]; - blk_mq_map_queues(&set->map[HCTX_TYPE_POLL]); + blk_mq_map_queues(&set->map[HCTX_TYPE_POLL], + ctrl->io_queues[HCTX_TYPE_POLL]); } dev_info(ctrl->ctrl.device, diff --git a/drivers/nvme/host/tcp.c b/drivers/nvme/host/tcp.c index 6d43b23a0fc8..c05ca7dec661 100644 --- a/drivers/nvme/host/tcp.c +++ b/drivers/nvme/host/tcp.c @@ -2192,17 +2192,18 @@ static int nvme_tcp_map_queues(struct blk_mq_tag_set *set) ctrl->io_queues[HCTX_TYPE_DEFAULT]; set->map[HCTX_TYPE_READ].queue_offset = 0; } - blk_mq_map_queues(&set->map[HCTX_TYPE_DEFAULT]); - blk_mq_map_queues(&set->map[HCTX_TYPE_READ]); + blk_mq_map_queues(&set->map[HCTX_TYPE_DEFAULT], + set->map[HCTX_TYPE_DEFAULT].nr_queues); + blk_mq_map_queues(&set->map[HCTX_TYPE_READ], + set->map[HCTX_TYPE_READ].nr_queues); if (opts->nr_poll_queues && ctrl->io_queues[HCTX_TYPE_POLL]) { /* map dedicated poll queues only if we have queues left */ - set->map[HCTX_TYPE_POLL].nr_queues = - ctrl->io_queues[HCTX_TYPE_POLL]; set->map[HCTX_TYPE_POLL].queue_offset = ctrl->io_queues[HCTX_TYPE_DEFAULT] + ctrl->io_queues[HCTX_TYPE_READ]; - blk_mq_map_queues(&set->map[HCTX_TYPE_POLL]); + blk_mq_map_queues(&set->map[HCTX_TYPE_POLL], + ctrl->io_queues[HCTX_TYPE_POLL]); } dev_info(ctrl->ctrl.device, diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c index b520a980d1dc..71058bec7d98 100644 --- a/drivers/scsi/qla2xxx/qla_os.c +++ b/drivers/scsi/qla2xxx/qla_os.c @@ -7114,10 +7114,12 @@ static int qla2xxx_map_queues(struct Scsi_Host *shost) scsi_qla_host_t *vha = (scsi_qla_host_t *)shost->hostdata; struct blk_mq_queue_map *qmap = &shost->tag_set.map[HCTX_TYPE_DEFAULT]; - if (USER_CTRL_IRQ(vha->hw) || !vha->hw->mqiobase) - rc = blk_mq_map_queues(qmap); - else + if (USER_CTRL_IRQ(vha->hw) || !vha->hw->mqiobase) { + rc = blk_mq_map_queues(qmap, shost->tag_set.nr_hw_queues); + } else { + qmap->nr_queues = shost->tag_set.nr_hw_queues; rc = blk_mq_pci_map_queues(qmap, vha->hw->pdev, vha->irq_offset); + } return rc; } diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c index 610ee41fa54c..45a4b115dadf 100644 --- a/drivers/scsi/scsi_lib.c +++ b/drivers/scsi/scsi_lib.c @@ -1775,7 +1775,8 @@ static int scsi_map_queues(struct blk_mq_tag_set *set) if (shost->hostt->map_queues) return shost->hostt->map_queues(shost); - return blk_mq_map_queues(&set->map[HCTX_TYPE_DEFAULT]); + return blk_mq_map_queues(&set->map[HCTX_TYPE_DEFAULT], + set->nr_hw_queues); } void __scsi_init_queue(struct Scsi_Host *shost, struct request_queue *q) diff --git a/drivers/scsi/smartpqi/smartpqi_init.c b/drivers/scsi/smartpqi/smartpqi_init.c index b7492568e02f..18ae5ce129b2 100644 --- a/drivers/scsi/smartpqi/smartpqi_init.c +++ b/drivers/scsi/smartpqi/smartpqi_init.c @@ -5826,9 +5826,10 @@ static int pqi_slave_alloc(struct scsi_device *sdev) static int pqi_map_queues(struct Scsi_Host *shost) { struct pqi_ctrl_info *ctrl_info = shost_to_hba(shost); + struct blk_mq_queue_map *qmap = &shost->tag_set.map[HCTX_TYPE_DEFAULT]; - return blk_mq_pci_map_queues(&shost->tag_set.map[HCTX_TYPE_DEFAULT], - ctrl_info->pci_dev, 0); + qmap->nr_queues = shost->tag_set.nr_hw_queues; + return blk_mq_pci_map_queues(qmap, ctrl_info->pci_dev, 0); } static int pqi_getpciinfo_ioctl(struct pqi_ctrl_info *ctrl_info, diff --git a/drivers/scsi/virtio_scsi.c b/drivers/scsi/virtio_scsi.c index bfec84aacd90..9b9da0409643 100644 --- a/drivers/scsi/virtio_scsi.c +++ b/drivers/scsi/virtio_scsi.c @@ -705,6 +705,7 @@ static int virtscsi_map_queues(struct Scsi_Host *shost) struct virtio_scsi *vscsi = shost_priv(shost); struct blk_mq_queue_map *qmap = &shost->tag_set.map[HCTX_TYPE_DEFAULT]; + qmap->nr_queues = shost->tag_set.nr_hw_queues; return blk_mq_virtio_map_queues(qmap, vscsi->vdev, 2); } diff --git a/include/linux/blk-mq.h b/include/linux/blk-mq.h index 31344d5f83e2..c63b315ed0c8 100644 --- a/include/linux/blk-mq.h +++ b/include/linux/blk-mq.h @@ -516,7 +516,7 @@ void blk_mq_freeze_queue_wait(struct request_queue *q); int blk_mq_freeze_queue_wait_timeout(struct request_queue *q, unsigned long timeout); -int blk_mq_map_queues(struct blk_mq_queue_map *qmap); +int blk_mq_map_queues(struct blk_mq_queue_map *qmap, unsigned int nr_queues); void blk_mq_update_nr_hw_queues(struct blk_mq_tag_set *set, int nr_hw_queues); void blk_mq_quiesce_queue_nowait(struct request_queue *q);