11 #include <linux/export.h>
12 #include <linux/kernel.h>
13 #include <linux/timex.h>
14 #include <linux/types.h>
15 #include <linux/time.h>
19 #include <asm/irq_regs.h>
20 #include <asm/cputime.h>
25 static void virt_timer_expire(
void);
34 static inline u64 get_vtimer(
void)
38 asm volatile(
"stpt %0" :
"=m" (
timer));
42 static inline void set_vtimer(
u64 expires)
49 :
"=m" (
timer) :
"m" (expires));
54 static inline int virt_timer_forward(
u64 elapsed)
58 if (list_empty(&virt_timer_list))
68 static int do_account_vtime(
struct task_struct *tsk,
int hardirq_offset)
94 if ((
s64) steal > 0) {
99 return virt_timer_forward(user + system);
106 do_account_vtime(prev, 0);
139 virt_timer_forward(system);
147 unsigned long psw_mask;
179 unsigned long long now, idle_enter, idle_exit;
187 }
while ((sequence & 1) || (idle->
sequence != sequence));
188 return idle_enter ? ((idle_exit ?: now) - idle_enter) : 0;
211 static void virt_timer_expire(
void)
214 unsigned long elapsed;
218 spin_lock(&virt_timer_lock);
223 list_move_tail(&timer->
entry, &cb_list);
227 if (!list_empty(&virt_timer_list)) {
233 spin_unlock(&virt_timer_lock);
237 list_del_init(&timer->
entry);
243 spin_lock(&virt_timer_lock);
244 list_add_sorted(timer, &virt_timer_list);
245 spin_unlock(&virt_timer_lock);
253 INIT_LIST_HEAD(&timer->
entry);
257 static inline int vtimer_pending(
struct vtimer_list *timer)
259 return !list_empty(&timer->
entry);
262 static void internal_add_vtimer(
struct vtimer_list *timer)
264 if (list_empty(&virt_timer_list)) {
268 list_add(&timer->
entry, &virt_timer_list);
277 list_add_sorted(timer, &virt_timer_list);
281 static void __add_vtimer(
struct vtimer_list *timer,
int periodic)
287 internal_add_vtimer(timer);
288 spin_unlock_irqrestore(&virt_timer_lock, flags);
296 __add_vtimer(timer, 0);
305 __add_vtimer(timer, 1);
309 static int __mod_vtimer(
struct vtimer_list *timer,
u64 expires,
int periodic)
316 if (timer->
expires == expires && vtimer_pending(timer))
319 rc = vtimer_pending(timer);
321 list_del_init(&timer->
entry);
322 timer->
interval = periodic ? expires : 0;
324 internal_add_vtimer(timer);
325 spin_unlock_irqrestore(&virt_timer_lock, flags);
334 return __mod_vtimer(timer, expires, 0);
343 return __mod_vtimer(timer, expires, 1);
356 if (!vtimer_pending(timer))
359 list_del_init(&timer->
entry);
360 spin_unlock_irqrestore(&virt_timer_lock, flags);
375 unsigned long action,
void *hcpu)
380 idle = &
per_cpu(s390_idle, cpu);