diff options
author | Mike Travis <travis@sgi.com> | 2008-12-31 20:34:16 -0500 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2009-01-03 12:53:31 -0500 |
commit | 7eb19553369c46cc1fa64caf120cbcab1b597f7c (patch) | |
tree | ef1a3beae706b9497c845d0a2557ceb4d2754998 /kernel/sched.c | |
parent | 6092848a2a23b660150a38bc06f59d75838d70c8 (diff) | |
parent | 8c384cdee3e04d6194a2c2b192b624754f990835 (diff) |
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/rusty/linux-2.6-cpumask into merge-rr-cpumask
Conflicts:
arch/x86/kernel/io_apic.c
kernel/rcuclassic.c
kernel/sched.c
kernel/time/tick-sched.c
Signed-off-by: Mike Travis <travis@sgi.com>
[ mingo@elte.hu: backmerged typo fix for io_apic.c ]
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'kernel/sched.c')
-rw-r--r-- | kernel/sched.c | 115 |
1 files changed, 87 insertions, 28 deletions
diff --git a/kernel/sched.c b/kernel/sched.c index 756d981d91a4..27ba1d642f0f 100644 --- a/kernel/sched.c +++ b/kernel/sched.c | |||
@@ -209,7 +209,6 @@ void init_rt_bandwidth(struct rt_bandwidth *rt_b, u64 period, u64 runtime) | |||
209 | hrtimer_init(&rt_b->rt_period_timer, | 209 | hrtimer_init(&rt_b->rt_period_timer, |
210 | CLOCK_MONOTONIC, HRTIMER_MODE_REL); | 210 | CLOCK_MONOTONIC, HRTIMER_MODE_REL); |
211 | rt_b->rt_period_timer.function = sched_rt_period_timer; | 211 | rt_b->rt_period_timer.function = sched_rt_period_timer; |
212 | rt_b->rt_period_timer.cb_mode = HRTIMER_CB_IRQSAFE_UNLOCKED; | ||
213 | } | 212 | } |
214 | 213 | ||
215 | static inline int rt_bandwidth_enabled(void) | 214 | static inline int rt_bandwidth_enabled(void) |
@@ -361,7 +360,9 @@ static inline struct task_group *task_group(struct task_struct *p) | |||
361 | struct task_group *tg; | 360 | struct task_group *tg; |
362 | 361 | ||
363 | #ifdef CONFIG_USER_SCHED | 362 | #ifdef CONFIG_USER_SCHED |
364 | tg = p->user->tg; | 363 | rcu_read_lock(); |
364 | tg = __task_cred(p)->user->tg; | ||
365 | rcu_read_unlock(); | ||
365 | #elif defined(CONFIG_CGROUP_SCHED) | 366 | #elif defined(CONFIG_CGROUP_SCHED) |
366 | tg = container_of(task_subsys_state(p, cpu_cgroup_subsys_id), | 367 | tg = container_of(task_subsys_state(p, cpu_cgroup_subsys_id), |
367 | struct task_group, css); | 368 | struct task_group, css); |
@@ -610,6 +611,8 @@ struct rq { | |||
610 | #ifdef CONFIG_SCHEDSTATS | 611 | #ifdef CONFIG_SCHEDSTATS |
611 | /* latency stats */ | 612 | /* latency stats */ |
612 | struct sched_info rq_sched_info; | 613 | struct sched_info rq_sched_info; |
614 | unsigned long long rq_cpu_time; | ||
615 | /* could above be rq->cfs_rq.exec_clock + rq->rt_rq.rt_runtime ? */ | ||
613 | 616 | ||
614 | /* sys_sched_yield() stats */ | 617 | /* sys_sched_yield() stats */ |
615 | unsigned int yld_exp_empty; | 618 | unsigned int yld_exp_empty; |
@@ -1143,7 +1146,6 @@ static void init_rq_hrtick(struct rq *rq) | |||
1143 | 1146 | ||
1144 | hrtimer_init(&rq->hrtick_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); | 1147 | hrtimer_init(&rq->hrtick_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); |
1145 | rq->hrtick_timer.function = hrtick; | 1148 | rq->hrtick_timer.function = hrtick; |
1146 | rq->hrtick_timer.cb_mode = HRTIMER_CB_IRQSAFE_PERCPU; | ||
1147 | } | 1149 | } |
1148 | #else /* CONFIG_SCHED_HRTICK */ | 1150 | #else /* CONFIG_SCHED_HRTICK */ |
1149 | static inline void hrtick_clear(struct rq *rq) | 1151 | static inline void hrtick_clear(struct rq *rq) |
@@ -1871,6 +1873,8 @@ void set_task_cpu(struct task_struct *p, unsigned int new_cpu) | |||
1871 | 1873 | ||
1872 | clock_offset = old_rq->clock - new_rq->clock; | 1874 | clock_offset = old_rq->clock - new_rq->clock; |
1873 | 1875 | ||
1876 | trace_sched_migrate_task(p, task_cpu(p), new_cpu); | ||
1877 | |||
1874 | #ifdef CONFIG_SCHEDSTATS | 1878 | #ifdef CONFIG_SCHEDSTATS |
1875 | if (p->se.wait_start) | 1879 | if (p->se.wait_start) |
1876 | p->se.wait_start -= clock_offset; | 1880 | p->se.wait_start -= clock_offset; |
@@ -2277,6 +2281,7 @@ static int try_to_wake_up(struct task_struct *p, unsigned int state, int sync) | |||
2277 | 2281 | ||
2278 | smp_wmb(); | 2282 | smp_wmb(); |
2279 | rq = task_rq_lock(p, &flags); | 2283 | rq = task_rq_lock(p, &flags); |
2284 | update_rq_clock(rq); | ||
2280 | old_state = p->state; | 2285 | old_state = p->state; |
2281 | if (!(old_state & state)) | 2286 | if (!(old_state & state)) |
2282 | goto out; | 2287 | goto out; |
@@ -2334,12 +2339,11 @@ out_activate: | |||
2334 | schedstat_inc(p, se.nr_wakeups_local); | 2339 | schedstat_inc(p, se.nr_wakeups_local); |
2335 | else | 2340 | else |
2336 | schedstat_inc(p, se.nr_wakeups_remote); | 2341 | schedstat_inc(p, se.nr_wakeups_remote); |
2337 | update_rq_clock(rq); | ||
2338 | activate_task(rq, p, 1); | 2342 | activate_task(rq, p, 1); |
2339 | success = 1; | 2343 | success = 1; |
2340 | 2344 | ||
2341 | out_running: | 2345 | out_running: |
2342 | trace_sched_wakeup(rq, p); | 2346 | trace_sched_wakeup(rq, p, success); |
2343 | check_preempt_curr(rq, p, sync); | 2347 | check_preempt_curr(rq, p, sync); |
2344 | 2348 | ||
2345 | p->state = TASK_RUNNING; | 2349 | p->state = TASK_RUNNING; |
@@ -2472,7 +2476,7 @@ void wake_up_new_task(struct task_struct *p, unsigned long clone_flags) | |||
2472 | p->sched_class->task_new(rq, p); | 2476 | p->sched_class->task_new(rq, p); |
2473 | inc_nr_running(rq); | 2477 | inc_nr_running(rq); |
2474 | } | 2478 | } |
2475 | trace_sched_wakeup_new(rq, p); | 2479 | trace_sched_wakeup_new(rq, p, 1); |
2476 | check_preempt_curr(rq, p, 0); | 2480 | check_preempt_curr(rq, p, 0); |
2477 | #ifdef CONFIG_SMP | 2481 | #ifdef CONFIG_SMP |
2478 | if (p->sched_class->task_wake_up) | 2482 | if (p->sched_class->task_wake_up) |
@@ -2851,7 +2855,6 @@ static void sched_migrate_task(struct task_struct *p, int dest_cpu) | |||
2851 | || unlikely(!cpu_active(dest_cpu))) | 2855 | || unlikely(!cpu_active(dest_cpu))) |
2852 | goto out; | 2856 | goto out; |
2853 | 2857 | ||
2854 | trace_sched_migrate_task(rq, p, dest_cpu); | ||
2855 | /* force the process onto the specified CPU */ | 2858 | /* force the process onto the specified CPU */ |
2856 | if (migrate_task(p, dest_cpu, &req)) { | 2859 | if (migrate_task(p, dest_cpu, &req)) { |
2857 | /* Need to wait for migration thread (might exit: take ref). */ | 2860 | /* Need to wait for migration thread (might exit: take ref). */ |
@@ -5187,6 +5190,22 @@ __setscheduler(struct rq *rq, struct task_struct *p, int policy, int prio) | |||
5187 | set_load_weight(p); | 5190 | set_load_weight(p); |
5188 | } | 5191 | } |
5189 | 5192 | ||
5193 | /* | ||
5194 | * check the target process has a UID that matches the current process's | ||
5195 | */ | ||
5196 | static bool check_same_owner(struct task_struct *p) | ||
5197 | { | ||
5198 | const struct cred *cred = current_cred(), *pcred; | ||
5199 | bool match; | ||
5200 | |||
5201 | rcu_read_lock(); | ||
5202 | pcred = __task_cred(p); | ||
5203 | match = (cred->euid == pcred->euid || | ||
5204 | cred->euid == pcred->uid); | ||
5205 | rcu_read_unlock(); | ||
5206 | return match; | ||
5207 | } | ||
5208 | |||
5190 | static int __sched_setscheduler(struct task_struct *p, int policy, | 5209 | static int __sched_setscheduler(struct task_struct *p, int policy, |
5191 | struct sched_param *param, bool user) | 5210 | struct sched_param *param, bool user) |
5192 | { | 5211 | { |
@@ -5246,8 +5265,7 @@ recheck: | |||
5246 | return -EPERM; | 5265 | return -EPERM; |
5247 | 5266 | ||
5248 | /* can't change other user's priorities */ | 5267 | /* can't change other user's priorities */ |
5249 | if ((current->euid != p->euid) && | 5268 | if (!check_same_owner(p)) |
5250 | (current->euid != p->uid)) | ||
5251 | return -EPERM; | 5269 | return -EPERM; |
5252 | } | 5270 | } |
5253 | 5271 | ||
@@ -5486,8 +5504,7 @@ long sched_setaffinity(pid_t pid, const struct cpumask *in_mask) | |||
5486 | goto out_free_cpus_allowed; | 5504 | goto out_free_cpus_allowed; |
5487 | } | 5505 | } |
5488 | retval = -EPERM; | 5506 | retval = -EPERM; |
5489 | if ((current->euid != p->euid) && (current->euid != p->uid) && | 5507 | if (!check_same_owner(p) && !capable(CAP_SYS_NICE)) |
5490 | !capable(CAP_SYS_NICE)) | ||
5491 | goto out_unlock; | 5508 | goto out_unlock; |
5492 | 5509 | ||
5493 | retval = security_task_setscheduler(p, 0, NULL); | 5510 | retval = security_task_setscheduler(p, 0, NULL); |
@@ -9423,6 +9440,41 @@ cpuacct_destroy(struct cgroup_subsys *ss, struct cgroup *cgrp) | |||
9423 | kfree(ca); | 9440 | kfree(ca); |
9424 | } | 9441 | } |
9425 | 9442 | ||
9443 | static u64 cpuacct_cpuusage_read(struct cpuacct *ca, int cpu) | ||
9444 | { | ||
9445 | u64 *cpuusage = percpu_ptr(ca->cpuusage, cpu); | ||
9446 | u64 data; | ||
9447 | |||
9448 | #ifndef CONFIG_64BIT | ||
9449 | /* | ||
9450 | * Take rq->lock to make 64-bit read safe on 32-bit platforms. | ||
9451 | */ | ||
9452 | spin_lock_irq(&cpu_rq(cpu)->lock); | ||
9453 | data = *cpuusage; | ||
9454 | spin_unlock_irq(&cpu_rq(cpu)->lock); | ||
9455 | #else | ||
9456 | data = *cpuusage; | ||
9457 | #endif | ||
9458 | |||
9459 | return data; | ||
9460 | } | ||
9461 | |||
9462 | static void cpuacct_cpuusage_write(struct cpuacct *ca, int cpu, u64 val) | ||
9463 | { | ||
9464 | u64 *cpuusage = percpu_ptr(ca->cpuusage, cpu); | ||
9465 | |||
9466 | #ifndef CONFIG_64BIT | ||
9467 | /* | ||
9468 | * Take rq->lock to make 64-bit write safe on 32-bit platforms. | ||
9469 | */ | ||
9470 | spin_lock_irq(&cpu_rq(cpu)->lock); | ||
9471 | *cpuusage = val; | ||
9472 | spin_unlock_irq(&cpu_rq(cpu)->lock); | ||
9473 | #else | ||
9474 | *cpuusage = val; | ||
9475 | #endif | ||
9476 | } | ||
9477 | |||
9426 | /* return total cpu usage (in nanoseconds) of a group */ | 9478 | /* return total cpu usage (in nanoseconds) of a group */ |
9427 | static u64 cpuusage_read(struct cgroup *cgrp, struct cftype *cft) | 9479 | static u64 cpuusage_read(struct cgroup *cgrp, struct cftype *cft) |
9428 | { | 9480 | { |
@@ -9430,17 +9482,8 @@ static u64 cpuusage_read(struct cgroup *cgrp, struct cftype *cft) | |||
9430 | u64 totalcpuusage = 0; | 9482 | u64 totalcpuusage = 0; |
9431 | int i; | 9483 | int i; |
9432 | 9484 | ||
9433 | for_each_possible_cpu(i) { | 9485 | for_each_present_cpu(i) |
9434 | u64 *cpuusage = percpu_ptr(ca->cpuusage, i); | 9486 | totalcpuusage += cpuacct_cpuusage_read(ca, i); |
9435 | |||
9436 | /* | ||
9437 | * Take rq->lock to make 64-bit addition safe on 32-bit | ||
9438 | * platforms. | ||
9439 | */ | ||
9440 | spin_lock_irq(&cpu_rq(i)->lock); | ||
9441 | totalcpuusage += *cpuusage; | ||
9442 | spin_unlock_irq(&cpu_rq(i)->lock); | ||
9443 | } | ||
9444 | 9487 | ||
9445 | return totalcpuusage; | 9488 | return totalcpuusage; |
9446 | } | 9489 | } |
@@ -9457,23 +9500,39 @@ static int cpuusage_write(struct cgroup *cgrp, struct cftype *cftype, | |||
9457 | goto out; | 9500 | goto out; |
9458 | } | 9501 | } |
9459 | 9502 | ||
9460 | for_each_possible_cpu(i) { | 9503 | for_each_present_cpu(i) |
9461 | u64 *cpuusage = percpu_ptr(ca->cpuusage, i); | 9504 | cpuacct_cpuusage_write(ca, i, 0); |
9462 | 9505 | ||
9463 | spin_lock_irq(&cpu_rq(i)->lock); | ||
9464 | *cpuusage = 0; | ||
9465 | spin_unlock_irq(&cpu_rq(i)->lock); | ||
9466 | } | ||
9467 | out: | 9506 | out: |
9468 | return err; | 9507 | return err; |
9469 | } | 9508 | } |
9470 | 9509 | ||
9510 | static int cpuacct_percpu_seq_read(struct cgroup *cgroup, struct cftype *cft, | ||
9511 | struct seq_file *m) | ||
9512 | { | ||
9513 | struct cpuacct *ca = cgroup_ca(cgroup); | ||
9514 | u64 percpu; | ||
9515 | int i; | ||
9516 | |||
9517 | for_each_present_cpu(i) { | ||
9518 | percpu = cpuacct_cpuusage_read(ca, i); | ||
9519 | seq_printf(m, "%llu ", (unsigned long long) percpu); | ||
9520 | } | ||
9521 | seq_printf(m, "\n"); | ||
9522 | return 0; | ||
9523 | } | ||
9524 | |||
9471 | static struct cftype files[] = { | 9525 | static struct cftype files[] = { |
9472 | { | 9526 | { |
9473 | .name = "usage", | 9527 | .name = "usage", |
9474 | .read_u64 = cpuusage_read, | 9528 | .read_u64 = cpuusage_read, |
9475 | .write_u64 = cpuusage_write, | 9529 | .write_u64 = cpuusage_write, |
9476 | }, | 9530 | }, |
9531 | { | ||
9532 | .name = "usage_percpu", | ||
9533 | .read_seq_string = cpuacct_percpu_seq_read, | ||
9534 | }, | ||
9535 | |||
9477 | }; | 9536 | }; |
9478 | 9537 | ||
9479 | static int cpuacct_populate(struct cgroup_subsys *ss, struct cgroup *cgrp) | 9538 | static int cpuacct_populate(struct cgroup_subsys *ss, struct cgroup *cgrp) |