From nobody Thu Nov 6 06:19:21 2025 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=gmail.com Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1539861025544708.6863221396876; Thu, 18 Oct 2018 04:10:25 -0700 (PDT) Received: from localhost ([::1]:41664 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gD6C8-0004fb-EV for importer@patchew.org; Thu, 18 Oct 2018 07:10:24 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:35596) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gD69I-0002dG-1T for qemu-devel@nongnu.org; Thu, 18 Oct 2018 07:07:29 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gD69E-000052-S4 for qemu-devel@nongnu.org; Thu, 18 Oct 2018 07:07:27 -0400 Received: from mail-lj1-x242.google.com ([2a00:1450:4864:20::242]:33806) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1gD69E-0008VY-IE for qemu-devel@nongnu.org; Thu, 18 Oct 2018 07:07:24 -0400 Received: by mail-lj1-x242.google.com with SMTP id j17-v6so27323468lja.1 for ; Thu, 18 Oct 2018 04:07:24 -0700 (PDT) Received: from localhost.localdomain ([77.221.221.49]) by smtp.gmail.com with ESMTPSA id u77-v6sm4575811lja.37.2018.10.18.04.07.20 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Thu, 18 Oct 2018 04:07:21 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references :in-reply-to:references; bh=NMAcGNcsZRW44ZhP62Qq/LgejL46qx5h1Hr+BVKdt+s=; b=qY3iWXcGMNzMMsuZR4qvZcJW9dpbV3roWobbxAsRYadonR+SE6W/nz5eOtpuOSs017 8ssMc1cgAIfwpOD72y1F4ky392tQeU2nYl5uxsttO47cRMlG/N8WljUAA4qGu6Q9tvaj QxWdnG1nMFdCmN0637jhc/3hyZphUQL4ojJ8uIlzcX6OjdTijJsmvfGoz4RJXVRyX6K8 fHjRB2Bit7RG6wycKoQRRrMdXNBi3hYxMCaPs0S0PeyCJgbkaTh4CUG9DEsfRfsV+Wbf 1tGt5YUbz9eeWb8BvpmV0s2BYs0YgB1xUQjVllwPmbj5REq0kNX6wcEtHdbC3NV0Z/Xg a+uQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:in-reply-to:references; bh=NMAcGNcsZRW44ZhP62Qq/LgejL46qx5h1Hr+BVKdt+s=; b=k1j+28TzHax6qnMw3p1Ho4dmiwul1mb8kQx0S+RwtSUdpVKwM/Br3873BrmGBXLpXR ALjWeou6h+jLMBoiyI0YWFN7SjMs0eI1RXknqp04C1s5rG8jAcmtgJyvO20w65uz4q/v ekyWYrMWa8rhYKE6pk8AesEi86UZz6fJXaXdGIVpIVH7Xs+unfdZd1/65YMG2XXy9TAd 6yqpTsKbQg63lNwyG5JWs0q63UI6KtHs3IlfOeFzFCiHvP915rK1PSH6lACYp2q2rxYc HC8RRKeVkiE7wbeV/BCoYdDHWaYJtxuKHeBqeYbdQUKQ8BM7d5+fNqkArKrw8mmnWfRg kZhg== X-Gm-Message-State: ABuFfog4QsJVad58aB8rcUBiHQ5daitrWjPq2ryCaUGy6ynaNj86mBa3 0Vz/37JXn/5oLe1v0twUK1o49aHB9TA= X-Google-Smtp-Source: ACcGV605XjmIvoRd9H4t0p/zOXNsLaJOJo+ATTva0BnosgRyUpoZoA3b9Mhe34cgXSGD21fyTVeY0A== X-Received: by 2002:a2e:2bd5:: with SMTP id r82-v6mr19421107ljr.63.1539860842625; Thu, 18 Oct 2018 04:07:22 -0700 (PDT) From: Artem Pisarenko To: qemu-devel@nongnu.org Date: Thu, 18 Oct 2018 17:04:30 +0600 Message-Id: X-Mailer: git-send-email 2.7.4 In-Reply-To: References: In-Reply-To: References: X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2a00:1450:4864:20::242 Subject: [Qemu-devel] [PATCH v3 3/4] Restores record/replay behavior related to special virtual clock processing for timers used in external subsystems. 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: Jan Kiszka , Gerd Hoffmann , Pavel Dovgalyuk , Samuel Thibault , Paolo Bonzini , Artem Pisarenko Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: fail (Header signature does not verify) X-ZohoMail: RDMRC_1 RDKM_2 RSF_0 Z_629925259 SPT_0 Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Adds EXTERNAL attribute definition to qemu timers subsystem and assigns it = to virtual clock timers, used in slirp (ICMP IPv6) and ui (key queue). Virtual clock processing in rr mode reimplemented using this attribute. Fixes: 87f4fe7653baf55b5c2f2753fe6003f473c07342 Fixes: 775a412bf83f6bc0c5c02091ee06cf649b34c593 Fixes: 9888091404a702d7ec79d51b088d994b9fc121bd Signed-off-by: Artem Pisarenko --- include/qemu/timer.h | 11 ++++++++++- slirp/ip6_icmp.c | 4 +++- ui/input.c | 5 +++-- util/qemu-timer.c | 50 +++++++++++++++++++++++++++++++++++++++++++-----= -- 4 files changed, 59 insertions(+), 11 deletions(-) diff --git a/include/qemu/timer.h b/include/qemu/timer.h index d45aded..dc0fd14 100644 --- a/include/qemu/timer.h +++ b/include/qemu/timer.h @@ -2,6 +2,7 @@ #define QEMU_TIMER_H =20 #include "qemu-common.h" +#include "qemu/bitops.h" #include "qemu/notify.h" #include "qemu/host-utils.h" =20 @@ -59,9 +60,17 @@ typedef enum { * Each attribute corresponds to one bit. Attributes modify the processing * of timers when they fire. * - * No attributes defined currently. + * The following attributes are available: + * + * QEMU_TIMER_ATTR_EXTERNAL: drives external subsystem + * + * Timers with this attribute do not recorded in rr mode, therefore it cou= ld be + * used for the subsystems that operate outside the guest core. Applicable= only + * with virtual clock type. */ =20 +#define QEMU_TIMER_ATTR_EXTERNAL BIT(0) + typedef struct QEMUTimerList QEMUTimerList; =20 struct QEMUTimerListGroup { diff --git a/slirp/ip6_icmp.c b/slirp/ip6_icmp.c index ee333d0..cd1e0b9 100644 --- a/slirp/ip6_icmp.c +++ b/slirp/ip6_icmp.c @@ -27,7 +27,9 @@ void icmp6_init(Slirp *slirp) return; } =20 - slirp->ra_timer =3D timer_new_ms(QEMU_CLOCK_VIRTUAL, ra_timer_handler,= slirp); + slirp->ra_timer =3D timer_new_full(NULL, QEMU_CLOCK_VIRTUAL, + SCALE_MS, QEMU_TIMER_ATTR_EXTERNAL, + ra_timer_handler, slirp); timer_mod(slirp->ra_timer, qemu_clock_get_ms(QEMU_CLOCK_VIRTUAL) + NDP_Interval); } diff --git a/ui/input.c b/ui/input.c index 51b1019..7c9a410 100644 --- a/ui/input.c +++ b/ui/input.c @@ -448,8 +448,9 @@ void qemu_input_event_send_key_delay(uint32_t delay_ms) } =20 if (!kbd_timer) { - kbd_timer =3D timer_new_ms(QEMU_CLOCK_VIRTUAL, qemu_input_queue_pr= ocess, - &kbd_queue); + kbd_timer =3D timer_new_full(NULL, QEMU_CLOCK_VIRTUAL, + SCALE_MS, QEMU_TIMER_ATTR_EXTERNAL, + qemu_input_queue_process, &kbd_queue); } if (queue_count < queue_limit) { qemu_input_queue_delay(&kbd_queue, kbd_timer, diff --git a/util/qemu-timer.c b/util/qemu-timer.c index 04527a3..e2746cf 100644 --- a/util/qemu-timer.c +++ b/util/qemu-timer.c @@ -489,6 +489,7 @@ bool timerlist_run_timers(QEMUTimerList *timer_list) bool progress =3D false; QEMUTimerCB *cb; void *opaque; + bool need_replay_checkpoint =3D false; =20 if (!atomic_read(&timer_list->active_timers)) { return false; @@ -504,8 +505,15 @@ bool timerlist_run_timers(QEMUTimerList *timer_list) break; default: case QEMU_CLOCK_VIRTUAL: - if (!replay_checkpoint(CHECKPOINT_CLOCK_VIRTUAL)) { - goto out; + if (replay_mode !=3D REPLAY_MODE_NONE) { + /* Checkpoint for virtual clock is redundant in cases where + * it's being triggered with only non-EXTERNAL timers, because + * these timers don't change guest state directly. + * Since it has conditional dependence on specific timers, it = is + * subject to race conditions and requires special handling. + * See below. + */ + need_replay_checkpoint =3D true; } break; case QEMU_CLOCK_HOST: @@ -520,13 +528,38 @@ bool timerlist_run_timers(QEMUTimerList *timer_list) break; } =20 + /* + * Extract expired timers from active timers list and and process them. + * + * In rr mode we need "filtered" checkpointing for virtual clock. + * Checkpoint must be replayed before any non-EXTERNAL timer has been + * processed and only one time (virtual clock value stays same). But t= hese + * timers may appear in the timers list while it being processed, so t= his + * must be checked until we finally decide that "no timers left - we a= re + * done". + */ current_time =3D qemu_clock_get_ns(timer_list->clock->type); - for(;;) { - qemu_mutex_lock(&timer_list->active_timers_lock); - ts =3D timer_list->active_timers; + qemu_mutex_lock(&timer_list->active_timers_lock); + while ((ts =3D timer_list->active_timers)) { if (!timer_expired_ns(ts, current_time)) { + /* No expired timers left. + * (If rr checkpoint was needed, it either already handled, + * or may be skipped.) */ + break; + } + if (need_replay_checkpoint + && !(ts->attributes & QEMU_TIMER_ATTR_EXTERNAL)) { + /* once we got here, checkpoint clock only once */ + need_replay_checkpoint =3D false; qemu_mutex_unlock(&timer_list->active_timers_lock); - break; + if (!replay_checkpoint(CHECKPOINT_CLOCK_VIRTUAL)) { + goto out; + } + qemu_mutex_lock(&timer_list->active_timers_lock); + /* it's better to start over again, + * just in case if timer list was modified + */ + continue; } =20 /* remove timer from the list before calling the callback */ @@ -535,12 +568,15 @@ bool timerlist_run_timers(QEMUTimerList *timer_list) ts->expire_time =3D -1; cb =3D ts->cb; opaque =3D ts->opaque; - qemu_mutex_unlock(&timer_list->active_timers_lock); =20 /* run the callback (the timer list can be modified) */ + qemu_mutex_unlock(&timer_list->active_timers_lock); cb(opaque); + qemu_mutex_lock(&timer_list->active_timers_lock); + progress =3D true; } + qemu_mutex_unlock(&timer_list->active_timers_lock); =20 out: qemu_event_set(&timer_list->timers_done_ev); --=20 2.7.4