2
0

cpu-timers.c 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274
  1. /*
  2. * QEMU System Emulator
  3. *
  4. * Copyright (c) 2003-2008 Fabrice Bellard
  5. *
  6. * Permission is hereby granted, free of charge, to any person obtaining a copy
  7. * of this software and associated documentation files (the "Software"), to deal
  8. * in the Software without restriction, including without limitation the rights
  9. * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  10. * copies of the Software, and to permit persons to whom the Software is
  11. * furnished to do so, subject to the following conditions:
  12. *
  13. * The above copyright notice and this permission notice shall be included in
  14. * all copies or substantial portions of the Software.
  15. *
  16. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  17. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  18. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
  19. * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  20. * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  21. * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  22. * THE SOFTWARE.
  23. */
  24. #include "qemu/osdep.h"
  25. #include "qemu/cutils.h"
  26. #include "migration/vmstate.h"
  27. #include "qapi/error.h"
  28. #include "qemu/error-report.h"
  29. #include "system/cpus.h"
  30. #include "qemu/main-loop.h"
  31. #include "qemu/option.h"
  32. #include "qemu/seqlock.h"
  33. #include "system/replay.h"
  34. #include "system/runstate.h"
  35. #include "hw/core/cpu.h"
  36. #include "system/cpu-timers.h"
  37. #include "system/cpu-timers-internal.h"
  38. /* clock and ticks */
  39. static int64_t cpu_get_ticks_locked(void)
  40. {
  41. int64_t ticks = timers_state.cpu_ticks_offset;
  42. if (timers_state.cpu_ticks_enabled) {
  43. ticks += cpu_get_host_ticks();
  44. }
  45. if (timers_state.cpu_ticks_prev > ticks) {
  46. /* Non increasing ticks may happen if the host uses software suspend. */
  47. timers_state.cpu_ticks_offset += timers_state.cpu_ticks_prev - ticks;
  48. ticks = timers_state.cpu_ticks_prev;
  49. }
  50. timers_state.cpu_ticks_prev = ticks;
  51. return ticks;
  52. }
  53. /*
  54. * return the time elapsed in VM between vm_start and vm_stop.
  55. * cpu_get_ticks() uses units of the host CPU cycle counter.
  56. */
  57. int64_t cpu_get_ticks(void)
  58. {
  59. int64_t ticks;
  60. qemu_spin_lock(&timers_state.vm_clock_lock);
  61. ticks = cpu_get_ticks_locked();
  62. qemu_spin_unlock(&timers_state.vm_clock_lock);
  63. return ticks;
  64. }
  65. int64_t cpu_get_clock_locked(void)
  66. {
  67. int64_t time;
  68. time = timers_state.cpu_clock_offset;
  69. if (timers_state.cpu_ticks_enabled) {
  70. time += get_clock();
  71. }
  72. return time;
  73. }
  74. /*
  75. * Return the monotonic time elapsed in VM, i.e.,
  76. * the time between vm_start and vm_stop
  77. */
  78. int64_t cpu_get_clock(void)
  79. {
  80. int64_t ti;
  81. unsigned start;
  82. do {
  83. start = seqlock_read_begin(&timers_state.vm_clock_seqlock);
  84. ti = cpu_get_clock_locked();
  85. } while (seqlock_read_retry(&timers_state.vm_clock_seqlock, start));
  86. return ti;
  87. }
  88. /*
  89. * enable cpu_get_ticks()
  90. * Caller must hold BQL which serves as mutex for vm_clock_seqlock.
  91. */
  92. void cpu_enable_ticks(void)
  93. {
  94. seqlock_write_lock(&timers_state.vm_clock_seqlock,
  95. &timers_state.vm_clock_lock);
  96. if (!timers_state.cpu_ticks_enabled) {
  97. timers_state.cpu_ticks_offset -= cpu_get_host_ticks();
  98. timers_state.cpu_clock_offset -= get_clock();
  99. timers_state.cpu_ticks_enabled = 1;
  100. }
  101. seqlock_write_unlock(&timers_state.vm_clock_seqlock,
  102. &timers_state.vm_clock_lock);
  103. }
  104. /*
  105. * disable cpu_get_ticks() : the clock is stopped. You must not call
  106. * cpu_get_ticks() after that.
  107. * Caller must hold BQL which serves as mutex for vm_clock_seqlock.
  108. */
  109. void cpu_disable_ticks(void)
  110. {
  111. seqlock_write_lock(&timers_state.vm_clock_seqlock,
  112. &timers_state.vm_clock_lock);
  113. if (timers_state.cpu_ticks_enabled) {
  114. timers_state.cpu_ticks_offset += cpu_get_host_ticks();
  115. timers_state.cpu_clock_offset = cpu_get_clock_locked();
  116. timers_state.cpu_ticks_enabled = 0;
  117. }
  118. seqlock_write_unlock(&timers_state.vm_clock_seqlock,
  119. &timers_state.vm_clock_lock);
  120. }
  121. static bool icount_state_needed(void *opaque)
  122. {
  123. return icount_enabled();
  124. }
  125. static bool warp_timer_state_needed(void *opaque)
  126. {
  127. TimersState *s = opaque;
  128. return s->icount_warp_timer != NULL;
  129. }
  130. static bool adjust_timers_state_needed(void *opaque)
  131. {
  132. TimersState *s = opaque;
  133. return s->icount_rt_timer != NULL;
  134. }
  135. static bool icount_shift_state_needed(void *opaque)
  136. {
  137. return icount_enabled() == ICOUNT_ADAPTATIVE;
  138. }
  139. /*
  140. * Subsection for warp timer migration is optional, because may not be created
  141. */
  142. static const VMStateDescription icount_vmstate_warp_timer = {
  143. .name = "timer/icount/warp_timer",
  144. .version_id = 1,
  145. .minimum_version_id = 1,
  146. .needed = warp_timer_state_needed,
  147. .fields = (const VMStateField[]) {
  148. VMSTATE_INT64(vm_clock_warp_start, TimersState),
  149. VMSTATE_TIMER_PTR(icount_warp_timer, TimersState),
  150. VMSTATE_END_OF_LIST()
  151. }
  152. };
  153. static const VMStateDescription icount_vmstate_adjust_timers = {
  154. .name = "timer/icount/timers",
  155. .version_id = 1,
  156. .minimum_version_id = 1,
  157. .needed = adjust_timers_state_needed,
  158. .fields = (const VMStateField[]) {
  159. VMSTATE_TIMER_PTR(icount_rt_timer, TimersState),
  160. VMSTATE_TIMER_PTR(icount_vm_timer, TimersState),
  161. VMSTATE_END_OF_LIST()
  162. }
  163. };
  164. static const VMStateDescription icount_vmstate_shift = {
  165. .name = "timer/icount/shift",
  166. .version_id = 2,
  167. .minimum_version_id = 2,
  168. .needed = icount_shift_state_needed,
  169. .fields = (const VMStateField[]) {
  170. VMSTATE_INT16(icount_time_shift, TimersState),
  171. VMSTATE_INT64(last_delta, TimersState),
  172. VMSTATE_END_OF_LIST()
  173. }
  174. };
  175. /*
  176. * This is a subsection for icount migration.
  177. */
  178. static const VMStateDescription icount_vmstate_timers = {
  179. .name = "timer/icount",
  180. .version_id = 1,
  181. .minimum_version_id = 1,
  182. .needed = icount_state_needed,
  183. .fields = (const VMStateField[]) {
  184. VMSTATE_INT64(qemu_icount_bias, TimersState),
  185. VMSTATE_INT64(qemu_icount, TimersState),
  186. VMSTATE_END_OF_LIST()
  187. },
  188. .subsections = (const VMStateDescription * const []) {
  189. &icount_vmstate_warp_timer,
  190. &icount_vmstate_adjust_timers,
  191. &icount_vmstate_shift,
  192. NULL
  193. }
  194. };
  195. static const VMStateDescription vmstate_timers = {
  196. .name = "timer",
  197. .version_id = 2,
  198. .minimum_version_id = 1,
  199. .fields = (const VMStateField[]) {
  200. VMSTATE_INT64(cpu_ticks_offset, TimersState),
  201. VMSTATE_UNUSED(8),
  202. VMSTATE_INT64_V(cpu_clock_offset, TimersState, 2),
  203. VMSTATE_END_OF_LIST()
  204. },
  205. .subsections = (const VMStateDescription * const []) {
  206. &icount_vmstate_timers,
  207. NULL
  208. }
  209. };
  210. static void do_nothing(CPUState *cpu, run_on_cpu_data unused)
  211. {
  212. }
  213. void qemu_timer_notify_cb(void *opaque, QEMUClockType type)
  214. {
  215. if (!icount_enabled() || type != QEMU_CLOCK_VIRTUAL) {
  216. qemu_notify_event();
  217. return;
  218. }
  219. if (qemu_in_vcpu_thread()) {
  220. /*
  221. * A CPU is currently running; kick it back out to the
  222. * tcg_cpu_exec() loop so it will recalculate its
  223. * icount deadline immediately.
  224. */
  225. qemu_cpu_kick(current_cpu);
  226. } else if (first_cpu) {
  227. /*
  228. * qemu_cpu_kick is not enough to kick a halted CPU out of
  229. * qemu_tcg_wait_io_event. async_run_on_cpu, instead,
  230. * causes cpu_thread_is_idle to return false. This way,
  231. * handle_icount_deadline can run.
  232. * If we have no CPUs at all for some reason, we don't
  233. * need to do anything.
  234. */
  235. async_run_on_cpu(first_cpu, do_nothing, RUN_ON_CPU_NULL);
  236. }
  237. }
  238. TimersState timers_state;
  239. /* initialize timers state and the cpu throttle for convenience */
  240. void cpu_timers_init(void)
  241. {
  242. seqlock_init(&timers_state.vm_clock_seqlock);
  243. qemu_spin_init(&timers_state.vm_clock_lock);
  244. vmstate_register(NULL, 0, &vmstate_timers, &timers_state);
  245. }