From patchwork Mon Dec 18 21:08:15 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jeff Cody X-Patchwork-Id: 850404 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=2001:4830:134:3::11; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) 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 3z0tyd5433z9rxm for ; Tue, 19 Dec 2017 08:12:09 +1100 (AEDT) Received: from localhost ([::1]:42414 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eR2hj-0004Me-NY for incoming@patchwork.ozlabs.org; Mon, 18 Dec 2017 16:12:07 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:59964) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eR2eX-00023W-3e for qemu-devel@nongnu.org; Mon, 18 Dec 2017 16:08:50 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1eR2eW-0003TC-3b for qemu-devel@nongnu.org; Mon, 18 Dec 2017 16:08:49 -0500 Received: from mx1.redhat.com ([209.132.183.28]:52368) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1eR2eT-0003RF-Py; Mon, 18 Dec 2017 16:08:45 -0500 Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.phx2.redhat.com [10.5.11.16]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 13AF6C01A69E; Mon, 18 Dec 2017 21:08:45 +0000 (UTC) Received: from localhost (ovpn-120-76.rdu2.redhat.com [10.10.120.76]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 9E9B917125; Mon, 18 Dec 2017 21:08:39 +0000 (UTC) From: Jeff Cody To: qemu-block@nongnu.org Date: Mon, 18 Dec 2017 16:08:15 -0500 Message-Id: <20171218210819.31576-7-jcody@redhat.com> In-Reply-To: <20171218210819.31576-1-jcody@redhat.com> References: <20171218210819.31576-1-jcody@redhat.com> X-Scanned-By: MIMEDefang 2.79 on 10.5.11.16 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.31]); Mon, 18 Dec 2017 21:08:45 +0000 (UTC) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [PULL 06/10] blockjob: kick jobs on set-speed 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: peter.maydell@linaro.org, jcody@redhat.com, vsementsov@virtuozzo.com, jsnow@redhat.com, qemu-devel@nongnu.org Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" From: John Snow If users set an unreasonably low speed (like one byte per second), the calculated delay may exceed many hours. While we like to punish users for asking for stupid things, we do also like to allow users to correct their wicked ways. When a user provides a new speed, kick the job to allow it to recalculate its delay. Signed-off-by: John Snow Reviewed-by: Stefan Hajnoczi Message-id: 20171213204611.26276-1-jsnow@redhat.com Signed-off-by: Jeff Cody --- blockjob.c | 30 +++++++++++++++++++++++++++++- 1 file changed, 29 insertions(+), 1 deletion(-) diff --git a/blockjob.c b/blockjob.c index 715c2c2..6173e47 100644 --- a/blockjob.c +++ b/blockjob.c @@ -59,6 +59,7 @@ static void __attribute__((__constructor__)) block_job_init(void) static void block_job_event_cancelled(BlockJob *job); static void block_job_event_completed(BlockJob *job, const char *msg); +static void block_job_enter_cond(BlockJob *job, bool(*fn)(BlockJob *job)); /* Transactional group of block jobs */ struct BlockJobTxn { @@ -480,9 +481,16 @@ static void block_job_completed_txn_success(BlockJob *job) } } +/* Assumes the block_job_mutex is held */ +static bool block_job_timer_pending(BlockJob *job) +{ + return timer_pending(&job->sleep_timer); +} + void block_job_set_speed(BlockJob *job, int64_t speed, Error **errp) { Error *local_err = NULL; + int64_t old_speed = job->speed; if (!job->driver->set_speed) { error_setg(errp, QERR_UNSUPPORTED); @@ -495,6 +503,12 @@ void block_job_set_speed(BlockJob *job, int64_t speed, Error **errp) } job->speed = speed; + if (speed <= old_speed) { + return; + } + + /* kick only if a timer is pending */ + block_job_enter_cond(job, block_job_timer_pending); } void block_job_complete(BlockJob *job, Error **errp) @@ -821,7 +835,11 @@ void block_job_resume_all(void) } } -void block_job_enter(BlockJob *job) +/* + * Conditionally enter a block_job pending a call to fn() while + * under the block_job_lock critical section. + */ +static void block_job_enter_cond(BlockJob *job, bool(*fn)(BlockJob *job)) { if (!block_job_started(job)) { return; @@ -836,6 +854,11 @@ void block_job_enter(BlockJob *job) return; } + if (fn && !fn(job)) { + block_job_unlock(); + return; + } + assert(!job->deferred_to_main_loop); timer_del(&job->sleep_timer); job->busy = true; @@ -843,6 +866,11 @@ void block_job_enter(BlockJob *job) aio_co_wake(job->co); } +void block_job_enter(BlockJob *job) +{ + block_job_enter_cond(job, NULL); +} + bool block_job_is_cancelled(BlockJob *job) { return job->cancelled;