nvme: Request cancelling helpers
Subsystems (2)
PATCH 1/5 nvme: Request cancelling helpers
This patch provides an API for cancelling IO requests, replacing each driver's use of blk_mq_busy_tag_iter with a more convenient API for nvme controllers.
The nvme_cancel_request is used only in the core now, so this patch makes that function private.
--- drivers/nvme/host/core.c | 31 +++++++++++++++++++++++++++++-- drivers/nvme/host/nvme.h | 8 +++++++- drivers/nvme/host/pci.c | 4 +--- drivers/nvme/host/rdma.c | 12 ++++-------- drivers/nvme/target/loop.c | 6 ++---- 5 files changed, 43 insertions(+), 18 deletions(-)
drivers/nvme/host/core.c +29 -2
@@ -233,7 +233,7 @@ void nvme_complete_rq(struct request *req) }EXPORT_SYMBOL_GPL (nvme_complete_rq); -void nvme_cancel_request (struct request *req,void *data,bool reserved) +static void nvme_cancel_request (struct request *req,void *data,bool reserved) {if (!blk_mq_request_started (req))return ;
@@ -245,7 +245,34 @@ void nvme_cancel_request(struct request *req, void *data, bool reserved)blk_mq_complete_request (req); } -EXPORT_SYMBOL_GPL (nvme_cancel_request); + +void nvme_set_iter (struct nvme_ctrl *ctrl,struct blk_mq_tag_set *set, +busy_tag_iter_fn *fn) +{ +if (!set) +return ; +blk_mq_tagset_busy_iter (set, fn, ctrl); +} +EXPORT_SYMBOL_GPL (nvme_set_iter); + +void nvme_cancel_io_requests (struct nvme_ctrl *ctrl) +{ +nvme_set_iter (ctrl, ctrl->tagset, nvme_cancel_request); +} +EXPORT_SYMBOL_GPL (nvme_cancel_io_requests); + +void nvme_cancel_admin_requests (struct nvme_ctrl *ctrl) +{ +nvme_set_iter (ctrl, ctrl->admin_tagset, nvme_cancel_request); +} +EXPORT_SYMBOL_GPL (nvme_cancel_admin_requests); + +void nvme_cancel_requests (struct nvme_ctrl *ctrl) +{ +nvme_cancel_io_requests (ctrl); +nvme_cancel_admin_requests (ctrl); +} +EXPORT_SYMBOL_GPL (nvme_cancel_requests);bool nvme_change_ctrl_state (struct nvme_ctrl *ctrl,enum nvme_ctrl_state new_state)
drivers/nvme/host/nvme.h +7 -1
@@ -349,7 +349,6 @@ static inline void nvme_put_ctrl(struct nvme_ctrl *ctrl) }void nvme_complete_rq (struct request *req); -void nvme_cancel_request (struct request *req,void *data,bool reserved);bool nvme_change_ctrl_state (struct nvme_ctrl *ctrl,enum nvme_ctrl_state new_state);int nvme_disable_ctrl (struct nvme_ctrl *ctrl,u64 cap);
@@ -372,6 +371,13 @@ int nvme_sec_submit(void *data, u16 spsp, u8 secp, void *buffer, size_t len,void nvme_complete_async_event (struct nvme_ctrl *ctrl,__le16 status,union nvme_result *res); +void nvme_cancel_requests (struct nvme_ctrl *ctrl); +void nvme_cancel_io_requests (struct nvme_ctrl *ctrl); +void nvme_cancel_admin_requests (struct nvme_ctrl *ctrl); + +void nvme_set_iter (struct nvme_ctrl *ctrl,struct blk_mq_tag_set *set, +busy_tag_iter_fn *fn); +void nvme_stop_queues (struct nvme_ctrl *ctrl);void nvme_start_queues (struct nvme_ctrl *ctrl);void nvme_kill_queues (struct nvme_ctrl *ctrl);
drivers/nvme/host/pci.c +1 -3
@@ -2213,9 +2213,7 @@ static void nvme_dev_disable(struct nvme_dev *dev, bool shutdown) }nvme_pci_disable (dev); -blk_mq_tagset_busy_iter (&dev->tagset, nvme_cancel_request, &dev->ctrl); -blk_mq_tagset_busy_iter (&dev->admin_tagset, nvme_cancel_request, &dev->ctrl); - +nvme_cancel_requests (&dev->ctrl);/* * The driver will not be starting up queues again if shutting down so * must flush all entered requests to their failed completion to avoid
drivers/nvme/host/rdma.c +4 -8
@@ -957,14 +957,12 @@ static void nvme_rdma_error_recovery_work(struct work_struct *work)if (ctrl->ctrl.queue_count >1 ) {nvme_stop_queues (&ctrl->ctrl); -blk_mq_tagset_busy_iter (&ctrl->tag_set, - nvme_cancel_request, &ctrl->ctrl); +nvme_cancel_io_requests (&ctrl->ctrl);nvme_rdma_destroy_io_queues (ctrl, false); }blk_mq_quiesce_queue (ctrl->ctrl.admin_q); -blk_mq_tagset_busy_iter (&ctrl->admin_tag_set, - nvme_cancel_request, &ctrl->ctrl); +nvme_cancel_admin_requests (&ctrl->ctrl);nvme_rdma_destroy_admin_queue (ctrl, false);/*
@@ -1721,8 +1719,7 @@ static void nvme_rdma_shutdown_ctrl(struct nvme_rdma_ctrl *ctrl, bool shutdown)if (ctrl->ctrl.queue_count >1 ) {nvme_stop_queues (&ctrl->ctrl); -blk_mq_tagset_busy_iter (&ctrl->tag_set, - nvme_cancel_request, &ctrl->ctrl); +nvme_cancel_io_requests (&ctrl->ctrl);nvme_rdma_destroy_io_queues (ctrl, shutdown); }
@@ -1732,8 +1729,7 @@ static void nvme_rdma_shutdown_ctrl(struct nvme_rdma_ctrl *ctrl, bool shutdown)nvme_disable_ctrl (&ctrl->ctrl, ctrl->ctrl.cap);blk_mq_quiesce_queue (ctrl->ctrl.admin_q); -blk_mq_tagset_busy_iter (&ctrl->admin_tag_set, - nvme_cancel_request, &ctrl->ctrl); +nvme_cancel_admin_requests (&ctrl->ctrl);blk_mq_unquiesce_queue (ctrl->ctrl.admin_q);nvme_rdma_destroy_admin_queue (ctrl, shutdown); }
drivers/nvme/target/loop.c +2 -4
@@ -439,8 +439,7 @@ static void nvme_loop_shutdown_ctrl(struct nvme_loop_ctrl *ctrl) {if (ctrl->ctrl.queue_count >1 ) {nvme_stop_queues (&ctrl->ctrl); -blk_mq_tagset_busy_iter (&ctrl->tag_set, - nvme_cancel_request, &ctrl->ctrl); +nvme_cancel_io_requests (&ctrl->ctrl);nvme_loop_destroy_io_queues (ctrl); }
@@ -448,8 +447,7 @@ static void nvme_loop_shutdown_ctrl(struct nvme_loop_ctrl *ctrl)nvme_shutdown_ctrl (&ctrl->ctrl);blk_mq_quiesce_queue (ctrl->ctrl.admin_q); -blk_mq_tagset_busy_iter (&ctrl->admin_tag_set, - nvme_cancel_request, &ctrl->ctrl); +nvme_cancel_admin_requests (&ctrl->ctrl);blk_mq_unquiesce_queue (ctrl->ctrl.admin_q);nvme_loop_destroy_admin_queue (ctrl); }
Signature · 1 line
2.14.3
PATCH 2/5 nvme: Ending failed unstarted requests
This patch provides new nvme driver APIs for directly ending unstarted requests when they need to be failed. Previously, drivers needed to temporarily quiesce request queues while setting up the IO path to take on the responsibilty of error handling, then restart those queues. Handling these errors should be done directly in the error handling path, freeing up the IO path to not concern itself with such failure cases.
--- drivers/nvme/host/core.c | 44 +++++++++++++++++++++++++++++++++++--------- drivers/nvme/host/nvme.h | 4 ++++ drivers/nvme/host/pci.c | 4 ++-- drivers/nvme/host/rdma.c | 8 +++----- 4 files changed, 44 insertions(+), 16 deletions(-)
drivers/nvme/host/core.c +35 -9
@@ -246,6 +246,17 @@ static void nvme_cancel_request(struct request *req, void *data, bool reserved) } +static void nvme_end_unstarted_request (struct request *req,void *data, +bool reserved) +{ +if (blk_mq_request_started (req)) +return ; + +dev_dbg_ratelimited (((struct nvme_ctrl *) data)->device, +"Ending I/O %d" , req->tag); +blk_mq_end_request (req,BLK_STS_IOERR ); +} +void nvme_set_iter (struct nvme_ctrl *ctrl,struct blk_mq_tag_set *set,busy_tag_iter_fn *fn) {
@@ -255,6 +266,25 @@ void nvme_set_iter(struct nvme_ctrl *ctrl, struct blk_mq_tag_set *set, }EXPORT_SYMBOL_GPL (nvme_set_iter); +void nvme_end_io_requests (struct nvme_ctrl *ctrl) +{ +nvme_set_iter (ctrl, ctrl->tagset, nvme_end_unstarted_request); +} +EXPORT_SYMBOL_GPL (nvme_end_io_requests); + +void nvme_end_admin_requests (struct nvme_ctrl *ctrl) +{ +nvme_set_iter (ctrl, ctrl->admin_tagset, nvme_end_unstarted_request); +} +EXPORT_SYMBOL_GPL (nvme_end_admin_requests); + +void nvme_end_requests (struct nvme_ctrl *ctrl) +{ +nvme_end_io_requests (ctrl); +nvme_end_admin_requests (ctrl); +} +EXPORT_SYMBOL_GPL (nvme_end_requests); +void nvme_cancel_io_requests (struct nvme_ctrl *ctrl) {nvme_set_iter (ctrl, ctrl->tagset, nvme_cancel_request);
@@ -3215,8 +3245,10 @@ void nvme_remove_namespaces(struct nvme_ctrl *ctrl)* removing the namespaces' disks; fail all the queues now to avoid * potentially having to clean up the failed sync later. */ -if (ctrl->state ==NVME_CTRL_DEAD ) +if (ctrl->state ==NVME_CTRL_DEAD ) {nvme_kill_queues (ctrl); +nvme_end_admin_requests (ctrl); + }list_for_each_entry_safe (ns, next, &ctrl->namespaces, list)nvme_ns_remove (ns);
@@ -3467,11 +3499,6 @@ void nvme_kill_queues(struct nvme_ctrl *ctrl)struct nvme_ns *ns;mutex_lock (&ctrl->namespaces_mutex); - -/* Forcibly unquiesce queues to avoid blocking dispatch */ -if (ctrl->admin_q) -blk_mq_unquiesce_queue (ctrl->admin_q); -list_for_each_entry (ns, &ctrl->namespaces, list) {/* * Revalidating a dead namespace sets capacity to 0. This will
@@ -3481,11 +3508,10 @@ void nvme_kill_queues(struct nvme_ctrl *ctrl)continue ;revalidate_disk (ns->disk);blk_set_queue_dying (ns->queue); - -/* Forcibly unquiesce queues to avoid blocking dispatch */ -blk_mq_unquiesce_queue (ns->queue); }mutex_unlock (&ctrl->namespaces_mutex); + +nvme_end_io_requests (ctrl); }EXPORT_SYMBOL_GPL (nvme_kill_queues);
drivers/nvme/host/nvme.h +4 -0
@@ -371,6 +371,10 @@ int nvme_sec_submit(void *data, u16 spsp, u8 secp, void *buffer, size_t len,void nvme_complete_async_event (struct nvme_ctrl *ctrl,__le16 status,union nvme_result *res); +void nvme_end_requests (struct nvme_ctrl *ctrl); +void nvme_end_io_requests (struct nvme_ctrl *ctrl); +void nvme_end_admin_requests (struct nvme_ctrl *ctrl); +void nvme_cancel_requests (struct nvme_ctrl *ctrl);void nvme_cancel_io_requests (struct nvme_ctrl *ctrl);void nvme_cancel_admin_requests (struct nvme_ctrl *ctrl);
drivers/nvme/host/pci.c +2 -2
@@ -2216,11 +2216,11 @@ static void nvme_dev_disable(struct nvme_dev *dev, bool shutdown)nvme_cancel_requests (&dev->ctrl);/* * The driver will not be starting up queues again if shutting down so -* must flush all entered requests to their failed completion to avoid +* must end all entered requests to their failed completion to avoid * deadlocking blk-mq hot-cpu notifier. */ if (shutdown) -nvme_start_queues (&dev->ctrl); +nvme_end_requests (&dev->ctrl);mutex_unlock (&dev->shutdown_lock); }
drivers/nvme/host/rdma.c +3 -5
@@ -966,11 +966,9 @@ static void nvme_rdma_error_recovery_work(struct work_struct *work)nvme_rdma_destroy_admin_queue (ctrl, false);/* -* queues are not a live anymore, so restart the queues to fail fast -* new IO +* queues are not a live anymore, so end all unstarted requests. */ -blk_mq_unquiesce_queue (ctrl->ctrl.admin_q); -nvme_start_queues (&ctrl->ctrl); +nvme_end_requests (&ctrl->ctrl);nvme_rdma_reconnect_or_remove (ctrl); }
@@ -1730,7 +1728,7 @@ static void nvme_rdma_shutdown_ctrl(struct nvme_rdma_ctrl *ctrl, bool shutdown)blk_mq_quiesce_queue (ctrl->ctrl.admin_q);nvme_cancel_admin_requests (&ctrl->ctrl); -blk_mq_unquiesce_queue (ctrl->ctrl.admin_q); +nvme_end_admin_requests (&ctrl->ctrl);nvme_rdma_destroy_admin_queue (ctrl, shutdown); }
Signature · 1 line
2.14.3
PATCH 2/5 nvme: Ending failed unstarted requests
Hi Keith
Quoted 6 lines · Keith Busch
This patch provides new nvme driver APIs for directly ending unstarted requests when they need to be failed. Previously, drivers needed to temporarily quiesce request queues while setting up the IO path to take on the responsibilty of error handling, then restart those queues. Handling these errors should be done directly in the error handling path, freeing up the IO path to not concern itself with such failure cases.
Yes, we indeed need to ensure the entered requests to be drained after nvme_dev_disable returns for shutdown case.
Quoted 17 lines
Signed-off-by Keith Busch <keith.busch at intel.com>--- drivers/nvme/host/core.c | 44 +++++++++++++++++++++++++++++++++++--------- drivers/nvme/host/nvme.h | 4 ++++ drivers/nvme/host/pci.c | 4 ++-- drivers/nvme/host/rdma.c | 8 +++----- 4 files changed, 44 insertions(+), 16 deletions(-)drivers/nvme/host/core.c +1
-0@@ -246,6 +246,17 @@ static void nvme_cancel_request(struct request *req, void *data, bool reserved) } +static void nvme_end_unstarted_request(struct request *req, void *data,
drivers/nvme/host/core.c static void nvme_cancel_request(struct request *req, void *data, bool reserved) · line 259
Quoted 10 lines
drivers/nvme/host/core.c +10
-0+ bool reserved) +{ +if (blk_mq_request_started (req)) +return ; + +dev_dbg_ratelimited (((struct nvme_ctrl *) data)->device, +"Ending I/O %d" , req->tag); +blk_mq_end_request (req,BLK_STS_IOERR ); +} +
This unstarted requests have not been dequeued from the blk-mq queue. We cannot end them directly.
Thanks
Jianchao
Sagi Grimberg
maintainerPATCH 2/5 nvme: Ending failed unstarted requests
Quoted 15 lines
drivers/nvme/host/core.c static void nvme_cancel_request(struct request *req, void *data, bool reserved) · line 259
Quoted 12 lines
drivers/nvme/host/core.c +11
-0+static void nvme_end_unstarted_request (struct request *req,void *data, +bool reserved) +{ +if (blk_mq_request_started (req)) +return ; + +dev_dbg_ratelimited (((struct nvme_ctrl *) data)->device, +"Ending I/O %d" , req->tag); +blk_mq_end_request (req,BLK_STS_IOERR ); +} +This unstarted requests have not been dequeued from the blk-mq queue. We cannot end them directly.
I think we cannot complete them. I think its fine to end them.
PATCH 2/5 nvme: Ending failed unstarted requests
Hi Sagi
Quoted 16 lines · Sagi Grimberg
Quoted 15 lines
Review
Quoted 12 lines
(quoted diff) +11
-0+static void nvme_end_unstarted_request(struct request *req, void *data, +?????????????????????? bool reserved) +{ +??? if (blk_mq_request_started(req)) +??????? return; + +??? dev_dbg_ratelimited(((struct nvme_ctrl *) data)->device, +??????????????? "Ending I/O %d", req->tag); +??? blk_mq_end_request(req, BLK_STS_IOERR); +} +This unstarted requests have not been dequeued from the blk-mq queue. We cannot end them directly.
Quoted 2 lines
I think we cannot complete them. I think its fine to end them.
The end here which is done by blk_mq_end_request is to free it,
blk_mq_end_request()
-> __blk_mq_end_request()
-> blk_mq_free_request()
The requests are still on the blk-mq queues.
How can we free them ?
Thanks
Jianchao
PATCH 2/5 nvme: Ending failed unstarted requests
In reply to Keith BuschHi Keith
drivers/nvme/host/pci.c static void nvme_dev_disable(struct nvme_dev *dev, bool shutdown) · line 2223
Quoted 10 lines · Keith Busch
drivers/nvme/host/pci.c +2
-2nvme_cancel_requests (&dev->ctrl);/* * The driver will not be starting up queues again if shutting down so -* must flush all entered requests to their failed completion to avoid +* must end all entered requests to their failed completion to avoid * deadlocking blk-mq hot-cpu notifier. */ if (shutdown) -nvme_start_queues (&dev->ctrl); +nvme_end_requests (&dev->ctrl);
The blk-mq cpuhp notifier has been changed by Christoph's 4b855ad (blk-mq: Create hctx for each present CPU), the deadlocking here should have been fixed here.
So the comment here should be modified at least to avoid confusion.
On the other hand, we needn't freeze the queue for reset case, the device will be setup soon later, just quiesce the blk-mq queue should be ok. And regarding to the shutdown case, frozen and drained queue will be safer. To drain the queue, we have to unquiesce it.
Finally, we get a quiesced queue for reset case, and frozen and drained queue for shutdown case.
Thanks
Jianchao
Sagi Grimberg
maintainerPATCH 2/5 nvme: Ending failed unstarted requests
Quoted 4 lines
Hi Keith
On 01/23/2018 05:56 AM, Keith Busch wrote:
Quoted 16 lines
drivers/nvme/host/pci.c static void nvme_dev_disable(struct nvme_dev *dev, bool shutdown) · line 2223
Quoted 10 lines
nvme_cancel_requests(&dev->ctrl);
/*
* The driver will not be starting up queues again if shutting down sodrivers/nvme/host/pci.c +2
-2-* must flush all entered requests to their failed completion to avoid +* must end all entered requests to their failed completion to avoid * deadlocking blk-mq hot-cpu notifier. */ if (shutdown) -nvme_start_queues (&dev->ctrl); +nvme_end_requests (&dev->ctrl);The blk-mq cpuhp notifier has been changed by Christoph's 4b855ad (blk-mq: Create hctx for each present CPU), the deadlocking here should have been fixed here.
So the comment here should be modified at least to avoid confusion.
On the other hand, we needn't freeze the queue for reset case, the device will be setup soon later, just quiesce the blk-mq queue should be ok. And regarding to the shutdown case, frozen and drained queue will be safer. To drain the queue, we have to unquiesce it.
I think that this is exactly the point of the patch, not to unquiesce and rely on .queue_rq to fail the requests.
Sagi Grimberg
maintainerPATCH 2/5 nvme: Ending failed unstarted requests
In reply to Keith BuschQuoted 20 lines
drivers/nvme/host/rdma.c +2
-4@@ -966,11 +966,9 @@ static void nvme_rdma_error_recovery_work(struct work_struct *work)nvme_rdma_destroy_admin_queue (ctrl, false);/* -* queues are not a live anymore, so restart the queues to fail fast -* new IO +* queues are not a live anymore, so end all unstarted requests. */ -blk_mq_unquiesce_queue (ctrl->ctrl.admin_q); -nvme_start_queues (&ctrl->ctrl); +nvme_end_requests (&ctrl->ctrl);nvme_rdma_reconnect_or_remove (ctrl); }
drivers/nvme/host/rdma.c static void nvme_rdma_shutdown_ctrl(struct nvme_rdma_ctrl *ctrl, bool shutdown) · line 1733
Quoted 7 lines
drivers/nvme/host/rdma.c +1
-1@@ -1730,7 +1728,7 @@ static void nvme_rdma_shutdown_ctrl(struct nvme_rdma_ctrl *ctrl, bool shutdown)blk_mq_quiesce_queue (ctrl->ctrl.admin_q);nvme_cancel_admin_requests (&ctrl->ctrl); -blk_mq_unquiesce_queue (ctrl->ctrl.admin_q); +nvme_end_admin_requests (&ctrl->ctrl);nvme_rdma_destroy_admin_queue (ctrl, shutdown); }
I think we need to end_io_requests a little above as well.
PATCH 3/5 nvme/pci: End stopped queue requests directly
In reply to Keith BuschFor requests that have entered a queue that is not able to be brought back online, this patch will end those requests directly rather than rely on the IO path to handle this error.
--- drivers/nvme/host/pci.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+)
drivers/nvme/host/pci.c +15 -0
@@ -2272,6 +2272,19 @@ static void nvme_remove_dead_ctrl(struct nvme_dev *dev, int status)nvme_put_ctrl (&dev->ctrl); } +static void nvme_end_stopped_queue_request (struct request *req,void *data, +bool reserved) +{ +struct nvme_iod *iod =blk_mq_rq_to_pdu (req); +struct nvme_queue *nvmeq = iod->nvmeq; + +if (nvmeq->cq_vector !=-1 ) +return ; +dev_dbg_ratelimited (((struct nvme_ctrl *) data)->device, +"Ending I/O %d QID:%d" , req->tag, nvmeq->qid); +blk_mq_end_request (req,BLK_STS_IOERR ); +} +static void nvme_reset_work (struct work_struct *work) { struct nvme_dev *dev =
@@ -2344,6 +2357,8 @@ static void nvme_reset_work(struct work_struct *work)nvme_remove_namespaces (&dev->ctrl); new_state =NVME_CTRL_ADMIN_ONLY ; }else { +nvme_set_iter (&dev->ctrl, dev->ctrl.tagset, + nvme_end_stopped_queue_request);nvme_start_queues (&dev->ctrl);nvme_wait_freeze (&dev->ctrl);/* hit this only when allocate tagset fails */
Signature · 1 line
2.14.3
Sagi Grimberg
maintainerPATCH 3/5 nvme/pci: End stopped queue requests directly
drivers/nvme/host/pci.c static void nvme_remove_dead_ctrl(struct nvme_dev *dev, int status) · line 2276
Quoted 3 lines
drivers/nvme/host/pci.c +2
-0+static void nvme_end_stopped_queue_request (struct request *req,void *data, +bool reserved)
nvme_pci_end_stopped_queue_request
Quoted 15 lines
drivers/nvme/host/pci.c +11
-0+{ +struct nvme_iod *iod =blk_mq_rq_to_pdu (req); +struct nvme_queue *nvmeq = iod->nvmeq; + +if (nvmeq->cq_vector !=-1 ) +return ; +dev_dbg_ratelimited (((struct nvme_ctrl *) data)->device, +"Ending I/O %d QID:%d" , req->tag, nvmeq->qid); +blk_mq_end_request (req,BLK_STS_IOERR ); +} +static void nvme_reset_work (struct work_struct *work) { struct nvme_dev *dev =
drivers/nvme/host/pci.c static void nvme_reset_work(struct work_struct *work) · line 2361
Quoted 5 lines
drivers/nvme/host/pci.c +2
-0@@ -2344,6 +2357,8 @@ static void nvme_reset_work(struct work_struct *work)nvme_remove_namespaces (&dev->ctrl); new_state =NVME_CTRL_ADMIN_ONLY ; }else { +nvme_set_iter (&dev->ctrl, dev->ctrl.tagset, + nvme_end_stopped_queue_request);
It would have been good if we could reuse that in other transports where we maintain state flags (NVME_*_Q_LIVE).
PATCH 4/5 nvme/pci: Remove cq_vector checks in io path
In reply to Keith BuschWe don't need to check for if the queue is suspended in the submission or completion path. Requests to suspended queues are no longer submitted, and we don't unmap the doorbell while requests are active.
--- drivers/nvme/host/pci.c | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-)
drivers/nvme/host/pci.c +3 -10
@@ -889,11 +889,6 @@ static blk_status_t nvme_queue_rq(struct blk_mq_hw_ctx *hctx,blk_mq_start_request (req);spin_lock_irq (&nvmeq->q_lock); -if (unlikely (nvmeq->cq_vector <0 )) { - ret =BLK_STS_IOERR ; -spin_unlock_irq (&nvmeq->q_lock); - goto out_cleanup_iod; - }__nvme_submit_cmd (nvmeq, &cmnd);nvme_process_cq (nvmeq);spin_unlock_irq (&nvmeq->q_lock);
@@ -924,11 +919,9 @@ static inline void nvme_ring_cq_doorbell(struct nvme_queue *nvmeq) {u16 head = nvmeq->cq_head; -if (likely (nvmeq->cq_vector >=0 )) { -if (nvme_dbbuf_update_and_check_event (head, nvmeq->dbbuf_cq_db, - nvmeq->dbbuf_cq_ei)) -writel (head, nvmeq->q_db + nvmeq->dev->db_stride); - } +if (nvme_dbbuf_update_and_check_event (head, nvmeq->dbbuf_cq_db, + nvmeq->dbbuf_cq_ei)) +writel (head, nvmeq->q_db + nvmeq->dev->db_stride); } static inline void nvme_handle_cqe(struct nvme_queue *nvmeq,
Signature · 1 line
2.14.3
PATCH 5/5 nvme: Sync queues on controller resets
In reply to Keith BuschThis patch has the nvme pci driver synchronize request queues to ensure that starting up the controller is not racing with a previously running timeout handler.
--- drivers/nvme/host/core.c | 15 ++++++++++++++- drivers/nvme/host/nvme.h | 1 + drivers/nvme/host/pci.c | 4 +++- 3 files changed, 18 insertions(+), 2 deletions(-)
drivers/nvme/host/core.c +14 -1
@@ -3578,12 +3578,25 @@ void nvme_start_queues(struct nvme_ctrl *ctrl)struct nvme_ns *ns;mutex_lock (&ctrl->namespaces_mutex); -list_for_each_entry (ns, &ctrl->namespaces, list) +list_for_each_entry (ns, &ctrl->namespaces, list) {blk_mq_unquiesce_queue (ns->queue); +blk_mq_kick_requeue_list (ns->queue); + }mutex_unlock (&ctrl->namespaces_mutex); }EXPORT_SYMBOL_GPL (nvme_start_queues); +void nvme_sync_queues (struct nvme_ctrl *ctrl) +{ +struct nvme_ns *ns; + +mutex_lock (&ctrl->namespaces_mutex); +list_for_each_entry (ns, &ctrl->namespaces, list) +blk_sync_queue (ns->queue); +mutex_unlock (&ctrl->namespaces_mutex); +} +EXPORT_SYMBOL_GPL (nvme_sync_queues); +int nvme_reinit_tagset (struct nvme_ctrl *ctrl,struct blk_mq_tag_set *set) {if (!ctrl->ops->reinit_request)
drivers/nvme/host/nvme.h +1 -0
@@ -384,6 +384,7 @@ void nvme_set_iter(struct nvme_ctrl *ctrl, struct blk_mq_tag_set *set,void nvme_stop_queues (struct nvme_ctrl *ctrl);void nvme_start_queues (struct nvme_ctrl *ctrl); +void nvme_sync_queues (struct nvme_ctrl *ctrl);void nvme_kill_queues (struct nvme_ctrl *ctrl);void nvme_unfreeze (struct nvme_ctrl *ctrl);void nvme_wait_freeze (struct nvme_ctrl *ctrl);
drivers/nvme/host/pci.c +3 -1
@@ -2293,8 +2293,10 @@ static void nvme_reset_work(struct work_struct *work)* If we're called to reset a live controller first shut it down before * moving on. */ -if (dev->ctrl.ctrl_config &NVME_CC_ENABLE ) +if (dev->ctrl.ctrl_config &NVME_CC_ENABLE ) {nvme_dev_disable (dev, false); +nvme_sync_queues (&dev->ctrl); + } result =nvme_pci_enable (dev);if (result)
Signature · 1 line
2.14.3
Sagi Grimberg
maintainerPATCH 1/5 nvme: Request cancelling helpers
In reply to Keith Buschdrivers/nvme/host/core.c void nvme_cancel_request(struct request *req, void *data, bool reserved) · line 250
Quoted 3 lines
drivers/nvme/host/core.c +2
-0+void nvme_set_iter (struct nvme_ctrl *ctrl,struct blk_mq_tag_set *set, +busy_tag_iter_fn *fn)
Nit: maybe nvme_tagset_iter?
Other than that looks good!