From patchwork Fri Apr 15 11:31:57 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paolo Bonzini X-Patchwork-Id: 610926 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [IPv6:2001:4830:134:3::11]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 3qmb7H5yZNz9ssM for ; Fri, 15 Apr 2016 21:35:07 +1000 (AEST) Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b=rYrSQgap; dkim-atps=neutral Received: from localhost ([::1]:60495 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ar21h-0002cA-9p for incoming@patchwork.ozlabs.org; Fri, 15 Apr 2016 07:35:05 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:55287) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ar1z3-0005lh-NM for qemu-devel@nongnu.org; Fri, 15 Apr 2016 07:32:25 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1ar1yy-0008NF-M4 for qemu-devel@nongnu.org; Fri, 15 Apr 2016 07:32:21 -0400 Received: from mail-wm0-x243.google.com ([2a00:1450:400c:c09::243]:36035) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ar1yy-0008Mv-Cr for qemu-devel@nongnu.org; Fri, 15 Apr 2016 07:32:16 -0400 Received: by mail-wm0-x243.google.com with SMTP id l6so5401550wml.3 for ; Fri, 15 Apr 2016 04:32:16 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=sender:from:to:cc:subject:date:message-id:in-reply-to:references; bh=PEsLLsP2FUPHT6M+lamiuvBV3c2uhAcDgRZLMbw+TqU=; b=rYrSQgap4c991V9jzkosPRoGeEpbmqoC51wNsxoV28i2JsPsQSUsSoIRrD0tKIt+i0 LpZQOCXnq99mxUgUkwbpSf1rgs91f7TOE8TuGxftIjydMA8T8d59ob2Ns1AdG2pFa1LZ eDwKEwLUL1FHK962aSH5VNbFqnIqHHnEDmeJuVX7tZxgGXPoW4TDQQe9RAChguQ2tLdi 9FOgbFzRr0Oaf8QYrOh7bpNMcX8KeH/S42WWBK28iesZCDxW/idLu/HEWXM3goaXeKYo yvN6v0TqV+N42RXGL3rC9pJRE7ftc62ezm5+hyJUBDCHZve5x1D1JdbcPFRXPEABL/yD zJEA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:sender:from:to:cc:subject:date:message-id :in-reply-to:references; bh=PEsLLsP2FUPHT6M+lamiuvBV3c2uhAcDgRZLMbw+TqU=; b=CqRH4qsHK5jLXLbVxNtbNQJmTnNi0crRaKep9VUYK8TEF2ZLEA0MxJn0b4/X5BIlwg IStHtiIYaKW3LqP81PNFHE6r4NtKdbRjNkZm/RFo16JdgkHoS001IlX/o6qotLRhEjx/ TV5fGOHoXKbZybtVSi98PHQNoBJnHTk6BfLrKAAd5Nzzf5VkZktrWmlILiWsLQyk030s +VJ0WP4vMlWcRfO33aiH4In/beTphYxjiPKm/TzjzBVBvyk4Eh+k5tlnUDTAcGzG/unA Kzotb164GRecYQIFW8U2h4sA6dpyS8SPevuO3QL9PJQhe+k7zAWGkAJnSWrouy4QyArE QI9A== X-Gm-Message-State: AOPr4FUP5kKTdEEONwkljDHJ28aX6tEtwUpuS67cOWvUp51Eur6Vt9nhaz8uKw0+czk4sg== X-Received: by 10.28.177.132 with SMTP id a126mr3726354wmf.86.1460719935789; Fri, 15 Apr 2016 04:32:15 -0700 (PDT) Received: from donizetti.redhat.com (94-39-141-76.adsl-ull.clienti.tiscali.it. [94.39.141.76]) by smtp.gmail.com with ESMTPSA id qt3sm15217493wjc.32.2016.04.15.04.32.14 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Fri, 15 Apr 2016 04:32:15 -0700 (PDT) From: Paolo Bonzini To: qemu-devel@nongnu.org Date: Fri, 15 Apr 2016 13:31:57 +0200 Message-Id: <1460719926-12950-3-git-send-email-pbonzini@redhat.com> X-Mailer: git-send-email 2.5.5 In-Reply-To: <1460719926-12950-1-git-send-email-pbonzini@redhat.com> References: <1460719926-12950-1-git-send-email-pbonzini@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::243 Subject: [Qemu-devel] [PATCH 02/11] throttle-groups: restart throttled requests from coroutine context 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: kwolf@redhat.com, berto@igalia.com, famz@redhat.com, stefanha@redhat.com Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" Signed-off-by: Paolo Bonzini Reviewed-by: Stefan Hajnoczi --- block/throttle-groups.c | 69 +++++++++++++++++++++++++++++++++++-------------- 1 file changed, 49 insertions(+), 20 deletions(-) diff --git a/block/throttle-groups.c b/block/throttle-groups.c index 1938e90..53e910e 100644 --- a/block/throttle-groups.c +++ b/block/throttle-groups.c @@ -264,8 +264,7 @@ static void schedule_next_request(BlockDriverState *bs, bool is_write) /* If it doesn't have to wait, queue it for immediate execution */ if (!must_wait) { /* Give preference to requests from the current bs */ - if (qemu_in_coroutine() && - qemu_co_queue_next(&bs->throttled_reqs[is_write])) { + if (qemu_co_queue_next(&bs->throttled_reqs[is_write])) { token = bs; } else { ThrottleTimers *tt = &token->throttle_timers; @@ -317,15 +316,54 @@ void coroutine_fn throttle_group_co_io_limits_intercept(BlockDriverState *bs, qemu_mutex_unlock(&tg->lock); } -void throttle_group_restart_bs(BlockDriverState *bs) -{ - int i; +typedef struct RestartData RestartData; +struct RestartData { + BlockDriverState *bs; + bool single; + bool is_write; +}; - for (i = 0; i < 2; i++) { - while (qemu_co_enter_next(&bs->throttled_reqs[i])) { - ; +static void throttle_group_restart_queue_entry(void *opaque) +{ + RestartData *data = opaque; + BlockDriverState *bs = data->bs; + bool single = data->single; + bool is_write = data->is_write; + unsigned count = 0; + + g_free(data); + while (qemu_co_queue_next(&bs->throttled_reqs[is_write])) { + count++; + if (single) { + break; } } + + if (count == 0) { + ThrottleGroup *tg = container_of(bs->throttle_state, ThrottleGroup, ts); + + qemu_mutex_lock(&tg->lock); + schedule_next_request(bs, is_write); + qemu_mutex_unlock(&tg->lock); + } +} + +static void throttle_group_restart_queue(BlockDriverState *bs, bool single, + bool is_write) +{ + RestartData *data = g_new(RestartData, 1); + + data->bs = bs; + data->single = single; + data->is_write = is_write; + qemu_coroutine_enter(qemu_coroutine_create(throttle_group_restart_queue_entry), + &data); +} + +void throttle_group_restart_bs(BlockDriverState *bs) +{ + throttle_group_restart_queue(bs, false, 0); + throttle_group_restart_queue(bs, false, 1); } /* Update the throttle configuration for a particular group. Similar @@ -351,8 +389,8 @@ void throttle_group_config(BlockDriverState *bs, ThrottleConfig *cfg) throttle_config(ts, tt, cfg); qemu_mutex_unlock(&tg->lock); - qemu_co_enter_next(&bs->throttled_reqs[0]); - qemu_co_enter_next(&bs->throttled_reqs[1]); + throttle_group_restart_queue(bs, true, 0); + throttle_group_restart_queue(bs, true, 1); } /* Get the throttle configuration from a particular group. Similar to @@ -381,7 +419,6 @@ static void timer_cb(BlockDriverState *bs, bool is_write) { ThrottleState *ts = bs->throttle_state; ThrottleGroup *tg = container_of(ts, ThrottleGroup, ts); - bool empty_queue; /* The timer has just been fired, so we can update the flag */ qemu_mutex_lock(&tg->lock); @@ -390,16 +427,8 @@ static void timer_cb(BlockDriverState *bs, bool is_write) /* Run the request that was waiting for this timer */ aio_context_acquire(bdrv_get_aio_context(bs)); - empty_queue = !qemu_co_enter_next(&bs->throttled_reqs[is_write]); + throttle_group_restart_queue(bs, true, is_write); aio_context_release(bdrv_get_aio_context(bs)); - - /* If the request queue was empty then we have to take care of - * scheduling the next one */ - if (empty_queue) { - qemu_mutex_lock(&tg->lock); - schedule_next_request(bs, is_write); - qemu_mutex_unlock(&tg->lock); - } } static void read_timer_cb(void *opaque)