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"
@@ -110,6 +111,16 @@ static void account_system_index_scaled(struct task_struct *p, u64 cputime,
110111 account_system_index_time (p , cputime_to_nsecs (cputime ), index );
111112}
112113
114+ static inline void vtime_reset_last_update (struct lowcore * lc )
115+ {
116+ asm volatile (
117+ " stpt %0\n" /* Store current cpu timer value */
118+ " stckf %1" /* Store current tod clock value */
119+ : "=Q" (lc -> last_update_timer ),
120+ "=Q" (lc -> last_update_clock )
121+ : : "cc" );
122+ }
123+
113124/*
114125 * Update process times based on virtual cpu times stored by entry.S
115126 * to the lowcore fields user_timer, system_timer & steal_clock.
@@ -121,12 +132,9 @@ static int do_account_vtime(struct task_struct *tsk)
121132
122133 timer = lc -> last_update_timer ;
123134 clock = lc -> last_update_clock ;
124- asm volatile (
125- " stpt %0\n" /* Store current cpu timer value */
126- " stckf %1" /* Store current tod clock value */
127- : "=Q" (lc -> last_update_timer ),
128- "=Q" (lc -> last_update_clock )
129- : : "cc" );
135+
136+ vtime_reset_last_update (lc );
137+
130138 clock = lc -> last_update_clock - clock ;
131139 timer -= lc -> last_update_timer ;
132140
@@ -239,6 +247,43 @@ void vtime_account_hardirq(struct task_struct *tsk)
239247 get_lowcore ()-> hardirq_timer += vtime_delta ();
240248}
241249
250+ #ifdef CONFIG_NO_HZ_COMMON
251+ /**
252+ * vtime_reset - Fast forward vtime entry clocks
253+ *
254+ * Called from dynticks idle IRQ entry to fast-forward the clocks to current time
255+ * so that the IRQ time is still accounted by vtime while nohz cputime is paused.
256+ */
257+ void vtime_reset (void )
258+ {
259+ vtime_reset_last_update (get_lowcore ());
260+ }
261+
262+ /**
263+ * vtime_dyntick_start - Inform vtime about entry to idle-dynticks
264+ *
265+ * Called when idle enters in dyntick mode. The idle cputime that elapsed so far
266+ * is flushed and the tick subsystem takes over the idle cputime accounting.
267+ */
268+ void vtime_dyntick_start (void )
269+ {
270+ __this_cpu_write (s390_idle .idle_dyntick , true);
271+ vtime_flush (current );
272+ }
273+
274+ /**
275+ * vtime_dyntick_stop - Inform vtime about exit from idle-dynticks
276+ *
277+ * Called when idle exits from dyntick mode. The vtime entry clocks are
278+ * fast-forward to current time and idle accounting resumes.
279+ */
280+ void vtime_dyntick_stop (void )
281+ {
282+ vtime_reset_last_update (get_lowcore ());
283+ __this_cpu_write (s390_idle .idle_dyntick , false);
284+ }
285+ #endif /* CONFIG_NO_HZ_COMMON */
286+
242287/*
243288 * Sorted add to a list. List is linear searched until first bigger
244289 * element is found.
0 commit comments