powerpc32: provide VIRT_CPU_ACCOUNTING
This patch provides VIRT_CPU_ACCOUTING to PPC32 architecture. PPC32 doesn't have the PACA structure, so we use the task_info structure to store the accounting data. In order to reuse on PPC32 the PPC64 functions, all u64 data has been replaced by 'unsigned long' so that it is u32 on PPC32 and u64 on PPC64 Signed-off-by: Christophe Leroy <christophe.leroy@c-s.fr> Signed-off-by: Scott Wood <oss@buserror.net>
This commit is contained in:

committed by
Scott Wood

parent
1afbf61750
commit
c223c90386
@@ -240,13 +240,28 @@ int main(void)
|
||||
DEFINE(PACAHWCPUID, offsetof(struct paca_struct, hw_cpu_id));
|
||||
DEFINE(PACAKEXECSTATE, offsetof(struct paca_struct, kexec_state));
|
||||
DEFINE(PACA_DSCR_DEFAULT, offsetof(struct paca_struct, dscr_default));
|
||||
DEFINE(PACA_STARTTIME, offsetof(struct paca_struct, starttime));
|
||||
DEFINE(PACA_STARTTIME_USER, offsetof(struct paca_struct, starttime_user));
|
||||
DEFINE(PACA_USER_TIME, offsetof(struct paca_struct, user_time));
|
||||
DEFINE(PACA_SYSTEM_TIME, offsetof(struct paca_struct, system_time));
|
||||
DEFINE(ACCOUNT_STARTTIME,
|
||||
offsetof(struct paca_struct, accounting.starttime));
|
||||
DEFINE(ACCOUNT_STARTTIME_USER,
|
||||
offsetof(struct paca_struct, accounting.starttime_user));
|
||||
DEFINE(ACCOUNT_USER_TIME,
|
||||
offsetof(struct paca_struct, accounting.user_time));
|
||||
DEFINE(ACCOUNT_SYSTEM_TIME,
|
||||
offsetof(struct paca_struct, accounting.system_time));
|
||||
DEFINE(PACA_TRAP_SAVE, offsetof(struct paca_struct, trap_save));
|
||||
DEFINE(PACA_NAPSTATELOST, offsetof(struct paca_struct, nap_state_lost));
|
||||
DEFINE(PACA_SPRG_VDSO, offsetof(struct paca_struct, sprg_vdso));
|
||||
#else /* CONFIG_PPC64 */
|
||||
#ifdef CONFIG_VIRT_CPU_ACCOUNTING_NATIVE
|
||||
DEFINE(ACCOUNT_STARTTIME,
|
||||
offsetof(struct thread_info, accounting.starttime));
|
||||
DEFINE(ACCOUNT_STARTTIME_USER,
|
||||
offsetof(struct thread_info, accounting.starttime_user));
|
||||
DEFINE(ACCOUNT_USER_TIME,
|
||||
offsetof(struct thread_info, accounting.user_time));
|
||||
DEFINE(ACCOUNT_SYSTEM_TIME,
|
||||
offsetof(struct thread_info, accounting.system_time));
|
||||
#endif
|
||||
#endif /* CONFIG_PPC64 */
|
||||
|
||||
/* RTAS */
|
||||
|
@@ -175,6 +175,12 @@ transfer_to_handler:
|
||||
addi r12,r12,-1
|
||||
stw r12,4(r11)
|
||||
#endif
|
||||
#ifdef CONFIG_VIRT_CPU_ACCOUNTING_NATIVE
|
||||
CURRENT_THREAD_INFO(r9, r1)
|
||||
tophys(r9, r9)
|
||||
ACCOUNT_CPU_USER_ENTRY(r9, r11, r12)
|
||||
#endif
|
||||
|
||||
b 3f
|
||||
|
||||
2: /* if from kernel, check interrupted DOZE/NAP mode and
|
||||
@@ -398,6 +404,13 @@ BEGIN_FTR_SECTION
|
||||
lwarx r7,0,r1
|
||||
END_FTR_SECTION_IFSET(CPU_FTR_NEED_PAIRED_STWCX)
|
||||
stwcx. r0,0,r1 /* to clear the reservation */
|
||||
#ifdef CONFIG_VIRT_CPU_ACCOUNTING_NATIVE
|
||||
andi. r4,r8,MSR_PR
|
||||
beq 3f
|
||||
CURRENT_THREAD_INFO(r4, r1)
|
||||
ACCOUNT_CPU_USER_EXIT(r4, r5, r7)
|
||||
3:
|
||||
#endif
|
||||
lwz r4,_LINK(r1)
|
||||
lwz r5,_CCR(r1)
|
||||
mtlr r4
|
||||
@@ -769,6 +782,10 @@ restore_user:
|
||||
andis. r10,r0,DBCR0_IDM@h
|
||||
bnel- load_dbcr0
|
||||
#endif
|
||||
#ifdef CONFIG_VIRT_CPU_ACCOUNTING_NATIVE
|
||||
CURRENT_THREAD_INFO(r9, r1)
|
||||
ACCOUNT_CPU_USER_EXIT(r9, r10, r11)
|
||||
#endif
|
||||
|
||||
b restore
|
||||
|
||||
|
@@ -72,7 +72,7 @@ END_FTR_SECTION_IFSET(CPU_FTR_TM)
|
||||
std r0,GPR0(r1)
|
||||
std r10,GPR1(r1)
|
||||
beq 2f /* if from kernel mode */
|
||||
ACCOUNT_CPU_USER_ENTRY(r10, r11)
|
||||
ACCOUNT_CPU_USER_ENTRY(r13, r10, r11)
|
||||
2: std r2,GPR2(r1)
|
||||
std r3,GPR3(r1)
|
||||
mfcr r2
|
||||
@@ -246,7 +246,7 @@ END_FTR_SECTION_IFCLR(CPU_FTR_STCX_CHECKS_ADDRESS)
|
||||
ld r4,_LINK(r1)
|
||||
|
||||
beq- 1f
|
||||
ACCOUNT_CPU_USER_EXIT(r11, r12)
|
||||
ACCOUNT_CPU_USER_EXIT(r13, r11, r12)
|
||||
|
||||
BEGIN_FTR_SECTION
|
||||
HMT_MEDIUM_LOW
|
||||
@@ -859,7 +859,7 @@ END_FTR_SECTION_IFSET(CPU_FTR_HAS_PPR)
|
||||
BEGIN_FTR_SECTION
|
||||
mtspr SPRN_PPR,r2 /* Restore PPR */
|
||||
END_FTR_SECTION_IFSET(CPU_FTR_HAS_PPR)
|
||||
ACCOUNT_CPU_USER_EXIT(r2, r4)
|
||||
ACCOUNT_CPU_USER_EXIT(r13, r2, r4)
|
||||
REST_GPR(13, r1)
|
||||
1:
|
||||
mtspr SPRN_SRR1,r3
|
||||
|
@@ -386,7 +386,7 @@ exc_##n##_common: \
|
||||
std r10,_NIP(r1); /* save SRR0 to stackframe */ \
|
||||
std r11,_MSR(r1); /* save SRR1 to stackframe */ \
|
||||
beq 2f; /* if from kernel mode */ \
|
||||
ACCOUNT_CPU_USER_ENTRY(r10,r11);/* accounting (uses cr0+eq) */ \
|
||||
ACCOUNT_CPU_USER_ENTRY(r13,r10,r11);/* accounting (uses cr0+eq) */ \
|
||||
2: ld r3,excf+EX_R10(r13); /* get back r10 */ \
|
||||
ld r4,excf+EX_R11(r13); /* get back r11 */ \
|
||||
mfspr r5,scratch; /* get back r13 */ \
|
||||
@@ -1059,7 +1059,7 @@ fast_exception_return:
|
||||
andi. r6,r10,MSR_PR
|
||||
REST_2GPRS(6, r1)
|
||||
beq 1f
|
||||
ACCOUNT_CPU_USER_EXIT(r10, r11)
|
||||
ACCOUNT_CPU_USER_EXIT(r13, r10, r11)
|
||||
ld r0,GPR13(r1)
|
||||
|
||||
1: stdcx. r0,0,r1 /* to clear the reservation */
|
||||
|
@@ -167,7 +167,15 @@ DEFINE_PER_CPU(unsigned long, cputime_scaled_last_delta);
|
||||
|
||||
cputime_t cputime_one_jiffy;
|
||||
|
||||
#ifdef CONFIG_PPC_SPLPAR
|
||||
void (*dtl_consumer)(struct dtl_entry *, u64);
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_PPC64
|
||||
#define get_accounting(tsk) (&get_paca()->accounting)
|
||||
#else
|
||||
#define get_accounting(tsk) (&task_thread_info(tsk)->accounting)
|
||||
#endif
|
||||
|
||||
static void calc_cputime_factors(void)
|
||||
{
|
||||
@@ -187,7 +195,7 @@ static void calc_cputime_factors(void)
|
||||
* Read the SPURR on systems that have it, otherwise the PURR,
|
||||
* or if that doesn't exist return the timebase value passed in.
|
||||
*/
|
||||
static u64 read_spurr(u64 tb)
|
||||
static unsigned long read_spurr(unsigned long tb)
|
||||
{
|
||||
if (cpu_has_feature(CPU_FTR_SPURR))
|
||||
return mfspr(SPRN_SPURR);
|
||||
@@ -250,8 +258,8 @@ static u64 scan_dispatch_log(u64 stop_tb)
|
||||
void accumulate_stolen_time(void)
|
||||
{
|
||||
u64 sst, ust;
|
||||
|
||||
u8 save_soft_enabled = local_paca->soft_enabled;
|
||||
struct cpu_accounting_data *acct = &local_paca->accounting;
|
||||
|
||||
/* We are called early in the exception entry, before
|
||||
* soft/hard_enabled are sync'ed to the expected state
|
||||
@@ -261,10 +269,10 @@ void accumulate_stolen_time(void)
|
||||
*/
|
||||
local_paca->soft_enabled = 0;
|
||||
|
||||
sst = scan_dispatch_log(local_paca->starttime_user);
|
||||
ust = scan_dispatch_log(local_paca->starttime);
|
||||
local_paca->system_time -= sst;
|
||||
local_paca->user_time -= ust;
|
||||
sst = scan_dispatch_log(acct->starttime_user);
|
||||
ust = scan_dispatch_log(acct->starttime);
|
||||
acct->system_time -= sst;
|
||||
acct->user_time -= ust;
|
||||
local_paca->stolen_time += ust + sst;
|
||||
|
||||
local_paca->soft_enabled = save_soft_enabled;
|
||||
@@ -276,7 +284,7 @@ static inline u64 calculate_stolen_time(u64 stop_tb)
|
||||
|
||||
if (get_paca()->dtl_ridx != be64_to_cpu(get_lppaca()->dtl_idx)) {
|
||||
stolen = scan_dispatch_log(stop_tb);
|
||||
get_paca()->system_time -= stolen;
|
||||
get_paca()->accounting.system_time -= stolen;
|
||||
}
|
||||
|
||||
stolen += get_paca()->stolen_time;
|
||||
@@ -296,27 +304,29 @@ static inline u64 calculate_stolen_time(u64 stop_tb)
|
||||
* Account time for a transition between system, hard irq
|
||||
* or soft irq state.
|
||||
*/
|
||||
static u64 vtime_delta(struct task_struct *tsk,
|
||||
u64 *sys_scaled, u64 *stolen)
|
||||
static unsigned long vtime_delta(struct task_struct *tsk,
|
||||
unsigned long *sys_scaled,
|
||||
unsigned long *stolen)
|
||||
{
|
||||
u64 now, nowscaled, deltascaled;
|
||||
u64 udelta, delta, user_scaled;
|
||||
unsigned long now, nowscaled, deltascaled;
|
||||
unsigned long udelta, delta, user_scaled;
|
||||
struct cpu_accounting_data *acct = get_accounting(tsk);
|
||||
|
||||
WARN_ON_ONCE(!irqs_disabled());
|
||||
|
||||
now = mftb();
|
||||
nowscaled = read_spurr(now);
|
||||
get_paca()->system_time += now - get_paca()->starttime;
|
||||
get_paca()->starttime = now;
|
||||
deltascaled = nowscaled - get_paca()->startspurr;
|
||||
get_paca()->startspurr = nowscaled;
|
||||
acct->system_time += now - acct->starttime;
|
||||
acct->starttime = now;
|
||||
deltascaled = nowscaled - acct->startspurr;
|
||||
acct->startspurr = nowscaled;
|
||||
|
||||
*stolen = calculate_stolen_time(now);
|
||||
|
||||
delta = get_paca()->system_time;
|
||||
get_paca()->system_time = 0;
|
||||
udelta = get_paca()->user_time - get_paca()->utime_sspurr;
|
||||
get_paca()->utime_sspurr = get_paca()->user_time;
|
||||
delta = acct->system_time;
|
||||
acct->system_time = 0;
|
||||
udelta = acct->user_time - acct->utime_sspurr;
|
||||
acct->utime_sspurr = acct->user_time;
|
||||
|
||||
/*
|
||||
* Because we don't read the SPURR on every kernel entry/exit,
|
||||
@@ -338,14 +348,14 @@ static u64 vtime_delta(struct task_struct *tsk,
|
||||
*sys_scaled = deltascaled;
|
||||
}
|
||||
}
|
||||
get_paca()->user_time_scaled += user_scaled;
|
||||
acct->user_time_scaled += user_scaled;
|
||||
|
||||
return delta;
|
||||
}
|
||||
|
||||
void vtime_account_system(struct task_struct *tsk)
|
||||
{
|
||||
u64 delta, sys_scaled, stolen;
|
||||
unsigned long delta, sys_scaled, stolen;
|
||||
|
||||
delta = vtime_delta(tsk, &sys_scaled, &stolen);
|
||||
account_system_time(tsk, 0, delta, sys_scaled);
|
||||
@@ -356,7 +366,7 @@ EXPORT_SYMBOL_GPL(vtime_account_system);
|
||||
|
||||
void vtime_account_idle(struct task_struct *tsk)
|
||||
{
|
||||
u64 delta, sys_scaled, stolen;
|
||||
unsigned long delta, sys_scaled, stolen;
|
||||
|
||||
delta = vtime_delta(tsk, &sys_scaled, &stolen);
|
||||
account_idle_time(delta + stolen);
|
||||
@@ -374,15 +384,32 @@ void vtime_account_idle(struct task_struct *tsk)
|
||||
void vtime_account_user(struct task_struct *tsk)
|
||||
{
|
||||
cputime_t utime, utimescaled;
|
||||
struct cpu_accounting_data *acct = get_accounting(tsk);
|
||||
|
||||
utime = get_paca()->user_time;
|
||||
utimescaled = get_paca()->user_time_scaled;
|
||||
get_paca()->user_time = 0;
|
||||
get_paca()->user_time_scaled = 0;
|
||||
get_paca()->utime_sspurr = 0;
|
||||
utime = acct->user_time;
|
||||
utimescaled = acct->user_time_scaled;
|
||||
acct->user_time = 0;
|
||||
acct->user_time_scaled = 0;
|
||||
acct->utime_sspurr = 0;
|
||||
account_user_time(tsk, utime, utimescaled);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PPC32
|
||||
/*
|
||||
* Called from the context switch with interrupts disabled, to charge all
|
||||
* accumulated times to the current process, and to prepare accounting on
|
||||
* the next process.
|
||||
*/
|
||||
void arch_vtime_task_switch(struct task_struct *prev)
|
||||
{
|
||||
struct cpu_accounting_data *acct = get_accounting(current);
|
||||
|
||||
acct->starttime = get_accounting(prev)->starttime;
|
||||
acct->system_time = 0;
|
||||
acct->user_time = 0;
|
||||
}
|
||||
#endif /* CONFIG_PPC32 */
|
||||
|
||||
#else /* ! CONFIG_VIRT_CPU_ACCOUNTING_NATIVE */
|
||||
#define calc_cputime_factors()
|
||||
#endif
|
||||
|
Reference in New Issue
Block a user