Skip to content

Commit 1b52671

Browse files
committed
Merge branch 'nvme-5.8' of git://git.infradead.org/nvme into block-5.8
Pull NVMe fixes from Christoph. * 'nvme-5.8' of git://git.infradead.org/nvme: nvme-multipath: fix bogus request queue reference put nvme-multipath: fix deadlock due to head->lock nvme: don't protect ns mutation with ns->head->lock nvme-multipath: fix deadlock between ana_work and scan_work nvme: fix possible deadlock when I/O is blocked nvme-rdma: assign completion vector correctly nvme-loop: initialize tagset numa value to the value of the ctrl nvme-tcp: initialize tagset numa value to the value of the ctrl nvme-pci: initialize tagset numa value to the value of the ctrl nvme-pci: override the value of the controller's numa node nvme: set initial value for controller's numa node
2 parents 0b8eb62 + c312446 commit 1b52671

File tree

7 files changed

+41
-25
lines changed

7 files changed

+41
-25
lines changed

drivers/nvme/host/core.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1974,7 +1974,6 @@ static int __nvme_revalidate_disk(struct gendisk *disk, struct nvme_id_ns *id)
19741974
if (ns->head->disk) {
19751975
nvme_update_disk_info(ns->head->disk, ns, id);
19761976
blk_queue_stack_limits(ns->head->disk->queue, ns->queue);
1977-
revalidate_disk(ns->head->disk);
19781977
}
19791978
#endif
19801979
return 0;
@@ -4174,6 +4173,7 @@ int nvme_init_ctrl(struct nvme_ctrl *ctrl, struct device *dev,
41744173
ctrl->dev = dev;
41754174
ctrl->ops = ops;
41764175
ctrl->quirks = quirks;
4176+
ctrl->numa_node = NUMA_NO_NODE;
41774177
INIT_WORK(&ctrl->scan_work, nvme_scan_work);
41784178
INIT_WORK(&ctrl->async_event_work, nvme_async_event_work);
41794179
INIT_WORK(&ctrl->fw_act_work, nvme_fw_act_work);

drivers/nvme/host/multipath.c

Lines changed: 29 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -409,15 +409,14 @@ static void nvme_mpath_set_live(struct nvme_ns *ns)
409409
{
410410
struct nvme_ns_head *head = ns->head;
411411

412-
lockdep_assert_held(&ns->head->lock);
413-
414412
if (!head->disk)
415413
return;
416414

417-
if (!(head->disk->flags & GENHD_FL_UP))
415+
if (!test_and_set_bit(NVME_NSHEAD_DISK_LIVE, &head->flags))
418416
device_add_disk(&head->subsys->dev, head->disk,
419417
nvme_ns_id_attr_groups);
420418

419+
mutex_lock(&head->lock);
421420
if (nvme_path_is_optimized(ns)) {
422421
int node, srcu_idx;
423422

@@ -426,9 +425,10 @@ static void nvme_mpath_set_live(struct nvme_ns *ns)
426425
__nvme_find_path(head, node);
427426
srcu_read_unlock(&head->srcu, srcu_idx);
428427
}
428+
mutex_unlock(&head->lock);
429429

430-
synchronize_srcu(&ns->head->srcu);
431-
kblockd_schedule_work(&ns->head->requeue_work);
430+
synchronize_srcu(&head->srcu);
431+
kblockd_schedule_work(&head->requeue_work);
432432
}
433433

434434
static int nvme_parse_ana_log(struct nvme_ctrl *ctrl, void *data,
@@ -483,14 +483,12 @@ static inline bool nvme_state_is_live(enum nvme_ana_state state)
483483
static void nvme_update_ns_ana_state(struct nvme_ana_group_desc *desc,
484484
struct nvme_ns *ns)
485485
{
486-
mutex_lock(&ns->head->lock);
487486
ns->ana_grpid = le32_to_cpu(desc->grpid);
488487
ns->ana_state = desc->state;
489488
clear_bit(NVME_NS_ANA_PENDING, &ns->flags);
490489

491490
if (nvme_state_is_live(ns->ana_state))
492491
nvme_mpath_set_live(ns);
493-
mutex_unlock(&ns->head->lock);
494492
}
495493

496494
static int nvme_update_ana_state(struct nvme_ctrl *ctrl,
@@ -640,31 +638,37 @@ static ssize_t ana_state_show(struct device *dev, struct device_attribute *attr,
640638
}
641639
DEVICE_ATTR_RO(ana_state);
642640

643-
static int nvme_set_ns_ana_state(struct nvme_ctrl *ctrl,
641+
static int nvme_lookup_ana_group_desc(struct nvme_ctrl *ctrl,
644642
struct nvme_ana_group_desc *desc, void *data)
645643
{
646-
struct nvme_ns *ns = data;
644+
struct nvme_ana_group_desc *dst = data;
647645

648-
if (ns->ana_grpid == le32_to_cpu(desc->grpid)) {
649-
nvme_update_ns_ana_state(desc, ns);
650-
return -ENXIO; /* just break out of the loop */
651-
}
646+
if (desc->grpid != dst->grpid)
647+
return 0;
652648

653-
return 0;
649+
*dst = *desc;
650+
return -ENXIO; /* just break out of the loop */
654651
}
655652

656653
void nvme_mpath_add_disk(struct nvme_ns *ns, struct nvme_id_ns *id)
657654
{
658655
if (nvme_ctrl_use_ana(ns->ctrl)) {
656+
struct nvme_ana_group_desc desc = {
657+
.grpid = id->anagrpid,
658+
.state = 0,
659+
};
660+
659661
mutex_lock(&ns->ctrl->ana_lock);
660662
ns->ana_grpid = le32_to_cpu(id->anagrpid);
661-
nvme_parse_ana_log(ns->ctrl, ns, nvme_set_ns_ana_state);
663+
nvme_parse_ana_log(ns->ctrl, &desc, nvme_lookup_ana_group_desc);
662664
mutex_unlock(&ns->ctrl->ana_lock);
665+
if (desc.state) {
666+
/* found the group desc: update */
667+
nvme_update_ns_ana_state(&desc, ns);
668+
}
663669
} else {
664-
mutex_lock(&ns->head->lock);
665670
ns->ana_state = NVME_ANA_OPTIMIZED;
666671
nvme_mpath_set_live(ns);
667-
mutex_unlock(&ns->head->lock);
668672
}
669673

670674
if (bdi_cap_stable_pages_required(ns->queue->backing_dev_info)) {
@@ -686,6 +690,14 @@ void nvme_mpath_remove_disk(struct nvme_ns_head *head)
686690
kblockd_schedule_work(&head->requeue_work);
687691
flush_work(&head->requeue_work);
688692
blk_cleanup_queue(head->disk->queue);
693+
if (!test_bit(NVME_NSHEAD_DISK_LIVE, &head->flags)) {
694+
/*
695+
* if device_add_disk wasn't called, prevent
696+
* disk release to put a bogus reference on the
697+
* request queue
698+
*/
699+
head->disk->queue = NULL;
700+
}
689701
put_disk(head->disk);
690702
}
691703

drivers/nvme/host/nvme.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -364,6 +364,8 @@ struct nvme_ns_head {
364364
spinlock_t requeue_lock;
365365
struct work_struct requeue_work;
366366
struct mutex lock;
367+
unsigned long flags;
368+
#define NVME_NSHEAD_DISK_LIVE 0
367369
struct nvme_ns __rcu *current_path[];
368370
#endif
369371
};

drivers/nvme/host/pci.c

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1593,7 +1593,7 @@ static int nvme_alloc_admin_tags(struct nvme_dev *dev)
15931593

15941594
dev->admin_tagset.queue_depth = NVME_AQ_MQ_TAG_DEPTH;
15951595
dev->admin_tagset.timeout = ADMIN_TIMEOUT;
1596-
dev->admin_tagset.numa_node = dev_to_node(dev->dev);
1596+
dev->admin_tagset.numa_node = dev->ctrl.numa_node;
15971597
dev->admin_tagset.cmd_size = sizeof(struct nvme_iod);
15981598
dev->admin_tagset.flags = BLK_MQ_F_NO_SCHED;
15991599
dev->admin_tagset.driver_data = dev;
@@ -1669,6 +1669,8 @@ static int nvme_pci_configure_admin_queue(struct nvme_dev *dev)
16691669
if (result)
16701670
return result;
16711671

1672+
dev->ctrl.numa_node = dev_to_node(dev->dev);
1673+
16721674
nvmeq = &dev->queues[0];
16731675
aqa = nvmeq->q_depth - 1;
16741676
aqa |= aqa << 16;
@@ -2257,7 +2259,7 @@ static void nvme_dev_add(struct nvme_dev *dev)
22572259
if (dev->io_queues[HCTX_TYPE_POLL])
22582260
dev->tagset.nr_maps++;
22592261
dev->tagset.timeout = NVME_IO_TIMEOUT;
2260-
dev->tagset.numa_node = dev_to_node(dev->dev);
2262+
dev->tagset.numa_node = dev->ctrl.numa_node;
22612263
dev->tagset.queue_depth =
22622264
min_t(int, dev->q_depth, BLK_MQ_MAX_DEPTH) - 1;
22632265
dev->tagset.cmd_size = sizeof(struct nvme_iod);

drivers/nvme/host/rdma.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -470,7 +470,7 @@ static int nvme_rdma_create_queue_ib(struct nvme_rdma_queue *queue)
470470
* Spread I/O queues completion vectors according their queue index.
471471
* Admin queues can always go on completion vector 0.
472472
*/
473-
comp_vector = idx == 0 ? idx : idx - 1;
473+
comp_vector = (idx == 0 ? idx : idx - 1) % ibdev->num_comp_vectors;
474474

475475
/* Polling queues need direct cq polling context */
476476
if (nvme_rdma_poll_queue(queue))

drivers/nvme/host/tcp.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1532,7 +1532,7 @@ static struct blk_mq_tag_set *nvme_tcp_alloc_tagset(struct nvme_ctrl *nctrl,
15321532
set->ops = &nvme_tcp_admin_mq_ops;
15331533
set->queue_depth = NVME_AQ_MQ_TAG_DEPTH;
15341534
set->reserved_tags = 2; /* connect + keep-alive */
1535-
set->numa_node = NUMA_NO_NODE;
1535+
set->numa_node = nctrl->numa_node;
15361536
set->flags = BLK_MQ_F_BLOCKING;
15371537
set->cmd_size = sizeof(struct nvme_tcp_request);
15381538
set->driver_data = ctrl;
@@ -1544,7 +1544,7 @@ static struct blk_mq_tag_set *nvme_tcp_alloc_tagset(struct nvme_ctrl *nctrl,
15441544
set->ops = &nvme_tcp_mq_ops;
15451545
set->queue_depth = nctrl->sqsize + 1;
15461546
set->reserved_tags = 1; /* fabric connect */
1547-
set->numa_node = NUMA_NO_NODE;
1547+
set->numa_node = nctrl->numa_node;
15481548
set->flags = BLK_MQ_F_SHOULD_MERGE | BLK_MQ_F_BLOCKING;
15491549
set->cmd_size = sizeof(struct nvme_tcp_request);
15501550
set->driver_data = ctrl;

drivers/nvme/target/loop.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -340,7 +340,7 @@ static int nvme_loop_configure_admin_queue(struct nvme_loop_ctrl *ctrl)
340340
ctrl->admin_tag_set.ops = &nvme_loop_admin_mq_ops;
341341
ctrl->admin_tag_set.queue_depth = NVME_AQ_MQ_TAG_DEPTH;
342342
ctrl->admin_tag_set.reserved_tags = 2; /* connect + keep-alive */
343-
ctrl->admin_tag_set.numa_node = NUMA_NO_NODE;
343+
ctrl->admin_tag_set.numa_node = ctrl->ctrl.numa_node;
344344
ctrl->admin_tag_set.cmd_size = sizeof(struct nvme_loop_iod) +
345345
NVME_INLINE_SG_CNT * sizeof(struct scatterlist);
346346
ctrl->admin_tag_set.driver_data = ctrl;
@@ -512,7 +512,7 @@ static int nvme_loop_create_io_queues(struct nvme_loop_ctrl *ctrl)
512512
ctrl->tag_set.ops = &nvme_loop_mq_ops;
513513
ctrl->tag_set.queue_depth = ctrl->ctrl.opts->queue_size;
514514
ctrl->tag_set.reserved_tags = 1; /* fabric connect */
515-
ctrl->tag_set.numa_node = NUMA_NO_NODE;
515+
ctrl->tag_set.numa_node = ctrl->ctrl.numa_node;
516516
ctrl->tag_set.flags = BLK_MQ_F_SHOULD_MERGE;
517517
ctrl->tag_set.cmd_size = sizeof(struct nvme_loop_iod) +
518518
NVME_INLINE_SG_CNT * sizeof(struct scatterlist);

0 commit comments

Comments
 (0)