diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2009-06-11 17:01:07 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2009-06-11 17:01:07 -0400 |
commit | 8a1ca8cedd108c8e76a6ab34079d0bbb4f244799 (patch) | |
tree | 636c715524f1718599209cc289908ea44b6cb859 /kernel/sched.c | |
parent | b640f042faa2a2fad6464f259a8afec06e2f6386 (diff) | |
parent | 940010c5a314a7bd9b498593bc6ba1718ac5aec5 (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.c | 57 |
1 files changed, 51 insertions, 6 deletions
diff --git a/kernel/sched.c b/kernel/sched.c index dcf2dc28931a..f04aa9664504 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 | ||
694 | static inline void update_rq_clock(struct rq *rq) | 696 | inline 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 | */ | ||
2386 | void 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 | */ | ||
3015 | u64 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 | */ |
7541 | static struct notifier_block __cpuinitdata migration_notifier = { | 7584 | static 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 | ||