aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/sched.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/sched.c')
-rw-r--r--kernel/sched.c55
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 */
656int 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
2320out_running: 2339out_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
4257static 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
4226void __kprobes add_preempt_count(int val) 4267void __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}
4240EXPORT_SYMBOL(add_preempt_count); 4287EXPORT_SYMBOL(add_preempt_count);
4241 4288
4242void __kprobes sub_preempt_count(int val) 4289void __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}
4258EXPORT_SYMBOL(sub_preempt_count); 4309EXPORT_SYMBOL(sub_preempt_count);
@@ -5566,7 +5617,7 @@ out_unlock:
5566 return retval; 5617 return retval;
5567} 5618}
5568 5619
5569static const char stat_nam[] = "RSDTtZX"; 5620static const char stat_nam[] = TASK_STATE_TO_CHAR_STR;
5570 5621
5571void sched_show_task(struct task_struct *p) 5622void sched_show_task(struct task_struct *p)
5572{ 5623{