1717#include <asm/vtimer.h>
1818#include <asm/vtime.h>
1919#include <asm/cpu_mf.h>
20+ #include <asm/idle.h>
2021#include <asm/smp.h>
2122
2223#include "entry.h"
@@ -111,6 +112,16 @@ static void account_system_index_scaled(struct task_struct *p, u64 cputime,
111112 account_system_index_time (p , cputime_to_nsecs (cputime ), index );
112113}
113114
115+ static inline void vtime_reset_last_update (struct lowcore * lc )
116+ {
117+ asm volatile (
118+ " stpt %0\n" /* Store current cpu timer value */
119+ " stckf %1" /* Store current tod clock value */
120+ : "=Q" (lc -> last_update_timer ),
121+ "=Q" (lc -> last_update_clock )
122+ : : "cc" );
123+ }
124+
114125/*
115126 * Update process times based on virtual cpu times stored by entry.S
116127 * to the lowcore fields user_timer, system_timer & steal_clock.
@@ -122,12 +133,9 @@ static int do_account_vtime(struct task_struct *tsk)
122133
123134 timer = lc -> last_update_timer ;
124135 clock = lc -> last_update_clock ;
125- asm volatile (
126- " stpt %0\n" /* Store current cpu timer value */
127- " stckf %1" /* Store current tod clock value */
128- : "=Q" (lc -> last_update_timer ),
129- "=Q" (lc -> last_update_clock )
130- : : "cc" );
136+
137+ vtime_reset_last_update (lc );
138+
131139 clock = lc -> last_update_clock - clock ;
132140 timer -= lc -> last_update_timer ;
133141
@@ -261,6 +269,43 @@ void vtime_account_hardirq(struct task_struct *tsk)
261269 virt_timer_forward (delta );
262270}
263271
272+ #ifdef CONFIG_NO_HZ_COMMON
273+ /**
274+ * vtime_reset - Fast forward vtime entry clocks
275+ *
276+ * Called from dynticks idle IRQ entry to fast-forward the clocks to current time
277+ * so that the IRQ time is still accounted by vtime while nohz cputime is paused.
278+ */
279+ void vtime_reset (void )
280+ {
281+ vtime_reset_last_update (get_lowcore ());
282+ }
283+
284+ /**
285+ * vtime_dyntick_start - Inform vtime about entry to idle-dynticks
286+ *
287+ * Called when idle enters in dyntick mode. The idle cputime that elapsed so far
288+ * is flushed and the tick subsystem takes over the idle cputime accounting.
289+ */
290+ void vtime_dyntick_start (void )
291+ {
292+ __this_cpu_write (s390_idle .idle_dyntick , true);
293+ vtime_flush (current );
294+ }
295+
296+ /**
297+ * vtime_dyntick_stop - Inform vtime about exit from idle-dynticks
298+ *
299+ * Called when idle exits from dyntick mode. The vtime entry clocks are
300+ * fast-forward to current time and idle accounting resumes.
301+ */
302+ void vtime_dyntick_stop (void )
303+ {
304+ vtime_reset_last_update (get_lowcore ());
305+ __this_cpu_write (s390_idle .idle_dyntick , false);
306+ }
307+ #endif /* CONFIG_NO_HZ_COMMON */
308+
264309/*
265310 * Sorted add to a list. List is linear searched until first bigger
266311 * element is found.
0 commit comments