Skip to content

Commit 1e06b3e

Browse files
committed
Merge tag 'nvme-5.18-2022-03-29' of git://git.infradead.org/nvme into for-5.18/drivers
Pull NVMe fixes from Christoph: "- fix multipath hang when disk goes live over reconnect (Anton Eidelman) - fix RCU hole that allowed for endless looping in multipath round robin (Chris Leech) - remove redundant assignment after left shift (Colin Ian King) - add quirks for Samsung X5 SSDs (Monish Kumar R) - fix the read-only state for zoned namespaces with unsupposed features (Pankaj Raghav) - use a private workqueue instead of the system workqueue in nvmet (Sagi Grimberg) - allow duplicate NSIDs for private namespaces (Sungup Moon) - expose use_threaded_interrupts read-only in sysfs (Xin Hao)" * tag 'nvme-5.18-2022-03-29' of git://git.infradead.org/nvme: nvme-multipath: fix hang when disk goes live over reconnect nvme: fix RCU hole that allowed for endless looping in multipath round robin nvme: allow duplicate NSIDs for private namespaces nvmet: remove redundant assignment after left shift nvmet: use a private workqueue instead of the system workqueue nvme-pci: add quirks for Samsung X5 SSDs nvme-pci: expose use_threaded_interrupts read-only in sysfs nvme: fix the read-only state for zoned namespaces with unsupposed features
2 parents b2479de + a4a6f3c commit 1e06b3e

16 files changed

Lines changed: 133 additions & 57 deletions

File tree

drivers/nvme/host/core.c

Lines changed: 26 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1867,9 +1867,6 @@ static void nvme_update_disk_info(struct gendisk *disk,
18671867
nvme_config_discard(disk, ns);
18681868
blk_queue_max_write_zeroes_sectors(disk->queue,
18691869
ns->ctrl->max_zeroes_sectors);
1870-
1871-
set_disk_ro(disk, (id->nsattr & NVME_NS_ATTR_RO) ||
1872-
test_bit(NVME_NS_FORCE_RO, &ns->flags));
18731870
}
18741871

18751872
static inline bool nvme_first_scan(struct gendisk *disk)
@@ -1930,6 +1927,8 @@ static int nvme_update_ns_info(struct nvme_ns *ns, struct nvme_id_ns *id)
19301927
goto out_unfreeze;
19311928
}
19321929

1930+
set_disk_ro(ns->disk, (id->nsattr & NVME_NS_ATTR_RO) ||
1931+
test_bit(NVME_NS_FORCE_RO, &ns->flags));
19331932
set_bit(NVME_NS_READY, &ns->flags);
19341933
blk_mq_unfreeze_queue(ns->disk->queue);
19351934

@@ -1942,6 +1941,9 @@ static int nvme_update_ns_info(struct nvme_ns *ns, struct nvme_id_ns *id)
19421941
if (nvme_ns_head_multipath(ns->head)) {
19431942
blk_mq_freeze_queue(ns->head->disk->queue);
19441943
nvme_update_disk_info(ns->head->disk, ns, id);
1944+
set_disk_ro(ns->head->disk,
1945+
(id->nsattr & NVME_NS_ATTR_RO) ||
1946+
test_bit(NVME_NS_FORCE_RO, &ns->flags));
19451947
nvme_mpath_revalidate_paths(ns);
19461948
blk_stack_limits(&ns->head->disk->queue->limits,
19471949
&ns->queue->limits, 0);
@@ -3625,15 +3627,20 @@ static const struct attribute_group *nvme_dev_attr_groups[] = {
36253627
NULL,
36263628
};
36273629

3628-
static struct nvme_ns_head *nvme_find_ns_head(struct nvme_subsystem *subsys,
3630+
static struct nvme_ns_head *nvme_find_ns_head(struct nvme_ctrl *ctrl,
36293631
unsigned nsid)
36303632
{
36313633
struct nvme_ns_head *h;
36323634

3633-
lockdep_assert_held(&subsys->lock);
3635+
lockdep_assert_held(&ctrl->subsys->lock);
36343636

3635-
list_for_each_entry(h, &subsys->nsheads, entry) {
3636-
if (h->ns_id != nsid)
3637+
list_for_each_entry(h, &ctrl->subsys->nsheads, entry) {
3638+
/*
3639+
* Private namespaces can share NSIDs under some conditions.
3640+
* In that case we can't use the same ns_head for namespaces
3641+
* with the same NSID.
3642+
*/
3643+
if (h->ns_id != nsid || !nvme_is_unique_nsid(ctrl, h))
36373644
continue;
36383645
if (!list_empty(&h->list) && nvme_tryget_ns_head(h))
36393646
return h;
@@ -3827,7 +3834,7 @@ static int nvme_init_ns_head(struct nvme_ns *ns, unsigned nsid,
38273834
}
38283835

38293836
mutex_lock(&ctrl->subsys->lock);
3830-
head = nvme_find_ns_head(ctrl->subsys, nsid);
3837+
head = nvme_find_ns_head(ctrl, nsid);
38313838
if (!head) {
38323839
ret = nvme_subsys_check_duplicate_ids(ctrl->subsys, ids);
38333840
if (ret) {
@@ -4024,6 +4031,16 @@ static void nvme_ns_remove(struct nvme_ns *ns)
40244031
set_capacity(ns->disk, 0);
40254032
nvme_fault_inject_fini(&ns->fault_inject);
40264033

4034+
/*
4035+
* Ensure that !NVME_NS_READY is seen by other threads to prevent
4036+
* this ns going back into current_path.
4037+
*/
4038+
synchronize_srcu(&ns->head->srcu);
4039+
4040+
/* wait for concurrent submissions */
4041+
if (nvme_mpath_clear_current_path(ns))
4042+
synchronize_srcu(&ns->head->srcu);
4043+
40274044
mutex_lock(&ns->ctrl->subsys->lock);
40284045
list_del_rcu(&ns->siblings);
40294046
if (list_empty(&ns->head->list)) {
@@ -4035,10 +4052,6 @@ static void nvme_ns_remove(struct nvme_ns *ns)
40354052
/* guarantee not available in head->list */
40364053
synchronize_rcu();
40374054

4038-
/* wait for concurrent submissions */
4039-
if (nvme_mpath_clear_current_path(ns))
4040-
synchronize_srcu(&ns->head->srcu);
4041-
40424055
if (!nvme_ns_head_multipath(ns->head))
40434056
nvme_cdev_del(&ns->cdev, &ns->cdev_device);
40444057
del_gendisk(ns->disk);
@@ -4509,6 +4522,7 @@ void nvme_start_ctrl(struct nvme_ctrl *ctrl)
45094522
if (ctrl->queue_count > 1) {
45104523
nvme_queue_scan(ctrl);
45114524
nvme_start_queues(ctrl);
4525+
nvme_mpath_update(ctrl);
45124526
}
45134527

45144528
nvme_change_uevent(ctrl, "NVME_EVENT=connected");

drivers/nvme/host/multipath.c

Lines changed: 27 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -482,10 +482,11 @@ int nvme_mpath_alloc_disk(struct nvme_ctrl *ctrl, struct nvme_ns_head *head)
482482

483483
/*
484484
* Add a multipath node if the subsystems supports multiple controllers.
485-
* We also do this for private namespaces as the namespace sharing data could
486-
* change after a rescan.
485+
* We also do this for private namespaces as the namespace sharing flag
486+
* could change after a rescan.
487487
*/
488-
if (!(ctrl->subsys->cmic & NVME_CTRL_CMIC_MULTI_CTRL) || !multipath)
488+
if (!(ctrl->subsys->cmic & NVME_CTRL_CMIC_MULTI_CTRL) ||
489+
!nvme_is_unique_nsid(ctrl, head) || !multipath)
489490
return 0;
490491

491492
head->disk = blk_alloc_disk(ctrl->numa_node);
@@ -612,8 +613,17 @@ static void nvme_update_ns_ana_state(struct nvme_ana_group_desc *desc,
612613
ns->ana_grpid = le32_to_cpu(desc->grpid);
613614
ns->ana_state = desc->state;
614615
clear_bit(NVME_NS_ANA_PENDING, &ns->flags);
615-
616-
if (nvme_state_is_live(ns->ana_state))
616+
/*
617+
* nvme_mpath_set_live() will trigger I/O to the multipath path device
618+
* and in turn to this path device. However we cannot accept this I/O
619+
* if the controller is not live. This may deadlock if called from
620+
* nvme_mpath_init_identify() and the ctrl will never complete
621+
* initialization, preventing I/O from completing. For this case we
622+
* will reprocess the ANA log page in nvme_mpath_update() once the
623+
* controller is ready.
624+
*/
625+
if (nvme_state_is_live(ns->ana_state) &&
626+
ns->ctrl->state == NVME_CTRL_LIVE)
617627
nvme_mpath_set_live(ns);
618628
}
619629

@@ -700,6 +710,18 @@ static void nvme_ana_work(struct work_struct *work)
700710
nvme_read_ana_log(ctrl);
701711
}
702712

713+
void nvme_mpath_update(struct nvme_ctrl *ctrl)
714+
{
715+
u32 nr_change_groups = 0;
716+
717+
if (!ctrl->ana_log_buf)
718+
return;
719+
720+
mutex_lock(&ctrl->ana_lock);
721+
nvme_parse_ana_log(ctrl, &nr_change_groups, nvme_update_ana_state);
722+
mutex_unlock(&ctrl->ana_lock);
723+
}
724+
703725
static void nvme_anatt_timeout(struct timer_list *t)
704726
{
705727
struct nvme_ctrl *ctrl = from_timer(ctrl, t, anatt_timer);

drivers/nvme/host/nvme.h

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -722,6 +722,25 @@ static inline bool nvme_check_ready(struct nvme_ctrl *ctrl, struct request *rq,
722722
return queue_live;
723723
return __nvme_check_ready(ctrl, rq, queue_live);
724724
}
725+
726+
/*
727+
* NSID shall be unique for all shared namespaces, or if at least one of the
728+
* following conditions is met:
729+
* 1. Namespace Management is supported by the controller
730+
* 2. ANA is supported by the controller
731+
* 3. NVM Set are supported by the controller
732+
*
733+
* In other case, private namespace are not required to report a unique NSID.
734+
*/
735+
static inline bool nvme_is_unique_nsid(struct nvme_ctrl *ctrl,
736+
struct nvme_ns_head *head)
737+
{
738+
return head->shared ||
739+
(ctrl->oacs & NVME_CTRL_OACS_NS_MNGT_SUPP) ||
740+
(ctrl->subsys->cmic & NVME_CTRL_CMIC_ANA) ||
741+
(ctrl->ctratt & NVME_CTRL_CTRATT_NVM_SETS);
742+
}
743+
725744
int nvme_submit_sync_cmd(struct request_queue *q, struct nvme_command *cmd,
726745
void *buf, unsigned bufflen);
727746
int __nvme_submit_sync_cmd(struct request_queue *q, struct nvme_command *cmd,
@@ -781,6 +800,7 @@ void nvme_mpath_add_disk(struct nvme_ns *ns, struct nvme_id_ns *id);
781800
void nvme_mpath_remove_disk(struct nvme_ns_head *head);
782801
int nvme_mpath_init_identify(struct nvme_ctrl *ctrl, struct nvme_id_ctrl *id);
783802
void nvme_mpath_init_ctrl(struct nvme_ctrl *ctrl);
803+
void nvme_mpath_update(struct nvme_ctrl *ctrl);
784804
void nvme_mpath_uninit(struct nvme_ctrl *ctrl);
785805
void nvme_mpath_stop(struct nvme_ctrl *ctrl);
786806
bool nvme_mpath_clear_current_path(struct nvme_ns *ns);
@@ -852,6 +872,9 @@ static inline int nvme_mpath_init_identify(struct nvme_ctrl *ctrl,
852872
"Please enable CONFIG_NVME_MULTIPATH for full support of multi-port devices.\n");
853873
return 0;
854874
}
875+
static inline void nvme_mpath_update(struct nvme_ctrl *ctrl)
876+
{
877+
}
855878
static inline void nvme_mpath_uninit(struct nvme_ctrl *ctrl)
856879
{
857880
}

drivers/nvme/host/pci.c

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@
4444
#define NVME_MAX_SEGS 127
4545

4646
static int use_threaded_interrupts;
47-
module_param(use_threaded_interrupts, int, 0);
47+
module_param(use_threaded_interrupts, int, 0444);
4848

4949
static bool use_cmb_sqes = true;
5050
module_param(use_cmb_sqes, bool, 0444);
@@ -3466,7 +3466,10 @@ static const struct pci_device_id nvme_id_table[] = {
34663466
NVME_QUIRK_128_BYTES_SQES |
34673467
NVME_QUIRK_SHARED_TAGS |
34683468
NVME_QUIRK_SKIP_CID_GEN },
3469-
3469+
{ PCI_DEVICE(0x144d, 0xa808), /* Samsung X5 */
3470+
.driver_data = NVME_QUIRK_DELAY_BEFORE_CHK_RDY|
3471+
NVME_QUIRK_NO_DEEPEST_PS |
3472+
NVME_QUIRK_IGNORE_DEV_SUBNQN, },
34703473
{ PCI_DEVICE_CLASS(PCI_CLASS_STORAGE_EXPRESS, 0xffffff) },
34713474
{ 0, }
34723475
};

drivers/nvme/target/admin-cmd.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -988,7 +988,7 @@ void nvmet_execute_async_event(struct nvmet_req *req)
988988
ctrl->async_event_cmds[ctrl->nr_async_event_cmds++] = req;
989989
mutex_unlock(&ctrl->lock);
990990

991-
schedule_work(&ctrl->async_event_work);
991+
queue_work(nvmet_wq, &ctrl->async_event_work);
992992
}
993993

994994
void nvmet_execute_keep_alive(struct nvmet_req *req)

drivers/nvme/target/configfs.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1593,7 +1593,7 @@ static void nvmet_port_release(struct config_item *item)
15931593
struct nvmet_port *port = to_nvmet_port(item);
15941594

15951595
/* Let inflight controllers teardown complete */
1596-
flush_scheduled_work();
1596+
flush_workqueue(nvmet_wq);
15971597
list_del(&port->global_entry);
15981598

15991599
kfree(port->ana_state);

drivers/nvme/target/core.c

Lines changed: 19 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,9 @@ struct workqueue_struct *zbd_wq;
2020
static const struct nvmet_fabrics_ops *nvmet_transports[NVMF_TRTYPE_MAX];
2121
static DEFINE_IDA(cntlid_ida);
2222

23+
struct workqueue_struct *nvmet_wq;
24+
EXPORT_SYMBOL_GPL(nvmet_wq);
25+
2326
/*
2427
* This read/write semaphore is used to synchronize access to configuration
2528
* information on a target system that will result in discovery log page
@@ -205,7 +208,7 @@ void nvmet_add_async_event(struct nvmet_ctrl *ctrl, u8 event_type,
205208
list_add_tail(&aen->entry, &ctrl->async_events);
206209
mutex_unlock(&ctrl->lock);
207210

208-
schedule_work(&ctrl->async_event_work);
211+
queue_work(nvmet_wq, &ctrl->async_event_work);
209212
}
210213

211214
static void nvmet_add_to_changed_ns_log(struct nvmet_ctrl *ctrl, __le32 nsid)
@@ -385,7 +388,7 @@ static void nvmet_keep_alive_timer(struct work_struct *work)
385388
if (reset_tbkas) {
386389
pr_debug("ctrl %d reschedule traffic based keep-alive timer\n",
387390
ctrl->cntlid);
388-
schedule_delayed_work(&ctrl->ka_work, ctrl->kato * HZ);
391+
queue_delayed_work(nvmet_wq, &ctrl->ka_work, ctrl->kato * HZ);
389392
return;
390393
}
391394

@@ -403,7 +406,7 @@ void nvmet_start_keep_alive_timer(struct nvmet_ctrl *ctrl)
403406
pr_debug("ctrl %d start keep-alive timer for %d secs\n",
404407
ctrl->cntlid, ctrl->kato);
405408

406-
schedule_delayed_work(&ctrl->ka_work, ctrl->kato * HZ);
409+
queue_delayed_work(nvmet_wq, &ctrl->ka_work, ctrl->kato * HZ);
407410
}
408411

409412
void nvmet_stop_keep_alive_timer(struct nvmet_ctrl *ctrl)
@@ -1120,7 +1123,7 @@ static inline u8 nvmet_cc_iocqes(u32 cc)
11201123

11211124
static inline bool nvmet_css_supported(u8 cc_css)
11221125
{
1123-
switch (cc_css <<= NVME_CC_CSS_SHIFT) {
1126+
switch (cc_css << NVME_CC_CSS_SHIFT) {
11241127
case NVME_CC_CSS_NVM:
11251128
case NVME_CC_CSS_CSI:
11261129
return true;
@@ -1478,7 +1481,7 @@ void nvmet_ctrl_fatal_error(struct nvmet_ctrl *ctrl)
14781481
mutex_lock(&ctrl->lock);
14791482
if (!(ctrl->csts & NVME_CSTS_CFS)) {
14801483
ctrl->csts |= NVME_CSTS_CFS;
1481-
schedule_work(&ctrl->fatal_err_work);
1484+
queue_work(nvmet_wq, &ctrl->fatal_err_work);
14821485
}
14831486
mutex_unlock(&ctrl->lock);
14841487
}
@@ -1620,9 +1623,15 @@ static int __init nvmet_init(void)
16201623
goto out_free_zbd_work_queue;
16211624
}
16221625

1626+
nvmet_wq = alloc_workqueue("nvmet-wq", WQ_MEM_RECLAIM, 0);
1627+
if (!nvmet_wq) {
1628+
error = -ENOMEM;
1629+
goto out_free_buffered_work_queue;
1630+
}
1631+
16231632
error = nvmet_init_discovery();
16241633
if (error)
1625-
goto out_free_work_queue;
1634+
goto out_free_nvmet_work_queue;
16261635

16271636
error = nvmet_init_configfs();
16281637
if (error)
@@ -1631,7 +1640,9 @@ static int __init nvmet_init(void)
16311640

16321641
out_exit_discovery:
16331642
nvmet_exit_discovery();
1634-
out_free_work_queue:
1643+
out_free_nvmet_work_queue:
1644+
destroy_workqueue(nvmet_wq);
1645+
out_free_buffered_work_queue:
16351646
destroy_workqueue(buffered_io_wq);
16361647
out_free_zbd_work_queue:
16371648
destroy_workqueue(zbd_wq);
@@ -1643,6 +1654,7 @@ static void __exit nvmet_exit(void)
16431654
nvmet_exit_configfs();
16441655
nvmet_exit_discovery();
16451656
ida_destroy(&cntlid_ida);
1657+
destroy_workqueue(nvmet_wq);
16461658
destroy_workqueue(buffered_io_wq);
16471659
destroy_workqueue(zbd_wq);
16481660

drivers/nvme/target/fc.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1491,7 +1491,7 @@ __nvmet_fc_free_assocs(struct nvmet_fc_tgtport *tgtport)
14911491
list_for_each_entry_rcu(assoc, &tgtport->assoc_list, a_list) {
14921492
if (!nvmet_fc_tgt_a_get(assoc))
14931493
continue;
1494-
if (!schedule_work(&assoc->del_work))
1494+
if (!queue_work(nvmet_wq, &assoc->del_work))
14951495
/* already deleting - release local reference */
14961496
nvmet_fc_tgt_a_put(assoc);
14971497
}
@@ -1546,7 +1546,7 @@ nvmet_fc_invalidate_host(struct nvmet_fc_target_port *target_port,
15461546
continue;
15471547
assoc->hostport->invalid = 1;
15481548
noassoc = false;
1549-
if (!schedule_work(&assoc->del_work))
1549+
if (!queue_work(nvmet_wq, &assoc->del_work))
15501550
/* already deleting - release local reference */
15511551
nvmet_fc_tgt_a_put(assoc);
15521552
}
@@ -1592,7 +1592,7 @@ nvmet_fc_delete_ctrl(struct nvmet_ctrl *ctrl)
15921592
nvmet_fc_tgtport_put(tgtport);
15931593

15941594
if (found_ctrl) {
1595-
if (!schedule_work(&assoc->del_work))
1595+
if (!queue_work(nvmet_wq, &assoc->del_work))
15961596
/* already deleting - release local reference */
15971597
nvmet_fc_tgt_a_put(assoc);
15981598
return;
@@ -2060,7 +2060,7 @@ nvmet_fc_rcv_ls_req(struct nvmet_fc_target_port *target_port,
20602060
iod->rqstdatalen = lsreqbuf_len;
20612061
iod->hosthandle = hosthandle;
20622062

2063-
schedule_work(&iod->work);
2063+
queue_work(nvmet_wq, &iod->work);
20642064

20652065
return 0;
20662066
}

0 commit comments

Comments
 (0)