aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/kernel/time.c
diff options
context:
space:
mode:
authorMilton Miller <miltonm@bga.com>2007-12-13 23:52:20 -0500
committerPaul Mackerras <paulus@samba.org>2007-12-20 00:15:46 -0500
commit53024fe250a0f044b114844a01456902bce40ade (patch)
treedd4b4c6165523bbb20767a192bc01681e370e009 /arch/powerpc/kernel/time.c
parentdb3801a858e97adee0f3b4c732e6ff325d95e0a5 (diff)
[POWERPC] Optimize account_system_vtime
We have multiple calls to has_feature being inlined, but gcc can't be sure that the store via get_paca() doesn't alias the path to cur_cpu_spec->feature. Reorder to put the calls to read_purr and read_spurr adjacent to each other. To add a sense of consistency, reorder the remaining lines to perform parallel steps on purr and scaled purr of each line instead of calculating and then using one value before going on to the next. In addition, we can tell gcc that no SPURR means no PURR. The test is completely hidden in the PURR case, and in the !PURR case the second test is eliminated resulting in the simple register copy in the out-of-line branch. Further, gcc sees get_paca()->system_time referenced several times and allocates a register to address it (shadowing r13) instead of caching its value. Reading into a local varable saves the shadow of r13 and removes a potentially duplicate load (between the nested if and its parent). Signed-off-by: Milton Miller <miltonm@bga.com> Signed-off-by: Paul Mackerras <paulus@samba.org>
Diffstat (limited to 'arch/powerpc/kernel/time.c')
-rw-r--r--arch/powerpc/kernel/time.c21
1 files changed, 13 insertions, 8 deletions
diff --git a/arch/powerpc/kernel/time.c b/arch/powerpc/kernel/time.c
index 398cd0c7b60f..85cf317c9069 100644
--- a/arch/powerpc/kernel/time.c
+++ b/arch/powerpc/kernel/time.c
@@ -219,7 +219,11 @@ static u64 read_purr(void)
219 */ 219 */
220static u64 read_spurr(u64 purr) 220static u64 read_spurr(u64 purr)
221{ 221{
222 if (cpu_has_feature(CPU_FTR_SPURR)) 222 /*
223 * cpus without PURR won't have a SPURR
224 * We already know the former when we use this, so tell gcc
225 */
226 if (cpu_has_feature(CPU_FTR_PURR) && cpu_has_feature(CPU_FTR_SPURR))
223 return mfspr(SPRN_SPURR); 227 return mfspr(SPRN_SPURR);
224 return purr; 228 return purr;
225} 229}
@@ -230,29 +234,30 @@ static u64 read_spurr(u64 purr)
230 */ 234 */
231void account_system_vtime(struct task_struct *tsk) 235void account_system_vtime(struct task_struct *tsk)
232{ 236{
233 u64 now, nowscaled, delta, deltascaled; 237 u64 now, nowscaled, delta, deltascaled, sys_time;
234 unsigned long flags; 238 unsigned long flags;
235 239
236 local_irq_save(flags); 240 local_irq_save(flags);
237 now = read_purr(); 241 now = read_purr();
238 delta = now - get_paca()->startpurr;
239 get_paca()->startpurr = now;
240 nowscaled = read_spurr(now); 242 nowscaled = read_spurr(now);
243 delta = now - get_paca()->startpurr;
241 deltascaled = nowscaled - get_paca()->startspurr; 244 deltascaled = nowscaled - get_paca()->startspurr;
245 get_paca()->startpurr = now;
242 get_paca()->startspurr = nowscaled; 246 get_paca()->startspurr = nowscaled;
243 if (!in_interrupt()) { 247 if (!in_interrupt()) {
244 /* deltascaled includes both user and system time. 248 /* deltascaled includes both user and system time.
245 * Hence scale it based on the purr ratio to estimate 249 * Hence scale it based on the purr ratio to estimate
246 * the system time */ 250 * the system time */
251 sys_time = get_paca()->system_time;
247 if (get_paca()->user_time) 252 if (get_paca()->user_time)
248 deltascaled = deltascaled * get_paca()->system_time / 253 deltascaled = deltascaled * sys_time /
249 (get_paca()->system_time + get_paca()->user_time); 254 (sys_time + get_paca()->user_time);
250 delta += get_paca()->system_time; 255 delta += sys_time;
251 get_paca()->system_time = 0; 256 get_paca()->system_time = 0;
252 } 257 }
253 account_system_time(tsk, 0, delta); 258 account_system_time(tsk, 0, delta);
254 get_paca()->purrdelta = delta;
255 account_system_time_scaled(tsk, deltascaled); 259 account_system_time_scaled(tsk, deltascaled);
260 get_paca()->purrdelta = delta;
256 get_paca()->spurrdelta = deltascaled; 261 get_paca()->spurrdelta = deltascaled;
257 local_irq_restore(flags); 262 local_irq_restore(flags);
258} 263}