diff options
author | jimharris <jimharris@FreeBSD.org> | 2013-03-26 21:48:41 +0000 |
---|---|---|
committer | jimharris <jimharris@FreeBSD.org> | 2013-03-26 21:48:41 +0000 |
commit | de155eb698ae9554bd2c7bcd7e22a4287e71f640 (patch) | |
tree | c844427895ad703c1b9a92899b75ce9361c486ff /sys/dev/nvme/nvme_qpair.c | |
parent | aa210ff37b607051879573aac42493a1dbedf82d (diff) | |
download | FreeBSD-src-de155eb698ae9554bd2c7bcd7e22a4287e71f640.zip FreeBSD-src-de155eb698ae9554bd2c7bcd7e22a4287e71f640.tar.gz |
Just disable the controller instead of deleting IO queues during detach.
This is just as effective, and removes the need for a bunch of admin commands
to a controller that's going to be disabled shortly anyways.
Sponsored by: Intel
Reviewed by: carl
Diffstat (limited to 'sys/dev/nvme/nvme_qpair.c')
-rw-r--r-- | sys/dev/nvme/nvme_qpair.c | 75 |
1 files changed, 16 insertions, 59 deletions
diff --git a/sys/dev/nvme/nvme_qpair.c b/sys/dev/nvme/nvme_qpair.c index 69842b3..a508f9e 100644 --- a/sys/dev/nvme/nvme_qpair.c +++ b/sys/dev/nvme/nvme_qpair.c @@ -324,6 +324,21 @@ nvme_qpair_destroy(struct nvme_qpair *qpair) bus_release_resource(qpair->ctrlr->dev, SYS_RES_IRQ, rman_get_rid(qpair->res), qpair->res); + if (qpair->cmd) { + bus_dmamap_unload(qpair->dma_tag, qpair->cmd_dma_map); + bus_dmamap_destroy(qpair->dma_tag, qpair->cmd_dma_map); + contigfree(qpair->cmd, + qpair->num_entries * sizeof(struct nvme_command), M_NVME); + } + + if (qpair->cpl) { + bus_dmamap_unload(qpair->dma_tag, qpair->cpl_dma_map); + bus_dmamap_destroy(qpair->dma_tag, qpair->cpl_dma_map); + contigfree(qpair->cpl, + qpair->num_entries * sizeof(struct nvme_completion), + M_NVME); + } + if (qpair->dma_tag) bus_dma_tag_destroy(qpair->dma_tag); @@ -362,72 +377,14 @@ nvme_admin_qpair_destroy(struct nvme_qpair *qpair) { nvme_admin_qpair_abort_aers(qpair); - - /* - * For NVMe, you don't send delete queue commands for the admin - * queue, so we just need to unload and free the cmd and cpl memory. - */ - bus_dmamap_unload(qpair->dma_tag, qpair->cmd_dma_map); - bus_dmamap_destroy(qpair->dma_tag, qpair->cmd_dma_map); - - contigfree(qpair->cmd, - qpair->num_entries * sizeof(struct nvme_command), M_NVME); - - bus_dmamap_unload(qpair->dma_tag, qpair->cpl_dma_map); - bus_dmamap_destroy(qpair->dma_tag, qpair->cpl_dma_map); - contigfree(qpair->cpl, - qpair->num_entries * sizeof(struct nvme_completion), M_NVME); - nvme_qpair_destroy(qpair); } -static void -nvme_free_cmd_ring(void *arg, const struct nvme_completion *status) -{ - struct nvme_qpair *qpair; - - qpair = (struct nvme_qpair *)arg; - bus_dmamap_unload(qpair->dma_tag, qpair->cmd_dma_map); - bus_dmamap_destroy(qpair->dma_tag, qpair->cmd_dma_map); - contigfree(qpair->cmd, - qpair->num_entries * sizeof(struct nvme_command), M_NVME); - qpair->cmd = NULL; -} - -static void -nvme_free_cpl_ring(void *arg, const struct nvme_completion *status) -{ - struct nvme_qpair *qpair; - - qpair = (struct nvme_qpair *)arg; - bus_dmamap_unload(qpair->dma_tag, qpair->cpl_dma_map); - bus_dmamap_destroy(qpair->dma_tag, qpair->cpl_dma_map); - contigfree(qpair->cpl, - qpair->num_entries * sizeof(struct nvme_completion), M_NVME); - qpair->cpl = NULL; -} - void nvme_io_qpair_destroy(struct nvme_qpair *qpair) { - struct nvme_controller *ctrlr = qpair->ctrlr; - if (qpair->num_entries > 0) { - - nvme_ctrlr_cmd_delete_io_sq(ctrlr, qpair, nvme_free_cmd_ring, - qpair); - /* Spin until free_cmd_ring sets qpair->cmd to NULL. */ - while (qpair->cmd) - DELAY(5); - - nvme_ctrlr_cmd_delete_io_cq(ctrlr, qpair, nvme_free_cpl_ring, - qpair); - /* Spin until free_cpl_ring sets qpair->cmd to NULL. */ - while (qpair->cpl) - DELAY(5); - - nvme_qpair_destroy(qpair); - } + nvme_qpair_destroy(qpair); } static void |