cpuidle-haltpoll.c (a1c4423b02b2121108e3ea9580741e0f26309a48) | cpuidle-haltpoll.c (97d3eb9da84cae0548359b0aecb8619faad003b7) |
---|---|
1// SPDX-License-Identifier: GPL-2.0 2/* 3 * cpuidle driver for haltpoll governor. 4 * 5 * Copyright 2019 Red Hat, Inc. and/or its affiliates. 6 * 7 * This work is licensed under the terms of the GNU GPL, version 2. See 8 * the COPYING file in the top-level directory. 9 * 10 * Authors: Marcelo Tosatti <mtosatti@redhat.com> 11 */ 12 13#include <linux/init.h> | 1// SPDX-License-Identifier: GPL-2.0 2/* 3 * cpuidle driver for haltpoll governor. 4 * 5 * Copyright 2019 Red Hat, Inc. and/or its affiliates. 6 * 7 * This work is licensed under the terms of the GNU GPL, version 2. See 8 * the COPYING file in the top-level directory. 9 * 10 * Authors: Marcelo Tosatti <mtosatti@redhat.com> 11 */ 12 13#include <linux/init.h> |
14#include <linux/cpu.h> |
|
14#include <linux/cpuidle.h> 15#include <linux/module.h> 16#include <linux/sched/idle.h> 17#include <linux/kvm_para.h> 18#include <linux/cpuidle_haltpoll.h> 19 | 15#include <linux/cpuidle.h> 16#include <linux/module.h> 17#include <linux/sched/idle.h> 18#include <linux/kvm_para.h> 19#include <linux/cpuidle_haltpoll.h> 20 |
21static struct cpuidle_device __percpu *haltpoll_cpuidle_devices; 22static enum cpuhp_state haltpoll_hp_state; 23 |
|
20static int default_enter_idle(struct cpuidle_device *dev, 21 struct cpuidle_driver *drv, int index) 22{ 23 if (current_clr_polling_and_test()) { 24 local_irq_enable(); 25 return index; 26 } 27 default_idle(); --- 13 unchanged lines hidden (view full) --- 41 .name = "haltpoll idle", 42 .desc = "default architecture idle", 43 }, 44 }, 45 .safe_state_index = 0, 46 .state_count = 2, 47}; 48 | 24static int default_enter_idle(struct cpuidle_device *dev, 25 struct cpuidle_driver *drv, int index) 26{ 27 if (current_clr_polling_and_test()) { 28 local_irq_enable(); 29 return index; 30 } 31 default_idle(); --- 13 unchanged lines hidden (view full) --- 45 .name = "haltpoll idle", 46 .desc = "default architecture idle", 47 }, 48 }, 49 .safe_state_index = 0, 50 .state_count = 2, 51}; 52 |
53static int haltpoll_cpu_online(unsigned int cpu) 54{ 55 struct cpuidle_device *dev; 56 57 dev = per_cpu_ptr(haltpoll_cpuidle_devices, cpu); 58 if (!dev->registered) { 59 dev->cpu = cpu; 60 if (cpuidle_register_device(dev)) { 61 pr_notice("cpuidle_register_device %d failed!\n", cpu); 62 return -EIO; 63 } 64 arch_haltpoll_enable(cpu); 65 } 66 67 return 0; 68} 69 70static int haltpoll_cpu_offline(unsigned int cpu) 71{ 72 struct cpuidle_device *dev; 73 74 dev = per_cpu_ptr(haltpoll_cpuidle_devices, cpu); 75 if (dev->registered) { 76 arch_haltpoll_disable(cpu); 77 cpuidle_unregister_device(dev); 78 } 79 80 return 0; 81} 82 83static void haltpoll_uninit(void) 84{ 85 if (haltpoll_hp_state) 86 cpuhp_remove_state(haltpoll_hp_state); 87 cpuidle_unregister_driver(&haltpoll_driver); 88 89 free_percpu(haltpoll_cpuidle_devices); 90 haltpoll_cpuidle_devices = NULL; 91} 92 |
|
49static int __init haltpoll_init(void) 50{ 51 int ret; 52 struct cpuidle_driver *drv = &haltpoll_driver; 53 54 cpuidle_poll_state_init(drv); 55 56 if (!kvm_para_available()) 57 return 0; 58 | 93static int __init haltpoll_init(void) 94{ 95 int ret; 96 struct cpuidle_driver *drv = &haltpoll_driver; 97 98 cpuidle_poll_state_init(drv); 99 100 if (!kvm_para_available()) 101 return 0; 102 |
59 ret = cpuidle_register(&haltpoll_driver, NULL); 60 if (ret == 0) 61 arch_haltpoll_enable(); | 103 ret = cpuidle_register_driver(drv); 104 if (ret < 0) 105 return ret; |
62 | 106 |
107 haltpoll_cpuidle_devices = alloc_percpu(struct cpuidle_device); 108 if (haltpoll_cpuidle_devices == NULL) { 109 cpuidle_unregister_driver(drv); 110 return -ENOMEM; 111 } 112 113 ret = cpuhp_setup_state(CPUHP_AP_ONLINE_DYN, "cpuidle/haltpoll:online", 114 haltpoll_cpu_online, haltpoll_cpu_offline); 115 if (ret < 0) { 116 haltpoll_uninit(); 117 } else { 118 haltpoll_hp_state = ret; 119 ret = 0; 120 } 121 |
|
63 return ret; 64} 65 66static void __exit haltpoll_exit(void) 67{ | 122 return ret; 123} 124 125static void __exit haltpoll_exit(void) 126{ |
68 arch_haltpoll_disable(); 69 cpuidle_unregister(&haltpoll_driver); | 127 haltpoll_uninit(); |
70} 71 72module_init(haltpoll_init); 73module_exit(haltpoll_exit); 74MODULE_LICENSE("GPL"); 75MODULE_AUTHOR("Marcelo Tosatti <mtosatti@redhat.com>"); | 128} 129 130module_init(haltpoll_init); 131module_exit(haltpoll_exit); 132MODULE_LICENSE("GPL"); 133MODULE_AUTHOR("Marcelo Tosatti <mtosatti@redhat.com>"); |