aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/sched.c
diff options
context:
space:
mode:
authorIngo Molnar <mingo@elte.hu>2009-04-24 04:11:18 -0400
committerIngo Molnar <mingo@elte.hu>2009-04-24 04:11:23 -0400
commit416dfdcdb894432547ead4fcb9fa6a36b396059e (patch)
tree8033fdda07397a59c5fa98c88927040906ce6c1a /kernel/sched.c
parent56449f437add737a1e5e1cb7e00f63ac8ead1938 (diff)
parent091069740304c979f957ceacec39c461d0192158 (diff)
Merge commit 'v2.6.30-rc3' into tracing/hw-branch-tracing
Conflicts: arch/x86/kernel/ptrace.c Merge reason: fix the conflict above, and also pick up the CONFIG_BROKEN dependency change from upstream so that we can remove it here. Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'kernel/sched.c')
-rw-r--r--kernel/sched.c164
1 files changed, 149 insertions, 15 deletions
diff --git a/kernel/sched.c b/kernel/sched.c
index f91bc8141dc3..36322e8682c7 100644
--- a/kernel/sched.c
+++ b/kernel/sched.c
@@ -1418,10 +1418,22 @@ iter_move_one_task(struct rq *this_rq, int this_cpu, struct rq *busiest,
1418 struct rq_iterator *iterator); 1418 struct rq_iterator *iterator);
1419#endif 1419#endif
1420 1420
1421/* Time spent by the tasks of the cpu accounting group executing in ... */
1422enum cpuacct_stat_index {
1423 CPUACCT_STAT_USER, /* ... user mode */
1424 CPUACCT_STAT_SYSTEM, /* ... kernel mode */
1425
1426 CPUACCT_STAT_NSTATS,
1427};
1428
1421#ifdef CONFIG_CGROUP_CPUACCT 1429#ifdef CONFIG_CGROUP_CPUACCT
1422static void cpuacct_charge(struct task_struct *tsk, u64 cputime); 1430static void cpuacct_charge(struct task_struct *tsk, u64 cputime);
1431static void cpuacct_update_stats(struct task_struct *tsk,
1432 enum cpuacct_stat_index idx, cputime_t val);
1423#else 1433#else
1424static inline void cpuacct_charge(struct task_struct *tsk, u64 cputime) {} 1434static inline void cpuacct_charge(struct task_struct *tsk, u64 cputime) {}
1435static inline void cpuacct_update_stats(struct task_struct *tsk,
1436 enum cpuacct_stat_index idx, cputime_t val) {}
1425#endif 1437#endif
1426 1438
1427static inline void inc_cpu_load(struct rq *rq, unsigned long load) 1439static inline void inc_cpu_load(struct rq *rq, unsigned long load)
@@ -4554,9 +4566,25 @@ DEFINE_PER_CPU(struct kernel_stat, kstat);
4554EXPORT_PER_CPU_SYMBOL(kstat); 4566EXPORT_PER_CPU_SYMBOL(kstat);
4555 4567
4556/* 4568/*
4557 * Return any ns on the sched_clock that have not yet been banked in 4569 * Return any ns on the sched_clock that have not yet been accounted in
4558 * @p in case that task is currently running. 4570 * @p in case that task is currently running.
4571 *
4572 * Called with task_rq_lock() held on @rq.
4559 */ 4573 */
4574static u64 do_task_delta_exec(struct task_struct *p, struct rq *rq)
4575{
4576 u64 ns = 0;
4577
4578 if (task_current(rq, p)) {
4579 update_rq_clock(rq);
4580 ns = rq->clock - p->se.exec_start;
4581 if ((s64)ns < 0)
4582 ns = 0;
4583 }
4584
4585 return ns;
4586}
4587
4560unsigned long long task_delta_exec(struct task_struct *p) 4588unsigned long long task_delta_exec(struct task_struct *p)
4561{ 4589{
4562 unsigned long flags; 4590 unsigned long flags;
@@ -4564,16 +4592,49 @@ unsigned long long task_delta_exec(struct task_struct *p)
4564 u64 ns = 0; 4592 u64 ns = 0;
4565 4593
4566 rq = task_rq_lock(p, &flags); 4594 rq = task_rq_lock(p, &flags);
4595 ns = do_task_delta_exec(p, rq);
4596 task_rq_unlock(rq, &flags);
4567 4597
4568 if (task_current(rq, p)) { 4598 return ns;
4569 u64 delta_exec; 4599}
4570 4600
4571 update_rq_clock(rq); 4601/*
4572 delta_exec = rq->clock - p->se.exec_start; 4602 * Return accounted runtime for the task.
4573 if ((s64)delta_exec > 0) 4603 * In case the task is currently running, return the runtime plus current's
4574 ns = delta_exec; 4604 * pending runtime that have not been accounted yet.
4575 } 4605 */
4606unsigned long long task_sched_runtime(struct task_struct *p)
4607{
4608 unsigned long flags;
4609 struct rq *rq;
4610 u64 ns = 0;
4611
4612 rq = task_rq_lock(p, &flags);
4613 ns = p->se.sum_exec_runtime + do_task_delta_exec(p, rq);
4614 task_rq_unlock(rq, &flags);
4615
4616 return ns;
4617}
4618
4619/*
4620 * Return sum_exec_runtime for the thread group.
4621 * In case the task is currently running, return the sum plus current's
4622 * pending runtime that have not been accounted yet.
4623 *
4624 * Note that the thread group might have other running tasks as well,
4625 * so the return value not includes other pending runtime that other
4626 * running tasks might have.
4627 */
4628unsigned long long thread_group_sched_runtime(struct task_struct *p)
4629{
4630 struct task_cputime totals;
4631 unsigned long flags;
4632 struct rq *rq;
4633 u64 ns;
4576 4634
4635 rq = task_rq_lock(p, &flags);
4636 thread_group_cputime(p, &totals);
4637 ns = totals.sum_exec_runtime + do_task_delta_exec(p, rq);
4577 task_rq_unlock(rq, &flags); 4638 task_rq_unlock(rq, &flags);
4578 4639
4579 return ns; 4640 return ns;
@@ -4602,6 +4663,8 @@ void account_user_time(struct task_struct *p, cputime_t cputime,
4602 cpustat->nice = cputime64_add(cpustat->nice, tmp); 4663 cpustat->nice = cputime64_add(cpustat->nice, tmp);
4603 else 4664 else
4604 cpustat->user = cputime64_add(cpustat->user, tmp); 4665 cpustat->user = cputime64_add(cpustat->user, tmp);
4666
4667 cpuacct_update_stats(p, CPUACCT_STAT_USER, cputime);
4605 /* Account for user time used */ 4668 /* Account for user time used */
4606 acct_update_integrals(p); 4669 acct_update_integrals(p);
4607} 4670}
@@ -4663,6 +4726,8 @@ void account_system_time(struct task_struct *p, int hardirq_offset,
4663 else 4726 else
4664 cpustat->system = cputime64_add(cpustat->system, tmp); 4727 cpustat->system = cputime64_add(cpustat->system, tmp);
4665 4728
4729 cpuacct_update_stats(p, CPUACCT_STAT_SYSTEM, cputime);
4730
4666 /* Account for system time used */ 4731 /* Account for system time used */
4667 acct_update_integrals(p); 4732 acct_update_integrals(p);
4668} 4733}
@@ -4824,7 +4889,7 @@ void scheduler_tick(void)
4824#endif 4889#endif
4825} 4890}
4826 4891
4827unsigned long get_parent_ip(unsigned long addr) 4892notrace unsigned long get_parent_ip(unsigned long addr)
4828{ 4893{
4829 if (in_lock_functions(addr)) { 4894 if (in_lock_functions(addr)) {
4830 addr = CALLER_ADDR2; 4895 addr = CALLER_ADDR2;
@@ -7345,7 +7410,12 @@ static int sched_domain_debug_one(struct sched_domain *sd, int cpu, int level,
7345 cpumask_or(groupmask, groupmask, sched_group_cpus(group)); 7410 cpumask_or(groupmask, groupmask, sched_group_cpus(group));
7346 7411
7347 cpulist_scnprintf(str, sizeof(str), sched_group_cpus(group)); 7412 cpulist_scnprintf(str, sizeof(str), sched_group_cpus(group));
7413
7348 printk(KERN_CONT " %s", str); 7414 printk(KERN_CONT " %s", str);
7415 if (group->__cpu_power != SCHED_LOAD_SCALE) {
7416 printk(KERN_CONT " (__cpu_power = %d)",
7417 group->__cpu_power);
7418 }
7349 7419
7350 group = group->next; 7420 group = group->next;
7351 } while (group != sd->groups); 7421 } while (group != sd->groups);
@@ -9968,6 +10038,7 @@ struct cpuacct {
9968 struct cgroup_subsys_state css; 10038 struct cgroup_subsys_state css;
9969 /* cpuusage holds pointer to a u64-type object on every cpu */ 10039 /* cpuusage holds pointer to a u64-type object on every cpu */
9970 u64 *cpuusage; 10040 u64 *cpuusage;
10041 struct percpu_counter cpustat[CPUACCT_STAT_NSTATS];
9971 struct cpuacct *parent; 10042 struct cpuacct *parent;
9972}; 10043};
9973 10044
@@ -9992,20 +10063,32 @@ static struct cgroup_subsys_state *cpuacct_create(
9992 struct cgroup_subsys *ss, struct cgroup *cgrp) 10063 struct cgroup_subsys *ss, struct cgroup *cgrp)
9993{ 10064{
9994 struct cpuacct *ca = kzalloc(sizeof(*ca), GFP_KERNEL); 10065 struct cpuacct *ca = kzalloc(sizeof(*ca), GFP_KERNEL);
10066 int i;
9995 10067
9996 if (!ca) 10068 if (!ca)
9997 return ERR_PTR(-ENOMEM); 10069 goto out;
9998 10070
9999 ca->cpuusage = alloc_percpu(u64); 10071 ca->cpuusage = alloc_percpu(u64);
10000 if (!ca->cpuusage) { 10072 if (!ca->cpuusage)
10001 kfree(ca); 10073 goto out_free_ca;
10002 return ERR_PTR(-ENOMEM); 10074
10003 } 10075 for (i = 0; i < CPUACCT_STAT_NSTATS; i++)
10076 if (percpu_counter_init(&ca->cpustat[i], 0))
10077 goto out_free_counters;
10004 10078
10005 if (cgrp->parent) 10079 if (cgrp->parent)
10006 ca->parent = cgroup_ca(cgrp->parent); 10080 ca->parent = cgroup_ca(cgrp->parent);
10007 10081
10008 return &ca->css; 10082 return &ca->css;
10083
10084out_free_counters:
10085 while (--i >= 0)
10086 percpu_counter_destroy(&ca->cpustat[i]);
10087 free_percpu(ca->cpuusage);
10088out_free_ca:
10089 kfree(ca);
10090out:
10091 return ERR_PTR(-ENOMEM);
10009} 10092}
10010 10093
10011/* destroy an existing cpu accounting group */ 10094/* destroy an existing cpu accounting group */
@@ -10013,7 +10096,10 @@ static void
10013cpuacct_destroy(struct cgroup_subsys *ss, struct cgroup *cgrp) 10096cpuacct_destroy(struct cgroup_subsys *ss, struct cgroup *cgrp)
10014{ 10097{
10015 struct cpuacct *ca = cgroup_ca(cgrp); 10098 struct cpuacct *ca = cgroup_ca(cgrp);
10099 int i;
10016 10100
10101 for (i = 0; i < CPUACCT_STAT_NSTATS; i++)
10102 percpu_counter_destroy(&ca->cpustat[i]);
10017 free_percpu(ca->cpuusage); 10103 free_percpu(ca->cpuusage);
10018 kfree(ca); 10104 kfree(ca);
10019} 10105}
@@ -10100,6 +10186,25 @@ static int cpuacct_percpu_seq_read(struct cgroup *cgroup, struct cftype *cft,
10100 return 0; 10186 return 0;
10101} 10187}
10102 10188
10189static const char *cpuacct_stat_desc[] = {
10190 [CPUACCT_STAT_USER] = "user",
10191 [CPUACCT_STAT_SYSTEM] = "system",
10192};
10193
10194static int cpuacct_stats_show(struct cgroup *cgrp, struct cftype *cft,
10195 struct cgroup_map_cb *cb)
10196{
10197 struct cpuacct *ca = cgroup_ca(cgrp);
10198 int i;
10199
10200 for (i = 0; i < CPUACCT_STAT_NSTATS; i++) {
10201 s64 val = percpu_counter_read(&ca->cpustat[i]);
10202 val = cputime64_to_clock_t(val);
10203 cb->fill(cb, cpuacct_stat_desc[i], val);
10204 }
10205 return 0;
10206}
10207
10103static struct cftype files[] = { 10208static struct cftype files[] = {
10104 { 10209 {
10105 .name = "usage", 10210 .name = "usage",
@@ -10110,7 +10215,10 @@ static struct cftype files[] = {
10110 .name = "usage_percpu", 10215 .name = "usage_percpu",
10111 .read_seq_string = cpuacct_percpu_seq_read, 10216 .read_seq_string = cpuacct_percpu_seq_read,
10112 }, 10217 },
10113 10218 {
10219 .name = "stat",
10220 .read_map = cpuacct_stats_show,
10221 },
10114}; 10222};
10115 10223
10116static int cpuacct_populate(struct cgroup_subsys *ss, struct cgroup *cgrp) 10224static int cpuacct_populate(struct cgroup_subsys *ss, struct cgroup *cgrp)
@@ -10132,12 +10240,38 @@ static void cpuacct_charge(struct task_struct *tsk, u64 cputime)
10132 return; 10240 return;
10133 10241
10134 cpu = task_cpu(tsk); 10242 cpu = task_cpu(tsk);
10243
10244 rcu_read_lock();
10245
10135 ca = task_ca(tsk); 10246 ca = task_ca(tsk);
10136 10247
10137 for (; ca; ca = ca->parent) { 10248 for (; ca; ca = ca->parent) {
10138 u64 *cpuusage = per_cpu_ptr(ca->cpuusage, cpu); 10249 u64 *cpuusage = per_cpu_ptr(ca->cpuusage, cpu);
10139 *cpuusage += cputime; 10250 *cpuusage += cputime;
10140 } 10251 }
10252
10253 rcu_read_unlock();
10254}
10255
10256/*
10257 * Charge the system/user time to the task's accounting group.
10258 */
10259static void cpuacct_update_stats(struct task_struct *tsk,
10260 enum cpuacct_stat_index idx, cputime_t val)
10261{
10262 struct cpuacct *ca;
10263
10264 if (unlikely(!cpuacct_subsys.active))
10265 return;
10266
10267 rcu_read_lock();
10268 ca = task_ca(tsk);
10269
10270 do {
10271 percpu_counter_add(&ca->cpustat[idx], val);
10272 ca = ca->parent;
10273 } while (ca);
10274 rcu_read_unlock();
10141} 10275}
10142 10276
10143struct cgroup_subsys cpuacct_subsys = { 10277struct cgroup_subsys cpuacct_subsys = {