KVM: s390: provide kvm_arch_no_poll function
We do track the current steal time of the host CPUs. Let us use this value to disable halt polling if the steal time goes beyond a configured value. Signed-off-by: Christian Borntraeger <borntraeger@de.ibm.com> Acked-by: Paolo Bonzini <pbonzini@redhat.com> Reviewed-by: Cornelia Huck <cohuck@redhat.com> Signed-off-by: Christian Borntraeger <borntraeger@de.ibm.com>
This commit is contained in:
parent
cdd6ad3ac6
commit
8b905d28ee
3 changed files with 19 additions and 0 deletions
|
@ -313,6 +313,7 @@ struct kvm_vcpu_stat {
|
||||||
u64 halt_successful_poll;
|
u64 halt_successful_poll;
|
||||||
u64 halt_attempted_poll;
|
u64 halt_attempted_poll;
|
||||||
u64 halt_poll_invalid;
|
u64 halt_poll_invalid;
|
||||||
|
u64 halt_no_poll_steal;
|
||||||
u64 halt_wakeup;
|
u64 halt_wakeup;
|
||||||
u64 instruction_lctl;
|
u64 instruction_lctl;
|
||||||
u64 instruction_lctlg;
|
u64 instruction_lctlg;
|
||||||
|
|
|
@ -31,6 +31,7 @@ config KVM
|
||||||
select HAVE_KVM_IRQFD
|
select HAVE_KVM_IRQFD
|
||||||
select HAVE_KVM_IRQ_ROUTING
|
select HAVE_KVM_IRQ_ROUTING
|
||||||
select HAVE_KVM_INVALID_WAKEUPS
|
select HAVE_KVM_INVALID_WAKEUPS
|
||||||
|
select HAVE_KVM_NO_POLL
|
||||||
select SRCU
|
select SRCU
|
||||||
select KVM_VFIO
|
select KVM_VFIO
|
||||||
---help---
|
---help---
|
||||||
|
|
|
@ -75,6 +75,7 @@ struct kvm_stats_debugfs_item debugfs_entries[] = {
|
||||||
{ "halt_successful_poll", VCPU_STAT(halt_successful_poll) },
|
{ "halt_successful_poll", VCPU_STAT(halt_successful_poll) },
|
||||||
{ "halt_attempted_poll", VCPU_STAT(halt_attempted_poll) },
|
{ "halt_attempted_poll", VCPU_STAT(halt_attempted_poll) },
|
||||||
{ "halt_poll_invalid", VCPU_STAT(halt_poll_invalid) },
|
{ "halt_poll_invalid", VCPU_STAT(halt_poll_invalid) },
|
||||||
|
{ "halt_no_poll_steal", VCPU_STAT(halt_no_poll_steal) },
|
||||||
{ "halt_wakeup", VCPU_STAT(halt_wakeup) },
|
{ "halt_wakeup", VCPU_STAT(halt_wakeup) },
|
||||||
{ "instruction_lctlg", VCPU_STAT(instruction_lctlg) },
|
{ "instruction_lctlg", VCPU_STAT(instruction_lctlg) },
|
||||||
{ "instruction_lctl", VCPU_STAT(instruction_lctl) },
|
{ "instruction_lctl", VCPU_STAT(instruction_lctl) },
|
||||||
|
@ -177,6 +178,11 @@ static int hpage;
|
||||||
module_param(hpage, int, 0444);
|
module_param(hpage, int, 0444);
|
||||||
MODULE_PARM_DESC(hpage, "1m huge page backing support");
|
MODULE_PARM_DESC(hpage, "1m huge page backing support");
|
||||||
|
|
||||||
|
/* maximum percentage of steal time for polling. >100 is treated like 100 */
|
||||||
|
static u8 halt_poll_max_steal = 10;
|
||||||
|
module_param(halt_poll_max_steal, byte, 0644);
|
||||||
|
MODULE_PARM_DESC(hpage, "Maximum percentage of steal time to allow polling");
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* For now we handle at most 16 double words as this is what the s390 base
|
* For now we handle at most 16 double words as this is what the s390 base
|
||||||
* kernel handles and stores in the prefix page. If we ever need to go beyond
|
* kernel handles and stores in the prefix page. If we ever need to go beyond
|
||||||
|
@ -3166,6 +3172,17 @@ static void kvm_gmap_notifier(struct gmap *gmap, unsigned long start,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool kvm_arch_no_poll(struct kvm_vcpu *vcpu)
|
||||||
|
{
|
||||||
|
/* do not poll with more than halt_poll_max_steal percent of steal time */
|
||||||
|
if (S390_lowcore.avg_steal_timer * 100 / (TICK_USEC << 12) >=
|
||||||
|
halt_poll_max_steal) {
|
||||||
|
vcpu->stat.halt_no_poll_steal++;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
int kvm_arch_vcpu_should_kick(struct kvm_vcpu *vcpu)
|
int kvm_arch_vcpu_should_kick(struct kvm_vcpu *vcpu)
|
||||||
{
|
{
|
||||||
/* kvm common code refers to this, but never calls it */
|
/* kvm common code refers to this, but never calls it */
|
||||||
|
|
Loading…
Add table
Reference in a new issue