diff options
author | Jason Wessel <jason.wessel@windriver.com> | 2009-06-03 15:06:57 -0400 |
---|---|---|
committer | Jason Wessel <jason.wessel@windriver.com> | 2010-05-20 22:04:26 -0400 |
commit | 1cee5e35f15d0893be1ba944f1aec8676e43ab76 (patch) | |
tree | 634f5365300cfb555c8e894ade79735bb91a690e /kernel | |
parent | 5dd11d5d47d248850c58292513f0e164ba98b01e (diff) |
kgdb: Add the ability to schedule a breakpoint via a tasklet
Some kgdb I/O modules require the ability to create a breakpoint
tasklet, such as kgdboc and external modules such as kgdboe. The
breakpoint tasklet is used as an asynchronous entry point into the
debugger which will have a different function scope than the current
execution path where it might not be safe to have an inline
breakpoint. This is true of some of the kgdb I/O drivers which share
code with kgdb and rest of the kernel users.
Signed-off-by: Jason Wessel <jason.wessel@windriver.com>
Diffstat (limited to 'kernel')
-rw-r--r-- | kernel/debug/debug_core.c | 26 |
1 files changed, 26 insertions, 0 deletions
diff --git a/kernel/debug/debug_core.c b/kernel/debug/debug_core.c index 375e42f0baf0..fff59019cca0 100644 --- a/kernel/debug/debug_core.c +++ b/kernel/debug/debug_core.c | |||
@@ -114,6 +114,7 @@ EXPORT_SYMBOL_GPL(kgdb_active); | |||
114 | */ | 114 | */ |
115 | static atomic_t passive_cpu_wait[NR_CPUS]; | 115 | static atomic_t passive_cpu_wait[NR_CPUS]; |
116 | static atomic_t cpu_in_kgdb[NR_CPUS]; | 116 | static atomic_t cpu_in_kgdb[NR_CPUS]; |
117 | static atomic_t kgdb_break_tasklet_var; | ||
117 | atomic_t kgdb_setting_breakpoint; | 118 | atomic_t kgdb_setting_breakpoint; |
118 | 119 | ||
119 | struct task_struct *kgdb_usethread; | 120 | struct task_struct *kgdb_usethread; |
@@ -789,6 +790,31 @@ static void kgdb_unregister_callbacks(void) | |||
789 | } | 790 | } |
790 | } | 791 | } |
791 | 792 | ||
793 | /* | ||
794 | * There are times a tasklet needs to be used vs a compiled in | ||
795 | * break point so as to cause an exception outside a kgdb I/O module, | ||
796 | * such as is the case with kgdboe, where calling a breakpoint in the | ||
797 | * I/O driver itself would be fatal. | ||
798 | */ | ||
799 | static void kgdb_tasklet_bpt(unsigned long ing) | ||
800 | { | ||
801 | kgdb_breakpoint(); | ||
802 | atomic_set(&kgdb_break_tasklet_var, 0); | ||
803 | } | ||
804 | |||
805 | static DECLARE_TASKLET(kgdb_tasklet_breakpoint, kgdb_tasklet_bpt, 0); | ||
806 | |||
807 | void kgdb_schedule_breakpoint(void) | ||
808 | { | ||
809 | if (atomic_read(&kgdb_break_tasklet_var) || | ||
810 | atomic_read(&kgdb_active) != -1 || | ||
811 | atomic_read(&kgdb_setting_breakpoint)) | ||
812 | return; | ||
813 | atomic_inc(&kgdb_break_tasklet_var); | ||
814 | tasklet_schedule(&kgdb_tasklet_breakpoint); | ||
815 | } | ||
816 | EXPORT_SYMBOL_GPL(kgdb_schedule_breakpoint); | ||
817 | |||
792 | static void kgdb_initial_breakpoint(void) | 818 | static void kgdb_initial_breakpoint(void) |
793 | { | 819 | { |
794 | kgdb_break_asap = 0; | 820 | kgdb_break_asap = 0; |