diff options
-rw-r--r-- | sys/dev/nvme/nvme_ctrlr.c | 20 |
1 files changed, 14 insertions, 6 deletions
diff --git a/sys/dev/nvme/nvme_ctrlr.c b/sys/dev/nvme/nvme_ctrlr.c index 91122c4..d0f9c32 100644 --- a/sys/dev/nvme/nvme_ctrlr.c +++ b/sys/dev/nvme/nvme_ctrlr.c @@ -489,7 +489,7 @@ static int nvme_ctrlr_set_num_qpairs(struct nvme_controller *ctrlr) { struct nvme_completion_poll_status status; - int cq_allocated, sq_allocated; + int cq_allocated, i, sq_allocated; status.done = FALSE; nvme_ctrlr_cmd_set_num_queues(ctrlr, ctrlr->num_io_queues, @@ -511,16 +511,24 @@ nvme_ctrlr_set_num_qpairs(struct nvme_controller *ctrlr) /* * Check that the controller was able to allocate the number of - * queues we requested. If not, revert to one IO queue. + * queues we requested. If not, revert to one IO queue pair. */ if (sq_allocated < ctrlr->num_io_queues || cq_allocated < ctrlr->num_io_queues) { - ctrlr->num_io_queues = 1; - ctrlr->per_cpu_io_queues = 0; - /* TODO: destroy extra queues that were created - * previously but now found to be not needed. + /* + * Destroy extra IO queue pairs that were created at + * controller construction time but are no longer + * needed. This will only happen when a controller + * supports fewer queues than MSI-X vectors. This + * is not the normal case, but does occur with the + * Chatham prototype board. */ + for (i = 1; i < ctrlr->num_io_queues; i++) + nvme_io_qpair_destroy(&ctrlr->ioq[i]); + + ctrlr->num_io_queues = 1; + ctrlr->per_cpu_io_queues = 0; } return (0); |