[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>
This commit is contained in:
Родитель
db3801a858
Коммит
53024fe250
|
@ -219,7 +219,11 @@ static u64 read_purr(void)
|
||||||
*/
|
*/
|
||||||
static u64 read_spurr(u64 purr)
|
static u64 read_spurr(u64 purr)
|
||||||
{
|
{
|
||||||
if (cpu_has_feature(CPU_FTR_SPURR))
|
/*
|
||||||
|
* cpus without PURR won't have a SPURR
|
||||||
|
* We already know the former when we use this, so tell gcc
|
||||||
|
*/
|
||||||
|
if (cpu_has_feature(CPU_FTR_PURR) && cpu_has_feature(CPU_FTR_SPURR))
|
||||||
return mfspr(SPRN_SPURR);
|
return mfspr(SPRN_SPURR);
|
||||||
return purr;
|
return purr;
|
||||||
}
|
}
|
||||||
|
@ -230,29 +234,30 @@ static u64 read_spurr(u64 purr)
|
||||||
*/
|
*/
|
||||||
void account_system_vtime(struct task_struct *tsk)
|
void account_system_vtime(struct task_struct *tsk)
|
||||||
{
|
{
|
||||||
u64 now, nowscaled, delta, deltascaled;
|
u64 now, nowscaled, delta, deltascaled, sys_time;
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
|
|
||||||
local_irq_save(flags);
|
local_irq_save(flags);
|
||||||
now = read_purr();
|
now = read_purr();
|
||||||
delta = now - get_paca()->startpurr;
|
|
||||||
get_paca()->startpurr = now;
|
|
||||||
nowscaled = read_spurr(now);
|
nowscaled = read_spurr(now);
|
||||||
|
delta = now - get_paca()->startpurr;
|
||||||
deltascaled = nowscaled - get_paca()->startspurr;
|
deltascaled = nowscaled - get_paca()->startspurr;
|
||||||
|
get_paca()->startpurr = now;
|
||||||
get_paca()->startspurr = nowscaled;
|
get_paca()->startspurr = nowscaled;
|
||||||
if (!in_interrupt()) {
|
if (!in_interrupt()) {
|
||||||
/* deltascaled includes both user and system time.
|
/* deltascaled includes both user and system time.
|
||||||
* Hence scale it based on the purr ratio to estimate
|
* Hence scale it based on the purr ratio to estimate
|
||||||
* the system time */
|
* the system time */
|
||||||
|
sys_time = get_paca()->system_time;
|
||||||
if (get_paca()->user_time)
|
if (get_paca()->user_time)
|
||||||
deltascaled = deltascaled * get_paca()->system_time /
|
deltascaled = deltascaled * sys_time /
|
||||||
(get_paca()->system_time + get_paca()->user_time);
|
(sys_time + get_paca()->user_time);
|
||||||
delta += get_paca()->system_time;
|
delta += sys_time;
|
||||||
get_paca()->system_time = 0;
|
get_paca()->system_time = 0;
|
||||||
}
|
}
|
||||||
account_system_time(tsk, 0, delta);
|
account_system_time(tsk, 0, delta);
|
||||||
get_paca()->purrdelta = delta;
|
|
||||||
account_system_time_scaled(tsk, deltascaled);
|
account_system_time_scaled(tsk, deltascaled);
|
||||||
|
get_paca()->purrdelta = delta;
|
||||||
get_paca()->spurrdelta = deltascaled;
|
get_paca()->spurrdelta = deltascaled;
|
||||||
local_irq_restore(flags);
|
local_irq_restore(flags);
|
||||||
}
|
}
|
||||||
|
|
Загрузка…
Ссылка в новой задаче