Message ID | 20200617132201.1832152-2-stefanha@redhat.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | block/nvme: support nested aio_poll() | expand |
On Wed, Jun 17, 2020 at 02:21:55PM +0100, Stefan Hajnoczi wrote: > A lot of CPU time is spent simply locking/unlocking q->lock during > polling. Check for completion outside the lock to make q->lock disappear > from the profile. > > Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com> > --- > block/nvme.c | 12 ++++++++++++ > 1 file changed, 12 insertions(+) > > diff --git a/block/nvme.c b/block/nvme.c > index eb2f54dd9d..e4375ec245 100644 > --- a/block/nvme.c > +++ b/block/nvme.c > @@ -512,6 +512,18 @@ static bool nvme_poll_queues(BDRVNVMeState *s) > > for (i = 0; i < s->nr_queues; i++) { > NVMeQueuePair *q = s->queues[i]; > + const size_t cqe_offset = q->cq.head * NVME_CQ_ENTRY_BYTES; > + NvmeCqe *cqe = (NvmeCqe *)&q->cq.queue[cqe_offset]; > + > + /* > + * Do an early check for completions. q->lock isn't needed because > + * nvme_process_completion() only runs in the event loop thread and > + * cannot race with itself. > + */ > + if ((le16_to_cpu(cqe->status) & 0x1) == q->cq_phase) { > + continue; > + } > + > qemu_mutex_lock(&q->lock); > while (nvme_process_completion(s, q)) { > /* Keep polling */ > -- > 2.26.2 > Thanks for extending the comment. Reviewed-by: Sergio Lopez <slp@redhat.com>
diff --git a/block/nvme.c b/block/nvme.c index eb2f54dd9d..e4375ec245 100644 --- a/block/nvme.c +++ b/block/nvme.c @@ -512,6 +512,18 @@ static bool nvme_poll_queues(BDRVNVMeState *s) for (i = 0; i < s->nr_queues; i++) { NVMeQueuePair *q = s->queues[i]; + const size_t cqe_offset = q->cq.head * NVME_CQ_ENTRY_BYTES; + NvmeCqe *cqe = (NvmeCqe *)&q->cq.queue[cqe_offset]; + + /* + * Do an early check for completions. q->lock isn't needed because + * nvme_process_completion() only runs in the event loop thread and + * cannot race with itself. + */ + if ((le16_to_cpu(cqe->status) & 0x1) == q->cq_phase) { + continue; + } + qemu_mutex_lock(&q->lock); while (nvme_process_completion(s, q)) { /* Keep polling */
A lot of CPU time is spent simply locking/unlocking q->lock during polling. Check for completion outside the lock to make q->lock disappear from the profile. Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com> --- block/nvme.c | 12 ++++++++++++ 1 file changed, 12 insertions(+)