Blame view
drivers/cpuidle/cpuidle-haltpoll.c
3.13 KB
fa86ee90e add cpuidle-haltp... |
1 2 3 4 5 6 7 8 9 10 11 12 13 |
// 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 <mtosatti@redhat.com> */ #include <linux/init.h> |
97d3eb9da cpuidle-haltpoll:... |
14 |
#include <linux/cpu.h> |
fa86ee90e add cpuidle-haltp... |
15 16 17 18 |
#include <linux/cpuidle.h> #include <linux/module.h> #include <linux/sched/idle.h> #include <linux/kvm_para.h> |
a1c4423b0 cpuidle-haltpoll:... |
19 |
#include <linux/cpuidle_haltpoll.h> |
fa86ee90e add cpuidle-haltp... |
20 |
|
dd52551fb cpuidle: haltpoll... |
21 22 23 |
static bool force __read_mostly; module_param(force, bool, 0444); MODULE_PARM_DESC(force, "Load unconditionally"); |
97d3eb9da cpuidle-haltpoll:... |
24 25 |
static struct cpuidle_device __percpu *haltpoll_cpuidle_devices; static enum cpuhp_state haltpoll_hp_state; |
fa86ee90e add cpuidle-haltp... |
26 27 28 29 30 31 32 33 34 35 36 37 38 |
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", |
732144082 cpuidle-haltpoll:... |
39 |
.governor = "haltpoll", |
fa86ee90e add cpuidle-haltp... |
40 41 42 43 44 45 46 47 48 49 50 51 52 53 |
.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, }; |
97d3eb9da cpuidle-haltpoll:... |
54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 |
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! ", 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; } |
4902f7fcb cpuidle-haltpoll:... |
94 |
static bool haltpoll_want(void) |
dd52551fb cpuidle: haltpoll... |
95 96 97 |
{ return kvm_para_has_hint(KVM_HINTS_REALTIME) || force; } |
fa86ee90e add cpuidle-haltp... |
98 99 |
static int __init haltpoll_init(void) { |
a1c4423b0 cpuidle-haltpoll:... |
100 |
int ret; |
fa86ee90e add cpuidle-haltp... |
101 |
struct cpuidle_driver *drv = &haltpoll_driver; |
31d851407 cpuidle: haltpoll... |
102 103 104 |
/* Do not load haltpoll if idle= is passed */ if (boot_option_idle_override != IDLE_NO_OVERRIDE) return -ENODEV; |
fa86ee90e add cpuidle-haltp... |
105 |
cpuidle_poll_state_init(drv); |
4902f7fcb cpuidle-haltpoll:... |
106 |
if (!kvm_para_available() || !haltpoll_want()) |
5cc59f597 cpuidle-haltpoll:... |
107 |
return -ENODEV; |
fa86ee90e add cpuidle-haltp... |
108 |
|
97d3eb9da cpuidle-haltpoll:... |
109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 |
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; } |
a1c4423b0 cpuidle-haltpoll:... |
127 128 |
return ret; |
fa86ee90e add cpuidle-haltp... |
129 130 131 132 |
} static void __exit haltpoll_exit(void) { |
97d3eb9da cpuidle-haltpoll:... |
133 |
haltpoll_uninit(); |
fa86ee90e add cpuidle-haltp... |
134 135 136 137 138 139 |
} module_init(haltpoll_init); module_exit(haltpoll_exit); MODULE_LICENSE("GPL"); MODULE_AUTHOR("Marcelo Tosatti <mtosatti@redhat.com>"); |