* [PATCH] accel/tcg: Make round-robin kick period configurable
@ 2025-06-05 6:18 Ethan Chen via
2025-06-05 7:21 ` Philippe Mathieu-Daudé
0 siblings, 1 reply; 3+ messages in thread
From: Ethan Chen via @ 2025-06-05 6:18 UTC (permalink / raw)
To: qemu-devel; +Cc: richard.henderson, pbonzini, Ethan Chen
This change introduces a configurable round-robin kick period, giving users the
flexibility to balance SMP simulation accuracy and performance according to
their specific needs.
The round-robin kick period is the time one vCPU can run before scheduler
switches to another vCPU when using a single thread TCG. The default value of
0.1 seconds may allow one vCPU to run for too long before the scheduler
switches to another. This behavior may not be suitable for workloads with
strict timing requirements.
Reducing the period can improve the fidelity of SMP simulation by allowing
more frequent vCPU switching, though it may negatively impact overall
simulation performance.
Signed-off-by: Ethan Chen <ethan84@andestech.com>
---
accel/tcg/tcg-accel-ops-rr.c | 2 +-
accel/tcg/tcg-accel-ops-rr.h | 2 +-
accel/tcg/tcg-all.c | 35 +++++++++++++++++++++++++++++++++++
qemu-options.hx | 9 ++++++++-
4 files changed, 45 insertions(+), 3 deletions(-)
diff --git a/accel/tcg/tcg-accel-ops-rr.c b/accel/tcg/tcg-accel-ops-rr.c
index 6eec5c9eee..65d8ed87a7 100644
--- a/accel/tcg/tcg-accel-ops-rr.c
+++ b/accel/tcg/tcg-accel-ops-rr.c
@@ -64,7 +64,7 @@ static CPUState *rr_current_cpu;
static inline int64_t rr_next_kick_time(void)
{
- return qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + TCG_KICK_PERIOD;
+ return qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + rr_kick_period;
}
/* Kick the currently round-robin scheduled vCPU to next */
diff --git a/accel/tcg/tcg-accel-ops-rr.h b/accel/tcg/tcg-accel-ops-rr.h
index 2a76a29612..324bb772cb 100644
--- a/accel/tcg/tcg-accel-ops-rr.h
+++ b/accel/tcg/tcg-accel-ops-rr.h
@@ -10,7 +10,7 @@
#ifndef TCG_ACCEL_OPS_RR_H
#define TCG_ACCEL_OPS_RR_H
-#define TCG_KICK_PERIOD (NANOSECONDS_PER_SECOND / 10)
+extern uint64_t rr_kick_period;
/* Kick all RR vCPUs. */
void rr_kick_vcpu_thread(CPUState *unused);
diff --git a/accel/tcg/tcg-all.c b/accel/tcg/tcg-all.c
index 6e5dc333d5..69390020aa 100644
--- a/accel/tcg/tcg-all.c
+++ b/accel/tcg/tcg-all.c
@@ -36,6 +36,7 @@
#include "qapi/qapi-builtin-visit.h"
#include "qemu/units.h"
#include "qemu/target-info.h"
+#include "qemu/timer.h"
#ifndef CONFIG_USER_ONLY
#include "hw/boards.h"
#endif
@@ -50,6 +51,7 @@ struct TCGState {
bool one_insn_per_tb;
int splitwx_enabled;
unsigned long tb_size;
+ uint64_t rr_kick_period;
};
typedef struct TCGState TCGState;
@@ -76,9 +78,11 @@ static void tcg_accel_instance_init(Object *obj)
#else
s->splitwx_enabled = 0;
#endif
+ s->rr_kick_period = NANOSECONDS_PER_SECOND / 10;
}
bool one_insn_per_tb;
+uint64_t rr_kick_period;
static int tcg_init_machine(MachineState *ms)
{
@@ -125,6 +129,7 @@ static int tcg_init_machine(MachineState *ms)
#endif
tcg_allowed = true;
+ rr_kick_period = s->rr_kick_period;
page_init();
tb_htable_init();
@@ -234,6 +239,30 @@ static int tcg_gdbstub_supported_sstep_flags(void)
}
}
+static void tcg_get_rr_kick_period(Object *obj, Visitor *v,
+ const char *name, void *opaque,
+ Error **errp)
+{
+ TCGState *s = TCG_STATE(obj);
+ uint64_t value = s->rr_kick_period;
+
+ visit_type_uint64(v, name, &value, errp);
+}
+
+static void tcg_set_rr_kick_period(Object *obj, Visitor *v,
+ const char *name, void *opaque,
+ Error **errp)
+{
+ TCGState *s = TCG_STATE(obj);
+ uint64_t value;
+
+ if (!visit_type_uint64(v, name, &value, errp)) {
+ return;
+ }
+
+ s->rr_kick_period = value;
+}
+
static void tcg_accel_class_init(ObjectClass *oc, const void *data)
{
AccelClass *ac = ACCEL_CLASS(oc);
@@ -264,6 +293,12 @@ static void tcg_accel_class_init(ObjectClass *oc, const void *data)
tcg_set_one_insn_per_tb);
object_class_property_set_description(oc, "one-insn-per-tb",
"Only put one guest insn in each translation block");
+
+ object_class_property_add(oc, "rr-kick-period", "uint64",
+ tcg_get_rr_kick_period, tcg_set_rr_kick_period,
+ NULL, NULL);
+ object_class_property_set_description(oc, "rr-kick-period",
+ "TCG round robin kick period in nanoseconds");
}
static const TypeInfo tcg_accel_type = {
diff --git a/qemu-options.hx b/qemu-options.hx
index 7eb8e02b4b..ec8ba79e37 100644
--- a/qemu-options.hx
+++ b/qemu-options.hx
@@ -232,7 +232,8 @@ DEF("accel", HAS_ARG, QEMU_OPTION_accel,
" eager-split-size=n (KVM Eager Page Split chunk size, default 0, disabled. ARM only)\n"
" notify-vmexit=run|internal-error|disable,notify-window=n (enable notify VM exit and set notify window, x86 only)\n"
" thread=single|multi (enable multi-threaded TCG)\n"
- " device=path (KVM device path, default /dev/kvm)\n", QEMU_ARCH_ALL)
+ " device=path (KVM device path, default /dev/kvm)\n"
+ " rr-kick-period=time (TCG round-robin kick period in nanoseconds)\n", QEMU_ARCH_ALL)
SRST
``-accel name[,prop=value[,...]]``
This is used to enable an accelerator. Depending on the target
@@ -318,6 +319,12 @@ SRST
option can be used to pass the KVM device to use via a file descriptor
by setting the value to ``/dev/fdset/NN``.
+ ``rr-kick-period=time``
+ Controls the TCG round-robin kick period in nanoseconds. This option is
+ only effective when using single-threaded TCG. Reducing the period
+ can improve the fidelity of SMP simulation by allowing more frequent
+ vCPU switching, though it may negatively impact overall simulation
+ performance.
ERST
DEF("smp", HAS_ARG, QEMU_OPTION_smp,
--
2.34.1
^ permalink raw reply related [flat|nested] 3+ messages in thread
* Re: [PATCH] accel/tcg: Make round-robin kick period configurable
2025-06-05 6:18 [PATCH] accel/tcg: Make round-robin kick period configurable Ethan Chen via
@ 2025-06-05 7:21 ` Philippe Mathieu-Daudé
2025-06-05 10:02 ` Ethan Chen via
0 siblings, 1 reply; 3+ messages in thread
From: Philippe Mathieu-Daudé @ 2025-06-05 7:21 UTC (permalink / raw)
To: Ethan Chen, qemu-devel; +Cc: richard.henderson, pbonzini
Hi Ethan,
On 5/6/25 08:18, Ethan Chen via wrote:
> This change introduces a configurable round-robin kick period, giving users the
> flexibility to balance SMP simulation accuracy and performance according to
> their specific needs.
>
> The round-robin kick period is the time one vCPU can run before scheduler
> switches to another vCPU when using a single thread TCG. The default value of
> 0.1 seconds may allow one vCPU to run for too long before the scheduler
> switches to another. This behavior may not be suitable for workloads with
> strict timing requirements.
>
> Reducing the period can improve the fidelity of SMP simulation by allowing
> more frequent vCPU switching, though it may negatively impact overall
> simulation performance.
>
> Signed-off-by: Ethan Chen <ethan84@andestech.com>
> ---
> accel/tcg/tcg-accel-ops-rr.c | 2 +-
> accel/tcg/tcg-accel-ops-rr.h | 2 +-
> accel/tcg/tcg-all.c | 35 +++++++++++++++++++++++++++++++++++
> qemu-options.hx | 9 ++++++++-
> 4 files changed, 45 insertions(+), 3 deletions(-)
> diff --git a/accel/tcg/tcg-accel-ops-rr.h b/accel/tcg/tcg-accel-ops-rr.h
> index 2a76a29612..324bb772cb 100644
> --- a/accel/tcg/tcg-accel-ops-rr.h
> +++ b/accel/tcg/tcg-accel-ops-rr.h
> @@ -10,7 +10,7 @@
> #ifndef TCG_ACCEL_OPS_RR_H
> #define TCG_ACCEL_OPS_RR_H
>
> -#define TCG_KICK_PERIOD (NANOSECONDS_PER_SECOND / 10)
> +extern uint64_t rr_kick_period;
No need for another extern, pass it as argument:
-- >8 --
diff --git a/accel/tcg/tcg-accel-ops-rr.c b/accel/tcg/tcg-accel-ops-rr.c
index f62cf24e1d4..551864b5509 100644
--- a/accel/tcg/tcg-accel-ops-rr.c
+++ b/accel/tcg/tcg-accel-ops-rr.c
@@ -62,9 +62,9 @@ void rr_kick_vcpu_thread(CPUState *unused)
static QEMUTimer *rr_kick_vcpu_timer;
static CPUState *rr_current_cpu;
-static inline int64_t rr_next_kick_time(void)
+static inline int64_t rr_next_kick_time(uint64_t kick_delay_ns)
{
- return qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + TCG_KICK_PERIOD;
+ return qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + kick_delay_ns;
}
/* Kick the currently round-robin scheduled vCPU to next */
@@ -83,15 +83,20 @@ static void rr_kick_next_cpu(void)
static void rr_kick_thread(void *opaque)
{
- timer_mod(rr_kick_vcpu_timer, rr_next_kick_time());
+ CPUState *cpu = opaque;
+
+ // here use rr_next_kick_time(cpu->accel->rr_kick_delay_ns):
+ timer_mod(rr_kick_vcpu_timer, rr_next_kick_time(TCG_KICK_PERIOD));
rr_kick_next_cpu();
}
static void rr_start_kick_timer(void)
{
- if (!rr_kick_vcpu_timer && CPU_NEXT(first_cpu)) {
+ CPUState *next_cpu = CPU_NEXT(first_cpu);
+
+ if (!rr_kick_vcpu_timer && next_cpu) {
rr_kick_vcpu_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL,
- rr_kick_thread, NULL);
+ rr_kick_thread, next_cpu);
}
if (rr_kick_vcpu_timer && !timer_pending(rr_kick_vcpu_timer)) {
timer_mod(rr_kick_vcpu_timer, rr_next_kick_time());
---
> diff --git a/accel/tcg/tcg-all.c b/accel/tcg/tcg-all.c
> index 6e5dc333d5..69390020aa 100644
> --- a/accel/tcg/tcg-all.c
> +++ b/accel/tcg/tcg-all.c
> @@ -36,6 +36,7 @@
> #include "qapi/qapi-builtin-visit.h"
> #include "qemu/units.h"
> #include "qemu/target-info.h"
> +#include "qemu/timer.h"
> #ifndef CONFIG_USER_ONLY
> #include "hw/boards.h"
> #endif
> @@ -50,6 +51,7 @@ struct TCGState {
> bool one_insn_per_tb;
> int splitwx_enabled;
> unsigned long tb_size;
> + uint64_t rr_kick_period;
'rr_kick_delay_ns' seems more accurate.
> };
> typedef struct TCGState TCGState;
>
> @@ -76,9 +78,11 @@ static void tcg_accel_instance_init(Object *obj)
> #else
> s->splitwx_enabled = 0;
> #endif
> + s->rr_kick_period = NANOSECONDS_PER_SECOND / 10;
> }
>
> bool one_insn_per_tb;
> +uint64_t rr_kick_period;
(Drop)
>
> static int tcg_init_machine(MachineState *ms)
> {
> @@ -125,6 +129,7 @@ static int tcg_init_machine(MachineState *ms)
> #endif
>
> tcg_allowed = true;
> + rr_kick_period = s->rr_kick_period;
(Drop)
>
> page_init();
> tb_htable_init();
> @@ -234,6 +239,30 @@ static int tcg_gdbstub_supported_sstep_flags(void)
> }
> }
Patch LGTM otherwise.
Regards,
Phil.
^ permalink raw reply related [flat|nested] 3+ messages in thread
* Re: [PATCH] accel/tcg: Make round-robin kick period configurable
2025-06-05 7:21 ` Philippe Mathieu-Daudé
@ 2025-06-05 10:02 ` Ethan Chen via
0 siblings, 0 replies; 3+ messages in thread
From: Ethan Chen via @ 2025-06-05 10:02 UTC (permalink / raw)
To: Philippe Mathieu-Daudé; +Cc: qemu-devel, richard.henderson, pbonzini
Hi Philippe,
Thank you for your response.
Since TCGState is currently defined only in tcg-all.c, we’re unable to access
rr_kick_delay_ns from other .c files through the struct.
One potential approach would be to introduce a tcg-all.h header and move the
TCGState definition there. This would allow us to access the struct in other
components by including the header and using TCG_STATE(current_accel()).
Would you be open to this direction, or do you have any alternative
suggestions?
Thanks,
Ethan
On Thu, Jun 05, 2025 at 09:21:55AM +0200, Philippe Mathieu-Daudé wrote:
> Hi Ethan,
>
> On 5/6/25 08:18, Ethan Chen via wrote:
> > This change introduces a configurable round-robin kick period, giving users the
> > flexibility to balance SMP simulation accuracy and performance according to
> > their specific needs.
> >
> > The round-robin kick period is the time one vCPU can run before scheduler
> > switches to another vCPU when using a single thread TCG. The default value of
> > 0.1 seconds may allow one vCPU to run for too long before the scheduler
> > switches to another. This behavior may not be suitable for workloads with
> > strict timing requirements.
> >
> > Reducing the period can improve the fidelity of SMP simulation by allowing
> > more frequent vCPU switching, though it may negatively impact overall
> > simulation performance.
> >
> > Signed-off-by: Ethan Chen <ethan84@andestech.com>
> > ---
> > accel/tcg/tcg-accel-ops-rr.c | 2 +-
> > accel/tcg/tcg-accel-ops-rr.h | 2 +-
> > accel/tcg/tcg-all.c | 35 +++++++++++++++++++++++++++++++++++
> > qemu-options.hx | 9 ++++++++-
> > 4 files changed, 45 insertions(+), 3 deletions(-)
>
>
> > diff --git a/accel/tcg/tcg-accel-ops-rr.h b/accel/tcg/tcg-accel-ops-rr.h
> > index 2a76a29612..324bb772cb 100644
> > --- a/accel/tcg/tcg-accel-ops-rr.h
> > +++ b/accel/tcg/tcg-accel-ops-rr.h
> > @@ -10,7 +10,7 @@
> > #ifndef TCG_ACCEL_OPS_RR_H
> > #define TCG_ACCEL_OPS_RR_H
> >
> > -#define TCG_KICK_PERIOD (NANOSECONDS_PER_SECOND / 10)
> > +extern uint64_t rr_kick_period;
>
> No need for another extern, pass it as argument:
>
> -- >8 --
> diff --git a/accel/tcg/tcg-accel-ops-rr.c b/accel/tcg/tcg-accel-ops-rr.c
> index f62cf24e1d4..551864b5509 100644
> --- a/accel/tcg/tcg-accel-ops-rr.c
> +++ b/accel/tcg/tcg-accel-ops-rr.c
> @@ -62,9 +62,9 @@ void rr_kick_vcpu_thread(CPUState *unused)
> static QEMUTimer *rr_kick_vcpu_timer;
> static CPUState *rr_current_cpu;
>
> -static inline int64_t rr_next_kick_time(void)
> +static inline int64_t rr_next_kick_time(uint64_t kick_delay_ns)
> {
> - return qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + TCG_KICK_PERIOD;
> + return qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + kick_delay_ns;
> }
>
> /* Kick the currently round-robin scheduled vCPU to next */
> @@ -83,15 +83,20 @@ static void rr_kick_next_cpu(void)
>
> static void rr_kick_thread(void *opaque)
> {
> - timer_mod(rr_kick_vcpu_timer, rr_next_kick_time());
> + CPUState *cpu = opaque;
> +
> + // here use rr_next_kick_time(cpu->accel->rr_kick_delay_ns):
> + timer_mod(rr_kick_vcpu_timer, rr_next_kick_time(TCG_KICK_PERIOD));
> rr_kick_next_cpu();
> }
>
> static void rr_start_kick_timer(void)
> {
> - if (!rr_kick_vcpu_timer && CPU_NEXT(first_cpu)) {
> + CPUState *next_cpu = CPU_NEXT(first_cpu);
> +
> + if (!rr_kick_vcpu_timer && next_cpu) {
> rr_kick_vcpu_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL,
> - rr_kick_thread, NULL);
> + rr_kick_thread, next_cpu);
> }
> if (rr_kick_vcpu_timer && !timer_pending(rr_kick_vcpu_timer)) {
> timer_mod(rr_kick_vcpu_timer, rr_next_kick_time());
> ---
>
> > diff --git a/accel/tcg/tcg-all.c b/accel/tcg/tcg-all.c
> > index 6e5dc333d5..69390020aa 100644
> > --- a/accel/tcg/tcg-all.c
> > +++ b/accel/tcg/tcg-all.c
> > @@ -36,6 +36,7 @@
> > #include "qapi/qapi-builtin-visit.h"
> > #include "qemu/units.h"
> > #include "qemu/target-info.h"
> > +#include "qemu/timer.h"
> > #ifndef CONFIG_USER_ONLY
> > #include "hw/boards.h"
> > #endif
> > @@ -50,6 +51,7 @@ struct TCGState {
> > bool one_insn_per_tb;
> > int splitwx_enabled;
> > unsigned long tb_size;
> > + uint64_t rr_kick_period;
>
> 'rr_kick_delay_ns' seems more accurate.
>
> > };
> > typedef struct TCGState TCGState;
> >
> > @@ -76,9 +78,11 @@ static void tcg_accel_instance_init(Object *obj)
> > #else
> > s->splitwx_enabled = 0;
> > #endif
> > + s->rr_kick_period = NANOSECONDS_PER_SECOND / 10;
> > }
> >
> > bool one_insn_per_tb;
> > +uint64_t rr_kick_period;
>
> (Drop)
>
> >
> > static int tcg_init_machine(MachineState *ms)
> > {
> > @@ -125,6 +129,7 @@ static int tcg_init_machine(MachineState *ms)
> > #endif
> >
> > tcg_allowed = true;
> > + rr_kick_period = s->rr_kick_period;
>
> (Drop)
>
> >
> > page_init();
> > tb_htable_init();
> > @@ -234,6 +239,30 @@ static int tcg_gdbstub_supported_sstep_flags(void)
> > }
> > }
>
> Patch LGTM otherwise.
>
> Regards,
>
> Phil.
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2025-06-05 10:03 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-06-05 6:18 [PATCH] accel/tcg: Make round-robin kick period configurable Ethan Chen via
2025-06-05 7:21 ` Philippe Mathieu-Daudé
2025-06-05 10:02 ` Ethan Chen via
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).