Commit 49113d36 authored by Nir Weiner's avatar Nir Weiner Committed by Paolo Bonzini

KVM: Expose the initial start value in grow_halt_poll_ns() as a module parameter

The hard-coded value 10000 in grow_halt_poll_ns() stands for the initial
start value when raising up vcpu->halt_poll_ns.
It actually sets the first timeout to the first polling session.
This value has significant effect on how tolerant we are to outliers.
On the standard case, higher value is better - we will spend more time
in the polling busyloop, handle events/interrupts faster and result
in better performance.
But on outliers it puts us in a busy loop that does nothing.
Even if the shrink factor is zero, we will still waste time on the first
iteration.
The optimal value changes between different workloads. It depends on
outliers rate and polling sessions length.
As this value has significant effect on the dynamic halt-polling
algorithm, it should be configurable and exposed.
Reviewed-by: default avatarBoris Ostrovsky <boris.ostrovsky@oracle.com>
Reviewed-by: default avatarLiran Alon <liran.alon@oracle.com>
Signed-off-by: default avatarNir Weiner <nir.weiner@oracle.com>
Signed-off-by: default avatarPaolo Bonzini <pbonzini@redhat.com>
parent 7fa08e71
...@@ -53,7 +53,8 @@ the global max polling interval then the polling interval can be increased in ...@@ -53,7 +53,8 @@ the global max polling interval then the polling interval can be increased in
the hope that next time during the longer polling interval the wake up source the hope that next time during the longer polling interval the wake up source
will be received while the host is polling and the latency benefits will be will be received while the host is polling and the latency benefits will be
received. The polling interval is grown in the function grow_halt_poll_ns() and received. The polling interval is grown in the function grow_halt_poll_ns() and
is multiplied by the module parameter halt_poll_ns_grow. is multiplied by the module parameters halt_poll_ns_grow and
halt_poll_ns_grow_start.
In the event that the total block time was greater than the global max polling In the event that the total block time was greater than the global max polling
interval then the host will never poll for long enough (limited by the global interval then the host will never poll for long enough (limited by the global
...@@ -80,22 +81,30 @@ shrunk. These variables are defined in include/linux/kvm_host.h and as module ...@@ -80,22 +81,30 @@ shrunk. These variables are defined in include/linux/kvm_host.h and as module
parameters in virt/kvm/kvm_main.c, or arch/powerpc/kvm/book3s_hv.c in the parameters in virt/kvm/kvm_main.c, or arch/powerpc/kvm/book3s_hv.c in the
powerpc kvm-hv case. powerpc kvm-hv case.
Module Parameter | Description | Default Value Module Parameter | Description | Default Value
-------------------------------------------------------------------------------- --------------------------------------------------------------------------------
halt_poll_ns | The global max polling interval | KVM_HALT_POLL_NS_DEFAULT halt_poll_ns | The global max polling | KVM_HALT_POLL_NS_DEFAULT
| which defines the ceiling value | | interval which defines |
| of the polling interval for | (per arch value) | the ceiling value of the |
| each vcpu. | | polling interval for | (per arch value)
| each vcpu. |
-------------------------------------------------------------------------------- --------------------------------------------------------------------------------
halt_poll_ns_grow | The value by which the halt | 2 halt_poll_ns_grow | The value by which the | 2
| polling interval is multiplied | | halt polling interval is |
| in the grow_halt_poll_ns() | | multiplied in the |
| function. | | grow_halt_poll_ns() |
| function. |
-------------------------------------------------------------------------------- --------------------------------------------------------------------------------
halt_poll_ns_shrink | The value by which the halt | 0 halt_poll_ns_grow_start | The initial value to grow | 10000
| polling interval is divided in | | to from zero in the |
| the shrink_halt_poll_ns() | | grow_halt_poll_ns() |
| function. | | function. |
--------------------------------------------------------------------------------
halt_poll_ns_shrink | The value by which the | 0
| halt polling interval is |
| divided in the |
| shrink_halt_poll_ns() |
| function. |
-------------------------------------------------------------------------------- --------------------------------------------------------------------------------
These module parameters can be set from the debugfs files in: These module parameters can be set from the debugfs files in:
......
...@@ -3634,9 +3634,8 @@ static void grow_halt_poll_ns(struct kvmppc_vcore *vc) ...@@ -3634,9 +3634,8 @@ static void grow_halt_poll_ns(struct kvmppc_vcore *vc)
if (!halt_poll_ns_grow) if (!halt_poll_ns_grow)
return; return;
/* 10us base */
if (vc->halt_poll_ns == 0) if (vc->halt_poll_ns == 0)
vc->halt_poll_ns = 10000; vc->halt_poll_ns = halt_poll_ns_grow_start;
else else
vc->halt_poll_ns *= halt_poll_ns_grow; vc->halt_poll_ns *= halt_poll_ns_grow;
} }
......
...@@ -1203,6 +1203,7 @@ extern bool kvm_rebooting; ...@@ -1203,6 +1203,7 @@ extern bool kvm_rebooting;
extern unsigned int halt_poll_ns; extern unsigned int halt_poll_ns;
extern unsigned int halt_poll_ns_grow; extern unsigned int halt_poll_ns_grow;
extern unsigned int halt_poll_ns_grow_start;
extern unsigned int halt_poll_ns_shrink; extern unsigned int halt_poll_ns_shrink;
struct kvm_device { struct kvm_device {
......
...@@ -81,6 +81,11 @@ unsigned int halt_poll_ns_grow = 2; ...@@ -81,6 +81,11 @@ unsigned int halt_poll_ns_grow = 2;
module_param(halt_poll_ns_grow, uint, 0644); module_param(halt_poll_ns_grow, uint, 0644);
EXPORT_SYMBOL_GPL(halt_poll_ns_grow); EXPORT_SYMBOL_GPL(halt_poll_ns_grow);
/* The start value to grow halt_poll_ns from */
unsigned int halt_poll_ns_grow_start = 10000; /* 10us */
module_param(halt_poll_ns_grow_start, uint, 0644);
EXPORT_SYMBOL_GPL(halt_poll_ns_grow_start);
/* Default resets per-vcpu halt_poll_ns . */ /* Default resets per-vcpu halt_poll_ns . */
unsigned int halt_poll_ns_shrink; unsigned int halt_poll_ns_shrink;
module_param(halt_poll_ns_shrink, uint, 0644); module_param(halt_poll_ns_shrink, uint, 0644);
...@@ -2191,9 +2196,8 @@ static void grow_halt_poll_ns(struct kvm_vcpu *vcpu) ...@@ -2191,9 +2196,8 @@ static void grow_halt_poll_ns(struct kvm_vcpu *vcpu)
if (!grow) if (!grow)
goto out; goto out;
/* 10us base */
if (val == 0) if (val == 0)
val = 10000; val = halt_poll_ns_grow_start;
else else
val *= grow; val *= grow;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment