diff options
Diffstat (limited to 'kernel/sched.c')
-rw-r--r-- | kernel/sched.c | 24 |
1 files changed, 23 insertions, 1 deletions
diff --git a/kernel/sched.c b/kernel/sched.c index 73e600852365..328494e28df2 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> |
@@ -4365,26 +4366,44 @@ void scheduler_tick(void) | |||
4365 | #endif | 4366 | #endif |
4366 | } | 4367 | } |
4367 | 4368 | ||
4368 | #if defined(CONFIG_PREEMPT) && defined(CONFIG_DEBUG_PREEMPT) | 4369 | #if defined(CONFIG_PREEMPT) && (defined(CONFIG_DEBUG_PREEMPT) || \ |
4370 | defined(CONFIG_PREEMPT_TRACER)) | ||
4371 | |||
4372 | static inline unsigned long get_parent_ip(unsigned long addr) | ||
4373 | { | ||
4374 | if (in_lock_functions(addr)) { | ||
4375 | addr = CALLER_ADDR2; | ||
4376 | if (in_lock_functions(addr)) | ||
4377 | addr = CALLER_ADDR3; | ||
4378 | } | ||
4379 | return addr; | ||
4380 | } | ||
4369 | 4381 | ||
4370 | void __kprobes add_preempt_count(int val) | 4382 | void __kprobes add_preempt_count(int val) |
4371 | { | 4383 | { |
4384 | #ifdef CONFIG_DEBUG_PREEMPT | ||
4372 | /* | 4385 | /* |
4373 | * Underflow? | 4386 | * Underflow? |
4374 | */ | 4387 | */ |
4375 | if (DEBUG_LOCKS_WARN_ON((preempt_count() < 0))) | 4388 | if (DEBUG_LOCKS_WARN_ON((preempt_count() < 0))) |
4376 | return; | 4389 | return; |
4390 | #endif | ||
4377 | preempt_count() += val; | 4391 | preempt_count() += val; |
4392 | #ifdef CONFIG_DEBUG_PREEMPT | ||
4378 | /* | 4393 | /* |
4379 | * Spinlock count overflowing soon? | 4394 | * Spinlock count overflowing soon? |
4380 | */ | 4395 | */ |
4381 | DEBUG_LOCKS_WARN_ON((preempt_count() & PREEMPT_MASK) >= | 4396 | DEBUG_LOCKS_WARN_ON((preempt_count() & PREEMPT_MASK) >= |
4382 | PREEMPT_MASK - 10); | 4397 | PREEMPT_MASK - 10); |
4398 | #endif | ||
4399 | if (preempt_count() == val) | ||
4400 | trace_preempt_off(CALLER_ADDR0, get_parent_ip(CALLER_ADDR1)); | ||
4383 | } | 4401 | } |
4384 | EXPORT_SYMBOL(add_preempt_count); | 4402 | EXPORT_SYMBOL(add_preempt_count); |
4385 | 4403 | ||
4386 | void __kprobes sub_preempt_count(int val) | 4404 | void __kprobes sub_preempt_count(int val) |
4387 | { | 4405 | { |
4406 | #ifdef CONFIG_DEBUG_PREEMPT | ||
4388 | /* | 4407 | /* |
4389 | * Underflow? | 4408 | * Underflow? |
4390 | */ | 4409 | */ |
@@ -4396,7 +4415,10 @@ void __kprobes sub_preempt_count(int val) | |||
4396 | if (DEBUG_LOCKS_WARN_ON((val < PREEMPT_MASK) && | 4415 | if (DEBUG_LOCKS_WARN_ON((val < PREEMPT_MASK) && |
4397 | !(preempt_count() & PREEMPT_MASK))) | 4416 | !(preempt_count() & PREEMPT_MASK))) |
4398 | return; | 4417 | return; |
4418 | #endif | ||
4399 | 4419 | ||
4420 | if (preempt_count() == val) | ||
4421 | trace_preempt_on(CALLER_ADDR0, get_parent_ip(CALLER_ADDR1)); | ||
4400 | preempt_count() -= val; | 4422 | preempt_count() -= val; |
4401 | } | 4423 | } |
4402 | EXPORT_SYMBOL(sub_preempt_count); | 4424 | EXPORT_SYMBOL(sub_preempt_count); |