diff options
author | Jens Axboe <axboe@kernel.dk> | 2019-05-23 12:27:04 -0400 |
---|---|---|
committer | Jens Axboe <axboe@kernel.dk> | 2019-05-23 12:27:04 -0400 |
commit | 096c7a6d90082586ff265d99e8e4a052dee3a403 (patch) | |
tree | 2f1e414e20a0a9a6c0f40761851e520227807a9b | |
parent | 004d564f908790efe815a6510a542ac1227ef2a2 (diff) | |
parent | cb9e0e5006064a807b5d722c7e3c42f307193792 (diff) |
Merge branch 'nvme-5.2-rc2' of git://git.infradead.org/nvme into for-linus
Pull NVMe changes from Keith.
* 'nvme-5.2-rc2' of git://git.infradead.org/nvme:
nvme-pci: use blk-mq mapping for unmanaged irqs
nvme: update MAINTAINERS
nvme: copy MTFA field from identify controller
nvme: fix memory leak for power latency tolerance
nvme: release namespace SRCU protection before performing controller ioctls
nvme: merge nvme_ns_ioctl into nvme_ioctl
nvme: remove the ifdef around nvme_nvm_ioctl
nvme: fix srcu locking on error return in nvme_get_ns_from_disk
nvme: Fix known effects
nvme-pci: Sync queues on reset
nvme-pci: Unblock reset_work on IO failure
nvme-pci: Don't disable on timeout in reset state
nvme-pci: Fix controller freeze wait disabling
-rw-r--r-- | MAINTAINERS | 2 | ||||
-rw-r--r-- | drivers/nvme/host/core.c | 89 | ||||
-rw-r--r-- | drivers/nvme/host/nvme.h | 1 | ||||
-rw-r--r-- | drivers/nvme/host/pci.c | 27 |
4 files changed, 77 insertions, 42 deletions
diff --git a/MAINTAINERS b/MAINTAINERS index 634f1d035767..82a9308ecb93 100644 --- a/MAINTAINERS +++ b/MAINTAINERS | |||
@@ -11227,7 +11227,7 @@ F: drivers/video/fbdev/riva/ | |||
11227 | F: drivers/video/fbdev/nvidia/ | 11227 | F: drivers/video/fbdev/nvidia/ |
11228 | 11228 | ||
11229 | NVM EXPRESS DRIVER | 11229 | NVM EXPRESS DRIVER |
11230 | M: Keith Busch <keith.busch@intel.com> | 11230 | M: Keith Busch <kbusch@kernel.org> |
11231 | M: Jens Axboe <axboe@fb.com> | 11231 | M: Jens Axboe <axboe@fb.com> |
11232 | M: Christoph Hellwig <hch@lst.de> | 11232 | M: Christoph Hellwig <hch@lst.de> |
11233 | M: Sagi Grimberg <sagi@grimberg.me> | 11233 | M: Sagi Grimberg <sagi@grimberg.me> |
diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c index 7da80f375315..1b7c2afd84cb 100644 --- a/drivers/nvme/host/core.c +++ b/drivers/nvme/host/core.c | |||
@@ -1257,9 +1257,9 @@ static u32 nvme_passthru_start(struct nvme_ctrl *ctrl, struct nvme_ns *ns, | |||
1257 | return 0; | 1257 | return 0; |
1258 | } | 1258 | } |
1259 | 1259 | ||
1260 | effects |= nvme_known_admin_effects(opcode); | ||
1261 | if (ctrl->effects) | 1260 | if (ctrl->effects) |
1262 | effects = le32_to_cpu(ctrl->effects->acs[opcode]); | 1261 | effects = le32_to_cpu(ctrl->effects->acs[opcode]); |
1262 | effects |= nvme_known_admin_effects(opcode); | ||
1263 | 1263 | ||
1264 | /* | 1264 | /* |
1265 | * For simplicity, IO to all namespaces is quiesced even if the command | 1265 | * For simplicity, IO to all namespaces is quiesced even if the command |
@@ -1361,9 +1361,14 @@ static struct nvme_ns *nvme_get_ns_from_disk(struct gendisk *disk, | |||
1361 | { | 1361 | { |
1362 | #ifdef CONFIG_NVME_MULTIPATH | 1362 | #ifdef CONFIG_NVME_MULTIPATH |
1363 | if (disk->fops == &nvme_ns_head_ops) { | 1363 | if (disk->fops == &nvme_ns_head_ops) { |
1364 | struct nvme_ns *ns; | ||
1365 | |||
1364 | *head = disk->private_data; | 1366 | *head = disk->private_data; |
1365 | *srcu_idx = srcu_read_lock(&(*head)->srcu); | 1367 | *srcu_idx = srcu_read_lock(&(*head)->srcu); |
1366 | return nvme_find_path(*head); | 1368 | ns = nvme_find_path(*head); |
1369 | if (!ns) | ||
1370 | srcu_read_unlock(&(*head)->srcu, *srcu_idx); | ||
1371 | return ns; | ||
1367 | } | 1372 | } |
1368 | #endif | 1373 | #endif |
1369 | *head = NULL; | 1374 | *head = NULL; |
@@ -1377,42 +1382,56 @@ static void nvme_put_ns_from_disk(struct nvme_ns_head *head, int idx) | |||
1377 | srcu_read_unlock(&head->srcu, idx); | 1382 | srcu_read_unlock(&head->srcu, idx); |
1378 | } | 1383 | } |
1379 | 1384 | ||
1380 | static int nvme_ns_ioctl(struct nvme_ns *ns, unsigned cmd, unsigned long arg) | 1385 | static int nvme_ioctl(struct block_device *bdev, fmode_t mode, |
1386 | unsigned int cmd, unsigned long arg) | ||
1381 | { | 1387 | { |
1388 | struct nvme_ns_head *head = NULL; | ||
1389 | void __user *argp = (void __user *)arg; | ||
1390 | struct nvme_ns *ns; | ||
1391 | int srcu_idx, ret; | ||
1392 | |||
1393 | ns = nvme_get_ns_from_disk(bdev->bd_disk, &head, &srcu_idx); | ||
1394 | if (unlikely(!ns)) | ||
1395 | return -EWOULDBLOCK; | ||
1396 | |||
1397 | /* | ||
1398 | * Handle ioctls that apply to the controller instead of the namespace | ||
1399 | * seperately and drop the ns SRCU reference early. This avoids a | ||
1400 | * deadlock when deleting namespaces using the passthrough interface. | ||
1401 | */ | ||
1402 | if (cmd == NVME_IOCTL_ADMIN_CMD || is_sed_ioctl(cmd)) { | ||
1403 | struct nvme_ctrl *ctrl = ns->ctrl; | ||
1404 | |||
1405 | nvme_get_ctrl(ns->ctrl); | ||
1406 | nvme_put_ns_from_disk(head, srcu_idx); | ||
1407 | |||
1408 | if (cmd == NVME_IOCTL_ADMIN_CMD) | ||
1409 | ret = nvme_user_cmd(ctrl, NULL, argp); | ||
1410 | else | ||
1411 | ret = sed_ioctl(ctrl->opal_dev, cmd, argp); | ||
1412 | |||
1413 | nvme_put_ctrl(ctrl); | ||
1414 | return ret; | ||
1415 | } | ||
1416 | |||
1382 | switch (cmd) { | 1417 | switch (cmd) { |
1383 | case NVME_IOCTL_ID: | 1418 | case NVME_IOCTL_ID: |
1384 | force_successful_syscall_return(); | 1419 | force_successful_syscall_return(); |
1385 | return ns->head->ns_id; | 1420 | ret = ns->head->ns_id; |
1386 | case NVME_IOCTL_ADMIN_CMD: | 1421 | break; |
1387 | return nvme_user_cmd(ns->ctrl, NULL, (void __user *)arg); | ||
1388 | case NVME_IOCTL_IO_CMD: | 1422 | case NVME_IOCTL_IO_CMD: |
1389 | return nvme_user_cmd(ns->ctrl, ns, (void __user *)arg); | 1423 | ret = nvme_user_cmd(ns->ctrl, ns, argp); |
1424 | break; | ||
1390 | case NVME_IOCTL_SUBMIT_IO: | 1425 | case NVME_IOCTL_SUBMIT_IO: |
1391 | return nvme_submit_io(ns, (void __user *)arg); | 1426 | ret = nvme_submit_io(ns, argp); |
1427 | break; | ||
1392 | default: | 1428 | default: |
1393 | #ifdef CONFIG_NVM | ||
1394 | if (ns->ndev) | 1429 | if (ns->ndev) |
1395 | return nvme_nvm_ioctl(ns, cmd, arg); | 1430 | ret = nvme_nvm_ioctl(ns, cmd, arg); |
1396 | #endif | 1431 | else |
1397 | if (is_sed_ioctl(cmd)) | 1432 | ret = -ENOTTY; |
1398 | return sed_ioctl(ns->ctrl->opal_dev, cmd, | ||
1399 | (void __user *) arg); | ||
1400 | return -ENOTTY; | ||
1401 | } | 1433 | } |
1402 | } | ||
1403 | |||
1404 | static int nvme_ioctl(struct block_device *bdev, fmode_t mode, | ||
1405 | unsigned int cmd, unsigned long arg) | ||
1406 | { | ||
1407 | struct nvme_ns_head *head = NULL; | ||
1408 | struct nvme_ns *ns; | ||
1409 | int srcu_idx, ret; | ||
1410 | 1434 | ||
1411 | ns = nvme_get_ns_from_disk(bdev->bd_disk, &head, &srcu_idx); | ||
1412 | if (unlikely(!ns)) | ||
1413 | ret = -EWOULDBLOCK; | ||
1414 | else | ||
1415 | ret = nvme_ns_ioctl(ns, cmd, arg); | ||
1416 | nvme_put_ns_from_disk(head, srcu_idx); | 1435 | nvme_put_ns_from_disk(head, srcu_idx); |
1417 | return ret; | 1436 | return ret; |
1418 | } | 1437 | } |
@@ -2557,6 +2576,7 @@ int nvme_init_identify(struct nvme_ctrl *ctrl) | |||
2557 | 2576 | ||
2558 | ctrl->oacs = le16_to_cpu(id->oacs); | 2577 | ctrl->oacs = le16_to_cpu(id->oacs); |
2559 | ctrl->oncs = le16_to_cpu(id->oncs); | 2578 | ctrl->oncs = le16_to_cpu(id->oncs); |
2579 | ctrl->mtfa = le16_to_cpu(id->mtfa); | ||
2560 | ctrl->oaes = le32_to_cpu(id->oaes); | 2580 | ctrl->oaes = le32_to_cpu(id->oaes); |
2561 | atomic_set(&ctrl->abort_limit, id->acl + 1); | 2581 | atomic_set(&ctrl->abort_limit, id->acl + 1); |
2562 | ctrl->vwc = id->vwc; | 2582 | ctrl->vwc = id->vwc; |
@@ -3681,6 +3701,7 @@ EXPORT_SYMBOL_GPL(nvme_start_ctrl); | |||
3681 | 3701 | ||
3682 | void nvme_uninit_ctrl(struct nvme_ctrl *ctrl) | 3702 | void nvme_uninit_ctrl(struct nvme_ctrl *ctrl) |
3683 | { | 3703 | { |
3704 | dev_pm_qos_hide_latency_tolerance(ctrl->device); | ||
3684 | cdev_device_del(&ctrl->cdev, ctrl->device); | 3705 | cdev_device_del(&ctrl->cdev, ctrl->device); |
3685 | } | 3706 | } |
3686 | EXPORT_SYMBOL_GPL(nvme_uninit_ctrl); | 3707 | EXPORT_SYMBOL_GPL(nvme_uninit_ctrl); |
@@ -3880,6 +3901,18 @@ void nvme_start_queues(struct nvme_ctrl *ctrl) | |||
3880 | } | 3901 | } |
3881 | EXPORT_SYMBOL_GPL(nvme_start_queues); | 3902 | EXPORT_SYMBOL_GPL(nvme_start_queues); |
3882 | 3903 | ||
3904 | |||
3905 | void nvme_sync_queues(struct nvme_ctrl *ctrl) | ||
3906 | { | ||
3907 | struct nvme_ns *ns; | ||
3908 | |||
3909 | down_read(&ctrl->namespaces_rwsem); | ||
3910 | list_for_each_entry(ns, &ctrl->namespaces, list) | ||
3911 | blk_sync_queue(ns->queue); | ||
3912 | up_read(&ctrl->namespaces_rwsem); | ||
3913 | } | ||
3914 | EXPORT_SYMBOL_GPL(nvme_sync_queues); | ||
3915 | |||
3883 | /* | 3916 | /* |
3884 | * Check we didn't inadvertently grow the command structure sizes: | 3917 | * Check we didn't inadvertently grow the command structure sizes: |
3885 | */ | 3918 | */ |
diff --git a/drivers/nvme/host/nvme.h b/drivers/nvme/host/nvme.h index 5ee75b5ff83f..55553d293a98 100644 --- a/drivers/nvme/host/nvme.h +++ b/drivers/nvme/host/nvme.h | |||
@@ -441,6 +441,7 @@ void nvme_complete_async_event(struct nvme_ctrl *ctrl, __le16 status, | |||
441 | void nvme_stop_queues(struct nvme_ctrl *ctrl); | 441 | void nvme_stop_queues(struct nvme_ctrl *ctrl); |
442 | void nvme_start_queues(struct nvme_ctrl *ctrl); | 442 | void nvme_start_queues(struct nvme_ctrl *ctrl); |
443 | void nvme_kill_queues(struct nvme_ctrl *ctrl); | 443 | void nvme_kill_queues(struct nvme_ctrl *ctrl); |
444 | void nvme_sync_queues(struct nvme_ctrl *ctrl); | ||
444 | void nvme_unfreeze(struct nvme_ctrl *ctrl); | 445 | void nvme_unfreeze(struct nvme_ctrl *ctrl); |
445 | void nvme_wait_freeze(struct nvme_ctrl *ctrl); | 446 | void nvme_wait_freeze(struct nvme_ctrl *ctrl); |
446 | void nvme_wait_freeze_timeout(struct nvme_ctrl *ctrl, long timeout); | 447 | void nvme_wait_freeze_timeout(struct nvme_ctrl *ctrl, long timeout); |
diff --git a/drivers/nvme/host/pci.c b/drivers/nvme/host/pci.c index 2a8708c9ac18..f562154551ce 100644 --- a/drivers/nvme/host/pci.c +++ b/drivers/nvme/host/pci.c | |||
@@ -464,7 +464,7 @@ static int nvme_pci_map_queues(struct blk_mq_tag_set *set) | |||
464 | * affinity), so use the regular blk-mq cpu mapping | 464 | * affinity), so use the regular blk-mq cpu mapping |
465 | */ | 465 | */ |
466 | map->queue_offset = qoff; | 466 | map->queue_offset = qoff; |
467 | if (i != HCTX_TYPE_POLL) | 467 | if (i != HCTX_TYPE_POLL && offset) |
468 | blk_mq_pci_map_queues(map, to_pci_dev(dev->dev), offset); | 468 | blk_mq_pci_map_queues(map, to_pci_dev(dev->dev), offset); |
469 | else | 469 | else |
470 | blk_mq_map_queues(map); | 470 | blk_mq_map_queues(map); |
@@ -1257,7 +1257,6 @@ static enum blk_eh_timer_return nvme_timeout(struct request *req, bool reserved) | |||
1257 | struct nvme_dev *dev = nvmeq->dev; | 1257 | struct nvme_dev *dev = nvmeq->dev; |
1258 | struct request *abort_req; | 1258 | struct request *abort_req; |
1259 | struct nvme_command cmd; | 1259 | struct nvme_command cmd; |
1260 | bool shutdown = false; | ||
1261 | u32 csts = readl(dev->bar + NVME_REG_CSTS); | 1260 | u32 csts = readl(dev->bar + NVME_REG_CSTS); |
1262 | 1261 | ||
1263 | /* If PCI error recovery process is happening, we cannot reset or | 1262 | /* If PCI error recovery process is happening, we cannot reset or |
@@ -1294,17 +1293,18 @@ static enum blk_eh_timer_return nvme_timeout(struct request *req, bool reserved) | |||
1294 | * shutdown, so we return BLK_EH_DONE. | 1293 | * shutdown, so we return BLK_EH_DONE. |
1295 | */ | 1294 | */ |
1296 | switch (dev->ctrl.state) { | 1295 | switch (dev->ctrl.state) { |
1297 | case NVME_CTRL_DELETING: | ||
1298 | shutdown = true; | ||
1299 | /* fall through */ | ||
1300 | case NVME_CTRL_CONNECTING: | 1296 | case NVME_CTRL_CONNECTING: |
1301 | case NVME_CTRL_RESETTING: | 1297 | nvme_change_ctrl_state(&dev->ctrl, NVME_CTRL_DELETING); |
1298 | /* fall through */ | ||
1299 | case NVME_CTRL_DELETING: | ||
1302 | dev_warn_ratelimited(dev->ctrl.device, | 1300 | dev_warn_ratelimited(dev->ctrl.device, |
1303 | "I/O %d QID %d timeout, disable controller\n", | 1301 | "I/O %d QID %d timeout, disable controller\n", |
1304 | req->tag, nvmeq->qid); | 1302 | req->tag, nvmeq->qid); |
1305 | nvme_dev_disable(dev, shutdown); | 1303 | nvme_dev_disable(dev, true); |
1306 | nvme_req(req)->flags |= NVME_REQ_CANCELLED; | 1304 | nvme_req(req)->flags |= NVME_REQ_CANCELLED; |
1307 | return BLK_EH_DONE; | 1305 | return BLK_EH_DONE; |
1306 | case NVME_CTRL_RESETTING: | ||
1307 | return BLK_EH_RESET_TIMER; | ||
1308 | default: | 1308 | default: |
1309 | break; | 1309 | break; |
1310 | } | 1310 | } |
@@ -2376,7 +2376,7 @@ static void nvme_pci_disable(struct nvme_dev *dev) | |||
2376 | 2376 | ||
2377 | static void nvme_dev_disable(struct nvme_dev *dev, bool shutdown) | 2377 | static void nvme_dev_disable(struct nvme_dev *dev, bool shutdown) |
2378 | { | 2378 | { |
2379 | bool dead = true; | 2379 | bool dead = true, freeze = false; |
2380 | struct pci_dev *pdev = to_pci_dev(dev->dev); | 2380 | struct pci_dev *pdev = to_pci_dev(dev->dev); |
2381 | 2381 | ||
2382 | mutex_lock(&dev->shutdown_lock); | 2382 | mutex_lock(&dev->shutdown_lock); |
@@ -2384,8 +2384,10 @@ static void nvme_dev_disable(struct nvme_dev *dev, bool shutdown) | |||
2384 | u32 csts = readl(dev->bar + NVME_REG_CSTS); | 2384 | u32 csts = readl(dev->bar + NVME_REG_CSTS); |
2385 | 2385 | ||
2386 | if (dev->ctrl.state == NVME_CTRL_LIVE || | 2386 | if (dev->ctrl.state == NVME_CTRL_LIVE || |
2387 | dev->ctrl.state == NVME_CTRL_RESETTING) | 2387 | dev->ctrl.state == NVME_CTRL_RESETTING) { |
2388 | freeze = true; | ||
2388 | nvme_start_freeze(&dev->ctrl); | 2389 | nvme_start_freeze(&dev->ctrl); |
2390 | } | ||
2389 | dead = !!((csts & NVME_CSTS_CFS) || !(csts & NVME_CSTS_RDY) || | 2391 | dead = !!((csts & NVME_CSTS_CFS) || !(csts & NVME_CSTS_RDY) || |
2390 | pdev->error_state != pci_channel_io_normal); | 2392 | pdev->error_state != pci_channel_io_normal); |
2391 | } | 2393 | } |
@@ -2394,10 +2396,8 @@ static void nvme_dev_disable(struct nvme_dev *dev, bool shutdown) | |||
2394 | * Give the controller a chance to complete all entered requests if | 2396 | * Give the controller a chance to complete all entered requests if |
2395 | * doing a safe shutdown. | 2397 | * doing a safe shutdown. |
2396 | */ | 2398 | */ |
2397 | if (!dead) { | 2399 | if (!dead && shutdown && freeze) |
2398 | if (shutdown) | 2400 | nvme_wait_freeze_timeout(&dev->ctrl, NVME_IO_TIMEOUT); |
2399 | nvme_wait_freeze_timeout(&dev->ctrl, NVME_IO_TIMEOUT); | ||
2400 | } | ||
2401 | 2401 | ||
2402 | nvme_stop_queues(&dev->ctrl); | 2402 | nvme_stop_queues(&dev->ctrl); |
2403 | 2403 | ||
@@ -2492,6 +2492,7 @@ static void nvme_reset_work(struct work_struct *work) | |||
2492 | */ | 2492 | */ |
2493 | if (dev->ctrl.ctrl_config & NVME_CC_ENABLE) | 2493 | if (dev->ctrl.ctrl_config & NVME_CC_ENABLE) |
2494 | nvme_dev_disable(dev, false); | 2494 | nvme_dev_disable(dev, false); |
2495 | nvme_sync_queues(&dev->ctrl); | ||
2495 | 2496 | ||
2496 | mutex_lock(&dev->shutdown_lock); | 2497 | mutex_lock(&dev->shutdown_lock); |
2497 | result = nvme_pci_enable(dev); | 2498 | result = nvme_pci_enable(dev); |