From nobody Thu Nov 6 03:29:17 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 153967936263479.91700112900628; Tue, 16 Oct 2018 01:42:42 -0700 (PDT) Received: from localhost ([::1]:56559 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gCKvv-0003w1-4o for importer@patchew.org; Tue, 16 Oct 2018 04:42:31 -0400 Received: from eggs.gnu.org ([208.118.235.92]:46427) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gCKv0-0003dB-Tf for qemu-devel@nongnu.org; Tue, 16 Oct 2018 04:41:37 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gCKuu-0000g9-SK for qemu-devel@nongnu.org; Tue, 16 Oct 2018 04:41:32 -0400 Received: from mail-lj1-x244.google.com ([2a00:1450:4864:20::244]:37486) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1gCKug-0000Rq-Tl for qemu-devel@nongnu.org; Tue, 16 Oct 2018 04:41:21 -0400 Received: by mail-lj1-x244.google.com with SMTP id 63-v6so20079720ljs.4 for ; Tue, 16 Oct 2018 01:41:11 -0700 (PDT) Received: from localhost.localdomain ([77.221.221.49]) by smtp.gmail.com with ESMTPSA id g68-v6sm3106088lje.44.2018.10.16.01.41.07 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Tue, 16 Oct 2018 01:41:08 -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; bh=R+fvbWJYFtdiz0IhIfNMlJ/QmFcRmWJbESKBnkMbHMY=; b=V9MjRu9NshWeRbB0GCgHf8+ByvU8XKunyFIerQehF0CnJrtxvrG9AwEm7jHoVPoN6U GtJV515EfiZ2ckuS4DVxdvcYe/stig4Wlcqb8nriISC9/g1vC2B6KzzrwHdC4x2lk70n dW4SY0Qo9jerBejKMoQmDjyfCA6IKPj2aIK6+TyG7QkZ9Xz0zHt50tyiUCaZX+8dvMj4 EYTsfR5qoEHsoj/4k3UuyNkQ13dYV9jLWD4PfsYZtL1fj+hnytG8XHYhxdVt5QNoYwPZ 9gNCTLnQm4Vthi/tNIygSLw1wLD7Ob1T5JJiXKLI2yHlh9h5gZ7yZZthm21bXu6B4HGH xv+Q== 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; bh=R+fvbWJYFtdiz0IhIfNMlJ/QmFcRmWJbESKBnkMbHMY=; b=Z6zlSbBKBO2LKXY+QGJZ3yO186DhbRy51vxoZW4IO4Ky3a4mWU+K5EVaYuGwW55Zzk Sp0aUqb51hJUgzIyLflKP0LTRMnHNsNsLBXuKkF4btKjLznReiMnBy8vouDG3dYuIudJ LVJ5ieLdySaysnAD9pOatdPs5Frc3s+uYQoJETZpgNRWcPsyLCb34OY70RgeUgu1nEvJ TOaroZJZ59c/ZVkZF+n0ORQZQeDr0LAavuVo6bJSygkLjqnWKklPK6jiQGGwakQmuvAC 1pOCoRK1OdyyWWPe/LWGRg47kGueOJvRLe/ONMAKsqWW0ih9oTaw3Xl7ZfI8bDHUtCuk E7cQ== X-Gm-Message-State: ABuFfogIWfVsIj5W/G3TlXsMoeE0JwU51i6LuT9dvWbj2iUUtK3NH49v 2agQTzxQ/RdILsEsxaXyN+xmqGyvu9k= X-Google-Smtp-Source: ACcGV60+d3J7DUcIQg2rDRPwxAXIcKyDiOy0L+IGaXfHGYD4Gj0vw+Io4lxxnAdeluypE1tUZIcLHA== X-Received: by 2002:a2e:8ec6:: with SMTP id e6-v6mr11512231ljl.166.1539679269575; Tue, 16 Oct 2018 01:41:09 -0700 (PDT) From: Artem Pisarenko To: qemu-devel@nongnu.org Date: Tue, 16 Oct 2018 14:40:16 +0600 Message-Id: <6068f4f0d641b7fe72816dad717b2c2b99e7d952.1539677935.git.artem.k.pisarenko@gmail.com> X-Mailer: git-send-email 2.7.4 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::244 Subject: [Qemu-devel] [PATCH v2] 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 --- Notes: v2: fixes race condition and reimplements synchronization between check= pointing and timers processing in qemu-timer.c =20 qemu-timer.c: It has one more difference from original behavior, which I'm not sure a= bout. If there are no timers will be processed for virtual clock (i.e. timer = list is empty), then checkpointing will be skipped, although it looks fine = for me. Is such scenario ever possible? include/qemu/timer.h | 10 ++++++++-- slirp/ip6_icmp.c | 4 +++- ui/input.c | 5 +++-- util/qemu-timer.c | 50 +++++++++++++++++++++++++++++++++++++++++++-----= -- 4 files changed, 57 insertions(+), 12 deletions(-) diff --git a/include/qemu/timer.h b/include/qemu/timer.h index 031e3a1..53bfba5 100644 --- a/include/qemu/timer.h +++ b/include/qemu/timer.h @@ -65,11 +65,17 @@ typedef enum { * instead each attribute in bit set accessed with QEMU_TIMER_ATTR(id) mac= ro, * where 'id' is a unique part of attribute identifier. * - * 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 typedef enum { - /* none */ + QEMU_TIMER_ATTRBIT_EXTERNAL, } QEMUTimerAttrBit; =20 #define QEMU_TIMER_ATTR(id) (1 << QEMU_TIMER_ATTRBIT_ ## id) diff --git a/slirp/ip6_icmp.c b/slirp/ip6_icmp.c index ee333d0..7c08433 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_a(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..6279187 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_a(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 29d8e39..7731dd9 100644 --- a/util/qemu-timer.c +++ b/util/qemu-timer.c @@ -490,6 +490,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; @@ -505,8 +506,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: @@ -521,13 +529,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 */ @@ -536,12 +569,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