aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/sched.c
diff options
context:
space:
mode:
authorMike Travis <travis@sgi.com>2008-12-31 20:34:16 -0500
committerIngo Molnar <mingo@elte.hu>2009-01-03 12:53:31 -0500
commit7eb19553369c46cc1fa64caf120cbcab1b597f7c (patch)
treeef1a3beae706b9497c845d0a2557ceb4d2754998 /kernel/sched.c
parent6092848a2a23b660150a38bc06f59d75838d70c8 (diff)
parent8c384cdee3e04d6194a2c2b192b624754f990835 (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.c115
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
215static inline int rt_bandwidth_enabled(void) 214static 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 */
1149static inline void hrtick_clear(struct rq *rq) 1151static 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
2341out_running: 2345out_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 */
5196static 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
5190static int __sched_setscheduler(struct task_struct *p, int policy, 5209static 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
9443static 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
9462static 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 */
9427static u64 cpuusage_read(struct cgroup *cgrp, struct cftype *cft) 9479static 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 }
9467out: 9506out:
9468 return err; 9507 return err;
9469} 9508}
9470 9509
9510static 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
9471static struct cftype files[] = { 9525static 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
9479static int cpuacct_populate(struct cgroup_subsys *ss, struct cgroup *cgrp) 9538static int cpuacct_populate(struct cgroup_subsys *ss, struct cgroup *cgrp)