From nobody Thu Nov 6 08:27:00 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 1539765024874592.1265794260382; Wed, 17 Oct 2018 01:30:24 -0700 (PDT) Received: from localhost ([::1]:34508 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gChDj-0002Kx-NP for importer@patchew.org; Wed, 17 Oct 2018 04:30:23 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:50660) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gCh9I-00074M-FI for qemu-devel@nongnu.org; Wed, 17 Oct 2018 04:25:49 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gCh9H-0008If-EI for qemu-devel@nongnu.org; Wed, 17 Oct 2018 04:25:48 -0400 Received: from mail-lj1-x241.google.com ([2a00:1450:4864:20::241]:36383) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1gCh9G-0008Hs-Vo for qemu-devel@nongnu.org; Wed, 17 Oct 2018 04:25:47 -0400 Received: by mail-lj1-x241.google.com with SMTP id p89-v6so23508342ljb.3 for ; Wed, 17 Oct 2018 01:25:46 -0700 (PDT) Received: from localhost.localdomain ([77.221.221.49]) by smtp.gmail.com with ESMTPSA id h77-v6sm3897735ljf.59.2018.10.17.01.25.43 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Wed, 17 Oct 2018 01:25:44 -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=zyg44Uif53G31ksnw3X/NJ0wz9CjUxs2wFTXEedoS04=; b=fMCZMSaIehZExd7FAQKu6wqW5/6BuuvXgQTRGuVMFXeJ4WOWCLfDo4tQynyB9vKwbV SJAm9158F3fxtmgRwm1ZJiGlW0XpEQ0rMuICmT4PWv2eUkhf5MLRLHlkNEUJgwKlmP5z u1Re5PALZu99aktkNWQenETvmEGreItOXWJdxafqIc36iWyVoD1uLEnpUsE5WXDrii0X LAXwZqE8V8C/+PEb6XcCHtVBDksSbB1mWtI+eHAatjgsz4lCgE81MPv94l+P/iKSh3gR vnyiHc5DK/43RbZV3vJqV7iyUIn36+463kbc60AI22XbrF17LFjf9DQ9unxbMgnWKRB0 +Xlw== 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=zyg44Uif53G31ksnw3X/NJ0wz9CjUxs2wFTXEedoS04=; b=AXjf8wUpbN+BpT79kUKuaOwfH0GfyAFLGwGB9I4q/2sT6/2E14i3jdGmsgm1D2/8kX B8pMxWN1Bepysk3LDgl2pRlw95RoF1GfTPuoZwSZfo+q6gna2vRxQvzbi5gnhP9StlDH txoliK3bHFGIf+dVZjFlcd4BYnoedeX5neLzqbGT/QXpMAVS9k2WEhLTTS7udUhtEPOv vviexN5W7PYyzwzy8BgcRbgXsZ9BUytWCImEK05ZQ3Y8VkjYwH2/skoWFNMs3aKiwpSY qYlwZNDh9TPvap0/G4cpALLD/rdw3tkswcfo29Mjw5iOCHenPFmrprtZ7qlufCId93tN KA6g== X-Gm-Message-State: ABuFfoh62lgwbroW7c/y/q9eK4YEdh+nHyOClQcG16swqZDIFoBrT3x9 26H1Hrg6hssCi5N9iSqvkiIPoptZaCY= X-Google-Smtp-Source: ACcGV63eMul7xIrcnNRj/mt0f0Ql/Q5yDh+Qjcmi4pa2hTh/IoVWXZwWhL7yiyStT4gr5AQE6kE/zw== X-Received: by 2002:a2e:9e88:: with SMTP id f8-v6mr15979065ljk.142.1539764745155; Wed, 17 Oct 2018 01:25:45 -0700 (PDT) From: Artem Pisarenko To: qemu-devel@nongnu.org Date: Wed, 17 Oct 2018 14:24:20 +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::241 Subject: [Qemu-devel] [PATCH v2 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 --- Notes: v2: fixes race condition and reimplements synchronization between check= pointing and timers processing in qemu-timer.c include/qemu/timer.h | 12 +++++++++--- slirp/ip6_icmp.c | 4 +++- ui/input.c | 5 +++-- util/qemu-timer.c | 50 +++++++++++++++++++++++++++++++++++++++++++-----= -- 4 files changed, 58 insertions(+), 13 deletions(-) diff --git a/include/qemu/timer.h b/include/qemu/timer.h index e225ad4..8e3f236 100644 --- a/include/qemu/timer.h +++ b/include/qemu/timer.h @@ -65,14 +65,20 @@ typedef enum { * instead each attribute in bit set accessed with QEMU_TIMER_ATTR_ ma= cro, * where 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 { - QEMU_TIMER_ATTRBIT__NONE + QEMU_TIMER_ATTRBIT_EXTERNAL, } QEMUTimerAttrBit; =20 -#define QEMU_TIMER_ATTR__NONE (1 << QEMU_TIMER_ATTRBIT__NONE) +#define QEMU_TIMER_ATTR_EXTERNAL (1 << QEMU_TIMER_ATTRBIT_EXTERNAL) =20 typedef struct QEMUTimerList QEMUTimerList; =20 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 2046b68..e9a0f00 100644 --- a/util/qemu-timer.c +++ b/util/qemu-timer.c @@ -494,6 +494,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; @@ -509,8 +510,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: @@ -525,13 +533,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 */ @@ -540,12 +573,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