From patchwork Wed Jul 13 07:57:09 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Roman Pen X-Patchwork-Id: 9227035 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 608576075D for ; Wed, 13 Jul 2016 08:00:16 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 52ED02621D for ; Wed, 13 Jul 2016 08:00:16 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 478392787D; Wed, 13 Jul 2016 08:00:16 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-6.8 required=2.0 tests=BAYES_00,DKIM_SIGNED, RCVD_IN_DNSWL_HI,T_DKIM_INVALID autolearn=ham version=3.3.1 Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id C7F202621D for ; Wed, 13 Jul 2016 08:00:13 +0000 (UTC) Received: from localhost ([::1]:45722 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1bNF5Y-0001Jv-PB for patchwork-qemu-devel@patchwork.kernel.org; Wed, 13 Jul 2016 04:00:12 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:42201) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1bNF3J-0006tV-1n for qemu-devel@nongnu.org; Wed, 13 Jul 2016 03:57:54 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1bNF3F-000744-Rj for qemu-devel@nongnu.org; Wed, 13 Jul 2016 03:57:53 -0400 Received: from mail-wm0-x22e.google.com ([2a00:1450:400c:c09::22e]:38526) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1bNF3F-000740-I5 for qemu-devel@nongnu.org; Wed, 13 Jul 2016 03:57:49 -0400 Received: by mail-wm0-x22e.google.com with SMTP id o80so55515219wme.1 for ; Wed, 13 Jul 2016 00:57:49 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=profitbricks-com.20150623.gappssmtp.com; s=20150623; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=kGFMC9a/dlucmgw63ZpxZLxo/hVXSdht9rUJnE9ulw8=; b=yZdVlSMW1RJsp4xgoo5I1aw0J61uVqDFCK++l37iIVqWEb4rU1UNcyTliSKBhmmnLx JB8t1elQIG47/MZ8C19WJ9SekCfscVXdeiy8+nJtF3qvQN4dl0TUQnF/FkpUEa3RZsw7 Gfswx+vEjzekXmfnJrsHXjSYKF6W+idmUsMUbzuE/MqVnxY6Hr3KZoNv9KYGhAF8wPGj oOcjpY37qWiUq0T7C/NcJcp7h3CFGKm9wuku4U0rDP3ZxF8RWs5MDvRR2WY+4KtP1jbH FLBEL26lzHkqCwJ0Y18hhPs+Nimpnv0obEXlNbI8OJEkA1JXTwgm+nkdB8syUAlxbo2/ Mt3Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=kGFMC9a/dlucmgw63ZpxZLxo/hVXSdht9rUJnE9ulw8=; b=kgHm0tx1W6K5d6C6eSPTmI6lRew3ijPRl38/7ilzj1fJrEJ6zIHI1kM6g8tCN9p4/l kEbmSg0mVpNvjqRTT4tVBfjaxSnWrNcSVKifoTLA8sHpw22KkXXwQH7lIyKo7aS22l11 VB2voo8i1cfFSiITV+0C+vdEaOlXi8WOEn9HCCnf0zf/XYBRC+PZhRpOm5CuEVOp0m7f rFAYsvKZH4AEJ7hhyxah47S11KGc4alE1KiZoHPLp9JAYSUq/tzOPP/jNl5zR4YbsmzM bP0ATyRT9GMVnwbhLBq+P13aoBTPpL/n9LPoeHDWOVSql4oEUiagsK4zGEcURv+hWpYW ETlw== X-Gm-Message-State: ALyK8tKNTj4yvfgOr3pR2yW7VEHsXbi0JG1EKRCYU6CF1Df3GTKPhUzBMBxJzYtT0s2l+VCZ X-Received: by 10.28.169.203 with SMTP id s194mr9057203wme.95.1468396668717; Wed, 13 Jul 2016 00:57:48 -0700 (PDT) Received: from pb.pb.local ([62.217.45.26]) by smtp.gmail.com with ESMTPSA id 17sm555611wmf.6.2016.07.13.00.57.47 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Wed, 13 Jul 2016 00:57:48 -0700 (PDT) From: Roman Pen To: Date: Wed, 13 Jul 2016 09:57:09 +0200 Message-Id: <1468396629-26094-1-git-send-email-roman.penyaev@profitbricks.com> X-Mailer: git-send-email 2.8.2 In-Reply-To: <20160713022334.GB16038@ad.usersys.redhat.com> References: <20160713022334.GB16038@ad.usersys.redhat.com> X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 2a00:1450:400c:c09::22e Subject: [Qemu-devel] [PATCH V2 1/1] linux-aio: prevent submitting more than MAX_EVENTS X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Paolo Bonzini , Fam Zheng , Stefan Hajnoczi , Roman Pen , qemu-devel@nongnu.org Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" X-Virus-Scanned: ClamAV using ClamSMTP v1..v2: o comment tweaks. o fix QEMU coding style. Invoking io_setup(MAX_EVENTS) we ask kernel to create ring buffer for us with specified number of events. But kernel ring buffer allocation logic is a bit tricky (ring buffer is page size aligned + some percpu allocation are required) so eventually more than requested events number is allocated. From a userspace side we have to follow the convention and should not try to io_submit() more or logic, which consumes completed events, should be changed accordingly. The pitfall is in the following sequence: MAX_EVENTS = 128 io_setup(MAX_EVENTS) io_submit(MAX_EVENTS) io_submit(MAX_EVENTS) /* now 256 events are in-flight */ io_getevents(MAX_EVENTS) = 128 /* we can handle only 128 events at once, to be sure * that nothing is pended the io_getevents(MAX_EVENTS) * call must be invoked once more or hang will happen. */ To prevent the hang or reiteration of io_getevents() call this patch restricts the number of in-flights, which is now limited to MAX_EVENTS. Signed-off-by: Roman Pen Reviewed-by: Fam Zheng Cc: Stefan Hajnoczi Cc: Paolo Bonzini Cc: qemu-devel@nongnu.org Reviewed-by: Paolo Bonzini --- block/linux-aio.c | 26 ++++++++++++++++---------- 1 file changed, 16 insertions(+), 10 deletions(-) diff --git a/block/linux-aio.c b/block/linux-aio.c index e468960..78f4524 100644 --- a/block/linux-aio.c +++ b/block/linux-aio.c @@ -28,8 +28,6 @@ */ #define MAX_EVENTS 128 -#define MAX_QUEUED_IO 128 - struct qemu_laiocb { BlockAIOCB common; Coroutine *co; @@ -44,7 +42,8 @@ struct qemu_laiocb { typedef struct { int plugged; - unsigned int n; + unsigned int in_queue; + unsigned int in_flight; bool blocked; QSIMPLEQ_HEAD(, qemu_laiocb) pending; } LaioQueue; @@ -129,6 +128,7 @@ static void qemu_laio_completion_bh(void *opaque) s->event_max = 0; return; /* no more events */ } + s->io_q.in_flight -= s->event_max; } /* Reschedule so nested event loops see currently pending completions */ @@ -190,7 +190,8 @@ static void ioq_init(LaioQueue *io_q) { QSIMPLEQ_INIT(&io_q->pending); io_q->plugged = 0; - io_q->n = 0; + io_q->in_queue = 0; + io_q->in_flight = 0; io_q->blocked = false; } @@ -198,14 +199,17 @@ static void ioq_submit(LinuxAioState *s) { int ret, len; struct qemu_laiocb *aiocb; - struct iocb *iocbs[MAX_QUEUED_IO]; + struct iocb *iocbs[MAX_EVENTS]; QSIMPLEQ_HEAD(, qemu_laiocb) completed; do { + if (s->io_q.in_flight >= MAX_EVENTS) { + break; + } len = 0; QSIMPLEQ_FOREACH(aiocb, &s->io_q.pending, next) { iocbs[len++] = &aiocb->iocb; - if (len == MAX_QUEUED_IO) { + if (s->io_q.in_flight + len >= MAX_EVENTS) { break; } } @@ -218,11 +222,12 @@ static void ioq_submit(LinuxAioState *s) abort(); } - s->io_q.n -= ret; + s->io_q.in_flight += ret; + s->io_q.in_queue -= ret; aiocb = container_of(iocbs[ret - 1], struct qemu_laiocb, iocb); QSIMPLEQ_SPLIT_AFTER(&s->io_q.pending, aiocb, next, &completed); } while (ret == len && !QSIMPLEQ_EMPTY(&s->io_q.pending)); - s->io_q.blocked = (s->io_q.n > 0); + s->io_q.blocked = (s->io_q.in_queue > 0); } void laio_io_plug(BlockDriverState *bs, LinuxAioState *s) @@ -263,9 +268,10 @@ static int laio_do_submit(int fd, struct qemu_laiocb *laiocb, off_t offset, io_set_eventfd(&laiocb->iocb, event_notifier_get_fd(&s->e)); QSIMPLEQ_INSERT_TAIL(&s->io_q.pending, laiocb, next); - s->io_q.n++; + s->io_q.in_queue++; if (!s->io_q.blocked && - (!s->io_q.plugged || s->io_q.n >= MAX_QUEUED_IO)) { + (!s->io_q.plugged || + s->io_q.in_flight + s->io_q.in_queue >= MAX_EVENTS)) { ioq_submit(s); }