diff --git a/hw/block/femu/femu.c b/hw/block/femu/femu.c index 0c0f51ca2d3..1ec3d410979 100644 --- a/hw/block/femu/femu.c +++ b/hw/block/femu/femu.c @@ -38,7 +38,6 @@ static void nvme_process_cq_cpl(void *arg) NvmeCQueue *cq = NULL; NvmeRequest *req = NULL; uint64_t now; - bool should_isr[5] = {false}; int rc; int i; @@ -64,29 +63,22 @@ static void nvme_process_cq_cpl(void *arg) cq = n->cq[req->sq->sqid]; nvme_post_cqe(cq, req); QTAILQ_INSERT_TAIL(&req->sq->req_list, req, entry); - req = pqueue_pop(n->pq); - should_isr[req->sq->sqid] = true; + pqueue_pop(n->pq); + n->should_isr[req->sq->sqid] = true; } - for (i = 1; i <= 4; i++) { - if (should_isr[i]) + for (i = 1; i <= n->num_io_queues; i++) { + if (n->should_isr[i]) { + n->should_isr[i] = false; nvme_isr_notify_io(n->cq[i]); + } + assert(n->should_isr[i] == false); } - -#if 0 - req = NULL; - while ((req = pqueue_pop(n->pq))) { - cq = n->cq[req->sq->sqid]; - nvme_post_cqe(cq, req); - QTAILQ_INSERT_TAIL(&req->sq->req_list, req, entry); - nvme_isr_notify_io(cq); - } -#endif } /* Coperd: IO thread for NVMe submission processing */ /* TODO: need to handle controller reset correctly */ -static void *nvme_sq_poller(void *arg) +static void *nvme_poller(void *arg) { FemuCtrl *n = (FemuCtrl *)arg; int i; @@ -132,39 +124,43 @@ static void set_pos(void *a, size_t pos) ((NvmeRequest *)a)->pos = pos; } -void femu_create_nvme_sq_poller(FemuCtrl *n) +void femu_create_nvme_poller(FemuCtrl *n) { - /* Coperd: we put NvmeRequest into these rings */ + n->should_isr = g_malloc0(sizeof(bool) * (n->num_io_queues + 1)); - n->to_ftl = femu_ring_create(FEMU_RING_TYPE_MP_SC, 2048); + /* Coperd: we put NvmeRequest into these rings */ + n->to_ftl = femu_ring_create(FEMU_RING_TYPE_MP_SC, FEMU_MAX_INF_REQS); if (!n->to_ftl) { printf("FEMU: failed to create ring (n->to_ftl) ...\n"); abort(); } assert(rte_ring_empty(n->to_ftl)); - n->to_poller = femu_ring_create(FEMU_RING_TYPE_MP_SC, 2048); + n->to_poller = femu_ring_create(FEMU_RING_TYPE_MP_SC, FEMU_MAX_INF_REQS); if (!n->to_poller) { printf("FEMU: failed to create ring (n->to_poller) ...\n"); abort(); } assert(rte_ring_empty(n->to_poller)); - n->pq = pqueue_init(2048, cmp_pri, get_pri, set_pri, get_pos, set_pos); + n->pq = pqueue_init(FEMU_MAX_INF_REQS, cmp_pri, get_pri, set_pri, get_pos, + set_pos); if (!n->pq) { printf("FEMU: failed to create pqueue (n->pq) ...\n"); abort(); } - qemu_thread_create(&n->sq_poller, "sq-poller", nvme_sq_poller, n, QEMU_THREAD_JOINABLE); + qemu_thread_create(&n->poller, "nvme-poller", nvme_poller, n, + QEMU_THREAD_JOINABLE); } -static void femu_destroy_nvme_sq_poller(FemuCtrl *n) +static void femu_destroy_nvme_poller(FemuCtrl *n) { - qemu_thread_join(&n->sq_poller); + qemu_thread_join(&n->poller); pqueue_free(n->pq); femu_ring_free(n->to_poller); femu_ring_free(n->to_ftl); + g_free(n->should_isr); } void nvme_post_cqes_io(void *opaque) @@ -1000,7 +996,6 @@ static int femu_init(PCIDevice *pci_dev) femu_init_mem_backend(&n->mbe, bs_size); - n->lisr_tick = 0; n->completed = 0; n->start_time = time(NULL); n->reg_size = pow2ceil(0x1004 + 2 * (n->num_io_queues + 1) * 4); @@ -1039,7 +1034,7 @@ static void femu_exit(PCIDevice *pci_dev) nvme_clear_ctrl(n, true); - femu_destroy_nvme_sq_poller(n); + femu_destroy_nvme_poller(n); femu_destroy_mem_backend(&n->mbe); g_free(n->namespaces); diff --git a/hw/block/femu/nvme-util.c b/hw/block/femu/nvme-util.c index 5aa403fed3b..82fcd40dd76 100644 --- a/hw/block/femu/nvme-util.c +++ b/hw/block/femu/nvme-util.c @@ -765,7 +765,7 @@ uint16_t nvme_set_db_memory(FemuCtrl *n, const NvmeCmd *cmd) } if (!n->dataplane_started) { - femu_create_nvme_sq_poller(n); + femu_create_nvme_poller(n); n->dataplane_started = true; } printf("FEMU:nvme_set_db_memory returns SUCCESS!\n"); diff --git a/hw/block/femu/nvme.h b/hw/block/femu/nvme.h index 7e7c55c44a6..8071e237ea5 100644 --- a/hw/block/femu/nvme.h +++ b/hw/block/femu/nvme.h @@ -35,7 +35,7 @@ enum NvmeCapShift { CAP_DSTRD_SHIFT = 32, CAP_NSSRS_SHIFT = 33, CAP_CSS_SHIFT = 37, - CAP_FEMU_OC_SHIFT = 44, + CAP_FEMU_OC_SHIFT = 44, CAP_MPSMIN_SHIFT = 48, CAP_MPSMAX_SHIFT = 52, }; @@ -48,7 +48,7 @@ enum NvmeCapMask { CAP_DSTRD_MASK = 0xf, CAP_NSSRS_MASK = 0x1, CAP_CSS_MASK = 0xff, - CAP_FEMU_OC_MASK = 0x1, + CAP_FEMU_OC_MASK = 0x1, CAP_MPSMIN_MASK = 0xf, CAP_MPSMAX_MASK = 0xf, }; @@ -894,7 +894,7 @@ typedef struct FemuCtrl { uint32_t cmbloc; uint8_t *cmbuf; - QemuThread sq_poller; + QemuThread poller; bool dataplane_started; bool vector_poll_started; @@ -924,11 +924,11 @@ typedef struct FemuCtrl { struct ssdstate ssd; struct femu_mbe mbe; int completed; - uint64_t lisr_tick; struct rte_ring *to_ftl; struct rte_ring *to_poller; pqueue_t *pq; + bool *should_isr; } FemuCtrl; typedef struct NvmeDifTuple { @@ -939,6 +939,7 @@ typedef struct NvmeDifTuple { #define SQ_POLLING_PERIOD_NS (5000) #define CQ_POLLING_PERIOD_NS (5000) +#define FEMU_MAX_INF_REQS (65536) enum { FEMU_WHITEBOX_MODE = 0, @@ -1054,7 +1055,7 @@ uint64_t ns_blks(NvmeNamespace *ns, uint8_t lba_idx); void nvme_partition_ns(NvmeNamespace *ns, uint8_t lba_idx); void nvme_post_cqes_io(void *opaque); -void femu_create_nvme_sq_poller(FemuCtrl *n); +void femu_create_nvme_poller(FemuCtrl *n); extern int64_t nand_read_upper_t;