aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/sched.c
diff options
context:
space:
mode:
authorThomas Gleixner <tglx@linutronix.de>2008-12-04 14:12:29 -0500
committerIngo Molnar <mingo@elte.hu>2008-12-08 09:47:03 -0500
commit0793a61d4df8daeac6492dbf8d2f3e5713caae5e (patch)
treecc9603eb8daffeb7ace521c42a6a44db164ac551 /kernel/sched.c
parentb5aa97e83bcc31a96374d18f5452d53909a16c90 (diff)
performance counters: core code
Implement the core kernel bits of Performance Counters subsystem. The Linux Performance Counter subsystem provides an abstraction of performance counter hardware capabilities. It provides per task and per CPU counters, and it provides event capabilities on top of those. Performance counters are accessed via special file descriptors. There's one file descriptor per virtual counter used. The special file descriptor is opened via the perf_counter_open() system call: int perf_counter_open(u32 hw_event_type, u32 hw_event_period, u32 record_type, pid_t pid, int cpu); The syscall returns the new fd. The fd can be used via the normal VFS system calls: read() can be used to read the counter, fcntl() can be used to set the blocking mode, etc. Multiple counters can be kept open at a time, and the counters can be poll()ed. See more details in Documentation/perf-counters.txt. Signed-off-by: Thomas Gleixner <tglx@linutronix.de> Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'kernel/sched.c')
-rw-r--r--kernel/sched.c24
1 files changed, 24 insertions, 0 deletions
diff --git a/kernel/sched.c b/kernel/sched.c
index b7480fb5c3dc..254d56de2548 100644
--- a/kernel/sched.c
+++ b/kernel/sched.c
@@ -2212,6 +2212,27 @@ static int sched_balance_self(int cpu, int flag)
2212 2212
2213#endif /* CONFIG_SMP */ 2213#endif /* CONFIG_SMP */
2214 2214
2215/**
2216 * task_oncpu_function_call - call a function on the cpu on which a task runs
2217 * @p: the task to evaluate
2218 * @func: the function to be called
2219 * @info: the function call argument
2220 *
2221 * Calls the function @func when the task is currently running. This might
2222 * be on the current CPU, which just calls the function directly
2223 */
2224void task_oncpu_function_call(struct task_struct *p,
2225 void (*func) (void *info), void *info)
2226{
2227 int cpu;
2228
2229 preempt_disable();
2230 cpu = task_cpu(p);
2231 if (task_curr(p))
2232 smp_call_function_single(cpu, func, info, 1);
2233 preempt_enable();
2234}
2235
2215/*** 2236/***
2216 * try_to_wake_up - wake up a thread 2237 * try_to_wake_up - wake up a thread
2217 * @p: the to-be-woken-up thread 2238 * @p: the to-be-woken-up thread
@@ -2534,6 +2555,7 @@ prepare_task_switch(struct rq *rq, struct task_struct *prev,
2534 struct task_struct *next) 2555 struct task_struct *next)
2535{ 2556{
2536 fire_sched_out_preempt_notifiers(prev, next); 2557 fire_sched_out_preempt_notifiers(prev, next);
2558 perf_counter_task_sched_out(prev, cpu_of(rq));
2537 prepare_lock_switch(rq, next); 2559 prepare_lock_switch(rq, next);
2538 prepare_arch_switch(next); 2560 prepare_arch_switch(next);
2539} 2561}
@@ -2574,6 +2596,7 @@ static void finish_task_switch(struct rq *rq, struct task_struct *prev)
2574 */ 2596 */
2575 prev_state = prev->state; 2597 prev_state = prev->state;
2576 finish_arch_switch(prev); 2598 finish_arch_switch(prev);
2599 perf_counter_task_sched_in(current, cpu_of(rq));
2577 finish_lock_switch(rq, prev); 2600 finish_lock_switch(rq, prev);
2578#ifdef CONFIG_SMP 2601#ifdef CONFIG_SMP
2579 if (current->sched_class->post_schedule) 2602 if (current->sched_class->post_schedule)
@@ -4296,6 +4319,7 @@ void scheduler_tick(void)
4296 rq->idle_at_tick = idle_cpu(cpu); 4319 rq->idle_at_tick = idle_cpu(cpu);
4297 trigger_load_balance(rq, cpu); 4320 trigger_load_balance(rq, cpu);
4298#endif 4321#endif
4322 perf_counter_task_tick(curr, cpu);
4299} 4323}
4300 4324
4301#if defined(CONFIG_PREEMPT) && (defined(CONFIG_DEBUG_PREEMPT) || \ 4325#if defined(CONFIG_PREEMPT) && (defined(CONFIG_DEBUG_PREEMPT) || \