diff options
| -rw-r--r-- | block/blk-core.c | 21 | ||||
| -rw-r--r-- | block/blk-mq-tag.c | 14 | ||||
| -rw-r--r-- | block/blk-mq-tag.h | 1 | ||||
| -rw-r--r-- | block/blk-mq.c | 75 | ||||
| -rw-r--r-- | block/blk-mq.h | 1 | ||||
| -rw-r--r-- | block/blk-timeout.c | 3 | ||||
| -rw-r--r-- | drivers/block/null_blk.c | 2 | ||||
| -rw-r--r-- | drivers/block/nvme-core.c | 175 | ||||
| -rw-r--r-- | drivers/block/virtio_blk.c | 2 | ||||
| -rw-r--r-- | include/linux/blk-mq.h | 8 | ||||
| -rw-r--r-- | include/linux/blk_types.h | 2 |
11 files changed, 240 insertions, 64 deletions
diff --git a/block/blk-core.c b/block/blk-core.c index 30f6153a40c2..3ad405571dcc 100644 --- a/block/blk-core.c +++ b/block/blk-core.c | |||
| @@ -473,6 +473,25 @@ void blk_queue_bypass_end(struct request_queue *q) | |||
| 473 | } | 473 | } |
| 474 | EXPORT_SYMBOL_GPL(blk_queue_bypass_end); | 474 | EXPORT_SYMBOL_GPL(blk_queue_bypass_end); |
| 475 | 475 | ||
| 476 | void blk_set_queue_dying(struct request_queue *q) | ||
| 477 | { | ||
| 478 | queue_flag_set_unlocked(QUEUE_FLAG_DYING, q); | ||
| 479 | |||
| 480 | if (q->mq_ops) | ||
| 481 | blk_mq_wake_waiters(q); | ||
| 482 | else { | ||
| 483 | struct request_list *rl; | ||
| 484 | |||
| 485 | blk_queue_for_each_rl(rl, q) { | ||
| 486 | if (rl->rq_pool) { | ||
| 487 | wake_up(&rl->wait[BLK_RW_SYNC]); | ||
| 488 | wake_up(&rl->wait[BLK_RW_ASYNC]); | ||
| 489 | } | ||
| 490 | } | ||
| 491 | } | ||
| 492 | } | ||
| 493 | EXPORT_SYMBOL_GPL(blk_set_queue_dying); | ||
| 494 | |||
| 476 | /** | 495 | /** |
| 477 | * blk_cleanup_queue - shutdown a request queue | 496 | * blk_cleanup_queue - shutdown a request queue |
| 478 | * @q: request queue to shutdown | 497 | * @q: request queue to shutdown |
| @@ -486,7 +505,7 @@ void blk_cleanup_queue(struct request_queue *q) | |||
| 486 | 505 | ||
| 487 | /* mark @q DYING, no new request or merges will be allowed afterwards */ | 506 | /* mark @q DYING, no new request or merges will be allowed afterwards */ |
| 488 | mutex_lock(&q->sysfs_lock); | 507 | mutex_lock(&q->sysfs_lock); |
| 489 | queue_flag_set_unlocked(QUEUE_FLAG_DYING, q); | 508 | blk_set_queue_dying(q); |
| 490 | spin_lock_irq(lock); | 509 | spin_lock_irq(lock); |
| 491 | 510 | ||
| 492 | /* | 511 | /* |
diff --git a/block/blk-mq-tag.c b/block/blk-mq-tag.c index 32e8dbb9ad1c..60c9d4a93fe4 100644 --- a/block/blk-mq-tag.c +++ b/block/blk-mq-tag.c | |||
| @@ -68,9 +68,9 @@ bool __blk_mq_tag_busy(struct blk_mq_hw_ctx *hctx) | |||
| 68 | } | 68 | } |
| 69 | 69 | ||
| 70 | /* | 70 | /* |
| 71 | * Wakeup all potentially sleeping on normal (non-reserved) tags | 71 | * Wakeup all potentially sleeping on tags |
| 72 | */ | 72 | */ |
| 73 | static void blk_mq_tag_wakeup_all(struct blk_mq_tags *tags) | 73 | void blk_mq_tag_wakeup_all(struct blk_mq_tags *tags, bool include_reserve) |
| 74 | { | 74 | { |
| 75 | struct blk_mq_bitmap_tags *bt; | 75 | struct blk_mq_bitmap_tags *bt; |
| 76 | int i, wake_index; | 76 | int i, wake_index; |
| @@ -85,6 +85,12 @@ static void blk_mq_tag_wakeup_all(struct blk_mq_tags *tags) | |||
| 85 | 85 | ||
| 86 | wake_index = bt_index_inc(wake_index); | 86 | wake_index = bt_index_inc(wake_index); |
| 87 | } | 87 | } |
| 88 | |||
| 89 | if (include_reserve) { | ||
| 90 | bt = &tags->breserved_tags; | ||
| 91 | if (waitqueue_active(&bt->bs[0].wait)) | ||
| 92 | wake_up(&bt->bs[0].wait); | ||
| 93 | } | ||
| 88 | } | 94 | } |
| 89 | 95 | ||
| 90 | /* | 96 | /* |
| @@ -100,7 +106,7 @@ void __blk_mq_tag_idle(struct blk_mq_hw_ctx *hctx) | |||
| 100 | 106 | ||
| 101 | atomic_dec(&tags->active_queues); | 107 | atomic_dec(&tags->active_queues); |
| 102 | 108 | ||
| 103 | blk_mq_tag_wakeup_all(tags); | 109 | blk_mq_tag_wakeup_all(tags, false); |
| 104 | } | 110 | } |
| 105 | 111 | ||
| 106 | /* | 112 | /* |
| @@ -584,7 +590,7 @@ int blk_mq_tag_update_depth(struct blk_mq_tags *tags, unsigned int tdepth) | |||
| 584 | * static and should never need resizing. | 590 | * static and should never need resizing. |
| 585 | */ | 591 | */ |
| 586 | bt_update_count(&tags->bitmap_tags, tdepth); | 592 | bt_update_count(&tags->bitmap_tags, tdepth); |
| 587 | blk_mq_tag_wakeup_all(tags); | 593 | blk_mq_tag_wakeup_all(tags, false); |
| 588 | return 0; | 594 | return 0; |
| 589 | } | 595 | } |
| 590 | 596 | ||
diff --git a/block/blk-mq-tag.h b/block/blk-mq-tag.h index 6206ed17ef76..a6fa0fc9d41a 100644 --- a/block/blk-mq-tag.h +++ b/block/blk-mq-tag.h | |||
| @@ -54,6 +54,7 @@ extern bool blk_mq_has_free_tags(struct blk_mq_tags *tags); | |||
| 54 | extern ssize_t blk_mq_tag_sysfs_show(struct blk_mq_tags *tags, char *page); | 54 | extern ssize_t blk_mq_tag_sysfs_show(struct blk_mq_tags *tags, char *page); |
| 55 | extern void blk_mq_tag_init_last_tag(struct blk_mq_tags *tags, unsigned int *last_tag); | 55 | extern void blk_mq_tag_init_last_tag(struct blk_mq_tags *tags, unsigned int *last_tag); |
| 56 | extern int blk_mq_tag_update_depth(struct blk_mq_tags *tags, unsigned int depth); | 56 | extern int blk_mq_tag_update_depth(struct blk_mq_tags *tags, unsigned int depth); |
| 57 | extern void blk_mq_tag_wakeup_all(struct blk_mq_tags *tags, bool); | ||
| 57 | 58 | ||
| 58 | enum { | 59 | enum { |
| 59 | BLK_MQ_TAG_CACHE_MIN = 1, | 60 | BLK_MQ_TAG_CACHE_MIN = 1, |
diff --git a/block/blk-mq.c b/block/blk-mq.c index da1ab5641227..2f95747c287e 100644 --- a/block/blk-mq.c +++ b/block/blk-mq.c | |||
| @@ -107,7 +107,7 @@ static void blk_mq_usage_counter_release(struct percpu_ref *ref) | |||
| 107 | wake_up_all(&q->mq_freeze_wq); | 107 | wake_up_all(&q->mq_freeze_wq); |
| 108 | } | 108 | } |
| 109 | 109 | ||
| 110 | static void blk_mq_freeze_queue_start(struct request_queue *q) | 110 | void blk_mq_freeze_queue_start(struct request_queue *q) |
| 111 | { | 111 | { |
| 112 | bool freeze; | 112 | bool freeze; |
| 113 | 113 | ||
| @@ -120,6 +120,7 @@ static void blk_mq_freeze_queue_start(struct request_queue *q) | |||
| 120 | blk_mq_run_queues(q, false); | 120 | blk_mq_run_queues(q, false); |
| 121 | } | 121 | } |
| 122 | } | 122 | } |
| 123 | EXPORT_SYMBOL_GPL(blk_mq_freeze_queue_start); | ||
| 123 | 124 | ||
| 124 | static void blk_mq_freeze_queue_wait(struct request_queue *q) | 125 | static void blk_mq_freeze_queue_wait(struct request_queue *q) |
| 125 | { | 126 | { |
| @@ -136,7 +137,7 @@ void blk_mq_freeze_queue(struct request_queue *q) | |||
| 136 | blk_mq_freeze_queue_wait(q); | 137 | blk_mq_freeze_queue_wait(q); |
| 137 | } | 138 | } |
| 138 | 139 | ||
| 139 | static void blk_mq_unfreeze_queue(struct request_queue *q) | 140 | void blk_mq_unfreeze_queue(struct request_queue *q) |
| 140 | { | 141 | { |
| 141 | bool wake; | 142 | bool wake; |
| 142 | 143 | ||
| @@ -149,6 +150,24 @@ static void blk_mq_unfreeze_queue(struct request_queue *q) | |||
| 149 | wake_up_all(&q->mq_freeze_wq); | 150 | wake_up_all(&q->mq_freeze_wq); |
| 150 | } | 151 | } |
| 151 | } | 152 | } |
| 153 | EXPORT_SYMBOL_GPL(blk_mq_unfreeze_queue); | ||
| 154 | |||
| 155 | void blk_mq_wake_waiters(struct request_queue *q) | ||
| 156 | { | ||
| 157 | struct blk_mq_hw_ctx *hctx; | ||
| 158 | unsigned int i; | ||
| 159 | |||
| 160 | queue_for_each_hw_ctx(q, hctx, i) | ||
| 161 | if (blk_mq_hw_queue_mapped(hctx)) | ||
| 162 | blk_mq_tag_wakeup_all(hctx->tags, true); | ||
| 163 | |||
| 164 | /* | ||
| 165 | * If we are called because the queue has now been marked as | ||
| 166 | * dying, we need to ensure that processes currently waiting on | ||
| 167 | * the queue are notified as well. | ||
| 168 | */ | ||
| 169 | wake_up_all(&q->mq_freeze_wq); | ||
| 170 | } | ||
| 152 | 171 | ||
| 153 | bool blk_mq_can_queue(struct blk_mq_hw_ctx *hctx) | 172 | bool blk_mq_can_queue(struct blk_mq_hw_ctx *hctx) |
| 154 | { | 173 | { |
| @@ -258,8 +277,10 @@ struct request *blk_mq_alloc_request(struct request_queue *q, int rw, gfp_t gfp, | |||
| 258 | ctx = alloc_data.ctx; | 277 | ctx = alloc_data.ctx; |
| 259 | } | 278 | } |
| 260 | blk_mq_put_ctx(ctx); | 279 | blk_mq_put_ctx(ctx); |
| 261 | if (!rq) | 280 | if (!rq) { |
| 281 | blk_mq_queue_exit(q); | ||
| 262 | return ERR_PTR(-EWOULDBLOCK); | 282 | return ERR_PTR(-EWOULDBLOCK); |
| 283 | } | ||
| 263 | return rq; | 284 | return rq; |
| 264 | } | 285 | } |
| 265 | EXPORT_SYMBOL(blk_mq_alloc_request); | 286 | EXPORT_SYMBOL(blk_mq_alloc_request); |
| @@ -383,6 +404,12 @@ void blk_mq_complete_request(struct request *rq) | |||
| 383 | } | 404 | } |
| 384 | EXPORT_SYMBOL(blk_mq_complete_request); | 405 | EXPORT_SYMBOL(blk_mq_complete_request); |
| 385 | 406 | ||
| 407 | int blk_mq_request_started(struct request *rq) | ||
| 408 | { | ||
| 409 | return test_bit(REQ_ATOM_STARTED, &rq->atomic_flags); | ||
| 410 | } | ||
| 411 | EXPORT_SYMBOL_GPL(blk_mq_request_started); | ||
| 412 | |||
| 386 | void blk_mq_start_request(struct request *rq) | 413 | void blk_mq_start_request(struct request *rq) |
| 387 | { | 414 | { |
| 388 | struct request_queue *q = rq->q; | 415 | struct request_queue *q = rq->q; |
| @@ -500,12 +527,38 @@ void blk_mq_add_to_requeue_list(struct request *rq, bool at_head) | |||
| 500 | } | 527 | } |
| 501 | EXPORT_SYMBOL(blk_mq_add_to_requeue_list); | 528 | EXPORT_SYMBOL(blk_mq_add_to_requeue_list); |
| 502 | 529 | ||
| 530 | void blk_mq_cancel_requeue_work(struct request_queue *q) | ||
| 531 | { | ||
| 532 | cancel_work_sync(&q->requeue_work); | ||
| 533 | } | ||
| 534 | EXPORT_SYMBOL_GPL(blk_mq_cancel_requeue_work); | ||
| 535 | |||
| 503 | void blk_mq_kick_requeue_list(struct request_queue *q) | 536 | void blk_mq_kick_requeue_list(struct request_queue *q) |
| 504 | { | 537 | { |
| 505 | kblockd_schedule_work(&q->requeue_work); | 538 | kblockd_schedule_work(&q->requeue_work); |
| 506 | } | 539 | } |
| 507 | EXPORT_SYMBOL(blk_mq_kick_requeue_list); | 540 | EXPORT_SYMBOL(blk_mq_kick_requeue_list); |
| 508 | 541 | ||
| 542 | void blk_mq_abort_requeue_list(struct request_queue *q) | ||
| 543 | { | ||
| 544 | unsigned long flags; | ||
| 545 | LIST_HEAD(rq_list); | ||
| 546 | |||
| 547 | spin_lock_irqsave(&q->requeue_lock, flags); | ||
| 548 | list_splice_init(&q->requeue_list, &rq_list); | ||
| 549 | spin_unlock_irqrestore(&q->requeue_lock, flags); | ||
| 550 | |||
| 551 | while (!list_empty(&rq_list)) { | ||
| 552 | struct request *rq; | ||
| 553 | |||
| 554 | rq = list_first_entry(&rq_list, struct request, queuelist); | ||
| 555 | list_del_init(&rq->queuelist); | ||
| 556 | rq->errors = -EIO; | ||
| 557 | blk_mq_end_request(rq, rq->errors); | ||
| 558 | } | ||
| 559 | } | ||
| 560 | EXPORT_SYMBOL(blk_mq_abort_requeue_list); | ||
| 561 | |||
| 509 | static inline bool is_flush_request(struct request *rq, | 562 | static inline bool is_flush_request(struct request *rq, |
| 510 | struct blk_flush_queue *fq, unsigned int tag) | 563 | struct blk_flush_queue *fq, unsigned int tag) |
| 511 | { | 564 | { |
| @@ -566,13 +619,24 @@ void blk_mq_rq_timed_out(struct request *req, bool reserved) | |||
| 566 | break; | 619 | break; |
| 567 | } | 620 | } |
| 568 | } | 621 | } |
| 569 | 622 | ||
| 570 | static void blk_mq_check_expired(struct blk_mq_hw_ctx *hctx, | 623 | static void blk_mq_check_expired(struct blk_mq_hw_ctx *hctx, |
| 571 | struct request *rq, void *priv, bool reserved) | 624 | struct request *rq, void *priv, bool reserved) |
| 572 | { | 625 | { |
| 573 | struct blk_mq_timeout_data *data = priv; | 626 | struct blk_mq_timeout_data *data = priv; |
| 574 | 627 | ||
| 575 | if (!test_bit(REQ_ATOM_STARTED, &rq->atomic_flags)) | 628 | if (!test_bit(REQ_ATOM_STARTED, &rq->atomic_flags)) { |
| 629 | /* | ||
| 630 | * If a request wasn't started before the queue was | ||
| 631 | * marked dying, kill it here or it'll go unnoticed. | ||
| 632 | */ | ||
| 633 | if (unlikely(blk_queue_dying(rq->q))) { | ||
| 634 | rq->errors = -EIO; | ||
| 635 | blk_mq_complete_request(rq); | ||
| 636 | } | ||
| 637 | return; | ||
| 638 | } | ||
| 639 | if (rq->cmd_flags & REQ_NO_TIMEOUT) | ||
| 576 | return; | 640 | return; |
| 577 | 641 | ||
| 578 | if (time_after_eq(jiffies, rq->deadline)) { | 642 | if (time_after_eq(jiffies, rq->deadline)) { |
| @@ -1601,7 +1665,6 @@ static int blk_mq_init_hctx(struct request_queue *q, | |||
| 1601 | hctx->queue = q; | 1665 | hctx->queue = q; |
| 1602 | hctx->queue_num = hctx_idx; | 1666 | hctx->queue_num = hctx_idx; |
| 1603 | hctx->flags = set->flags; | 1667 | hctx->flags = set->flags; |
| 1604 | hctx->cmd_size = set->cmd_size; | ||
| 1605 | 1668 | ||
| 1606 | blk_mq_init_cpu_notifier(&hctx->cpu_notifier, | 1669 | blk_mq_init_cpu_notifier(&hctx->cpu_notifier, |
| 1607 | blk_mq_hctx_notify, hctx); | 1670 | blk_mq_hctx_notify, hctx); |
diff --git a/block/blk-mq.h b/block/blk-mq.h index 206230e64f79..4f4f943c22c3 100644 --- a/block/blk-mq.h +++ b/block/blk-mq.h | |||
| @@ -32,6 +32,7 @@ void blk_mq_free_queue(struct request_queue *q); | |||
| 32 | void blk_mq_clone_flush_request(struct request *flush_rq, | 32 | void blk_mq_clone_flush_request(struct request *flush_rq, |
| 33 | struct request *orig_rq); | 33 | struct request *orig_rq); |
| 34 | int blk_mq_update_nr_requests(struct request_queue *q, unsigned int nr); | 34 | int blk_mq_update_nr_requests(struct request_queue *q, unsigned int nr); |
| 35 | void blk_mq_wake_waiters(struct request_queue *q); | ||
| 35 | 36 | ||
| 36 | /* | 37 | /* |
| 37 | * CPU hotplug helpers | 38 | * CPU hotplug helpers |
diff --git a/block/blk-timeout.c b/block/blk-timeout.c index 56c025894cdf..246dfb16c3d9 100644 --- a/block/blk-timeout.c +++ b/block/blk-timeout.c | |||
| @@ -190,6 +190,9 @@ void blk_add_timer(struct request *req) | |||
| 190 | struct request_queue *q = req->q; | 190 | struct request_queue *q = req->q; |
| 191 | unsigned long expiry; | 191 | unsigned long expiry; |
| 192 | 192 | ||
| 193 | if (req->cmd_flags & REQ_NO_TIMEOUT) | ||
| 194 | return; | ||
| 195 | |||
| 193 | /* blk-mq has its own handler, so we don't need ->rq_timed_out_fn */ | 196 | /* blk-mq has its own handler, so we don't need ->rq_timed_out_fn */ |
| 194 | if (!q->mq_ops && !q->rq_timed_out_fn) | 197 | if (!q->mq_ops && !q->rq_timed_out_fn) |
| 195 | return; | 198 | return; |
diff --git a/drivers/block/null_blk.c b/drivers/block/null_blk.c index ae9f615382f6..aa2224aa7caa 100644 --- a/drivers/block/null_blk.c +++ b/drivers/block/null_blk.c | |||
| @@ -530,7 +530,7 @@ static int null_add_dev(void) | |||
| 530 | goto out_cleanup_queues; | 530 | goto out_cleanup_queues; |
| 531 | 531 | ||
| 532 | nullb->q = blk_mq_init_queue(&nullb->tag_set); | 532 | nullb->q = blk_mq_init_queue(&nullb->tag_set); |
| 533 | if (!nullb->q) { | 533 | if (IS_ERR(nullb->q)) { |
| 534 | rv = -ENOMEM; | 534 | rv = -ENOMEM; |
| 535 | goto out_cleanup_tags; | 535 | goto out_cleanup_tags; |
| 536 | } | 536 | } |
diff --git a/drivers/block/nvme-core.c b/drivers/block/nvme-core.c index b1d5d8797315..cb529e9a82dd 100644 --- a/drivers/block/nvme-core.c +++ b/drivers/block/nvme-core.c | |||
| @@ -215,6 +215,7 @@ static void nvme_set_info(struct nvme_cmd_info *cmd, void *ctx, | |||
| 215 | cmd->fn = handler; | 215 | cmd->fn = handler; |
| 216 | cmd->ctx = ctx; | 216 | cmd->ctx = ctx; |
| 217 | cmd->aborted = 0; | 217 | cmd->aborted = 0; |
| 218 | blk_mq_start_request(blk_mq_rq_from_pdu(cmd)); | ||
| 218 | } | 219 | } |
| 219 | 220 | ||
| 220 | /* Special values must be less than 0x1000 */ | 221 | /* Special values must be less than 0x1000 */ |
| @@ -431,8 +432,13 @@ static void req_completion(struct nvme_queue *nvmeq, void *ctx, | |||
| 431 | if (unlikely(status)) { | 432 | if (unlikely(status)) { |
| 432 | if (!(status & NVME_SC_DNR || blk_noretry_request(req)) | 433 | if (!(status & NVME_SC_DNR || blk_noretry_request(req)) |
| 433 | && (jiffies - req->start_time) < req->timeout) { | 434 | && (jiffies - req->start_time) < req->timeout) { |
| 435 | unsigned long flags; | ||
| 436 | |||
| 434 | blk_mq_requeue_request(req); | 437 | blk_mq_requeue_request(req); |
| 435 | blk_mq_kick_requeue_list(req->q); | 438 | spin_lock_irqsave(req->q->queue_lock, flags); |
| 439 | if (!blk_queue_stopped(req->q)) | ||
| 440 | blk_mq_kick_requeue_list(req->q); | ||
| 441 | spin_unlock_irqrestore(req->q->queue_lock, flags); | ||
| 436 | return; | 442 | return; |
| 437 | } | 443 | } |
| 438 | req->errors = nvme_error_status(status); | 444 | req->errors = nvme_error_status(status); |
| @@ -664,8 +670,6 @@ static int nvme_queue_rq(struct blk_mq_hw_ctx *hctx, | |||
| 664 | } | 670 | } |
| 665 | } | 671 | } |
| 666 | 672 | ||
| 667 | blk_mq_start_request(req); | ||
| 668 | |||
| 669 | nvme_set_info(cmd, iod, req_completion); | 673 | nvme_set_info(cmd, iod, req_completion); |
| 670 | spin_lock_irq(&nvmeq->q_lock); | 674 | spin_lock_irq(&nvmeq->q_lock); |
| 671 | if (req->cmd_flags & REQ_DISCARD) | 675 | if (req->cmd_flags & REQ_DISCARD) |
| @@ -835,6 +839,7 @@ static int nvme_submit_async_admin_req(struct nvme_dev *dev) | |||
| 835 | if (IS_ERR(req)) | 839 | if (IS_ERR(req)) |
| 836 | return PTR_ERR(req); | 840 | return PTR_ERR(req); |
| 837 | 841 | ||
| 842 | req->cmd_flags |= REQ_NO_TIMEOUT; | ||
| 838 | cmd_info = blk_mq_rq_to_pdu(req); | 843 | cmd_info = blk_mq_rq_to_pdu(req); |
| 839 | nvme_set_info(cmd_info, req, async_req_completion); | 844 | nvme_set_info(cmd_info, req, async_req_completion); |
| 840 | 845 | ||
| @@ -1016,14 +1021,19 @@ static void nvme_abort_req(struct request *req) | |||
| 1016 | struct nvme_command cmd; | 1021 | struct nvme_command cmd; |
| 1017 | 1022 | ||
| 1018 | if (!nvmeq->qid || cmd_rq->aborted) { | 1023 | if (!nvmeq->qid || cmd_rq->aborted) { |
| 1024 | unsigned long flags; | ||
| 1025 | |||
| 1026 | spin_lock_irqsave(&dev_list_lock, flags); | ||
| 1019 | if (work_busy(&dev->reset_work)) | 1027 | if (work_busy(&dev->reset_work)) |
| 1020 | return; | 1028 | goto out; |
| 1021 | list_del_init(&dev->node); | 1029 | list_del_init(&dev->node); |
| 1022 | dev_warn(&dev->pci_dev->dev, | 1030 | dev_warn(&dev->pci_dev->dev, |
| 1023 | "I/O %d QID %d timeout, reset controller\n", | 1031 | "I/O %d QID %d timeout, reset controller\n", |
| 1024 | req->tag, nvmeq->qid); | 1032 | req->tag, nvmeq->qid); |
| 1025 | dev->reset_workfn = nvme_reset_failed_dev; | 1033 | dev->reset_workfn = nvme_reset_failed_dev; |
| 1026 | queue_work(nvme_workq, &dev->reset_work); | 1034 | queue_work(nvme_workq, &dev->reset_work); |
| 1035 | out: | ||
| 1036 | spin_unlock_irqrestore(&dev_list_lock, flags); | ||
| 1027 | return; | 1037 | return; |
| 1028 | } | 1038 | } |
| 1029 | 1039 | ||
| @@ -1064,15 +1074,22 @@ static void nvme_cancel_queue_ios(struct blk_mq_hw_ctx *hctx, | |||
| 1064 | void *ctx; | 1074 | void *ctx; |
| 1065 | nvme_completion_fn fn; | 1075 | nvme_completion_fn fn; |
| 1066 | struct nvme_cmd_info *cmd; | 1076 | struct nvme_cmd_info *cmd; |
| 1067 | static struct nvme_completion cqe = { | 1077 | struct nvme_completion cqe; |
| 1068 | .status = cpu_to_le16(NVME_SC_ABORT_REQ << 1), | 1078 | |
| 1069 | }; | 1079 | if (!blk_mq_request_started(req)) |
| 1080 | return; | ||
| 1070 | 1081 | ||
| 1071 | cmd = blk_mq_rq_to_pdu(req); | 1082 | cmd = blk_mq_rq_to_pdu(req); |
| 1072 | 1083 | ||
| 1073 | if (cmd->ctx == CMD_CTX_CANCELLED) | 1084 | if (cmd->ctx == CMD_CTX_CANCELLED) |
| 1074 | return; | 1085 | return; |
| 1075 | 1086 | ||
| 1087 | if (blk_queue_dying(req->q)) | ||
| 1088 | cqe.status = cpu_to_le16((NVME_SC_ABORT_REQ | NVME_SC_DNR) << 1); | ||
| 1089 | else | ||
| 1090 | cqe.status = cpu_to_le16(NVME_SC_ABORT_REQ << 1); | ||
| 1091 | |||
| 1092 | |||
| 1076 | dev_warn(nvmeq->q_dmadev, "Cancelling I/O %d QID %d\n", | 1093 | dev_warn(nvmeq->q_dmadev, "Cancelling I/O %d QID %d\n", |
| 1077 | req->tag, nvmeq->qid); | 1094 | req->tag, nvmeq->qid); |
| 1078 | ctx = cancel_cmd_info(cmd, &fn); | 1095 | ctx = cancel_cmd_info(cmd, &fn); |
| @@ -1084,17 +1101,29 @@ static enum blk_eh_timer_return nvme_timeout(struct request *req, bool reserved) | |||
| 1084 | struct nvme_cmd_info *cmd = blk_mq_rq_to_pdu(req); | 1101 | struct nvme_cmd_info *cmd = blk_mq_rq_to_pdu(req); |
| 1085 | struct nvme_queue *nvmeq = cmd->nvmeq; | 1102 | struct nvme_queue *nvmeq = cmd->nvmeq; |
| 1086 | 1103 | ||
| 1087 | dev_warn(nvmeq->q_dmadev, "Timeout I/O %d QID %d\n", req->tag, | ||
| 1088 | nvmeq->qid); | ||
| 1089 | if (nvmeq->dev->initialized) | ||
| 1090 | nvme_abort_req(req); | ||
| 1091 | |||
| 1092 | /* | 1104 | /* |
| 1093 | * The aborted req will be completed on receiving the abort req. | 1105 | * The aborted req will be completed on receiving the abort req. |
| 1094 | * We enable the timer again. If hit twice, it'll cause a device reset, | 1106 | * We enable the timer again. If hit twice, it'll cause a device reset, |
| 1095 | * as the device then is in a faulty state. | 1107 | * as the device then is in a faulty state. |
| 1096 | */ | 1108 | */ |
| 1097 | return BLK_EH_RESET_TIMER; | 1109 | int ret = BLK_EH_RESET_TIMER; |
| 1110 | |||
| 1111 | dev_warn(nvmeq->q_dmadev, "Timeout I/O %d QID %d\n", req->tag, | ||
| 1112 | nvmeq->qid); | ||
| 1113 | |||
| 1114 | spin_lock_irq(&nvmeq->q_lock); | ||
| 1115 | if (!nvmeq->dev->initialized) { | ||
| 1116 | /* | ||
| 1117 | * Force cancelled command frees the request, which requires we | ||
| 1118 | * return BLK_EH_NOT_HANDLED. | ||
| 1119 | */ | ||
| 1120 | nvme_cancel_queue_ios(nvmeq->hctx, req, nvmeq, reserved); | ||
| 1121 | ret = BLK_EH_NOT_HANDLED; | ||
| 1122 | } else | ||
| 1123 | nvme_abort_req(req); | ||
| 1124 | spin_unlock_irq(&nvmeq->q_lock); | ||
| 1125 | |||
| 1126 | return ret; | ||
| 1098 | } | 1127 | } |
| 1099 | 1128 | ||
| 1100 | static void nvme_free_queue(struct nvme_queue *nvmeq) | 1129 | static void nvme_free_queue(struct nvme_queue *nvmeq) |
| @@ -1131,10 +1160,16 @@ static void nvme_free_queues(struct nvme_dev *dev, int lowest) | |||
| 1131 | */ | 1160 | */ |
| 1132 | static int nvme_suspend_queue(struct nvme_queue *nvmeq) | 1161 | static int nvme_suspend_queue(struct nvme_queue *nvmeq) |
| 1133 | { | 1162 | { |
| 1134 | int vector = nvmeq->dev->entry[nvmeq->cq_vector].vector; | 1163 | int vector; |
| 1135 | 1164 | ||
| 1136 | spin_lock_irq(&nvmeq->q_lock); | 1165 | spin_lock_irq(&nvmeq->q_lock); |
| 1166 | if (nvmeq->cq_vector == -1) { | ||
| 1167 | spin_unlock_irq(&nvmeq->q_lock); | ||
| 1168 | return 1; | ||
| 1169 | } | ||
| 1170 | vector = nvmeq->dev->entry[nvmeq->cq_vector].vector; | ||
| 1137 | nvmeq->dev->online_queues--; | 1171 | nvmeq->dev->online_queues--; |
| 1172 | nvmeq->cq_vector = -1; | ||
| 1138 | spin_unlock_irq(&nvmeq->q_lock); | 1173 | spin_unlock_irq(&nvmeq->q_lock); |
| 1139 | 1174 | ||
| 1140 | irq_set_affinity_hint(vector, NULL); | 1175 | irq_set_affinity_hint(vector, NULL); |
| @@ -1169,11 +1204,13 @@ static void nvme_disable_queue(struct nvme_dev *dev, int qid) | |||
| 1169 | adapter_delete_sq(dev, qid); | 1204 | adapter_delete_sq(dev, qid); |
| 1170 | adapter_delete_cq(dev, qid); | 1205 | adapter_delete_cq(dev, qid); |
| 1171 | } | 1206 | } |
| 1207 | if (!qid && dev->admin_q) | ||
| 1208 | blk_mq_freeze_queue_start(dev->admin_q); | ||
| 1172 | nvme_clear_queue(nvmeq); | 1209 | nvme_clear_queue(nvmeq); |
| 1173 | } | 1210 | } |
| 1174 | 1211 | ||
| 1175 | static struct nvme_queue *nvme_alloc_queue(struct nvme_dev *dev, int qid, | 1212 | static struct nvme_queue *nvme_alloc_queue(struct nvme_dev *dev, int qid, |
| 1176 | int depth, int vector) | 1213 | int depth) |
| 1177 | { | 1214 | { |
| 1178 | struct device *dmadev = &dev->pci_dev->dev; | 1215 | struct device *dmadev = &dev->pci_dev->dev; |
| 1179 | struct nvme_queue *nvmeq = kzalloc(sizeof(*nvmeq), GFP_KERNEL); | 1216 | struct nvme_queue *nvmeq = kzalloc(sizeof(*nvmeq), GFP_KERNEL); |
| @@ -1199,7 +1236,6 @@ static struct nvme_queue *nvme_alloc_queue(struct nvme_dev *dev, int qid, | |||
| 1199 | nvmeq->cq_phase = 1; | 1236 | nvmeq->cq_phase = 1; |
| 1200 | nvmeq->q_db = &dev->dbs[qid * 2 * dev->db_stride]; | 1237 | nvmeq->q_db = &dev->dbs[qid * 2 * dev->db_stride]; |
| 1201 | nvmeq->q_depth = depth; | 1238 | nvmeq->q_depth = depth; |
| 1202 | nvmeq->cq_vector = vector; | ||
| 1203 | nvmeq->qid = qid; | 1239 | nvmeq->qid = qid; |
| 1204 | dev->queue_count++; | 1240 | dev->queue_count++; |
| 1205 | dev->queues[qid] = nvmeq; | 1241 | dev->queues[qid] = nvmeq; |
| @@ -1244,6 +1280,7 @@ static int nvme_create_queue(struct nvme_queue *nvmeq, int qid) | |||
| 1244 | struct nvme_dev *dev = nvmeq->dev; | 1280 | struct nvme_dev *dev = nvmeq->dev; |
| 1245 | int result; | 1281 | int result; |
| 1246 | 1282 | ||
| 1283 | nvmeq->cq_vector = qid - 1; | ||
| 1247 | result = adapter_alloc_cq(dev, qid, nvmeq); | 1284 | result = adapter_alloc_cq(dev, qid, nvmeq); |
| 1248 | if (result < 0) | 1285 | if (result < 0) |
| 1249 | return result; | 1286 | return result; |
| @@ -1355,6 +1392,14 @@ static struct blk_mq_ops nvme_mq_ops = { | |||
| 1355 | .timeout = nvme_timeout, | 1392 | .timeout = nvme_timeout, |
| 1356 | }; | 1393 | }; |
| 1357 | 1394 | ||
| 1395 | static void nvme_dev_remove_admin(struct nvme_dev *dev) | ||
| 1396 | { | ||
| 1397 | if (dev->admin_q && !blk_queue_dying(dev->admin_q)) { | ||
| 1398 | blk_cleanup_queue(dev->admin_q); | ||
| 1399 | blk_mq_free_tag_set(&dev->admin_tagset); | ||
| 1400 | } | ||
| 1401 | } | ||
| 1402 | |||
| 1358 | static int nvme_alloc_admin_tags(struct nvme_dev *dev) | 1403 | static int nvme_alloc_admin_tags(struct nvme_dev *dev) |
| 1359 | { | 1404 | { |
| 1360 | if (!dev->admin_q) { | 1405 | if (!dev->admin_q) { |
| @@ -1370,21 +1415,20 @@ static int nvme_alloc_admin_tags(struct nvme_dev *dev) | |||
| 1370 | return -ENOMEM; | 1415 | return -ENOMEM; |
| 1371 | 1416 | ||
| 1372 | dev->admin_q = blk_mq_init_queue(&dev->admin_tagset); | 1417 | dev->admin_q = blk_mq_init_queue(&dev->admin_tagset); |
| 1373 | if (!dev->admin_q) { | 1418 | if (IS_ERR(dev->admin_q)) { |
| 1374 | blk_mq_free_tag_set(&dev->admin_tagset); | 1419 | blk_mq_free_tag_set(&dev->admin_tagset); |
| 1375 | return -ENOMEM; | 1420 | return -ENOMEM; |
| 1376 | } | 1421 | } |
| 1377 | } | 1422 | if (!blk_get_queue(dev->admin_q)) { |
| 1423 | nvme_dev_remove_admin(dev); | ||
| 1424 | return -ENODEV; | ||
| 1425 | } | ||
| 1426 | } else | ||
| 1427 | blk_mq_unfreeze_queue(dev->admin_q); | ||
| 1378 | 1428 | ||
| 1379 | return 0; | 1429 | return 0; |
| 1380 | } | 1430 | } |
| 1381 | 1431 | ||
| 1382 | static void nvme_free_admin_tags(struct nvme_dev *dev) | ||
| 1383 | { | ||
| 1384 | if (dev->admin_q) | ||
| 1385 | blk_mq_free_tag_set(&dev->admin_tagset); | ||
| 1386 | } | ||
| 1387 | |||
| 1388 | static int nvme_configure_admin_queue(struct nvme_dev *dev) | 1432 | static int nvme_configure_admin_queue(struct nvme_dev *dev) |
| 1389 | { | 1433 | { |
| 1390 | int result; | 1434 | int result; |
| @@ -1416,7 +1460,7 @@ static int nvme_configure_admin_queue(struct nvme_dev *dev) | |||
| 1416 | 1460 | ||
| 1417 | nvmeq = dev->queues[0]; | 1461 | nvmeq = dev->queues[0]; |
| 1418 | if (!nvmeq) { | 1462 | if (!nvmeq) { |
| 1419 | nvmeq = nvme_alloc_queue(dev, 0, NVME_AQ_DEPTH, 0); | 1463 | nvmeq = nvme_alloc_queue(dev, 0, NVME_AQ_DEPTH); |
| 1420 | if (!nvmeq) | 1464 | if (!nvmeq) |
| 1421 | return -ENOMEM; | 1465 | return -ENOMEM; |
| 1422 | } | 1466 | } |
| @@ -1439,18 +1483,13 @@ static int nvme_configure_admin_queue(struct nvme_dev *dev) | |||
| 1439 | if (result) | 1483 | if (result) |
| 1440 | goto free_nvmeq; | 1484 | goto free_nvmeq; |
| 1441 | 1485 | ||
| 1442 | result = nvme_alloc_admin_tags(dev); | 1486 | nvmeq->cq_vector = 0; |
| 1443 | if (result) | ||
| 1444 | goto free_nvmeq; | ||
| 1445 | |||
| 1446 | result = queue_request_irq(dev, nvmeq, nvmeq->irqname); | 1487 | result = queue_request_irq(dev, nvmeq, nvmeq->irqname); |
| 1447 | if (result) | 1488 | if (result) |
| 1448 | goto free_tags; | 1489 | goto free_nvmeq; |
| 1449 | 1490 | ||
| 1450 | return result; | 1491 | return result; |
| 1451 | 1492 | ||
| 1452 | free_tags: | ||
| 1453 | nvme_free_admin_tags(dev); | ||
| 1454 | free_nvmeq: | 1493 | free_nvmeq: |
| 1455 | nvme_free_queues(dev, 0); | 1494 | nvme_free_queues(dev, 0); |
| 1456 | return result; | 1495 | return result; |
| @@ -1944,7 +1983,7 @@ static void nvme_create_io_queues(struct nvme_dev *dev) | |||
| 1944 | unsigned i; | 1983 | unsigned i; |
| 1945 | 1984 | ||
| 1946 | for (i = dev->queue_count; i <= dev->max_qid; i++) | 1985 | for (i = dev->queue_count; i <= dev->max_qid; i++) |
| 1947 | if (!nvme_alloc_queue(dev, i, dev->q_depth, i - 1)) | 1986 | if (!nvme_alloc_queue(dev, i, dev->q_depth)) |
| 1948 | break; | 1987 | break; |
| 1949 | 1988 | ||
| 1950 | for (i = dev->online_queues; i <= dev->queue_count - 1; i++) | 1989 | for (i = dev->online_queues; i <= dev->queue_count - 1; i++) |
| @@ -2235,13 +2274,18 @@ static void nvme_wait_dq(struct nvme_delq_ctx *dq, struct nvme_dev *dev) | |||
| 2235 | break; | 2274 | break; |
| 2236 | if (!schedule_timeout(ADMIN_TIMEOUT) || | 2275 | if (!schedule_timeout(ADMIN_TIMEOUT) || |
| 2237 | fatal_signal_pending(current)) { | 2276 | fatal_signal_pending(current)) { |
| 2277 | /* | ||
| 2278 | * Disable the controller first since we can't trust it | ||
| 2279 | * at this point, but leave the admin queue enabled | ||
| 2280 | * until all queue deletion requests are flushed. | ||
| 2281 | * FIXME: This may take a while if there are more h/w | ||
| 2282 | * queues than admin tags. | ||
| 2283 | */ | ||
| 2238 | set_current_state(TASK_RUNNING); | 2284 | set_current_state(TASK_RUNNING); |
| 2239 | |||
| 2240 | nvme_disable_ctrl(dev, readq(&dev->bar->cap)); | 2285 | nvme_disable_ctrl(dev, readq(&dev->bar->cap)); |
| 2241 | nvme_disable_queue(dev, 0); | 2286 | nvme_clear_queue(dev->queues[0]); |
| 2242 | |||
| 2243 | send_sig(SIGKILL, dq->worker->task, 1); | ||
| 2244 | flush_kthread_worker(dq->worker); | 2287 | flush_kthread_worker(dq->worker); |
| 2288 | nvme_disable_queue(dev, 0); | ||
| 2245 | return; | 2289 | return; |
| 2246 | } | 2290 | } |
| 2247 | } | 2291 | } |
| @@ -2318,7 +2362,6 @@ static void nvme_del_queue_start(struct kthread_work *work) | |||
| 2318 | { | 2362 | { |
| 2319 | struct nvme_queue *nvmeq = container_of(work, struct nvme_queue, | 2363 | struct nvme_queue *nvmeq = container_of(work, struct nvme_queue, |
| 2320 | cmdinfo.work); | 2364 | cmdinfo.work); |
| 2321 | allow_signal(SIGKILL); | ||
| 2322 | if (nvme_delete_sq(nvmeq)) | 2365 | if (nvme_delete_sq(nvmeq)) |
| 2323 | nvme_del_queue_end(nvmeq); | 2366 | nvme_del_queue_end(nvmeq); |
| 2324 | } | 2367 | } |
| @@ -2376,6 +2419,34 @@ static void nvme_dev_list_remove(struct nvme_dev *dev) | |||
| 2376 | kthread_stop(tmp); | 2419 | kthread_stop(tmp); |
| 2377 | } | 2420 | } |
| 2378 | 2421 | ||
| 2422 | static void nvme_freeze_queues(struct nvme_dev *dev) | ||
| 2423 | { | ||
| 2424 | struct nvme_ns *ns; | ||
| 2425 | |||
| 2426 | list_for_each_entry(ns, &dev->namespaces, list) { | ||
| 2427 | blk_mq_freeze_queue_start(ns->queue); | ||
| 2428 | |||
| 2429 | spin_lock(ns->queue->queue_lock); | ||
| 2430 | queue_flag_set(QUEUE_FLAG_STOPPED, ns->queue); | ||
| 2431 | spin_unlock(ns->queue->queue_lock); | ||
| 2432 | |||
| 2433 | blk_mq_cancel_requeue_work(ns->queue); | ||
| 2434 | blk_mq_stop_hw_queues(ns->queue); | ||
| 2435 | } | ||
| 2436 | } | ||
| 2437 | |||
| 2438 | static void nvme_unfreeze_queues(struct nvme_dev *dev) | ||
| 2439 | { | ||
| 2440 | struct nvme_ns *ns; | ||
| 2441 | |||
| 2442 | list_for_each_entry(ns, &dev->namespaces, list) { | ||
| 2443 | queue_flag_clear_unlocked(QUEUE_FLAG_STOPPED, ns->queue); | ||
| 2444 | blk_mq_unfreeze_queue(ns->queue); | ||
| 2445 | blk_mq_start_stopped_hw_queues(ns->queue, true); | ||
| 2446 | blk_mq_kick_requeue_list(ns->queue); | ||
| 2447 | } | ||
| 2448 | } | ||
| 2449 | |||
| 2379 | static void nvme_dev_shutdown(struct nvme_dev *dev) | 2450 | static void nvme_dev_shutdown(struct nvme_dev *dev) |
| 2380 | { | 2451 | { |
| 2381 | int i; | 2452 | int i; |
| @@ -2384,8 +2455,10 @@ static void nvme_dev_shutdown(struct nvme_dev *dev) | |||
| 2384 | dev->initialized = 0; | 2455 | dev->initialized = 0; |
| 2385 | nvme_dev_list_remove(dev); | 2456 | nvme_dev_list_remove(dev); |
| 2386 | 2457 | ||
| 2387 | if (dev->bar) | 2458 | if (dev->bar) { |
| 2459 | nvme_freeze_queues(dev); | ||
| 2388 | csts = readl(&dev->bar->csts); | 2460 | csts = readl(&dev->bar->csts); |
| 2461 | } | ||
| 2389 | if (csts & NVME_CSTS_CFS || !(csts & NVME_CSTS_RDY)) { | 2462 | if (csts & NVME_CSTS_CFS || !(csts & NVME_CSTS_RDY)) { |
| 2390 | for (i = dev->queue_count - 1; i >= 0; i--) { | 2463 | for (i = dev->queue_count - 1; i >= 0; i--) { |
| 2391 | struct nvme_queue *nvmeq = dev->queues[i]; | 2464 | struct nvme_queue *nvmeq = dev->queues[i]; |
| @@ -2400,12 +2473,6 @@ static void nvme_dev_shutdown(struct nvme_dev *dev) | |||
| 2400 | nvme_dev_unmap(dev); | 2473 | nvme_dev_unmap(dev); |
| 2401 | } | 2474 | } |
| 2402 | 2475 | ||
| 2403 | static void nvme_dev_remove_admin(struct nvme_dev *dev) | ||
| 2404 | { | ||
| 2405 | if (dev->admin_q && !blk_queue_dying(dev->admin_q)) | ||
| 2406 | blk_cleanup_queue(dev->admin_q); | ||
| 2407 | } | ||
| 2408 | |||
| 2409 | static void nvme_dev_remove(struct nvme_dev *dev) | 2476 | static void nvme_dev_remove(struct nvme_dev *dev) |
| 2410 | { | 2477 | { |
| 2411 | struct nvme_ns *ns; | 2478 | struct nvme_ns *ns; |
| @@ -2413,8 +2480,10 @@ static void nvme_dev_remove(struct nvme_dev *dev) | |||
| 2413 | list_for_each_entry(ns, &dev->namespaces, list) { | 2480 | list_for_each_entry(ns, &dev->namespaces, list) { |
| 2414 | if (ns->disk->flags & GENHD_FL_UP) | 2481 | if (ns->disk->flags & GENHD_FL_UP) |
| 2415 | del_gendisk(ns->disk); | 2482 | del_gendisk(ns->disk); |
| 2416 | if (!blk_queue_dying(ns->queue)) | 2483 | if (!blk_queue_dying(ns->queue)) { |
| 2484 | blk_mq_abort_requeue_list(ns->queue); | ||
| 2417 | blk_cleanup_queue(ns->queue); | 2485 | blk_cleanup_queue(ns->queue); |
| 2486 | } | ||
| 2418 | } | 2487 | } |
| 2419 | } | 2488 | } |
| 2420 | 2489 | ||
| @@ -2495,6 +2564,7 @@ static void nvme_free_dev(struct kref *kref) | |||
| 2495 | nvme_free_namespaces(dev); | 2564 | nvme_free_namespaces(dev); |
| 2496 | nvme_release_instance(dev); | 2565 | nvme_release_instance(dev); |
| 2497 | blk_mq_free_tag_set(&dev->tagset); | 2566 | blk_mq_free_tag_set(&dev->tagset); |
| 2567 | blk_put_queue(dev->admin_q); | ||
| 2498 | kfree(dev->queues); | 2568 | kfree(dev->queues); |
| 2499 | kfree(dev->entry); | 2569 | kfree(dev->entry); |
| 2500 | kfree(dev); | 2570 | kfree(dev); |
| @@ -2591,15 +2661,20 @@ static int nvme_dev_start(struct nvme_dev *dev) | |||
| 2591 | } | 2661 | } |
| 2592 | 2662 | ||
| 2593 | nvme_init_queue(dev->queues[0], 0); | 2663 | nvme_init_queue(dev->queues[0], 0); |
| 2664 | result = nvme_alloc_admin_tags(dev); | ||
| 2665 | if (result) | ||
| 2666 | goto disable; | ||
| 2594 | 2667 | ||
| 2595 | result = nvme_setup_io_queues(dev); | 2668 | result = nvme_setup_io_queues(dev); |
| 2596 | if (result) | 2669 | if (result) |
| 2597 | goto disable; | 2670 | goto free_tags; |
| 2598 | 2671 | ||
| 2599 | nvme_set_irq_hints(dev); | 2672 | nvme_set_irq_hints(dev); |
| 2600 | 2673 | ||
| 2601 | return result; | 2674 | return result; |
| 2602 | 2675 | ||
| 2676 | free_tags: | ||
| 2677 | nvme_dev_remove_admin(dev); | ||
| 2603 | disable: | 2678 | disable: |
| 2604 | nvme_disable_queue(dev, 0); | 2679 | nvme_disable_queue(dev, 0); |
| 2605 | nvme_dev_list_remove(dev); | 2680 | nvme_dev_list_remove(dev); |
| @@ -2639,6 +2714,9 @@ static int nvme_dev_resume(struct nvme_dev *dev) | |||
| 2639 | dev->reset_workfn = nvme_remove_disks; | 2714 | dev->reset_workfn = nvme_remove_disks; |
| 2640 | queue_work(nvme_workq, &dev->reset_work); | 2715 | queue_work(nvme_workq, &dev->reset_work); |
| 2641 | spin_unlock(&dev_list_lock); | 2716 | spin_unlock(&dev_list_lock); |
| 2717 | } else { | ||
| 2718 | nvme_unfreeze_queues(dev); | ||
| 2719 | nvme_set_irq_hints(dev); | ||
| 2642 | } | 2720 | } |
| 2643 | dev->initialized = 1; | 2721 | dev->initialized = 1; |
| 2644 | return 0; | 2722 | return 0; |
| @@ -2776,11 +2854,10 @@ static void nvme_remove(struct pci_dev *pdev) | |||
| 2776 | pci_set_drvdata(pdev, NULL); | 2854 | pci_set_drvdata(pdev, NULL); |
| 2777 | flush_work(&dev->reset_work); | 2855 | flush_work(&dev->reset_work); |
| 2778 | misc_deregister(&dev->miscdev); | 2856 | misc_deregister(&dev->miscdev); |
| 2779 | nvme_dev_remove(dev); | ||
| 2780 | nvme_dev_shutdown(dev); | 2857 | nvme_dev_shutdown(dev); |
| 2858 | nvme_dev_remove(dev); | ||
| 2781 | nvme_dev_remove_admin(dev); | 2859 | nvme_dev_remove_admin(dev); |
| 2782 | nvme_free_queues(dev, 0); | 2860 | nvme_free_queues(dev, 0); |
| 2783 | nvme_free_admin_tags(dev); | ||
| 2784 | nvme_release_prp_pools(dev); | 2861 | nvme_release_prp_pools(dev); |
| 2785 | kref_put(&dev->kref, nvme_free_dev); | 2862 | kref_put(&dev->kref, nvme_free_dev); |
| 2786 | } | 2863 | } |
diff --git a/drivers/block/virtio_blk.c b/drivers/block/virtio_blk.c index 7ef7c098708f..cdfbd21e3597 100644 --- a/drivers/block/virtio_blk.c +++ b/drivers/block/virtio_blk.c | |||
| @@ -638,7 +638,7 @@ static int virtblk_probe(struct virtio_device *vdev) | |||
| 638 | goto out_put_disk; | 638 | goto out_put_disk; |
| 639 | 639 | ||
| 640 | q = vblk->disk->queue = blk_mq_init_queue(&vblk->tag_set); | 640 | q = vblk->disk->queue = blk_mq_init_queue(&vblk->tag_set); |
| 641 | if (!q) { | 641 | if (IS_ERR(q)) { |
| 642 | err = -ENOMEM; | 642 | err = -ENOMEM; |
| 643 | goto out_free_tags; | 643 | goto out_free_tags; |
| 644 | } | 644 | } |
diff --git a/include/linux/blk-mq.h b/include/linux/blk-mq.h index 8aded9ab2e4e..5735e7130d63 100644 --- a/include/linux/blk-mq.h +++ b/include/linux/blk-mq.h | |||
| @@ -34,7 +34,6 @@ struct blk_mq_hw_ctx { | |||
| 34 | unsigned long flags; /* BLK_MQ_F_* flags */ | 34 | unsigned long flags; /* BLK_MQ_F_* flags */ |
| 35 | 35 | ||
| 36 | struct request_queue *queue; | 36 | struct request_queue *queue; |
| 37 | unsigned int queue_num; | ||
| 38 | struct blk_flush_queue *fq; | 37 | struct blk_flush_queue *fq; |
| 39 | 38 | ||
| 40 | void *driver_data; | 39 | void *driver_data; |
| @@ -54,7 +53,7 @@ struct blk_mq_hw_ctx { | |||
| 54 | unsigned long dispatched[BLK_MQ_MAX_DISPATCH_ORDER]; | 53 | unsigned long dispatched[BLK_MQ_MAX_DISPATCH_ORDER]; |
| 55 | 54 | ||
| 56 | unsigned int numa_node; | 55 | unsigned int numa_node; |
| 57 | unsigned int cmd_size; /* per-request extra data */ | 56 | unsigned int queue_num; |
| 58 | 57 | ||
| 59 | atomic_t nr_active; | 58 | atomic_t nr_active; |
| 60 | 59 | ||
| @@ -195,13 +194,16 @@ static inline u16 blk_mq_unique_tag_to_tag(u32 unique_tag) | |||
| 195 | struct blk_mq_hw_ctx *blk_mq_map_queue(struct request_queue *, const int ctx_index); | 194 | struct blk_mq_hw_ctx *blk_mq_map_queue(struct request_queue *, const int ctx_index); |
| 196 | struct blk_mq_hw_ctx *blk_mq_alloc_single_hw_queue(struct blk_mq_tag_set *, unsigned int, int); | 195 | struct blk_mq_hw_ctx *blk_mq_alloc_single_hw_queue(struct blk_mq_tag_set *, unsigned int, int); |
| 197 | 196 | ||
| 197 | int blk_mq_request_started(struct request *rq); | ||
| 198 | void blk_mq_start_request(struct request *rq); | 198 | void blk_mq_start_request(struct request *rq); |
| 199 | void blk_mq_end_request(struct request *rq, int error); | 199 | void blk_mq_end_request(struct request *rq, int error); |
| 200 | void __blk_mq_end_request(struct request *rq, int error); | 200 | void __blk_mq_end_request(struct request *rq, int error); |
| 201 | 201 | ||
| 202 | void blk_mq_requeue_request(struct request *rq); | 202 | void blk_mq_requeue_request(struct request *rq); |
| 203 | void blk_mq_add_to_requeue_list(struct request *rq, bool at_head); | 203 | void blk_mq_add_to_requeue_list(struct request *rq, bool at_head); |
| 204 | void blk_mq_cancel_requeue_work(struct request_queue *q); | ||
| 204 | void blk_mq_kick_requeue_list(struct request_queue *q); | 205 | void blk_mq_kick_requeue_list(struct request_queue *q); |
| 206 | void blk_mq_abort_requeue_list(struct request_queue *q); | ||
| 205 | void blk_mq_complete_request(struct request *rq); | 207 | void blk_mq_complete_request(struct request *rq); |
| 206 | 208 | ||
| 207 | void blk_mq_stop_hw_queue(struct blk_mq_hw_ctx *hctx); | 209 | void blk_mq_stop_hw_queue(struct blk_mq_hw_ctx *hctx); |
| @@ -212,6 +214,8 @@ void blk_mq_start_stopped_hw_queues(struct request_queue *q, bool async); | |||
| 212 | void blk_mq_delay_queue(struct blk_mq_hw_ctx *hctx, unsigned long msecs); | 214 | void blk_mq_delay_queue(struct blk_mq_hw_ctx *hctx, unsigned long msecs); |
| 213 | void blk_mq_tag_busy_iter(struct blk_mq_hw_ctx *hctx, busy_iter_fn *fn, | 215 | void blk_mq_tag_busy_iter(struct blk_mq_hw_ctx *hctx, busy_iter_fn *fn, |
| 214 | void *priv); | 216 | void *priv); |
| 217 | void blk_mq_unfreeze_queue(struct request_queue *q); | ||
| 218 | void blk_mq_freeze_queue_start(struct request_queue *q); | ||
| 215 | 219 | ||
| 216 | /* | 220 | /* |
| 217 | * Driver command data is immediately after the request. So subtract request | 221 | * Driver command data is immediately after the request. So subtract request |
diff --git a/include/linux/blk_types.h b/include/linux/blk_types.h index 445d59231bc4..c294e3e25e37 100644 --- a/include/linux/blk_types.h +++ b/include/linux/blk_types.h | |||
| @@ -190,6 +190,7 @@ enum rq_flag_bits { | |||
| 190 | __REQ_PM, /* runtime pm request */ | 190 | __REQ_PM, /* runtime pm request */ |
| 191 | __REQ_HASHED, /* on IO scheduler merge hash */ | 191 | __REQ_HASHED, /* on IO scheduler merge hash */ |
| 192 | __REQ_MQ_INFLIGHT, /* track inflight for MQ */ | 192 | __REQ_MQ_INFLIGHT, /* track inflight for MQ */ |
| 193 | __REQ_NO_TIMEOUT, /* requests may never expire */ | ||
| 193 | __REQ_NR_BITS, /* stops here */ | 194 | __REQ_NR_BITS, /* stops here */ |
| 194 | }; | 195 | }; |
| 195 | 196 | ||
| @@ -243,5 +244,6 @@ enum rq_flag_bits { | |||
| 243 | #define REQ_PM (1ULL << __REQ_PM) | 244 | #define REQ_PM (1ULL << __REQ_PM) |
| 244 | #define REQ_HASHED (1ULL << __REQ_HASHED) | 245 | #define REQ_HASHED (1ULL << __REQ_HASHED) |
| 245 | #define REQ_MQ_INFLIGHT (1ULL << __REQ_MQ_INFLIGHT) | 246 | #define REQ_MQ_INFLIGHT (1ULL << __REQ_MQ_INFLIGHT) |
| 247 | #define REQ_NO_TIMEOUT (1ULL << __REQ_NO_TIMEOUT) | ||
| 246 | 248 | ||
| 247 | #endif /* __LINUX_BLK_TYPES_H */ | 249 | #endif /* __LINUX_BLK_TYPES_H */ |
