aboutsummaryrefslogtreecommitdiffstats
path: root/arch/s390/kernel/vtime.c
diff options
context:
space:
mode:
authorMartin Schwidefsky <schwidefsky@de.ibm.com>2008-12-31 09:11:39 -0500
committerMartin Schwidefsky <schwidefsky@de.ibm.com>2008-12-31 09:11:47 -0500
commitaa5e97ce4bbc9d5daeec16b1d15bb3f6b7b4f4d4 (patch)
tree6bf29daaaca165108bcafa68105d18e64ef01ea2 /arch/s390/kernel/vtime.c
parent79741dd35713ff4f6fd0eafd59fa94e8a4ba922d (diff)
[PATCH] improve precision of process accounting.
The unit of the cputime accouting values that are stored per process is currently a microsecond. The CPU timer has a maximum granularity of 2**-12 microseconds. There is no benefit in storing the per process values in the lesser precision and there is the disadvantage that the backend has to do the rounding to microseconds. The better solution is to use the maximum granularity of the CPU timer as cputime unit. Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
Diffstat (limited to 'arch/s390/kernel/vtime.c')
-rw-r--r--arch/s390/kernel/vtime.c93
1 files changed, 40 insertions, 53 deletions
diff --git a/arch/s390/kernel/vtime.c b/arch/s390/kernel/vtime.c
index 4a4a34caec55..1254a4d0d762 100644
--- a/arch/s390/kernel/vtime.c
+++ b/arch/s390/kernel/vtime.c
@@ -31,11 +31,10 @@ static DEFINE_PER_CPU(struct vtimer_queue, virt_cpu_timer);
31 * Update process times based on virtual cpu times stored by entry.S 31 * Update process times based on virtual cpu times stored by entry.S
32 * to the lowcore fields user_timer, system_timer & steal_clock. 32 * to the lowcore fields user_timer, system_timer & steal_clock.
33 */ 33 */
34void account_process_tick(struct task_struct *tsk, int user_tick) 34static void do_account_vtime(struct task_struct *tsk, int hardirq_offset)
35{ 35{
36 cputime_t cputime; 36 struct thread_info *ti = task_thread_info(tsk);
37 __u64 timer, clock; 37 __u64 timer, clock, user, system, steal;
38 int rcu_user_flag;
39 38
40 timer = S390_lowcore.last_update_timer; 39 timer = S390_lowcore.last_update_timer;
41 clock = S390_lowcore.last_update_clock; 40 clock = S390_lowcore.last_update_clock;
@@ -44,59 +43,47 @@ void account_process_tick(struct task_struct *tsk, int user_tick)
44 : "=m" (S390_lowcore.last_update_timer), 43 : "=m" (S390_lowcore.last_update_timer),
45 "=m" (S390_lowcore.last_update_clock) ); 44 "=m" (S390_lowcore.last_update_clock) );
46 S390_lowcore.system_timer += timer - S390_lowcore.last_update_timer; 45 S390_lowcore.system_timer += timer - S390_lowcore.last_update_timer;
47 S390_lowcore.steal_clock += S390_lowcore.last_update_clock - clock; 46 S390_lowcore.steal_timer += S390_lowcore.last_update_clock - clock;
48 47
49 cputime = S390_lowcore.user_timer >> 12; 48 user = S390_lowcore.user_timer - ti->user_timer;
50 rcu_user_flag = cputime != 0; 49 S390_lowcore.steal_timer -= user;
51 S390_lowcore.user_timer -= cputime << 12; 50 ti->user_timer = S390_lowcore.user_timer;
52 S390_lowcore.steal_clock -= cputime << 12; 51 account_user_time(tsk, user, user);
53 account_user_time(tsk, cputime, cputime);
54 52
55 cputime = S390_lowcore.system_timer >> 12; 53 system = S390_lowcore.system_timer - ti->system_timer;
56 S390_lowcore.system_timer -= cputime << 12; 54 S390_lowcore.steal_timer -= system;
57 S390_lowcore.steal_clock -= cputime << 12; 55 ti->system_timer = S390_lowcore.system_timer;
58 if (idle_task(smp_processor_id()) != current) 56 if (idle_task(smp_processor_id()) != current)
59 account_system_time(tsk, HARDIRQ_OFFSET, cputime, cputime); 57 account_system_time(tsk, hardirq_offset, system, system);
60 else 58 else
61 account_idle_time(cputime); 59 account_idle_time(system);
62 60
63 cputime = S390_lowcore.steal_clock; 61 steal = S390_lowcore.steal_timer;
64 if ((__s64) cputime > 0) { 62 if ((s64) steal > 0) {
65 cputime >>= 12; 63 S390_lowcore.steal_timer = 0;
66 S390_lowcore.steal_clock -= cputime << 12;
67 if (idle_task(smp_processor_id()) != current) 64 if (idle_task(smp_processor_id()) != current)
68 account_steal_time(cputime); 65 account_steal_time(steal);
69 else 66 else
70 account_idle_time(cputime); 67 account_idle_time(steal);
71 } 68 }
72} 69}
73 70
74/* 71void account_vtime(struct task_struct *prev, struct task_struct *next)
75 * Update process times based on virtual cpu times stored by entry.S
76 * to the lowcore fields user_timer, system_timer & steal_clock.
77 */
78void account_vtime(struct task_struct *tsk)
79{ 72{
80 cputime_t cputime; 73 struct thread_info *ti;
81 __u64 timer; 74
82 75 do_account_vtime(prev, 0);
83 timer = S390_lowcore.last_update_timer; 76 ti = task_thread_info(prev);
84 asm volatile (" STPT %0" /* Store current cpu timer value */ 77 ti->user_timer = S390_lowcore.user_timer;
85 : "=m" (S390_lowcore.last_update_timer) ); 78 ti->system_timer = S390_lowcore.system_timer;
86 S390_lowcore.system_timer += timer - S390_lowcore.last_update_timer; 79 ti = task_thread_info(next);
87 80 S390_lowcore.user_timer = ti->user_timer;
88 cputime = S390_lowcore.user_timer >> 12; 81 S390_lowcore.system_timer = ti->system_timer;
89 S390_lowcore.user_timer -= cputime << 12; 82}
90 S390_lowcore.steal_clock -= cputime << 12;
91 account_user_time(tsk, cputime, cputime);
92 83
93 cputime = S390_lowcore.system_timer >> 12; 84void account_process_tick(struct task_struct *tsk, int user_tick)
94 S390_lowcore.system_timer -= cputime << 12; 85{
95 S390_lowcore.steal_clock -= cputime << 12; 86 do_account_vtime(tsk, HARDIRQ_OFFSET);
96 if (idle_task(smp_processor_id()) != current)
97 account_system_time(tsk, 0, cputime, cputime);
98 else
99 account_idle_time(cputime);
100} 87}
101 88
102/* 89/*
@@ -105,21 +92,21 @@ void account_vtime(struct task_struct *tsk)
105 */ 92 */
106void account_system_vtime(struct task_struct *tsk) 93void account_system_vtime(struct task_struct *tsk)
107{ 94{
108 cputime_t cputime; 95 struct thread_info *ti = task_thread_info(tsk);
109 __u64 timer; 96 __u64 timer, system;
110 97
111 timer = S390_lowcore.last_update_timer; 98 timer = S390_lowcore.last_update_timer;
112 asm volatile (" STPT %0" /* Store current cpu timer value */ 99 asm volatile (" STPT %0" /* Store current cpu timer value */
113 : "=m" (S390_lowcore.last_update_timer) ); 100 : "=m" (S390_lowcore.last_update_timer) );
114 S390_lowcore.system_timer += timer - S390_lowcore.last_update_timer; 101 S390_lowcore.system_timer += timer - S390_lowcore.last_update_timer;
115 102
116 cputime = S390_lowcore.system_timer >> 12; 103 system = S390_lowcore.system_timer - ti->system_timer;
117 S390_lowcore.system_timer -= cputime << 12; 104 S390_lowcore.steal_timer -= system;
118 S390_lowcore.steal_clock -= cputime << 12; 105 ti->system_timer = S390_lowcore.system_timer;
119 if (in_irq() || idle_task(smp_processor_id()) != current) 106 if (in_irq() || idle_task(smp_processor_id()) != current)
120 account_system_time(tsk, 0, cputime, cputime); 107 account_system_time(tsk, 0, system, system);
121 else 108 else
122 account_idle_time(cputime); 109 account_idle_time(system);
123} 110}
124EXPORT_SYMBOL_GPL(account_system_vtime); 111EXPORT_SYMBOL_GPL(account_system_vtime);
125 112
@@ -490,8 +477,8 @@ void init_cpu_vtimer(void)
490 /* kick the virtual timer */ 477 /* kick the virtual timer */
491 S390_lowcore.exit_timer = VTIMER_MAX_SLICE; 478 S390_lowcore.exit_timer = VTIMER_MAX_SLICE;
492 S390_lowcore.last_update_timer = VTIMER_MAX_SLICE; 479 S390_lowcore.last_update_timer = VTIMER_MAX_SLICE;
493 asm volatile ("SPT %0" : : "m" (S390_lowcore.last_update_timer));
494 asm volatile ("STCK %0" : "=m" (S390_lowcore.last_update_clock)); 480 asm volatile ("STCK %0" : "=m" (S390_lowcore.last_update_clock));
481 asm volatile ("SPT %0" : : "m" (S390_lowcore.last_update_timer));
495 482
496 /* enable cpu timer interrupts */ 483 /* enable cpu timer interrupts */
497 __ctl_set_bit(0,10); 484 __ctl_set_bit(0,10);