Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 125491
b: refs/heads/master
c: 79741dd
h: refs/heads/master
i:
  125489: 14a34e0
  125487: 425bf4f
v: v3
  • Loading branch information
Martin Schwidefsky committed Dec 31, 2008
1 parent 8436d54 commit 50e8331
Show file tree
Hide file tree
Showing 11 changed files with 115 additions and 55 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 457533a7d3402d1d91fbc125c8bd1bd16dcd3cd4
refs/heads/master: 79741dd35713ff4f6fd0eafd59fa94e8a4ba922d
10 changes: 8 additions & 2 deletions trunk/arch/ia64/kernel/time.c
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,10 @@ void ia64_account_on_switch(struct task_struct *prev, struct task_struct *next)
now = ia64_get_itc();

delta_stime = cycle_to_cputime(pi->ac_stime + (now - pi->ac_stamp));
account_system_time(prev, 0, delta_stime, delta_stime);
if (idle_task(smp_processor_id()) != prev)
account_system_time(prev, 0, delta_stime, delta_stime);
else
account_idle_time(delta_stime);

if (pi->ac_utime) {
delta_utime = cycle_to_cputime(pi->ac_utime);
Expand All @@ -120,7 +123,10 @@ void account_system_vtime(struct task_struct *tsk)
now = ia64_get_itc();

delta_stime = cycle_to_cputime(ti->ac_stime + (now - ti->ac_stamp));
account_system_time(tsk, 0, delta_stime, delta_stime);
if (irq_count() || idle_task(smp_processor_id()) != tsk)
account_system_time(tsk, 0, delta_stime, delta_stime);
else
account_idle_time(delta_stime);
ti->ac_stime = 0;

ti->ac_stamp = now;
Expand Down
1 change: 1 addition & 0 deletions trunk/arch/powerpc/kernel/process.c
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
#include <linux/mqueue.h>
#include <linux/hardirq.h>
#include <linux/utsname.h>
#include <linux/kernel_stat.h>

#include <asm/pgtable.h>
#include <asm/uaccess.h>
Expand Down
13 changes: 10 additions & 3 deletions trunk/arch/powerpc/kernel/time.c
Original file line number Diff line number Diff line change
Expand Up @@ -256,7 +256,10 @@ void account_system_vtime(struct task_struct *tsk)
delta += sys_time;
get_paca()->system_time = 0;
}
account_system_time(tsk, 0, delta, deltascaled);
if (in_irq() || idle_task(smp_processor_id()) != tsk)
account_system_time(tsk, 0, delta, deltascaled);
else
account_idle_time(delta);
per_cpu(cputime_last_delta, smp_processor_id()) = delta;
per_cpu(cputime_scaled_last_delta, smp_processor_id()) = deltascaled;
local_irq_restore(flags);
Expand Down Expand Up @@ -335,8 +338,12 @@ void calculate_steal_time(void)
tb = mftb();
purr = mfspr(SPRN_PURR);
stolen = (tb - pme->tb) - (purr - pme->purr);
if (stolen > 0)
account_steal_time(current, stolen);
if (stolen > 0) {
if (idle_task(smp_processor_id()) != current)
account_steal_time(stolen);
else
account_idle_time(stolen);
}
pme->tb = tb;
pme->purr = purr;
}
Expand Down
20 changes: 16 additions & 4 deletions trunk/arch/s390/kernel/vtime.c
Original file line number Diff line number Diff line change
Expand Up @@ -55,13 +55,19 @@ void account_process_tick(struct task_struct *tsk, int user_tick)
cputime = S390_lowcore.system_timer >> 12;
S390_lowcore.system_timer -= cputime << 12;
S390_lowcore.steal_clock -= cputime << 12;
account_system_time(tsk, HARDIRQ_OFFSET, cputime, cputime);
if (idle_task(smp_processor_id()) != current)
account_system_time(tsk, HARDIRQ_OFFSET, cputime, cputime);
else
account_idle_time(cputime);

cputime = S390_lowcore.steal_clock;
if ((__s64) cputime > 0) {
cputime >>= 12;
S390_lowcore.steal_clock -= cputime << 12;
account_steal_time(tsk, cputime);
if (idle_task(smp_processor_id()) != current)
account_steal_time(cputime);
else
account_idle_time(cputime);
}
}

Expand All @@ -87,7 +93,10 @@ void account_vtime(struct task_struct *tsk)
cputime = S390_lowcore.system_timer >> 12;
S390_lowcore.system_timer -= cputime << 12;
S390_lowcore.steal_clock -= cputime << 12;
account_system_time(tsk, 0, cputime, cputime);
if (idle_task(smp_processor_id()) != current)
account_system_time(tsk, 0, cputime, cputime);
else
account_idle_time(cputime);
}

/*
Expand All @@ -107,7 +116,10 @@ void account_system_vtime(struct task_struct *tsk)
cputime = S390_lowcore.system_timer >> 12;
S390_lowcore.system_timer -= cputime << 12;
S390_lowcore.steal_clock -= cputime << 12;
account_system_time(tsk, 0, cputime, cputime);
if (in_irq() || idle_task(smp_processor_id()) != current)
account_system_time(tsk, 0, cputime, cputime);
else
account_idle_time(cputime);
}
EXPORT_SYMBOL_GPL(account_system_vtime);

Expand Down
10 changes: 4 additions & 6 deletions trunk/arch/x86/xen/time.c
Original file line number Diff line number Diff line change
Expand Up @@ -132,28 +132,26 @@ static void do_stolen_accounting(void)
*snap = state;

/* Add the appropriate number of ticks of stolen time,
including any left-overs from last time. Passing NULL to
account_steal_time accounts the time as stolen. */
including any left-overs from last time. */
stolen = runnable + offline + __get_cpu_var(residual_stolen);

if (stolen < 0)
stolen = 0;

ticks = iter_div_u64_rem(stolen, NS_PER_TICK, &stolen);
__get_cpu_var(residual_stolen) = stolen;
account_steal_time(NULL, ticks);
account_steal_ticks(ticks);

/* Add the appropriate number of ticks of blocked time,
including any left-overs from last time. Passing idle to
account_steal_time accounts the time as idle/wait. */
including any left-overs from last time. */
blocked += __get_cpu_var(residual_blocked);

if (blocked < 0)
blocked = 0;

ticks = iter_div_u64_rem(blocked, NS_PER_TICK, &blocked);
__get_cpu_var(residual_blocked) = blocked;
account_steal_time(idle_task(smp_processor_id()), ticks);
account_idle_ticks(ticks);
}

/*
Expand Down
7 changes: 6 additions & 1 deletion trunk/include/linux/kernel_stat.h
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,11 @@ static inline unsigned int kstat_irqs(unsigned int irq)
extern unsigned long long task_delta_exec(struct task_struct *);
extern void account_user_time(struct task_struct *, cputime_t, cputime_t);
extern void account_system_time(struct task_struct *, int, cputime_t, cputime_t);
extern void account_steal_time(struct task_struct *, cputime_t);
extern void account_steal_time(cputime_t);
extern void account_idle_time(cputime_t);

extern void account_process_tick(struct task_struct *, int user);
extern void account_steal_ticks(unsigned long ticks);
extern void account_idle_ticks(unsigned long ticks);

#endif /* _LINUX_KERNEL_STAT_H */
1 change: 0 additions & 1 deletion trunk/include/linux/sched.h
Original file line number Diff line number Diff line change
Expand Up @@ -284,7 +284,6 @@ long io_schedule_timeout(long timeout);

extern void cpu_init (void);
extern void trap_init(void);
extern void account_process_tick(struct task_struct *task, int user);
extern void update_process_times(int user);
extern void scheduler_tick(void);

Expand Down
80 changes: 63 additions & 17 deletions trunk/kernel/sched.c
Original file line number Diff line number Diff line change
Expand Up @@ -4139,7 +4139,6 @@ void account_system_time(struct task_struct *p, int hardirq_offset,
cputime_t cputime, cputime_t cputime_scaled)
{
struct cpu_usage_stat *cpustat = &kstat_this_cpu.cpustat;
struct rq *rq = this_rq();
cputime64_t tmp;

if ((p->flags & PF_VCPU) && (irq_count() - hardirq_offset == 0)) {
Expand All @@ -4158,37 +4157,84 @@ void account_system_time(struct task_struct *p, int hardirq_offset,
cpustat->irq = cputime64_add(cpustat->irq, tmp);
else if (softirq_count())
cpustat->softirq = cputime64_add(cpustat->softirq, tmp);
else if (p != rq->idle)
cpustat->system = cputime64_add(cpustat->system, tmp);
else if (atomic_read(&rq->nr_iowait) > 0)
cpustat->iowait = cputime64_add(cpustat->iowait, tmp);
else
cpustat->idle = cputime64_add(cpustat->idle, tmp);
cpustat->system = cputime64_add(cpustat->system, tmp);

/* Account for system time used */
acct_update_integrals(p);
}

/*
* Account for involuntary wait time.
* @p: the process from which the cpu time has been stolen
* @steal: the cpu time spent in involuntary wait
*/
void account_steal_time(struct task_struct *p, cputime_t steal)
void account_steal_time(cputime_t cputime)
{
struct cpu_usage_stat *cpustat = &kstat_this_cpu.cpustat;
cputime64_t cputime64 = cputime_to_cputime64(cputime);

cpustat->steal = cputime64_add(cpustat->steal, cputime64);
}

/*
* Account for idle time.
* @cputime: the cpu time spent in idle wait
*/
void account_idle_time(cputime_t cputime)
{
struct cpu_usage_stat *cpustat = &kstat_this_cpu.cpustat;
cputime64_t tmp = cputime_to_cputime64(steal);
cputime64_t cputime64 = cputime_to_cputime64(cputime);
struct rq *rq = this_rq();

if (p == rq->idle) {
p->stime = cputime_add(p->stime, steal);
if (atomic_read(&rq->nr_iowait) > 0)
cpustat->iowait = cputime64_add(cpustat->iowait, tmp);
else
cpustat->idle = cputime64_add(cpustat->idle, tmp);
} else
cpustat->steal = cputime64_add(cpustat->steal, tmp);
if (atomic_read(&rq->nr_iowait) > 0)
cpustat->iowait = cputime64_add(cpustat->iowait, cputime64);
else
cpustat->idle = cputime64_add(cpustat->idle, cputime64);
}

#ifndef CONFIG_VIRT_CPU_ACCOUNTING

/*
* Account a single tick of cpu time.
* @p: the process that the cpu time gets accounted to
* @user_tick: indicates if the tick is a user or a system tick
*/
void account_process_tick(struct task_struct *p, int user_tick)
{
cputime_t one_jiffy = jiffies_to_cputime(1);
cputime_t one_jiffy_scaled = cputime_to_scaled(one_jiffy);
struct rq *rq = this_rq();

if (user_tick)
account_user_time(p, one_jiffy, one_jiffy_scaled);
else if (p != rq->idle)
account_system_time(p, HARDIRQ_OFFSET, one_jiffy,
one_jiffy_scaled);
else
account_idle_time(one_jiffy);
}

/*
* Account multiple ticks of steal time.
* @p: the process from which the cpu time has been stolen
* @ticks: number of stolen ticks
*/
void account_steal_ticks(unsigned long ticks)
{
account_steal_time(jiffies_to_cputime(ticks));
}

/*
* Account multiple ticks of idle time.
* @ticks: number of stolen ticks
*/
void account_idle_ticks(unsigned long ticks)
{
account_idle_time(jiffies_to_cputime(ticks));
}

#endif

/*
* Use precise platform statistics if available:
*/
Expand Down
13 changes: 6 additions & 7 deletions trunk/kernel/time/tick-sched.c
Original file line number Diff line number Diff line change
Expand Up @@ -419,8 +419,9 @@ void tick_nohz_restart_sched_tick(void)
{
int cpu = smp_processor_id();
struct tick_sched *ts = &per_cpu(tick_cpu_sched, cpu);
#ifndef CONFIG_VIRT_CPU_ACCOUNTING
unsigned long ticks;
cputime_t cputime;
#endif
ktime_t now;

local_irq_disable();
Expand All @@ -442,6 +443,7 @@ void tick_nohz_restart_sched_tick(void)
tick_do_update_jiffies64(now);
cpu_clear(cpu, nohz_cpu_mask);

#ifndef CONFIG_VIRT_CPU_ACCOUNTING
/*
* We stopped the tick in idle. Update process times would miss the
* time we slept as update_process_times does only a 1 tick
Expand All @@ -451,12 +453,9 @@ void tick_nohz_restart_sched_tick(void)
/*
* We might be one off. Do not randomly account a huge number of ticks!
*/
if (ticks && ticks < LONG_MAX) {
add_preempt_count(HARDIRQ_OFFSET);
cputime = jiffies_to_cputime(ticks);
account_system_time(current, HARDIRQ_OFFSET, cputime, cputime);
sub_preempt_count(HARDIRQ_OFFSET);
}
if (ticks && ticks < LONG_MAX)
account_idle_ticks(ticks);
#endif

touch_softlockup_watchdog();
/*
Expand Down
13 changes: 0 additions & 13 deletions trunk/kernel/timer.c
Original file line number Diff line number Diff line change
Expand Up @@ -1018,19 +1018,6 @@ unsigned long get_next_timer_interrupt(unsigned long now)
}
#endif

#ifndef CONFIG_VIRT_CPU_ACCOUNTING
void account_process_tick(struct task_struct *p, int user_tick)
{
cputime_t one_jiffy = jiffies_to_cputime(1);

if (user_tick)
account_user_time(p, one_jiffy, cputime_to_scaled(one_jiffy));
else
account_system_time(p, HARDIRQ_OFFSET, one_jiffy,
cputime_to_scaled(one_jiffy));
}
#endif

/*
* Called from the timer interrupt handler to charge one tick to the current
* process. user_tick is 1 if the tick is user time, 0 for system.
Expand Down

0 comments on commit 50e8331

Please sign in to comment.