From 32bd7eb5a7f4596c8440dd9440322fe9e686634d Mon Sep 17 00:00:00 2001 From: Li Zefan Date: Wed, 24 Mar 2010 13:17:19 +0800 Subject: sched: Remove remaining USER_SCHED code This is left over from commit 7c9414385e ("sched: Remove USER_SCHED"") Signed-off-by: Li Zefan Acked-by: Dhaval Giani Signed-off-by: Peter Zijlstra Cc: David Howells LKML-Reference: <4BA9A05F.7010407@cn.fujitsu.com> Signed-off-by: Ingo Molnar --- init/Kconfig | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'init') diff --git a/init/Kconfig b/init/Kconfig index eb77e8ccde1c..5fe94b82e4c0 100644 --- a/init/Kconfig +++ b/init/Kconfig @@ -604,8 +604,7 @@ config RT_GROUP_SCHED default n help This feature lets you explicitly allocate real CPU bandwidth - to users or control groups (depending on the "Basis for grouping tasks" - setting below. If enabled, it will also make it impossible to + to task groups. If enabled, it will also make it impossible to schedule realtime tasks for non-root users until you allocate realtime bandwidth for them. See Documentation/scheduler/sched-rt-group.txt for more information. -- cgit v1.2.3 From 67fc4e0cb931d6b4ccf21248e4199b154478ecea Mon Sep 17 00:00:00 2001 From: Jason Wessel Date: Thu, 20 May 2010 21:04:21 -0500 Subject: kdb: core for kgdb back end (2 of 2) This patch contains the hooks and instrumentation into kernel which live outside the kernel/debug directory, which the kdb core will call to run commands like lsmod, dmesg, bt etc... CC: linux-arch@vger.kernel.org Signed-off-by: Jason Wessel Signed-off-by: Martin Hicks --- arch/arm/include/asm/kmap_types.h | 1 + arch/powerpc/include/asm/kmap_types.h | 1 + include/asm-generic/kmap_types.h | 3 ++- init/main.c | 2 ++ kernel/kallsyms.c | 21 ++++++++++++++++++ kernel/module.c | 4 ++++ kernel/printk.c | 16 ++++++++++++++ kernel/sched.c | 7 ++++-- kernel/signal.c | 40 +++++++++++++++++++++++++++++++++++ 9 files changed, 92 insertions(+), 3 deletions(-) (limited to 'init') diff --git a/arch/arm/include/asm/kmap_types.h b/arch/arm/include/asm/kmap_types.h index c4b2ea3fbe42..e51b1e81df05 100644 --- a/arch/arm/include/asm/kmap_types.h +++ b/arch/arm/include/asm/kmap_types.h @@ -20,6 +20,7 @@ enum km_type { KM_SOFTIRQ1, KM_L1_CACHE, KM_L2_CACHE, + KM_KDB, KM_TYPE_NR }; diff --git a/arch/powerpc/include/asm/kmap_types.h b/arch/powerpc/include/asm/kmap_types.h index 916369575c97..bca8fdcd2542 100644 --- a/arch/powerpc/include/asm/kmap_types.h +++ b/arch/powerpc/include/asm/kmap_types.h @@ -26,6 +26,7 @@ enum km_type { KM_SOFTIRQ1, KM_PPC_SYNC_PAGE, KM_PPC_SYNC_ICACHE, + KM_KDB, KM_TYPE_NR }; diff --git a/include/asm-generic/kmap_types.h b/include/asm-generic/kmap_types.h index e5f234a08540..97e807c8c812 100644 --- a/include/asm-generic/kmap_types.h +++ b/include/asm-generic/kmap_types.h @@ -28,7 +28,8 @@ KMAP_D(15) KM_UML_USERCOPY, KMAP_D(16) KM_IRQ_PTE, KMAP_D(17) KM_NMI, KMAP_D(18) KM_NMI_PTE, -KMAP_D(19) KM_TYPE_NR +KMAP_D(19) KM_KDB, +KMAP_D(20) KM_TYPE_NR }; #undef KMAP_D diff --git a/init/main.c b/init/main.c index 5c8540271529..372771333d98 100644 --- a/init/main.c +++ b/init/main.c @@ -62,6 +62,7 @@ #include #include #include +#include #include #include #include @@ -675,6 +676,7 @@ asmlinkage void __init start_kernel(void) buffer_init(); key_init(); security_init(); + kdb_init(KDB_INIT_FULL); vfs_caches_init(totalram_pages); signals_init(); /* rootfs populating might need page-writeback */ diff --git a/kernel/kallsyms.c b/kernel/kallsyms.c index 13aff293f4de..6f6d091b5757 100644 --- a/kernel/kallsyms.c +++ b/kernel/kallsyms.c @@ -16,6 +16,7 @@ #include #include #include +#include #include #include #include /* for cond_resched */ @@ -516,6 +517,26 @@ static int kallsyms_open(struct inode *inode, struct file *file) return ret; } +#ifdef CONFIG_KGDB_KDB +const char *kdb_walk_kallsyms(loff_t *pos) +{ + static struct kallsym_iter kdb_walk_kallsyms_iter; + if (*pos == 0) { + memset(&kdb_walk_kallsyms_iter, 0, + sizeof(kdb_walk_kallsyms_iter)); + reset_iter(&kdb_walk_kallsyms_iter, 0); + } + while (1) { + if (!update_iter(&kdb_walk_kallsyms_iter, *pos)) + return NULL; + ++*pos; + /* Some debugging symbols have no name. Ignore them. */ + if (kdb_walk_kallsyms_iter.name[0]) + return kdb_walk_kallsyms_iter.name; + } +} +#endif /* CONFIG_KGDB_KDB */ + static const struct file_operations kallsyms_operations = { .open = kallsyms_open, .read = seq_read, diff --git a/kernel/module.c b/kernel/module.c index e2564580f3f1..b751f1902476 100644 --- a/kernel/module.c +++ b/kernel/module.c @@ -77,6 +77,10 @@ DEFINE_MUTEX(module_mutex); EXPORT_SYMBOL_GPL(module_mutex); static LIST_HEAD(modules); +#ifdef CONFIG_KGDB_KDB +struct list_head *kdb_modules = &modules; /* kdb needs the list of modules */ +#endif /* CONFIG_KGDB_KDB */ + /* Block module loading/unloading? */ int modules_disabled = 0; diff --git a/kernel/printk.c b/kernel/printk.c index 75077ad0b537..9213b8b5bb4f 100644 --- a/kernel/printk.c +++ b/kernel/printk.c @@ -413,6 +413,22 @@ SYSCALL_DEFINE3(syslog, int, type, char __user *, buf, int, len) return do_syslog(type, buf, len, SYSLOG_FROM_CALL); } +#ifdef CONFIG_KGDB_KDB +/* kdb dmesg command needs access to the syslog buffer. do_syslog() + * uses locks so it cannot be used during debugging. Just tell kdb + * where the start and end of the physical and logical logs are. This + * is equivalent to do_syslog(3). + */ +void kdb_syslog_data(char *syslog_data[4]) +{ + syslog_data[0] = log_buf; + syslog_data[1] = log_buf + log_buf_len; + syslog_data[2] = log_buf + log_end - + (logged_chars < log_buf_len ? logged_chars : log_buf_len); + syslog_data[3] = log_buf + log_end; +} +#endif /* CONFIG_KGDB_KDB */ + /* * Call the console drivers on a range of log_buf */ diff --git a/kernel/sched.c b/kernel/sched.c index 1d93cd0ae4d3..a25c1324af54 100644 --- a/kernel/sched.c +++ b/kernel/sched.c @@ -7758,9 +7758,9 @@ void normalize_rt_tasks(void) #endif /* CONFIG_MAGIC_SYSRQ */ -#ifdef CONFIG_IA64 +#if defined(CONFIG_IA64) || defined(CONFIG_KGDB_KDB) /* - * These functions are only useful for the IA64 MCA handling. + * These functions are only useful for the IA64 MCA handling, or kdb. * * They can only be called when the whole system has been * stopped - every CPU needs to be quiescent, and no scheduling @@ -7780,6 +7780,9 @@ struct task_struct *curr_task(int cpu) return cpu_curr(cpu); } +#endif /* defined(CONFIG_IA64) || defined(CONFIG_KGDB_KDB) */ + +#ifdef CONFIG_IA64 /** * set_curr_task - set the current task for a given cpu. * @cpu: the processor in question. diff --git a/kernel/signal.c b/kernel/signal.c index dbd7fe073c55..825a3f24ad76 100644 --- a/kernel/signal.c +++ b/kernel/signal.c @@ -2735,3 +2735,43 @@ void __init signals_init(void) { sigqueue_cachep = KMEM_CACHE(sigqueue, SLAB_PANIC); } + +#ifdef CONFIG_KGDB_KDB +#include +/* + * kdb_send_sig_info - Allows kdb to send signals without exposing + * signal internals. This function checks if the required locks are + * available before calling the main signal code, to avoid kdb + * deadlocks. + */ +void +kdb_send_sig_info(struct task_struct *t, struct siginfo *info) +{ + static struct task_struct *kdb_prev_t; + int sig, new_t; + if (!spin_trylock(&t->sighand->siglock)) { + kdb_printf("Can't do kill command now.\n" + "The sigmask lock is held somewhere else in " + "kernel, try again later\n"); + return; + } + spin_unlock(&t->sighand->siglock); + new_t = kdb_prev_t != t; + kdb_prev_t = t; + if (t->state != TASK_RUNNING && new_t) { + kdb_printf("Process is not RUNNING, sending a signal from " + "kdb risks deadlock\n" + "on the run queue locks. " + "The signal has _not_ been sent.\n" + "Reissue the kill command if you want to risk " + "the deadlock.\n"); + return; + } + sig = info->si_signo; + if (send_sig_info(sig, info, t)) + kdb_printf("Fail to deliver Signal %d to process %d.\n", + sig, t->pid); + else + kdb_printf("Signal %d is sent to process %d.\n", sig, t->pid); +} +#endif /* CONFIG_KGDB_KDB */ -- cgit v1.2.3 From 0b4b3827db386ec6034a5aba1261025b039440c2 Mon Sep 17 00:00:00 2001 From: Jason Wessel Date: Thu, 20 May 2010 21:04:29 -0500 Subject: x86, kgdb, init: Add early and late debug states The kernel debugger can operate well before mm_init(), but the x86 hardware breakpoint code which uses the perf api requires that the kernel allocators are initialized. This means the kernel debug core needs to provide an optional arch specific call back to allow the initialization functions to run after the kernel has been further initialized. The kdb shell already had a similar restriction with an early initialization and late initialization. The kdb_init() was moved into the debug core's version of the late init which is called dbg_late_init(); CC: kgdb-bugreport@lists.sourceforge.net Signed-off-by: Jason Wessel --- arch/x86/kernel/kgdb.c | 17 ++++++++++------- include/linux/kgdb.h | 14 ++++++++++++++ init/main.c | 4 ++-- kernel/debug/debug_core.c | 16 ++++++++++++++++ 4 files changed, 42 insertions(+), 9 deletions(-) (limited to 'init') diff --git a/arch/x86/kernel/kgdb.c b/arch/x86/kernel/kgdb.c index 95b89d4cb8f1..2b71ec41869f 100644 --- a/arch/x86/kernel/kgdb.c +++ b/arch/x86/kernel/kgdb.c @@ -595,15 +595,16 @@ static struct notifier_block kgdb_notifier = { * specific callbacks. */ int kgdb_arch_init(void) +{ + return register_die_notifier(&kgdb_notifier); +} + +void kgdb_arch_late(void) { int i, cpu; - int ret; struct perf_event_attr attr; struct perf_event **pevent; - ret = register_die_notifier(&kgdb_notifier); - if (ret != 0) - return ret; /* * Pre-allocate the hw breakpoint structions in the non-atomic * portion of kgdb because this operation requires mutexs to @@ -615,12 +616,15 @@ int kgdb_arch_init(void) attr.bp_type = HW_BREAKPOINT_W; attr.disabled = 1; for (i = 0; i < 4; i++) { + if (breakinfo[i].pev) + continue; breakinfo[i].pev = register_wide_hw_breakpoint(&attr, NULL); if (IS_ERR(breakinfo[i].pev)) { - printk(KERN_ERR "kgdb: Could not allocate hw breakpoints\n"); + printk(KERN_ERR "kgdb: Could not allocate hw" + "breakpoints\nDisabling the kernel debugger\n"); breakinfo[i].pev = NULL; kgdb_arch_exit(); - return -1; + return; } for_each_online_cpu(cpu) { pevent = per_cpu_ptr(breakinfo[i].pev, cpu); @@ -631,7 +635,6 @@ int kgdb_arch_init(void) } } } - return ret; } /** diff --git a/include/linux/kgdb.h b/include/linux/kgdb.h index 6c784ab6856a..9340f34d1bb5 100644 --- a/include/linux/kgdb.h +++ b/include/linux/kgdb.h @@ -207,6 +207,17 @@ extern int kgdb_validate_break_address(unsigned long addr); extern int kgdb_arch_set_breakpoint(unsigned long addr, char *saved_instr); extern int kgdb_arch_remove_breakpoint(unsigned long addr, char *bundle); +/** + * kgdb_arch_late - Perform any architecture specific initalization. + * + * This function will handle the late initalization of any + * architecture specific callbacks. This is an optional function for + * handling things like late initialization of hw breakpoints. The + * default implementation does nothing. + */ +extern void kgdb_arch_late(void); + + /** * struct kgdb_arch - Describe architecture specific values. * @gdb_bpt_instr: The instruction to trigger a breakpoint. @@ -285,7 +296,10 @@ extern int kgdb_single_step; extern atomic_t kgdb_active; #define in_dbg_master() \ (raw_smp_processor_id() == atomic_read(&kgdb_active)) +extern bool dbg_is_early; +extern void __init dbg_late_init(void); #else /* ! CONFIG_KGDB */ #define in_dbg_master() (0) +#define dbg_late_init() #endif /* ! CONFIG_KGDB */ #endif /* _KGDB_H_ */ diff --git a/init/main.c b/init/main.c index 372771333d98..22881b5e95e3 100644 --- a/init/main.c +++ b/init/main.c @@ -62,7 +62,7 @@ #include #include #include -#include +#include #include #include #include @@ -676,7 +676,7 @@ asmlinkage void __init start_kernel(void) buffer_init(); key_init(); security_init(); - kdb_init(KDB_INIT_FULL); + dbg_late_init(); vfs_caches_init(totalram_pages); signals_init(); /* rootfs populating might need page-writeback */ diff --git a/kernel/debug/debug_core.c b/kernel/debug/debug_core.c index 64b5588c9638..5cb7cd1de10c 100644 --- a/kernel/debug/debug_core.c +++ b/kernel/debug/debug_core.c @@ -78,6 +78,8 @@ static DEFINE_SPINLOCK(kgdb_registration_lock); static int kgdb_con_registered; /* determine if kgdb console output should be used */ static int kgdb_use_con; +/* Flag for alternate operations for early debugging */ +bool dbg_is_early = true; /* Next cpu to become the master debug core */ int dbg_switch_cpu; @@ -777,11 +779,25 @@ static struct notifier_block kgdb_panic_event_nb = { .priority = INT_MAX, }; +void __weak kgdb_arch_late(void) +{ +} + +void __init dbg_late_init(void) +{ + dbg_is_early = false; + if (kgdb_io_module_registered) + kgdb_arch_late(); + kdb_init(KDB_INIT_FULL); +} + static void kgdb_register_callbacks(void) { if (!kgdb_io_module_registered) { kgdb_io_module_registered = 1; kgdb_arch_init(); + if (!dbg_is_early) + kgdb_arch_late(); atomic_notifier_chain_register(&panic_notifier_list, &kgdb_panic_event_nb); #ifdef CONFIG_MAGIC_SYSRQ -- cgit v1.2.3