forked from torvalds/linux
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* pm-cpuidle: cpuidle-haltpoll: Enable kvm guest polling when dedicated physical CPUs are available cpuidle-haltpoll: do not set an owner to allow modunload cpuidle-haltpoll: return -ENODEV on modinit failure cpuidle-haltpoll: set haltpoll as preferred governor cpuidle: allow governor switch on cpuidle_register_driver() powercap: idle_inject: Use higher resolution for idle injection cpuidle: play_idle: Increase the resolution to usec cpuidle-haltpoll: vcpu hotplug support cpuidle: teo: Get rid of redundant check in teo_update() cpuidle: teo: Allow tick to be stopped if PM QoS is used cpuidle: menu: Allow tick to be stopped if PM QoS is used cpuidle: header file stubs must be "static inline" cpuidle-haltpoll: disable host side polling when kvm virtualized cpuidle: add haltpoll governor governors: unify last_state_idx cpuidle: add poll_limit_ns to cpuidle_device structure add cpuidle-haltpoll driver
- Loading branch information
Showing
26 changed files
with
613 additions
and
107 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,78 @@ | ||
Guest halt polling | ||
================== | ||
|
||
The cpuidle_haltpoll driver, with the haltpoll governor, allows | ||
the guest vcpus to poll for a specified amount of time before | ||
halting. | ||
This provides the following benefits to host side polling: | ||
|
||
1) The POLL flag is set while polling is performed, which allows | ||
a remote vCPU to avoid sending an IPI (and the associated | ||
cost of handling the IPI) when performing a wakeup. | ||
|
||
2) The VM-exit cost can be avoided. | ||
|
||
The downside of guest side polling is that polling is performed | ||
even with other runnable tasks in the host. | ||
|
||
The basic logic as follows: A global value, guest_halt_poll_ns, | ||
is configured by the user, indicating the maximum amount of | ||
time polling is allowed. This value is fixed. | ||
|
||
Each vcpu has an adjustable guest_halt_poll_ns | ||
("per-cpu guest_halt_poll_ns"), which is adjusted by the algorithm | ||
in response to events (explained below). | ||
|
||
Module Parameters | ||
================= | ||
|
||
The haltpoll governor has 5 tunable module parameters: | ||
|
||
1) guest_halt_poll_ns: | ||
Maximum amount of time, in nanoseconds, that polling is | ||
performed before halting. | ||
|
||
Default: 200000 | ||
|
||
2) guest_halt_poll_shrink: | ||
Division factor used to shrink per-cpu guest_halt_poll_ns when | ||
wakeup event occurs after the global guest_halt_poll_ns. | ||
|
||
Default: 2 | ||
|
||
3) guest_halt_poll_grow: | ||
Multiplication factor used to grow per-cpu guest_halt_poll_ns | ||
when event occurs after per-cpu guest_halt_poll_ns | ||
but before global guest_halt_poll_ns. | ||
|
||
Default: 2 | ||
|
||
4) guest_halt_poll_grow_start: | ||
The per-cpu guest_halt_poll_ns eventually reaches zero | ||
in case of an idle system. This value sets the initial | ||
per-cpu guest_halt_poll_ns when growing. This can | ||
be increased from 10000, to avoid misses during the initial | ||
growth stage: | ||
|
||
10k, 20k, 40k, ... (example assumes guest_halt_poll_grow=2). | ||
|
||
Default: 50000 | ||
|
||
5) guest_halt_poll_allow_shrink: | ||
|
||
Bool parameter which allows shrinking. Set to N | ||
to avoid it (per-cpu guest_halt_poll_ns will remain | ||
high once achieves global guest_halt_poll_ns value). | ||
|
||
Default: Y | ||
|
||
The module parameters can be set from the debugfs files in: | ||
|
||
/sys/module/haltpoll/parameters/ | ||
|
||
Further Notes | ||
============= | ||
|
||
- Care should be taken when setting the guest_halt_poll_ns parameter as a | ||
large value has the potential to drive the cpu usage to 100% on a machine which | ||
would be almost entirely idle otherwise. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
/* SPDX-License-Identifier: GPL-2.0 */ | ||
#ifndef _ARCH_HALTPOLL_H | ||
#define _ARCH_HALTPOLL_H | ||
|
||
void arch_haltpoll_enable(unsigned int cpu); | ||
void arch_haltpoll_disable(unsigned int cpu); | ||
|
||
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,134 @@ | ||
// SPDX-License-Identifier: GPL-2.0 | ||
/* | ||
* cpuidle driver for haltpoll governor. | ||
* | ||
* Copyright 2019 Red Hat, Inc. and/or its affiliates. | ||
* | ||
* This work is licensed under the terms of the GNU GPL, version 2. See | ||
* the COPYING file in the top-level directory. | ||
* | ||
* Authors: Marcelo Tosatti <[email protected]> | ||
*/ | ||
|
||
#include <linux/init.h> | ||
#include <linux/cpu.h> | ||
#include <linux/cpuidle.h> | ||
#include <linux/module.h> | ||
#include <linux/sched/idle.h> | ||
#include <linux/kvm_para.h> | ||
#include <linux/cpuidle_haltpoll.h> | ||
|
||
static struct cpuidle_device __percpu *haltpoll_cpuidle_devices; | ||
static enum cpuhp_state haltpoll_hp_state; | ||
|
||
static int default_enter_idle(struct cpuidle_device *dev, | ||
struct cpuidle_driver *drv, int index) | ||
{ | ||
if (current_clr_polling_and_test()) { | ||
local_irq_enable(); | ||
return index; | ||
} | ||
default_idle(); | ||
return index; | ||
} | ||
|
||
static struct cpuidle_driver haltpoll_driver = { | ||
.name = "haltpoll", | ||
.governor = "haltpoll", | ||
.states = { | ||
{ /* entry 0 is for polling */ }, | ||
{ | ||
.enter = default_enter_idle, | ||
.exit_latency = 1, | ||
.target_residency = 1, | ||
.power_usage = -1, | ||
.name = "haltpoll idle", | ||
.desc = "default architecture idle", | ||
}, | ||
}, | ||
.safe_state_index = 0, | ||
.state_count = 2, | ||
}; | ||
|
||
static int haltpoll_cpu_online(unsigned int cpu) | ||
{ | ||
struct cpuidle_device *dev; | ||
|
||
dev = per_cpu_ptr(haltpoll_cpuidle_devices, cpu); | ||
if (!dev->registered) { | ||
dev->cpu = cpu; | ||
if (cpuidle_register_device(dev)) { | ||
pr_notice("cpuidle_register_device %d failed!\n", cpu); | ||
return -EIO; | ||
} | ||
arch_haltpoll_enable(cpu); | ||
} | ||
|
||
return 0; | ||
} | ||
|
||
static int haltpoll_cpu_offline(unsigned int cpu) | ||
{ | ||
struct cpuidle_device *dev; | ||
|
||
dev = per_cpu_ptr(haltpoll_cpuidle_devices, cpu); | ||
if (dev->registered) { | ||
arch_haltpoll_disable(cpu); | ||
cpuidle_unregister_device(dev); | ||
} | ||
|
||
return 0; | ||
} | ||
|
||
static void haltpoll_uninit(void) | ||
{ | ||
if (haltpoll_hp_state) | ||
cpuhp_remove_state(haltpoll_hp_state); | ||
cpuidle_unregister_driver(&haltpoll_driver); | ||
|
||
free_percpu(haltpoll_cpuidle_devices); | ||
haltpoll_cpuidle_devices = NULL; | ||
} | ||
|
||
static int __init haltpoll_init(void) | ||
{ | ||
int ret; | ||
struct cpuidle_driver *drv = &haltpoll_driver; | ||
|
||
cpuidle_poll_state_init(drv); | ||
|
||
if (!kvm_para_available() || | ||
!kvm_para_has_hint(KVM_HINTS_REALTIME)) | ||
return -ENODEV; | ||
|
||
ret = cpuidle_register_driver(drv); | ||
if (ret < 0) | ||
return ret; | ||
|
||
haltpoll_cpuidle_devices = alloc_percpu(struct cpuidle_device); | ||
if (haltpoll_cpuidle_devices == NULL) { | ||
cpuidle_unregister_driver(drv); | ||
return -ENOMEM; | ||
} | ||
|
||
ret = cpuhp_setup_state(CPUHP_AP_ONLINE_DYN, "cpuidle/haltpoll:online", | ||
haltpoll_cpu_online, haltpoll_cpu_offline); | ||
if (ret < 0) { | ||
haltpoll_uninit(); | ||
} else { | ||
haltpoll_hp_state = ret; | ||
ret = 0; | ||
} | ||
|
||
return ret; | ||
} | ||
|
||
static void __exit haltpoll_exit(void) | ||
{ | ||
haltpoll_uninit(); | ||
} | ||
|
||
module_init(haltpoll_init); | ||
module_exit(haltpoll_exit); | ||
MODULE_LICENSE("GPL"); | ||
MODULE_AUTHOR("Marcelo Tosatti <[email protected]>"); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.