diff options
Diffstat (limited to 'kernel/sched.c')
-rw-r--r-- | kernel/sched.c | 55 |
1 files changed, 53 insertions, 2 deletions
diff --git a/kernel/sched.c b/kernel/sched.c index 591d5e7f757a..c74b0d23c752 100644 --- a/kernel/sched.c +++ b/kernel/sched.c | |||
@@ -70,6 +70,7 @@ | |||
70 | #include <linux/bootmem.h> | 70 | #include <linux/bootmem.h> |
71 | #include <linux/debugfs.h> | 71 | #include <linux/debugfs.h> |
72 | #include <linux/ctype.h> | 72 | #include <linux/ctype.h> |
73 | #include <linux/ftrace.h> | ||
73 | 74 | ||
74 | #include <asm/tlb.h> | 75 | #include <asm/tlb.h> |
75 | #include <asm/irq_regs.h> | 76 | #include <asm/irq_regs.h> |
@@ -645,6 +646,24 @@ static inline void update_rq_clock(struct rq *rq) | |||
645 | # define const_debug static const | 646 | # define const_debug static const |
646 | #endif | 647 | #endif |
647 | 648 | ||
649 | /** | ||
650 | * runqueue_is_locked | ||
651 | * | ||
652 | * Returns true if the current cpu runqueue is locked. | ||
653 | * This interface allows printk to be called with the runqueue lock | ||
654 | * held and know whether or not it is OK to wake up the klogd. | ||
655 | */ | ||
656 | int runqueue_is_locked(void) | ||
657 | { | ||
658 | int cpu = get_cpu(); | ||
659 | struct rq *rq = cpu_rq(cpu); | ||
660 | int ret; | ||
661 | |||
662 | ret = spin_is_locked(&rq->lock); | ||
663 | put_cpu(); | ||
664 | return ret; | ||
665 | } | ||
666 | |||
648 | /* | 667 | /* |
649 | * Debugging: various feature bits | 668 | * Debugging: various feature bits |
650 | */ | 669 | */ |
@@ -2318,6 +2337,9 @@ out_activate: | |||
2318 | success = 1; | 2337 | success = 1; |
2319 | 2338 | ||
2320 | out_running: | 2339 | out_running: |
2340 | trace_mark(kernel_sched_wakeup, | ||
2341 | "pid %d state %ld ## rq %p task %p rq->curr %p", | ||
2342 | p->pid, p->state, rq, p, rq->curr); | ||
2321 | check_preempt_curr(rq, p); | 2343 | check_preempt_curr(rq, p); |
2322 | 2344 | ||
2323 | p->state = TASK_RUNNING; | 2345 | p->state = TASK_RUNNING; |
@@ -2450,6 +2472,9 @@ void wake_up_new_task(struct task_struct *p, unsigned long clone_flags) | |||
2450 | p->sched_class->task_new(rq, p); | 2472 | p->sched_class->task_new(rq, p); |
2451 | inc_nr_running(rq); | 2473 | inc_nr_running(rq); |
2452 | } | 2474 | } |
2475 | trace_mark(kernel_sched_wakeup_new, | ||
2476 | "pid %d state %ld ## rq %p task %p rq->curr %p", | ||
2477 | p->pid, p->state, rq, p, rq->curr); | ||
2453 | check_preempt_curr(rq, p); | 2478 | check_preempt_curr(rq, p); |
2454 | #ifdef CONFIG_SMP | 2479 | #ifdef CONFIG_SMP |
2455 | if (p->sched_class->task_wake_up) | 2480 | if (p->sched_class->task_wake_up) |
@@ -2622,6 +2647,11 @@ context_switch(struct rq *rq, struct task_struct *prev, | |||
2622 | struct mm_struct *mm, *oldmm; | 2647 | struct mm_struct *mm, *oldmm; |
2623 | 2648 | ||
2624 | prepare_task_switch(rq, prev, next); | 2649 | prepare_task_switch(rq, prev, next); |
2650 | trace_mark(kernel_sched_schedule, | ||
2651 | "prev_pid %d next_pid %d prev_state %ld " | ||
2652 | "## rq %p prev %p next %p", | ||
2653 | prev->pid, next->pid, prev->state, | ||
2654 | rq, prev, next); | ||
2625 | mm = next->mm; | 2655 | mm = next->mm; |
2626 | oldmm = prev->active_mm; | 2656 | oldmm = prev->active_mm; |
2627 | /* | 2657 | /* |
@@ -4221,26 +4251,44 @@ void scheduler_tick(void) | |||
4221 | #endif | 4251 | #endif |
4222 | } | 4252 | } |
4223 | 4253 | ||
4224 | #if defined(CONFIG_PREEMPT) && defined(CONFIG_DEBUG_PREEMPT) | 4254 | #if defined(CONFIG_PREEMPT) && (defined(CONFIG_DEBUG_PREEMPT) || \ |
4255 | defined(CONFIG_PREEMPT_TRACER)) | ||
4256 | |||
4257 | static inline unsigned long get_parent_ip(unsigned long addr) | ||
4258 | { | ||
4259 | if (in_lock_functions(addr)) { | ||
4260 | addr = CALLER_ADDR2; | ||
4261 | if (in_lock_functions(addr)) | ||
4262 | addr = CALLER_ADDR3; | ||
4263 | } | ||
4264 | return addr; | ||
4265 | } | ||
4225 | 4266 | ||
4226 | void __kprobes add_preempt_count(int val) | 4267 | void __kprobes add_preempt_count(int val) |
4227 | { | 4268 | { |
4269 | #ifdef CONFIG_DEBUG_PREEMPT | ||
4228 | /* | 4270 | /* |
4229 | * Underflow? | 4271 | * Underflow? |
4230 | */ | 4272 | */ |
4231 | if (DEBUG_LOCKS_WARN_ON((preempt_count() < 0))) | 4273 | if (DEBUG_LOCKS_WARN_ON((preempt_count() < 0))) |
4232 | return; | 4274 | return; |
4275 | #endif | ||
4233 | preempt_count() += val; | 4276 | preempt_count() += val; |
4277 | #ifdef CONFIG_DEBUG_PREEMPT | ||
4234 | /* | 4278 | /* |
4235 | * Spinlock count overflowing soon? | 4279 | * Spinlock count overflowing soon? |
4236 | */ | 4280 | */ |
4237 | DEBUG_LOCKS_WARN_ON((preempt_count() & PREEMPT_MASK) >= | 4281 | DEBUG_LOCKS_WARN_ON((preempt_count() & PREEMPT_MASK) >= |
4238 | PREEMPT_MASK - 10); | 4282 | PREEMPT_MASK - 10); |
4283 | #endif | ||
4284 | if (preempt_count() == val) | ||
4285 | trace_preempt_off(CALLER_ADDR0, get_parent_ip(CALLER_ADDR1)); | ||
4239 | } | 4286 | } |
4240 | EXPORT_SYMBOL(add_preempt_count); | 4287 | EXPORT_SYMBOL(add_preempt_count); |
4241 | 4288 | ||
4242 | void __kprobes sub_preempt_count(int val) | 4289 | void __kprobes sub_preempt_count(int val) |
4243 | { | 4290 | { |
4291 | #ifdef CONFIG_DEBUG_PREEMPT | ||
4244 | /* | 4292 | /* |
4245 | * Underflow? | 4293 | * Underflow? |
4246 | */ | 4294 | */ |
@@ -4252,7 +4300,10 @@ void __kprobes sub_preempt_count(int val) | |||
4252 | if (DEBUG_LOCKS_WARN_ON((val < PREEMPT_MASK) && | 4300 | if (DEBUG_LOCKS_WARN_ON((val < PREEMPT_MASK) && |
4253 | !(preempt_count() & PREEMPT_MASK))) | 4301 | !(preempt_count() & PREEMPT_MASK))) |
4254 | return; | 4302 | return; |
4303 | #endif | ||
4255 | 4304 | ||
4305 | if (preempt_count() == val) | ||
4306 | trace_preempt_on(CALLER_ADDR0, get_parent_ip(CALLER_ADDR1)); | ||
4256 | preempt_count() -= val; | 4307 | preempt_count() -= val; |
4257 | } | 4308 | } |
4258 | EXPORT_SYMBOL(sub_preempt_count); | 4309 | EXPORT_SYMBOL(sub_preempt_count); |
@@ -5566,7 +5617,7 @@ out_unlock: | |||
5566 | return retval; | 5617 | return retval; |
5567 | } | 5618 | } |
5568 | 5619 | ||
5569 | static const char stat_nam[] = "RSDTtZX"; | 5620 | static const char stat_nam[] = TASK_STATE_TO_CHAR_STR; |
5570 | 5621 | ||
5571 | void sched_show_task(struct task_struct *p) | 5622 | void sched_show_task(struct task_struct *p) |
5572 | { | 5623 | { |