aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/sched.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2009-06-11 17:01:07 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2009-06-11 17:01:07 -0400
commit8a1ca8cedd108c8e76a6ab34079d0bbb4f244799 (patch)
tree636c715524f1718599209cc289908ea44b6cb859 /kernel/sched.c
parentb640f042faa2a2fad6464f259a8afec06e2f6386 (diff)
parent940010c5a314a7bd9b498593bc6ba1718ac5aec5 (diff)
Merge branch 'perfcounters-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip
* 'perfcounters-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip: (574 commits) perf_counter: Turn off by default perf_counter: Add counter->id to the throttle event perf_counter: Better align code perf_counter: Rename L2 to LL cache perf_counter: Standardize event names perf_counter: Rename enums perf_counter tools: Clean up u64 usage perf_counter: Rename perf_counter_limit sysctl perf_counter: More paranoia settings perf_counter: powerpc: Implement generalized cache events for POWER processors perf_counters: powerpc: Add support for POWER7 processors perf_counter: Accurate period data perf_counter: Introduce struct for sample data perf_counter tools: Normalize data using per sample period data perf_counter: Annotate exit ctx recursion perf_counter tools: Propagate signals properly perf_counter tools: Small frequency related fixes perf_counter: More aggressive frequency adjustment perf_counter/x86: Fix the model number of Intel Core2 processors perf_counter, x86: Correct some event and umask values for Intel processors ...
Diffstat (limited to 'kernel/sched.c')
-rw-r--r--kernel/sched.c57
1 files changed, 51 insertions, 6 deletions
diff --git a/kernel/sched.c b/kernel/sched.c
index dcf2dc28931..f04aa966450 100644
--- a/kernel/sched.c
+++ b/kernel/sched.c
@@ -39,6 +39,7 @@
39#include <linux/completion.h> 39#include <linux/completion.h>
40#include <linux/kernel_stat.h> 40#include <linux/kernel_stat.h>
41#include <linux/debug_locks.h> 41#include <linux/debug_locks.h>
42#include <linux/perf_counter.h>
42#include <linux/security.h> 43#include <linux/security.h>
43#include <linux/notifier.h> 44#include <linux/notifier.h>
44#include <linux/profile.h> 45#include <linux/profile.h>
@@ -579,6 +580,7 @@ struct rq {
579 struct load_weight load; 580 struct load_weight load;
580 unsigned long nr_load_updates; 581 unsigned long nr_load_updates;
581 u64 nr_switches; 582 u64 nr_switches;
583 u64 nr_migrations_in;
582 584
583 struct cfs_rq cfs; 585 struct cfs_rq cfs;
584 struct rt_rq rt; 586 struct rt_rq rt;
@@ -691,7 +693,7 @@ static inline int cpu_of(struct rq *rq)
691#define task_rq(p) cpu_rq(task_cpu(p)) 693#define task_rq(p) cpu_rq(task_cpu(p))
692#define cpu_curr(cpu) (cpu_rq(cpu)->curr) 694#define cpu_curr(cpu) (cpu_rq(cpu)->curr)
693 695
694static inline void update_rq_clock(struct rq *rq) 696inline void update_rq_clock(struct rq *rq)
695{ 697{
696 rq->clock = sched_clock_cpu(cpu_of(rq)); 698 rq->clock = sched_clock_cpu(cpu_of(rq));
697} 699}
@@ -1968,12 +1970,16 @@ void set_task_cpu(struct task_struct *p, unsigned int new_cpu)
1968 p->se.sleep_start -= clock_offset; 1970 p->se.sleep_start -= clock_offset;
1969 if (p->se.block_start) 1971 if (p->se.block_start)
1970 p->se.block_start -= clock_offset; 1972 p->se.block_start -= clock_offset;
1973#endif
1971 if (old_cpu != new_cpu) { 1974 if (old_cpu != new_cpu) {
1972 schedstat_inc(p, se.nr_migrations); 1975 p->se.nr_migrations++;
1976 new_rq->nr_migrations_in++;
1977#ifdef CONFIG_SCHEDSTATS
1973 if (task_hot(p, old_rq->clock, NULL)) 1978 if (task_hot(p, old_rq->clock, NULL))
1974 schedstat_inc(p, se.nr_forced2_migrations); 1979 schedstat_inc(p, se.nr_forced2_migrations);
1975 }
1976#endif 1980#endif
1981 perf_counter_task_migration(p, new_cpu);
1982 }
1977 p->se.vruntime -= old_cfsrq->min_vruntime - 1983 p->se.vruntime -= old_cfsrq->min_vruntime -
1978 new_cfsrq->min_vruntime; 1984 new_cfsrq->min_vruntime;
1979 1985
@@ -2368,6 +2374,27 @@ static int sched_balance_self(int cpu, int flag)
2368 2374
2369#endif /* CONFIG_SMP */ 2375#endif /* CONFIG_SMP */
2370 2376
2377/**
2378 * task_oncpu_function_call - call a function on the cpu on which a task runs
2379 * @p: the task to evaluate
2380 * @func: the function to be called
2381 * @info: the function call argument
2382 *
2383 * Calls the function @func when the task is currently running. This might
2384 * be on the current CPU, which just calls the function directly
2385 */
2386void task_oncpu_function_call(struct task_struct *p,
2387 void (*func) (void *info), void *info)
2388{
2389 int cpu;
2390
2391 preempt_disable();
2392 cpu = task_cpu(p);
2393 if (task_curr(p))
2394 smp_call_function_single(cpu, func, info, 1);
2395 preempt_enable();
2396}
2397
2371/*** 2398/***
2372 * try_to_wake_up - wake up a thread 2399 * try_to_wake_up - wake up a thread
2373 * @p: the to-be-woken-up thread 2400 * @p: the to-be-woken-up thread
@@ -2535,6 +2562,7 @@ static void __sched_fork(struct task_struct *p)
2535 p->se.exec_start = 0; 2562 p->se.exec_start = 0;
2536 p->se.sum_exec_runtime = 0; 2563 p->se.sum_exec_runtime = 0;
2537 p->se.prev_sum_exec_runtime = 0; 2564 p->se.prev_sum_exec_runtime = 0;
2565 p->se.nr_migrations = 0;
2538 p->se.last_wakeup = 0; 2566 p->se.last_wakeup = 0;
2539 p->se.avg_overlap = 0; 2567 p->se.avg_overlap = 0;
2540 p->se.start_runtime = 0; 2568 p->se.start_runtime = 0;
@@ -2765,6 +2793,7 @@ static void finish_task_switch(struct rq *rq, struct task_struct *prev)
2765 */ 2793 */
2766 prev_state = prev->state; 2794 prev_state = prev->state;
2767 finish_arch_switch(prev); 2795 finish_arch_switch(prev);
2796 perf_counter_task_sched_in(current, cpu_of(rq));
2768 finish_lock_switch(rq, prev); 2797 finish_lock_switch(rq, prev);
2769#ifdef CONFIG_SMP 2798#ifdef CONFIG_SMP
2770 if (post_schedule) 2799 if (post_schedule)
@@ -2980,6 +3009,15 @@ static void calc_load_account_active(struct rq *this_rq)
2980} 3009}
2981 3010
2982/* 3011/*
3012 * Externally visible per-cpu scheduler statistics:
3013 * cpu_nr_migrations(cpu) - number of migrations into that cpu
3014 */
3015u64 cpu_nr_migrations(int cpu)
3016{
3017 return cpu_rq(cpu)->nr_migrations_in;
3018}
3019
3020/*
2983 * Update rq->cpu_load[] statistics. This function is usually called every 3021 * Update rq->cpu_load[] statistics. This function is usually called every
2984 * scheduler tick (TICK_NSEC). 3022 * scheduler tick (TICK_NSEC).
2985 */ 3023 */
@@ -5077,6 +5115,8 @@ void scheduler_tick(void)
5077 curr->sched_class->task_tick(rq, curr, 0); 5115 curr->sched_class->task_tick(rq, curr, 0);
5078 spin_unlock(&rq->lock); 5116 spin_unlock(&rq->lock);
5079 5117
5118 perf_counter_task_tick(curr, cpu);
5119
5080#ifdef CONFIG_SMP 5120#ifdef CONFIG_SMP
5081 rq->idle_at_tick = idle_cpu(cpu); 5121 rq->idle_at_tick = idle_cpu(cpu);
5082 trigger_load_balance(rq, cpu); 5122 trigger_load_balance(rq, cpu);
@@ -5292,6 +5332,7 @@ need_resched_nonpreemptible:
5292 5332
5293 if (likely(prev != next)) { 5333 if (likely(prev != next)) {
5294 sched_info_switch(prev, next); 5334 sched_info_switch(prev, next);
5335 perf_counter_task_sched_out(prev, next, cpu);
5295 5336
5296 rq->nr_switches++; 5337 rq->nr_switches++;
5297 rq->curr = next; 5338 rq->curr = next;
@@ -7535,8 +7576,10 @@ migration_call(struct notifier_block *nfb, unsigned long action, void *hcpu)
7535 return NOTIFY_OK; 7576 return NOTIFY_OK;
7536} 7577}
7537 7578
7538/* Register at highest priority so that task migration (migrate_all_tasks) 7579/*
7539 * happens before everything else. 7580 * Register at high priority so that task migration (migrate_all_tasks)
7581 * happens before everything else. This has to be lower priority than
7582 * the notifier in the perf_counter subsystem, though.
7540 */ 7583 */
7541static struct notifier_block __cpuinitdata migration_notifier = { 7584static struct notifier_block __cpuinitdata migration_notifier = {
7542 .notifier_call = migration_call, 7585 .notifier_call = migration_call,
@@ -9214,7 +9257,7 @@ void __init sched_init(void)
9214 * 1024) and two child groups A0 and A1 (of weight 1024 each), 9257 * 1024) and two child groups A0 and A1 (of weight 1024 each),
9215 * then A0's share of the cpu resource is: 9258 * then A0's share of the cpu resource is:
9216 * 9259 *
9217 * A0's bandwidth = 1024 / (10*1024 + 1024 + 1024) = 8.33% 9260 * A0's bandwidth = 1024 / (10*1024 + 1024 + 1024) = 8.33%
9218 * 9261 *
9219 * We achieve this by letting init_task_group's tasks sit 9262 * We achieve this by letting init_task_group's tasks sit
9220 * directly in rq->cfs (i.e init_task_group->se[] = NULL). 9263 * directly in rq->cfs (i.e init_task_group->se[] = NULL).
@@ -9319,6 +9362,8 @@ void __init sched_init(void)
9319 alloc_cpumask_var(&cpu_isolated_map, GFP_NOWAIT); 9362 alloc_cpumask_var(&cpu_isolated_map, GFP_NOWAIT);
9320#endif /* SMP */ 9363#endif /* SMP */
9321 9364
9365 perf_counter_init();
9366
9322 scheduler_running = 1; 9367 scheduler_running = 1;
9323} 9368}
9324 9369