From patchwork Wed Mar 13 10:55:00 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Pierrick Bouvier X-Patchwork-Id: 13591225 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 4C74DC54791 for ; Wed, 13 Mar 2024 10:55:42 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1rkMGj-0005CC-Js; Wed, 13 Mar 2024 06:55:33 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1rkMGb-00059F-VU for qemu-devel@nongnu.org; Wed, 13 Mar 2024 06:55:26 -0400 Received: from mail-lf1-x12c.google.com ([2a00:1450:4864:20::12c]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1rkMGa-000796-20 for qemu-devel@nongnu.org; Wed, 13 Mar 2024 06:55:25 -0400 Received: by mail-lf1-x12c.google.com with SMTP id 2adb3069b0e04-513c847c24dso610598e87.1 for ; Wed, 13 Mar 2024 03:55:22 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1710327321; x=1710932121; darn=nongnu.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=5oT1XKXBFQsUGk4QG2qYw4iHv7mWal+0jdHBO1XvE/8=; b=VpaSVLkaOmbmm7LsPaZYn6MVTvDU1Mv73nm/9clRz68mIAeuy8Jm/Jjjw7Wydilsl+ KtrOeQN1uu6POuT6fOzXxE0LlqsatV9kZkMhk84U/Dq3oy7dHqAy6NCcmw2Ynxynsa/S MQZYTCcG8YVzIcXweCm10bqmvcCYRCPfdH06yA25HQzudCpc6c7KmhnCHb4hfeFmnhdJ vMHfZyJny2ZhVM+9aQCkck26uxsx839ekEKjasHRCdNX6IcyQOFSD2abqPMrW9KV3Zh3 7bUuOlh+9U46KsBdc/xMTFD+cfqur6qRLxb9np4XI6fy5rg0HBcMEuaIqYLRNunR/keb kJ6w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1710327321; x=1710932121; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=5oT1XKXBFQsUGk4QG2qYw4iHv7mWal+0jdHBO1XvE/8=; b=Sf07XxGJwMadPgFfTCdRoba5NI4fS0tQBhdc7xtdbwbD9HmzJLoMXFiuZXbYgHXD+M +5cB4mLN1Cxpbczt8aKF7M/T1O55t0kwUTbbPUdYokODXe+0er1TY9DQyoV5onfMUI/O xPNnXjqHq8+P6EULB0G187+g5mCbLHNul03EkEBmtjLUDqKAKieD7DDq114nSVAZfhfk HtiwLgyT4cDIdA4aSncwn58Ct3dGOy9BVBC8kWG2ARs9+a5izBVXK/jIGh7W6qQbSFCw mvM0JsAT2X0VZQhiIEnci887yJaQmnn4TE/ebp+Ipg8G2MxA8wPLPOobzPNW5rmJbkUx lvIA== X-Gm-Message-State: AOJu0Yxp86il+o8JrJP11z1He3kFEGX2CvpBe9AYSfztKEVTVotZC/ae n6FXPAJCZcww2DiHZGPbjfnVABbUyUbQ8ZrWm0gOOXjpWgQoa4KLfo1gOrERaADWgDSY1tkBF7p n4Gs= X-Google-Smtp-Source: AGHT+IGW8eag6E9K9MiCk7cY3Xd6Y4/xgoeq/RbYeXS/vtpaOMAGxd9pJ+BXuW9w+qR9GQQQuEK3Fg== X-Received: by 2002:ac2:4c42:0:b0:513:2004:43e4 with SMTP id o2-20020ac24c42000000b00513200443e4mr4071069lfk.36.1710327321112; Wed, 13 Mar 2024 03:55:21 -0700 (PDT) Received: from linaro.. ([102.35.208.160]) by smtp.gmail.com with ESMTPSA id w17-20020adfee51000000b0033e1be7f3d8sm11390338wro.70.2024.03.13.03.55.18 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 13 Mar 2024 03:55:20 -0700 (PDT) From: Pierrick Bouvier To: qemu-devel@nongnu.org Cc: Paolo Bonzini , Alexandre Iooss , Richard Henderson , Laurent Vivier , Thomas Huth , Pierrick Bouvier , Mahmoud Mandour , =?utf-8?q?Alex_Benn=C3=A9e?= , =?utf-8?q?Philippe_M?= =?utf-8?q?athieu-Daud=C3=A9?= Subject: [RFC PATCH 1/5] sysemu: add set_virtual_time to accel ops Date: Wed, 13 Mar 2024 14:55:00 +0400 Message-Id: <20240313105504.341875-2-pierrick.bouvier@linaro.org> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20240313105504.341875-1-pierrick.bouvier@linaro.org> References: <20240313105504.341875-1-pierrick.bouvier@linaro.org> MIME-Version: 1.0 Received-SPF: pass client-ip=2a00:1450:4864:20::12c; envelope-from=pierrick.bouvier@linaro.org; helo=mail-lf1-x12c.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001, T_SCC_BODY_TEXT_LINE=-0.01 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org From: Alex Bennée We are about to remove direct calls to individual accelerators for this information and will need a central point for plugins to hook into time changes. Signed-off-by: Alex Bennée Reviewed-by: Philippe Mathieu-Daudé --- include/sysemu/accel-ops.h | 18 +++++++++++++++++- include/sysemu/cpu-timers.h | 3 ++- ...et-virtual-clock.c => cpus-virtual-clock.c} | 5 +++++ system/cpus.c | 11 +++++++++++ stubs/meson.build | 2 +- 5 files changed, 36 insertions(+), 3 deletions(-) rename stubs/{cpus-get-virtual-clock.c => cpus-virtual-clock.c} (68%) diff --git a/include/sysemu/accel-ops.h b/include/sysemu/accel-ops.h index ef91fc28bbd..a0886722305 100644 --- a/include/sysemu/accel-ops.h +++ b/include/sysemu/accel-ops.h @@ -20,7 +20,12 @@ typedef struct AccelOpsClass AccelOpsClass; DECLARE_CLASS_CHECKERS(AccelOpsClass, ACCEL_OPS, TYPE_ACCEL_OPS) -/* cpus.c operations interface */ +/** + * struct AccelOpsClass - accelerator interfaces + * + * This structure is used to abstract accelerator differences from the + * core CPU code. Not all have to be implemented. + */ struct AccelOpsClass { /*< private >*/ ObjectClass parent_class; @@ -44,7 +49,18 @@ struct AccelOpsClass { void (*handle_interrupt)(CPUState *cpu, int mask); + /** + * @get_virtual_clock: fetch virtual clock + * @set_virtual_clock: set virtual clock + * + * These allow the timer subsystem to defer to the accelerator to + * fetch time. The set function is needed if the accelerator wants + * to track the changes to time as the timer is warped through + * various timer events. + */ int64_t (*get_virtual_clock)(void); + void (*set_virtual_clock)(int64_t time); + int64_t (*get_elapsed_ticks)(void); /* gdbstub hooks */ diff --git a/include/sysemu/cpu-timers.h b/include/sysemu/cpu-timers.h index d86738a378d..7bfa960fbd6 100644 --- a/include/sysemu/cpu-timers.h +++ b/include/sysemu/cpu-timers.h @@ -96,8 +96,9 @@ int64_t cpu_get_clock(void); void qemu_timer_notify_cb(void *opaque, QEMUClockType type); -/* get the VIRTUAL clock and VM elapsed ticks via the cpus accel interface */ +/* get/set VIRTUAL clock and VM elapsed ticks via the cpus accel interface */ int64_t cpus_get_virtual_clock(void); +void cpus_set_virtual_clock(int64_t new_time); int64_t cpus_get_elapsed_ticks(void); #endif /* SYSEMU_CPU_TIMERS_H */ diff --git a/stubs/cpus-get-virtual-clock.c b/stubs/cpus-virtual-clock.c similarity index 68% rename from stubs/cpus-get-virtual-clock.c rename to stubs/cpus-virtual-clock.c index fd447d53f3c..af7c1a1d403 100644 --- a/stubs/cpus-get-virtual-clock.c +++ b/stubs/cpus-virtual-clock.c @@ -6,3 +6,8 @@ int64_t cpus_get_virtual_clock(void) { return cpu_get_clock(); } + +void cpus_set_virtual_clock(int64_t new_time) +{ + /* do nothing */ +} diff --git a/system/cpus.c b/system/cpus.c index 68d161d96b7..03ba026667c 100644 --- a/system/cpus.c +++ b/system/cpus.c @@ -229,6 +229,17 @@ int64_t cpus_get_virtual_clock(void) return cpu_get_clock(); } +/* + * Signal the new virtual time to the accelerator. This is only needed + * by accelerators that need to track the changes as we warp time. + */ +void cpus_set_virtual_clock(int64_t new_time) +{ + if (cpus_accel && cpus_accel->set_virtual_clock) { + cpus_accel->set_virtual_clock(new_time); + } +} + /* * return the time elapsed in VM between vm_start and vm_stop. Unless * icount is active, cpus_get_elapsed_ticks() uses units of the host CPU cycle diff --git a/stubs/meson.build b/stubs/meson.build index 0bf25e6ca53..1a7957352b1 100644 --- a/stubs/meson.build +++ b/stubs/meson.build @@ -5,7 +5,7 @@ stub_ss.add(files('blockdev-close-all-bdrv-states.c')) stub_ss.add(files('change-state-handler.c')) stub_ss.add(files('cmos.c')) stub_ss.add(files('cpu-get-clock.c')) -stub_ss.add(files('cpus-get-virtual-clock.c')) +stub_ss.add(files('cpus-virtual-clock.c')) stub_ss.add(files('qemu-timer-notify-cb.c')) stub_ss.add(files('icount.c')) stub_ss.add(files('dump.c')) From patchwork Wed Mar 13 10:55:01 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Pierrick Bouvier X-Patchwork-Id: 13591227 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 7B8C0C54791 for ; Wed, 13 Mar 2024 10:56:18 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1rkMH1-0005Nc-A4; Wed, 13 Mar 2024 06:55:51 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1rkMGs-0005Fy-Id for qemu-devel@nongnu.org; Wed, 13 Mar 2024 06:55:46 -0400 Received: from mail-wm1-x32a.google.com ([2a00:1450:4864:20::32a]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1rkMGe-00079b-5L for qemu-devel@nongnu.org; Wed, 13 Mar 2024 06:55:40 -0400 Received: by mail-wm1-x32a.google.com with SMTP id 5b1f17b1804b1-413e7b96403so3864095e9.3 for ; Wed, 13 Mar 2024 03:55:26 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1710327324; x=1710932124; darn=nongnu.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=2A4y2sEoIfQRif0BIyFTxg0vj8eN3cypCY900sTp17U=; b=HTXeTRGSsRV0o18Homys9BVeMWwuwI0EZrS+bEb85KxUCpdOOHI679UVO8YRyL/g2h O1Rz8z0h5UsWZvuN+QNNtPeW67lARBSEE4/zWOK7NPj/1/tjy5ZFUJzBwZZdSfor8Pf6 dwn6WM3NkTZus9Gl0Sda9KQVa/hzutd27+vY++uAB1e909AqtKd2SonDwuHt/kTOVVxH RuovVmpvLda/356V2NIt2StY+zcU+DfiM1l8HONOo+BKZWGzdzL9VtJFE/fg0InroX+E fGGMAA3BPW6LMKnA9lU2jBuzTNndh91RUvE7QVtCmehX5JAN/dAPFu2rpt9S298/tDtR C+rw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1710327324; x=1710932124; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=2A4y2sEoIfQRif0BIyFTxg0vj8eN3cypCY900sTp17U=; b=RRt2fWTxx+8We8ip9rf2o9q2v1GI8FKJBWHZ86pvKdjtrCjOOv5t773Z+Iw/1QPmkJ boHw9m1Oa4+paS6K42KijG4BK+k9/7EvPAuDR2SIud3eIrMztJdkRq6zZOIlC+YWms8a Bfa++5s/kQv4jTD1hGfMYuItyOAr0cZE1PPJofaUbsT8dVWPNh2tMaC4stkRqN9/uLZ7 cbtUPgdXYOKZxJjEYpgGigBv0kTpv+N4f8aABo1tuTGPP9WBDCD3DhHXQLuIat+B5b+P YaFLzICyEh6DGihF73g/6oFd+UKutga+ASFv8Dbw9hTUkC10BD69BWWbD1Fek/GiP2Zw WvYw== X-Gm-Message-State: AOJu0Yz0kDG3YK+uCxRKTLeNDld/WG37rYl15l0j/I8AIUiLjCPcIKqo AJU/wO4xvEzkLs8SbVbiQFiOTPF8rUur1XktvshD8UzZ1xrh3a8PzYVosJ2vVYqBXGG7hg+BCrx n22M= X-Google-Smtp-Source: AGHT+IHWbcikkOy6DyWYKzBQVWyxJ2s+IxR2kYvfFzttjpuxWMJgBjxWJDhLrWcvjdsMGYQB/+i4Eg== X-Received: by 2002:a05:600c:1e29:b0:413:32ff:2000 with SMTP id ay41-20020a05600c1e2900b0041332ff2000mr3764796wmb.36.1710327324258; Wed, 13 Mar 2024 03:55:24 -0700 (PDT) Received: from linaro.. ([102.35.208.160]) by smtp.gmail.com with ESMTPSA id w17-20020adfee51000000b0033e1be7f3d8sm11390338wro.70.2024.03.13.03.55.21 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 13 Mar 2024 03:55:24 -0700 (PDT) From: Pierrick Bouvier To: qemu-devel@nongnu.org Cc: Paolo Bonzini , Alexandre Iooss , Richard Henderson , Laurent Vivier , Thomas Huth , Pierrick Bouvier , Mahmoud Mandour , =?utf-8?q?Alex_Benn=C3=A9e?= Subject: [RFC PATCH 2/5] qtest: use cpu interface in qtest_clock_warp Date: Wed, 13 Mar 2024 14:55:01 +0400 Message-Id: <20240313105504.341875-3-pierrick.bouvier@linaro.org> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20240313105504.341875-1-pierrick.bouvier@linaro.org> References: <20240313105504.341875-1-pierrick.bouvier@linaro.org> MIME-Version: 1.0 Received-SPF: pass client-ip=2a00:1450:4864:20::32a; envelope-from=pierrick.bouvier@linaro.org; helo=mail-wm1-x32a.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001, T_SCC_BODY_TEXT_LINE=-0.01 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org From: Alex Bennée This generalises the qtest_clock_warp code to use the AccelOps handlers for updating its own sense of time. This will make the next patch which moves the warp code closer to pure code motion. Signed-off-by: Alex Bennée Acked-by: Thomas Huth --- include/sysemu/qtest.h | 1 + accel/qtest/qtest.c | 1 + system/qtest.c | 6 +++--- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/include/sysemu/qtest.h b/include/sysemu/qtest.h index b5d5fd34637..45f3b7e1df5 100644 --- a/include/sysemu/qtest.h +++ b/include/sysemu/qtest.h @@ -36,6 +36,7 @@ void qtest_server_set_send_handler(void (*send)(void *, const char *), void qtest_server_inproc_recv(void *opaque, const char *buf); int64_t qtest_get_virtual_clock(void); +void qtest_set_virtual_clock(int64_t count); #endif #endif diff --git a/accel/qtest/qtest.c b/accel/qtest/qtest.c index f6056ac8361..53182e6c2ae 100644 --- a/accel/qtest/qtest.c +++ b/accel/qtest/qtest.c @@ -52,6 +52,7 @@ static void qtest_accel_ops_class_init(ObjectClass *oc, void *data) ops->create_vcpu_thread = dummy_start_vcpu_thread; ops->get_virtual_clock = qtest_get_virtual_clock; + ops->set_virtual_clock = qtest_set_virtual_clock; }; static const TypeInfo qtest_accel_ops_type = { diff --git a/system/qtest.c b/system/qtest.c index 6da58b3874e..ee8b139e982 100644 --- a/system/qtest.c +++ b/system/qtest.c @@ -332,14 +332,14 @@ int64_t qtest_get_virtual_clock(void) return qatomic_read_i64(&qtest_clock_counter); } -static void qtest_set_virtual_clock(int64_t count) +void qtest_set_virtual_clock(int64_t count) { qatomic_set_i64(&qtest_clock_counter, count); } static void qtest_clock_warp(int64_t dest) { - int64_t clock = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL); + int64_t clock = cpus_get_virtual_clock(); AioContext *aio_context; assert(qtest_enabled()); aio_context = qemu_get_aio_context(); @@ -348,7 +348,7 @@ static void qtest_clock_warp(int64_t dest) QEMU_TIMER_ATTR_ALL); int64_t warp = qemu_soonest_timeout(dest - clock, deadline); - qtest_set_virtual_clock(qtest_get_virtual_clock() + warp); + cpus_set_virtual_clock(cpus_get_virtual_clock() + warp); qemu_clock_run_timers(QEMU_CLOCK_VIRTUAL); timerlist_run_timers(aio_context->tlg.tl[QEMU_CLOCK_VIRTUAL]); From patchwork Wed Mar 13 10:55:02 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Pierrick Bouvier X-Patchwork-Id: 13591228 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 5DF95C54E58 for ; Wed, 13 Mar 2024 10:56:29 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1rkMH1-0005Mq-4P; Wed, 13 Mar 2024 06:55:51 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1rkMGs-0005Fr-GA for qemu-devel@nongnu.org; Wed, 13 Mar 2024 06:55:44 -0400 Received: from mail-wr1-x436.google.com ([2a00:1450:4864:20::436]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1rkMGf-0007BD-Ja for qemu-devel@nongnu.org; Wed, 13 Mar 2024 06:55:32 -0400 Received: by mail-wr1-x436.google.com with SMTP id ffacd0b85a97d-33eaafc4419so494717f8f.0 for ; Wed, 13 Mar 2024 03:55:29 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1710327327; x=1710932127; darn=nongnu.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=o6QDwYzo62XZFD/GhIgkJ+Hn9SLx+3ew7YSnia2dKPw=; b=KbZcYWxHGSTdiKxGQwf0+6YciI+lXCywEJNgh8RUOjVXxU4loeOeb3Esp4e2snRgd9 H2Z0REjfzgaKDNVgPjMDDDnLDjhKPeI41Eh/zxWsaKvJLwQRcvaiJVsKOvbD/g/Pgx2+ bq8d7VtP3LsQsjbiIIgEcfwGfaRQJOyW0W/z1oYzlUWGyrDCKuaoGON1XOSz3RzYsADo s82UoJbgG0jjsbxyF86ju3V1PcL36Ie/aEoDx3qq+e585lkeH6ErPbzhD6r//pJ0Hq86 aHIb1f+Mtxb+0q0vhduU79/+XQR7oeXP9JQAc0Dsysq5c5m9rEBKsej3U4NJZnZLnCJM LJmA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1710327327; x=1710932127; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=o6QDwYzo62XZFD/GhIgkJ+Hn9SLx+3ew7YSnia2dKPw=; b=Drw9uJdb4Bw3jnbTZmsp7bNlR2N/5wRNS5CvL/1x4WE9hg1+ADtf9fp7xHfuI9bTcK qjQp5EJ9c86S3mqGXFbuQ6v59qcCIENmlXPF2pzSgoZEBgBHK5MCcu8ihZtsOCBEtihP 5UtDUQQxqFk4R7H8wA1HoGDaTavI16nQJ7hob5z2CHhf4k5rdBYk8kDpx5TCcxjHmuNG r7xC5M7noVNzwstFn2ETCaK/quNxt72O0BBuI3OmquQB/11cPDJdlowLymYJj0WcOWh9 IUNvCTfyWGBKikztBEVF84Zov+6nsI5XpZ9HHH0c/f3MMZJI6XA+o026RpCqoIbyYv4x Hp6Q== X-Gm-Message-State: AOJu0YzBc96NTei2QXGMoUBnhcZnbxPQlwR/c2gyvrjKrgqaaxlB6PJN haP5/fz85+GSv8c2caWecdOhCgG5YJsSfSwl7fCC9t2hwqMfE4vFUrBCHUFCM949+OPsIgQbWpk k1lw= X-Google-Smtp-Source: AGHT+IH2f6l+N9h9kzGaK/HSFs//sPvc8rd9tHX95QULWLEgH3PwyZ33UfRyMjLc2D+Y4zWt71TPmA== X-Received: by 2002:a5d:5956:0:b0:33e:621e:35b2 with SMTP id e22-20020a5d5956000000b0033e621e35b2mr1808362wri.6.1710327327323; Wed, 13 Mar 2024 03:55:27 -0700 (PDT) Received: from linaro.. ([102.35.208.160]) by smtp.gmail.com with ESMTPSA id w17-20020adfee51000000b0033e1be7f3d8sm11390338wro.70.2024.03.13.03.55.24 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 13 Mar 2024 03:55:27 -0700 (PDT) From: Pierrick Bouvier To: qemu-devel@nongnu.org Cc: Paolo Bonzini , Alexandre Iooss , Richard Henderson , Laurent Vivier , Thomas Huth , Pierrick Bouvier , Mahmoud Mandour , =?utf-8?q?Alex_Benn=C3=A9e?= Subject: [RFC PATCH 3/5] sysemu: generalise qtest_warp_clock as qemu_clock_advance_virtual_time Date: Wed, 13 Mar 2024 14:55:02 +0400 Message-Id: <20240313105504.341875-4-pierrick.bouvier@linaro.org> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20240313105504.341875-1-pierrick.bouvier@linaro.org> References: <20240313105504.341875-1-pierrick.bouvier@linaro.org> MIME-Version: 1.0 Received-SPF: pass client-ip=2a00:1450:4864:20::436; envelope-from=pierrick.bouvier@linaro.org; helo=mail-wr1-x436.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001, T_SCC_BODY_TEXT_LINE=-0.01 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org From: Alex Bennée Move the key functionality of moving time forward into the clock sub-system itself. This will allow us to plumb in time control into plugins. Signed-off-by: Alex Bennée --- include/qemu/timer.h | 15 +++++++++++++++ system/qtest.c | 25 +++---------------------- util/qemu-timer.c | 26 ++++++++++++++++++++++++++ 3 files changed, 44 insertions(+), 22 deletions(-) diff --git a/include/qemu/timer.h b/include/qemu/timer.h index 9a366e551fb..910587d8293 100644 --- a/include/qemu/timer.h +++ b/include/qemu/timer.h @@ -245,6 +245,21 @@ bool qemu_clock_run_timers(QEMUClockType type); */ bool qemu_clock_run_all_timers(void); +/** + * qemu_clock_advance_virtual_time(): advance the virtual time tick + * @target: target time in nanoseconds + * + * This function is used where the control of the flow of time has + * been delegated to outside the clock subsystem (be it qtest, icount + * or some other external source). You can ask the clock system to + * return @early at the first expired timer. + * + * Time can only move forward, attempts to reverse time would lead to + * an error. + * + * Returns: new virtual time. + */ +int64_t qemu_clock_advance_virtual_time(int64_t dest); /* * QEMUTimerList diff --git a/system/qtest.c b/system/qtest.c index ee8b139e982..e6f6b4e62d5 100644 --- a/system/qtest.c +++ b/system/qtest.c @@ -337,26 +337,6 @@ void qtest_set_virtual_clock(int64_t count) qatomic_set_i64(&qtest_clock_counter, count); } -static void qtest_clock_warp(int64_t dest) -{ - int64_t clock = cpus_get_virtual_clock(); - AioContext *aio_context; - assert(qtest_enabled()); - aio_context = qemu_get_aio_context(); - while (clock < dest) { - int64_t deadline = qemu_clock_deadline_ns_all(QEMU_CLOCK_VIRTUAL, - QEMU_TIMER_ATTR_ALL); - int64_t warp = qemu_soonest_timeout(dest - clock, deadline); - - cpus_set_virtual_clock(cpus_get_virtual_clock() + warp); - - qemu_clock_run_timers(QEMU_CLOCK_VIRTUAL); - timerlist_run_timers(aio_context->tlg.tl[QEMU_CLOCK_VIRTUAL]); - clock = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL); - } - qemu_clock_notify(QEMU_CLOCK_VIRTUAL); -} - static bool (*process_command_cb)(CharBackend *chr, gchar **words); void qtest_set_command_cb(bool (*pc_cb)(CharBackend *chr, gchar **words)) @@ -755,7 +735,8 @@ static void qtest_process_command(CharBackend *chr, gchar **words) ns = qemu_clock_deadline_ns_all(QEMU_CLOCK_VIRTUAL, QEMU_TIMER_ATTR_ALL); } - qtest_clock_warp(qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + ns); + qemu_clock_advance_virtual_time( + qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + ns); qtest_send_prefix(chr); qtest_sendf(chr, "OK %"PRIi64"\n", (int64_t)qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL)); @@ -781,7 +762,7 @@ static void qtest_process_command(CharBackend *chr, gchar **words) g_assert(words[1]); ret = qemu_strtoi64(words[1], NULL, 0, &ns); g_assert(ret == 0); - qtest_clock_warp(ns); + qemu_clock_advance_virtual_time(ns); qtest_send_prefix(chr); qtest_sendf(chr, "OK %"PRIi64"\n", (int64_t)qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL)); diff --git a/util/qemu-timer.c b/util/qemu-timer.c index 6a0de33dd2b..213114be68c 100644 --- a/util/qemu-timer.c +++ b/util/qemu-timer.c @@ -645,6 +645,11 @@ int64_t qemu_clock_get_ns(QEMUClockType type) } } +static void qemu_virtual_clock_set_ns(int64_t time) +{ + return cpus_set_virtual_clock(time); +} + void init_clocks(QEMUTimerListNotifyCB *notify_cb) { QEMUClockType type; @@ -675,3 +680,24 @@ bool qemu_clock_run_all_timers(void) return progress; } + +int64_t qemu_clock_advance_virtual_time(int64_t dest) +{ + int64_t clock = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL); + AioContext *aio_context; + aio_context = qemu_get_aio_context(); + while (clock < dest) { + int64_t deadline = qemu_clock_deadline_ns_all(QEMU_CLOCK_VIRTUAL, + QEMU_TIMER_ATTR_ALL); + int64_t warp = qemu_soonest_timeout(dest - clock, deadline); + + qemu_virtual_clock_set_ns(qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + warp); + + qemu_clock_run_timers(QEMU_CLOCK_VIRTUAL); + timerlist_run_timers(aio_context->tlg.tl[QEMU_CLOCK_VIRTUAL]); + clock = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL); + } + qemu_clock_notify(QEMU_CLOCK_VIRTUAL); + + return clock; +} From patchwork Wed Mar 13 10:55:03 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Pierrick Bouvier X-Patchwork-Id: 13591229 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 53786C54E58 for ; Wed, 13 Mar 2024 10:56:37 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1rkMH2-0005TP-VW; Wed, 13 Mar 2024 06:55:52 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1rkMGw-0005Js-7k for qemu-devel@nongnu.org; Wed, 13 Mar 2024 06:55:47 -0400 Received: from mail-wr1-x434.google.com ([2a00:1450:4864:20::434]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1rkMGq-0007BV-Gp for qemu-devel@nongnu.org; Wed, 13 Mar 2024 06:55:43 -0400 Received: by mail-wr1-x434.google.com with SMTP id ffacd0b85a97d-33e82c720f8so6022927f8f.3 for ; Wed, 13 Mar 2024 03:55:32 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1710327330; x=1710932130; darn=nongnu.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=soYSMJfeLTvbBwxImuPxvWm5QbEE1JXCi8SjK5Hn4SE=; b=HLQg16zCAq2Cf15Um0tValJcl818D9x0mudZluzZSUN5R2log1KINrb1R6Mc8PXLrx cJ24uSwDTvaC8F0Ufqtp4so+Do82XlH2+HVuMGNPQs7Xpg/F9RiotTo7gfrVeTfFXTmc yMgDWnim+7Le4FzfysB6XXQB2GRgpNxlNFvi8tjEp7gGSfaDen+Ih4BDy02zz5SxRspP 0O05NN6jGf4KQEnaRXBSDQTgUqQFFDzVKqxVeENXeE/P1IFR8xueveO7+Ro++NX/2Bs5 Rp+3auUwDIgkloE8NlYptoLBuC/WJw6U6M9trM8OomWn9y2ppQlqjLsaBMr1oHwQpUXp De0Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1710327330; x=1710932130; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=soYSMJfeLTvbBwxImuPxvWm5QbEE1JXCi8SjK5Hn4SE=; b=nY8O7t8cXndr65fyH4Wzdr35BtweIF5aRE77F8In3MYsZSkl/nq09l+o5Cg93x6laU F7iOOUwcGK0PAWlj7TwmVFZc6jCZa/xCHHD8DADbAsFrb4jl4POIDLLPhkf75akCXnee +ar0pb7MpfBCZDdUUq8KaqEZzOBUpbpjnjosEdq0Rce3tOIkzBlb3i1OMhRMJpJ+STdP hSyS1fTtn0i9mTshU1Ew7fCaM8YeD2DDu8cmRRd6XeSXh3Zo9n1QPXKdjlvT2F4avgtm 3neBzmjtz+0f7k+J0vNOd133BG/SWwITbNbctZ63BAouzwhlhR9VFuTPK/Pg5+nqrsy+ TcvQ== X-Gm-Message-State: AOJu0YxHUELJDSwQ3MmdWoOVOsEY4DNYwQ7CRaEPth5tqO0EgLdOoOKm 8FwgaDl5vAW+oLhC+LxMe8573MX8EeZ5S2PvT7XqJiTVljTfzMoleZIkNqjl3dnStGJ3LbOoKeI ifhs= X-Google-Smtp-Source: AGHT+IGImhN33nvs0KkNR1+8IOE+2ILEhlawoyCSz+NOzDGzhPsCOxT6oRtctXfZpExBtCCDAuP3Ug== X-Received: by 2002:a5d:4533:0:b0:33d:1f11:33c1 with SMTP id j19-20020a5d4533000000b0033d1f1133c1mr1431587wra.55.1710327330376; Wed, 13 Mar 2024 03:55:30 -0700 (PDT) Received: from linaro.. ([102.35.208.160]) by smtp.gmail.com with ESMTPSA id w17-20020adfee51000000b0033e1be7f3d8sm11390338wro.70.2024.03.13.03.55.27 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 13 Mar 2024 03:55:30 -0700 (PDT) From: Pierrick Bouvier To: qemu-devel@nongnu.org Cc: Paolo Bonzini , Alexandre Iooss , Richard Henderson , Laurent Vivier , Thomas Huth , Pierrick Bouvier , Mahmoud Mandour , =?utf-8?q?Alex_Benn=C3=A9e?= Subject: [RFC PATCH 4/5] plugins: add time control API Date: Wed, 13 Mar 2024 14:55:03 +0400 Message-Id: <20240313105504.341875-5-pierrick.bouvier@linaro.org> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20240313105504.341875-1-pierrick.bouvier@linaro.org> References: <20240313105504.341875-1-pierrick.bouvier@linaro.org> MIME-Version: 1.0 Received-SPF: pass client-ip=2a00:1450:4864:20::434; envelope-from=pierrick.bouvier@linaro.org; helo=mail-wr1-x434.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001, T_SCC_BODY_TEXT_LINE=-0.01 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org From: Alex Bennée Expose the ability to control time through the plugin API. Only one plugin can control time so it has to request control when loaded. There are probably more corner cases to catch here. Signed-off-by: Alex Bennée --- include/qemu/qemu-plugin.h | 23 +++++++++++++++++++++++ plugins/api.c | 31 +++++++++++++++++++++++++++++++ plugins/qemu-plugins.symbols | 2 ++ 3 files changed, 56 insertions(+) diff --git a/include/qemu/qemu-plugin.h b/include/qemu/qemu-plugin.h index 337de25ece7..f2a0253e594 100644 --- a/include/qemu/qemu-plugin.h +++ b/include/qemu/qemu-plugin.h @@ -662,6 +662,29 @@ void qemu_plugin_register_vcpu_mem_inline_per_vcpu( qemu_plugin_u64 entry, uint64_t imm); +/** + * qemu_plugin_request_time_control() - request the ability to control time + * + * This grants the plugin the ability to control system time. Only one + * plugin can control time so if multiple plugins request the ability + * all but the first will fail. + * + * Returns an opaque handle or NULL if fails + */ +const void *qemu_plugin_request_time_control(void); + +/** + * qemu_plugin_update_ns() - update system emulation time + * @handle: opaque handle returned by qemu_plugin_request_time_control() + * @time: time in nanoseconds + * + * This allows an appropriately authorised plugin (i.e. holding the + * time control handle) to move system time forward to @time. + * + * Start time is 0. + */ +void qemu_plugin_update_ns(const void *handle, int64_t time); + typedef void (*qemu_plugin_vcpu_syscall_cb_t)(qemu_plugin_id_t id, unsigned int vcpu_index, int64_t num, uint64_t a1, uint64_t a2, diff --git a/plugins/api.c b/plugins/api.c index fdf6167655e..f8b2d09ad0c 100644 --- a/plugins/api.c +++ b/plugins/api.c @@ -39,6 +39,7 @@ #include "qemu/main-loop.h" #include "qemu/plugin.h" #include "qemu/log.h" +#include "qemu/timer.h" #include "tcg/tcg.h" #include "exec/exec-all.h" #include "exec/gdbstub.h" @@ -591,3 +592,33 @@ uint64_t qemu_plugin_u64_sum(qemu_plugin_u64 entry) } return total; } + +/* + * Time control + */ +static bool has_control; + +const void *qemu_plugin_request_time_control(void) +{ + if (!has_control) { + has_control = true; + return &has_control; + } + return NULL; +} + +static void advance_virtual_time__async(CPUState *cpu, run_on_cpu_data data) +{ + int64_t new_time = data.host_ulong; + qemu_clock_advance_virtual_time(new_time); +} + +void qemu_plugin_update_ns(const void *handle, int64_t new_time) +{ + if (handle == &has_control) { + /* Need to execute out of cpu_exec, so bql can be locked. */ + async_run_on_cpu(current_cpu, + advance_virtual_time__async, + RUN_ON_CPU_HOST_ULONG(new_time)); + } +} diff --git a/plugins/qemu-plugins.symbols b/plugins/qemu-plugins.symbols index aa0a77a319f..ca773d8d9fe 100644 --- a/plugins/qemu-plugins.symbols +++ b/plugins/qemu-plugins.symbols @@ -38,6 +38,7 @@ qemu_plugin_register_vcpu_tb_exec_cond_cb; qemu_plugin_register_vcpu_tb_exec_inline_per_vcpu; qemu_plugin_register_vcpu_tb_trans_cb; + qemu_plugin_request_time_control; qemu_plugin_reset; qemu_plugin_scoreboard_free; qemu_plugin_scoreboard_find; @@ -51,5 +52,6 @@ qemu_plugin_u64_set; qemu_plugin_u64_sum; qemu_plugin_uninstall; + qemu_plugin_update_ns; qemu_plugin_vcpu_for_each; }; From patchwork Wed Mar 13 10:55:04 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Pierrick Bouvier X-Patchwork-Id: 13591242 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 2FE33C54E60 for ; Wed, 13 Mar 2024 10:56:43 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1rkMH5-0005Yp-Fk; Wed, 13 Mar 2024 06:55:55 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1rkMGw-0005K0-KV for qemu-devel@nongnu.org; Wed, 13 Mar 2024 06:55:47 -0400 Received: from mail-lf1-x129.google.com ([2a00:1450:4864:20::129]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1rkMGs-0007Bm-RT for qemu-devel@nongnu.org; Wed, 13 Mar 2024 06:55:46 -0400 Received: by mail-lf1-x129.google.com with SMTP id 2adb3069b0e04-512f892500cso5120650e87.3 for ; Wed, 13 Mar 2024 03:55:35 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1710327333; x=1710932133; darn=nongnu.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=hpyBaozCQ+jLuJlITaCU3JbnujRlJ74PNyfyU9cltA0=; b=Top6NOHWm7NfRPTUWyNFO7U64kjUesZObnc3wyof6nH5pGdPDQ83MMKQWbiAqXYqjh 3xop+eqzB6S27FkN2eLd7pOQf0NT4iWt4OUjNoX1GrQvEsBQuWJt6QjiwYoUFX7pcQWr i9rFwgHzhQAghtjoGHAbndebNK/OeU8uJsu4zpzIZhV3LXNCdlv335fjkVwmJufCID7K rMgdRAo+fQhcenx7wem3z9w/c4+YijKgzUOe19bFa5k5N2pRhNQ2NH2xFDPAaWT3KOnf Aw8RJOmvtEbIHzg1+HZFhDrjPhJQ6JIvUGGkHvZcGXlVtpshXQu31RKwkkV4PUI0FQzH zunQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1710327333; x=1710932133; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=hpyBaozCQ+jLuJlITaCU3JbnujRlJ74PNyfyU9cltA0=; b=E9oa2ZjJ1oXE9nbZrpDIDotlN6g1kF9hj3uBBv40B8TajcMpJA8Y0vRvnYrxhW6MHo ZBM3a5SPWIXrLDDqltaM8b6o2NcvR91seFavvZdHZjbnGumTsZ9m9WIafz/G2q5eCFyC duU3+4PrdihBXIVOZHQFfO6Jr2gk0kp9G0IrJXWhKueeCyO20Tmaq7lYVSjGFEZYZzd4 EV3MaSDJceJtkgIOVQ4AEXLAtufZjs3BGe/qQ6t+LoZjPpmkh8Fq8UZdWWxP5pxF1cx6 tGqxoqnx2SQRUXzKUeWeAXmTUFfvoVJyhoRenjQ/mxmASQX5LwLQPB62kkWyINMVvCLU zSMA== X-Gm-Message-State: AOJu0YxNRWPEvl9J+ZxqItW68gfQLlg5wLwOfcc9U4y8EBBMKZn4diWc wjIy9L0bmAg6fdO/l+JRq4e3bFF78pSgiVoRpTeUR6Zpq/kRg3pXEtDqZ1uhVawQjMw+m3V4DrH V1go= X-Google-Smtp-Source: AGHT+IH5nhbVata33LCPS3PnrtOLJEhwCR8/fqh39Tn7/eOVsdPMcMbd2Uf6fsF8IwEG/663nzX+KQ== X-Received: by 2002:a05:6512:3d03:b0:513:ca6b:864b with SMTP id d3-20020a0565123d0300b00513ca6b864bmr962756lfv.48.1710327333481; Wed, 13 Mar 2024 03:55:33 -0700 (PDT) Received: from linaro.. ([102.35.208.160]) by smtp.gmail.com with ESMTPSA id w17-20020adfee51000000b0033e1be7f3d8sm11390338wro.70.2024.03.13.03.55.30 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 13 Mar 2024 03:55:33 -0700 (PDT) From: Pierrick Bouvier To: qemu-devel@nongnu.org Cc: Paolo Bonzini , Alexandre Iooss , Richard Henderson , Laurent Vivier , Thomas Huth , Pierrick Bouvier , Mahmoud Mandour , =?utf-8?q?Alex_Benn=C3=A9e?= Subject: [RFC PATCH 5/5] contrib/plugins: add ips plugin example for cost modelling Date: Wed, 13 Mar 2024 14:55:04 +0400 Message-Id: <20240313105504.341875-6-pierrick.bouvier@linaro.org> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20240313105504.341875-1-pierrick.bouvier@linaro.org> References: <20240313105504.341875-1-pierrick.bouvier@linaro.org> MIME-Version: 1.0 Received-SPF: pass client-ip=2a00:1450:4864:20::129; envelope-from=pierrick.bouvier@linaro.org; helo=mail-lf1-x129.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001, T_SCC_BODY_TEXT_LINE=-0.01 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org This plugin uses the new time control interface to make decisions about the state of time during the emulation. The algorithm is currently very simple. The user specifies an ips rate which applies per core. If the core runs ahead of its allocated execution time the plugin sleeps for a bit to let real time catch up. Either way time is updated for the emulation as a function of total executed instructions with some adjustments for cores that idle. Signed-off-by: Pierrick Bouvier --- contrib/plugins/ips.c | 239 +++++++++++++++++++++++++++++++++++++++ contrib/plugins/Makefile | 1 + 2 files changed, 240 insertions(+) create mode 100644 contrib/plugins/ips.c diff --git a/contrib/plugins/ips.c b/contrib/plugins/ips.c new file mode 100644 index 00000000000..cf3159df391 --- /dev/null +++ b/contrib/plugins/ips.c @@ -0,0 +1,239 @@ +/* + * ips rate limiting plugin. + * + * This plugin can be used to restrict the execution of a system to a + * particular number of Instructions Per Second (ips). This controls + * time as seen by the guest so while wall-clock time may be longer + * from the guests point of view time will pass at the normal rate. + * + * This uses the new plugin API which allows the plugin to control + * system time. + * + * Copyright (c) 2023 Linaro Ltd + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +#include +#include +#include + +QEMU_PLUGIN_EXPORT int qemu_plugin_version = QEMU_PLUGIN_VERSION; + +/* how many times do we update time per sec */ +#define NUM_TIME_UPDATE_PER_SEC 10 +#define NSEC_IN_ONE_SEC (1000 * 1000 * 1000) + +static GMutex global_state_lock; + +static uint64_t insn_per_second = 1000 * 1000; /* ips per core, per second */ +static uint64_t insn_quantum; /* trap every N instructions */ +static bool precise_execution; /* count every instruction */ +static int64_t start_time_ns; /* time (ns since epoch) first vCPU started */ +static int64_t virtual_time_ns; /* last set virtual time */ + +static const void *time_handle; + +typedef enum { + UNKNOWN = 0, + EXECUTING, + IDLE, + FINISHED +} vCPUState; + +typedef struct { + uint64_t counter; + uint64_t track_insn; + vCPUState state; + /* timestamp when vCPU entered state */ + int64_t last_state_time; +} vCPUTime; + +struct qemu_plugin_scoreboard *vcpus; + +/* return epoch time in ns */ +static int64_t now_ns(void) +{ + return g_get_real_time() * 1000; +} + +static uint64_t num_insn_during(int64_t elapsed_ns) +{ + double num_secs = elapsed_ns / (double) NSEC_IN_ONE_SEC; + return num_secs * (double) insn_per_second; +} + +static int64_t time_for_insn(uint64_t num_insn) +{ + double num_secs = (double) num_insn / (double) insn_per_second; + return num_secs * (double) NSEC_IN_ONE_SEC; +} + +static int64_t uptime_ns(void) +{ + int64_t now = now_ns(); + g_assert(now >= start_time_ns); + return now - start_time_ns; +} + +static void vcpu_set_state(vCPUTime *vcpu, vCPUState new_state) +{ + vcpu->last_state_time = now_ns(); + vcpu->state = new_state; +} + +static void update_system_time(vCPUTime *vcpu) +{ + /* flush remaining instructions */ + vcpu->counter += vcpu->track_insn; + vcpu->track_insn = 0; + + int64_t uptime = uptime_ns(); + uint64_t expected_insn = num_insn_during(uptime); + + if (vcpu->counter >= expected_insn) { + /* this vcpu ran faster than expected, so it has to sleep */ + uint64_t insn_advance = vcpu->counter - expected_insn; + uint64_t time_advance_ns = time_for_insn(insn_advance); + int64_t sleep_us = time_advance_ns / 1000; + g_usleep(sleep_us); + } + + /* based on number of instructions, what should be the new time? */ + int64_t new_virtual_time = time_for_insn(vcpu->counter); + + g_mutex_lock(&global_state_lock); + + /* Time only moves forward. Another vcpu might have updated it already. */ + if (new_virtual_time > virtual_time_ns) { + qemu_plugin_update_ns(time_handle, new_virtual_time); + virtual_time_ns = new_virtual_time; + } + + g_mutex_unlock(&global_state_lock); +} + +static void set_start_time() +{ + g_mutex_lock(&global_state_lock); + if (!start_time_ns) { + start_time_ns = now_ns(); + } + g_mutex_unlock(&global_state_lock); +} + +static void vcpu_init(qemu_plugin_id_t id, unsigned int cpu_index) +{ + vCPUTime *vcpu = qemu_plugin_scoreboard_find(vcpus, cpu_index); + /* ensure start time is set first */ + set_start_time(); + /* start counter from absolute time reference */ + vcpu->counter = num_insn_during(uptime_ns()); + vcpu_set_state(vcpu, EXECUTING); +} + +static void vcpu_idle(qemu_plugin_id_t id, unsigned int cpu_index) +{ + vCPUTime *vcpu = qemu_plugin_scoreboard_find(vcpus, cpu_index); + vcpu_set_state(vcpu, IDLE); +} + +static void vcpu_resume(qemu_plugin_id_t id, unsigned int cpu_index) +{ + vCPUTime *vcpu = qemu_plugin_scoreboard_find(vcpus, cpu_index); + g_assert(vcpu->state == IDLE); + int64_t idle_time = now_ns() - vcpu->last_state_time; + /* accumulate expected number of instructions */ + vcpu->counter += num_insn_during(idle_time); + vcpu_set_state(vcpu, EXECUTING); +} + +static void vcpu_exit(qemu_plugin_id_t id, unsigned int cpu_index) +{ + vCPUTime *vcpu = qemu_plugin_scoreboard_find(vcpus, cpu_index); + vcpu_set_state(vcpu, FINISHED); + update_system_time(vcpu); + vcpu->counter = 0; +} + +static void every_insn_quantum(unsigned int cpu_index, void *udata) +{ + vCPUTime *vcpu = qemu_plugin_scoreboard_find(vcpus, cpu_index); + g_assert(vcpu->track_insn >= insn_quantum); + update_system_time(vcpu); +} + +static void vcpu_tb_trans(qemu_plugin_id_t id, struct qemu_plugin_tb *tb) +{ + size_t n_insns = qemu_plugin_tb_n_insns(tb); + qemu_plugin_u64 track_insn = + qemu_plugin_scoreboard_u64_in_struct(vcpus, vCPUTime, track_insn); + if (precise_execution) { + /* count (and eventually trap) on every instruction */ + for (int idx = 0; idx < qemu_plugin_tb_n_insns(tb); ++idx) { + struct qemu_plugin_insn *insn = qemu_plugin_tb_get_insn(tb, idx); + qemu_plugin_register_vcpu_insn_exec_inline_per_vcpu( + insn, QEMU_PLUGIN_INLINE_ADD_U64, track_insn, 1); + qemu_plugin_register_vcpu_insn_exec_cond_cb( + insn, every_insn_quantum, + QEMU_PLUGIN_CB_NO_REGS, QEMU_PLUGIN_COND_GE, + track_insn, insn_quantum, NULL); + } + } else { + /* count (and eventually trap) once per tb */ + qemu_plugin_register_vcpu_tb_exec_inline_per_vcpu( + tb, QEMU_PLUGIN_INLINE_ADD_U64, track_insn, n_insns); + qemu_plugin_register_vcpu_tb_exec_cond_cb( + tb, every_insn_quantum, + QEMU_PLUGIN_CB_NO_REGS, QEMU_PLUGIN_COND_GE, + track_insn, insn_quantum, NULL); + } +} + +static void plugin_exit(qemu_plugin_id_t id, void *udata) +{ + qemu_plugin_scoreboard_free(vcpus); +} + +QEMU_PLUGIN_EXPORT int qemu_plugin_install(qemu_plugin_id_t id, + const qemu_info_t *info, int argc, + char **argv) +{ + for (int i = 0; i < argc; i++) { + char *opt = argv[i]; + g_auto(GStrv) tokens = g_strsplit(opt, "=", 2); + if (g_strcmp0(tokens[0], "ips") == 0) { + insn_per_second = g_ascii_strtoull(tokens[1], NULL, 10); + if (!insn_per_second && errno) { + fprintf(stderr, "%s: couldn't parse %s (%s)\n", + __func__, tokens[1], g_strerror(errno)); + return -1; + } + + } else if (g_strcmp0(tokens[0], "precise") == 0) { + if (!qemu_plugin_bool_parse(tokens[0], tokens[1], + &precise_execution)) { + fprintf(stderr, "boolean argument parsing failed: %s\n", opt); + return -1; + } + } else { + fprintf(stderr, "option parsing failed: %s\n", opt); + return -1; + } + } + + vcpus = qemu_plugin_scoreboard_new(sizeof(vCPUTime)); + insn_quantum = insn_per_second / NUM_TIME_UPDATE_PER_SEC; + + time_handle = qemu_plugin_request_time_control(); + g_assert(time_handle); + + qemu_plugin_register_vcpu_tb_trans_cb(id, vcpu_tb_trans); + qemu_plugin_register_vcpu_init_cb(id, vcpu_init); + qemu_plugin_register_vcpu_idle_cb(id, vcpu_idle); + qemu_plugin_register_vcpu_resume_cb(id, vcpu_resume); + qemu_plugin_register_vcpu_exit_cb(id, vcpu_exit); + qemu_plugin_register_atexit_cb(id, plugin_exit, NULL); + + return 0; +} diff --git a/contrib/plugins/Makefile b/contrib/plugins/Makefile index 0b64d2c1e3a..449ead11305 100644 --- a/contrib/plugins/Makefile +++ b/contrib/plugins/Makefile @@ -27,6 +27,7 @@ endif NAMES += hwprofile NAMES += cache NAMES += drcov +NAMES += ips ifeq ($(CONFIG_WIN32),y) SO_SUFFIX := .dll