From: Ingo Molnar Date: Tue, 7 Apr 2009 09:15:40 +0000 (+0200) Subject: Merge branch 'linus' into core/softlockup X-Git-Tag: v2.6.30-rc1~1^2 X-Git-Url: https://git.openpandora.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=5e34437840d33554f69380584311743b39e8fbeb;hp=-c;p=pandora-kernel.git Merge branch 'linus' into core/softlockup Conflicts: kernel/sysctl.c --- 5e34437840d33554f69380584311743b39e8fbeb diff --combined include/linux/sched.h index d05e2b3ae41a,b94f3541f67b..763b525227dc --- a/include/linux/sched.h +++ b/include/linux/sched.h @@@ -68,7 -68,7 +68,7 @@@ struct sched_param #include #include #include - #include + #include #include #include #include @@@ -97,6 -97,7 +97,7 @@@ struct futex_pi_state struct robust_list_head; struct bio; struct bts_tracer; + struct fs_struct; /* * List of flags we want to share for kernel threads, @@@ -137,6 -138,8 +138,8 @@@ extern unsigned long nr_uninterruptible extern unsigned long nr_active(void); extern unsigned long nr_iowait(void); + extern unsigned long get_parent_ip(unsigned long addr); + struct seq_file; struct cfs_rq; struct task_group; @@@ -297,11 -300,17 +300,11 @@@ extern int proc_dosoftlockup_thresh(str struct file *filp, void __user *buffer, size_t *lenp, loff_t *ppos); extern unsigned int softlockup_panic; -extern unsigned long sysctl_hung_task_check_count; -extern unsigned long sysctl_hung_task_timeout_secs; -extern unsigned long sysctl_hung_task_warnings; extern int softlockup_thresh; #else static inline void softlockup_tick(void) { } -static inline void spawn_softlockup_task(void) -{ -} static inline void touch_softlockup_watchdog(void) { } @@@ -310,15 -319,6 +313,15 @@@ static inline void touch_all_softlockup } #endif +#ifdef CONFIG_DETECT_HUNG_TASK +extern unsigned int sysctl_hung_task_panic; +extern unsigned long sysctl_hung_task_check_count; +extern unsigned long sysctl_hung_task_timeout_secs; +extern unsigned long sysctl_hung_task_warnings; +extern int proc_dohung_task_timeout_secs(struct ctl_table *table, int write, + struct file *filp, void __user *buffer, + size_t *lenp, loff_t *ppos); +#endif /* Attach to any functions which should be ignored in wchan output. */ #define __sched __attribute__((__section__(".sched.text"))) @@@ -334,7 -334,9 +337,9 @@@ extern signed long schedule_timeout(sig extern signed long schedule_timeout_interruptible(signed long timeout); extern signed long schedule_timeout_killable(signed long timeout); extern signed long schedule_timeout_uninterruptible(signed long timeout); + asmlinkage void __schedule(void); asmlinkage void schedule(void); + extern int mutex_spin_on_owner(struct mutex *lock, struct thread_info *owner); struct nsproxy; struct user_namespace; @@@ -392,8 -394,15 +397,15 @@@ extern void arch_unmap_area_topdown(str (mm)->hiwater_vm = (mm)->total_vm; \ } while (0) - #define get_mm_hiwater_rss(mm) max((mm)->hiwater_rss, get_mm_rss(mm)) - #define get_mm_hiwater_vm(mm) max((mm)->hiwater_vm, (mm)->total_vm) + static inline unsigned long get_mm_hiwater_rss(struct mm_struct *mm) + { + return max(mm->hiwater_rss, get_mm_rss(mm)); + } + + static inline unsigned long get_mm_hiwater_vm(struct mm_struct *mm) + { + return max(mm->hiwater_vm, mm->total_vm); + } extern void set_dumpable(struct mm_struct *mm, int value); extern int get_dumpable(struct mm_struct *mm); @@@ -541,25 -550,8 +553,8 @@@ struct signal_struct struct list_head cpu_timers[3]; - /* job control IDs */ - - /* - * pgrp and session fields are deprecated. - * use the task_session_Xnr and task_pgrp_Xnr routines below - */ - - union { - pid_t pgrp __deprecated; - pid_t __pgrp; - }; - struct pid *tty_old_pgrp; - union { - pid_t session __deprecated; - pid_t __session; - }; - /* boolean value for session group leader */ int leader; @@@ -1001,6 -993,7 +996,7 @@@ struct sched_class struct rq *busiest, struct sched_domain *sd, enum cpu_idle_type idle); void (*pre_schedule) (struct rq *this_rq, struct task_struct *task); + int (*needs_post_schedule) (struct rq *this_rq); void (*post_schedule) (struct rq *this_rq); void (*task_wake_up) (struct rq *this_rq, struct task_struct *task); @@@ -1055,6 -1048,10 +1051,10 @@@ struct sched_entity u64 last_wakeup; u64 avg_overlap; + u64 start_runtime; + u64 avg_wakeup; + u64 nr_migrations; + #ifdef CONFIG_SCHEDSTATS u64 wait_start; u64 wait_max; @@@ -1070,7 -1067,6 +1070,6 @@@ u64 exec_max; u64 slice_max; - u64 nr_migrations; u64 nr_migrations_cold; u64 nr_failed_migrations_affine; u64 nr_failed_migrations_running; @@@ -1167,6 -1163,7 +1166,7 @@@ struct task_struct #endif struct list_head tasks; + struct plist_node pushable_tasks; struct mm_struct *mm, *active_mm; @@@ -1178,13 -1175,14 +1178,14 @@@ /* ??? */ unsigned int personality; unsigned did_exec:1; + unsigned in_execve:1; /* Tell the LSMs that the process is doing an + * execve */ pid_t pid; pid_t tgid; - #ifdef CONFIG_CC_STACKPROTECTOR /* Canary value for the -fstack-protector gcc feature */ unsigned long stack_canary; - #endif + /* * pointers to (original) parent process, youngest child, younger sibling, * older sibling, respectively. (p->father can be replaced with @@@ -1257,8 -1255,9 +1258,8 @@@ /* ipc stuff */ struct sysv_sem sysvsem; #endif -#ifdef CONFIG_DETECT_SOFTLOCKUP +#ifdef CONFIG_DETECT_HUNG_TASK /* hung task detection */ - unsigned long last_switch_timestamp; unsigned long last_switch_count; #endif /* CPU-specific state of this task */ @@@ -1330,6 -1329,7 +1331,7 @@@ int lockdep_depth; unsigned int lockdep_recursion; struct held_lock held_locks[MAX_LOCK_DEPTH]; + gfp_t lockdep_reclaim_gfp; #endif /* journalling filesystem info */ @@@ -1407,6 -1407,8 +1409,8 @@@ int curr_ret_stack; /* Stack of return addresses for return function tracing */ struct ftrace_ret_stack *ret_stack; + /* time stamp for last schedule */ + unsigned long long ftrace_timestamp; /* * Number of functions that haven't been traced * because of depth overrun. @@@ -1421,6 -1423,9 +1425,9 @@@ #endif }; + /* Future-safe accessor for struct task_struct's cpus_allowed. */ + #define tsk_cpumask(tsk) (&(tsk)->cpus_allowed) + /* * Priority of a process goes from 0..MAX_PRIO-1, valid RT * priority is 0..MAX_RT_PRIO-1, and SCHED_NORMAL/SCHED_BATCH @@@ -1452,16 -1457,6 +1459,6 @@@ static inline int rt_task(struct task_s return rt_prio(p->prio); } - static inline void set_task_session(struct task_struct *tsk, pid_t session) - { - tsk->signal->__session = session; - } - - static inline void set_task_pgrp(struct task_struct *tsk, pid_t pgrp) - { - tsk->signal->__pgrp = pgrp; - } - static inline struct pid *task_pid(struct task_struct *task) { return task->pids[PIDTYPE_PID].pid; @@@ -1472,6 -1467,11 +1469,11 @@@ static inline struct pid *task_tgid(str return task->group_leader->pids[PIDTYPE_PID].pid; } + /* + * Without tasklist or rcu lock it is not safe to dereference + * the result of task_pgrp/task_session even if task == current, + * we can race with another thread doing sys_setsid/sys_setpgid. + */ static inline struct pid *task_pgrp(struct task_struct *task) { return task->group_leader->pids[PIDTYPE_PGID].pid; @@@ -1497,17 -1497,23 +1499,23 @@@ struct pid_namespace * * see also pid_nr() etc in include/linux/pid.h */ + pid_t __task_pid_nr_ns(struct task_struct *task, enum pid_type type, + struct pid_namespace *ns); static inline pid_t task_pid_nr(struct task_struct *tsk) { return tsk->pid; } - pid_t task_pid_nr_ns(struct task_struct *tsk, struct pid_namespace *ns); + static inline pid_t task_pid_nr_ns(struct task_struct *tsk, + struct pid_namespace *ns) + { + return __task_pid_nr_ns(tsk, PIDTYPE_PID, ns); + } static inline pid_t task_pid_vnr(struct task_struct *tsk) { - return pid_vnr(task_pid(tsk)); + return __task_pid_nr_ns(tsk, PIDTYPE_PID, NULL); } @@@ -1524,31 -1530,34 +1532,34 @@@ static inline pid_t task_tgid_vnr(struc } - static inline pid_t task_pgrp_nr(struct task_struct *tsk) + static inline pid_t task_pgrp_nr_ns(struct task_struct *tsk, + struct pid_namespace *ns) { - return tsk->signal->__pgrp; + return __task_pid_nr_ns(tsk, PIDTYPE_PGID, ns); } - pid_t task_pgrp_nr_ns(struct task_struct *tsk, struct pid_namespace *ns); - static inline pid_t task_pgrp_vnr(struct task_struct *tsk) { - return pid_vnr(task_pgrp(tsk)); + return __task_pid_nr_ns(tsk, PIDTYPE_PGID, NULL); } - static inline pid_t task_session_nr(struct task_struct *tsk) + static inline pid_t task_session_nr_ns(struct task_struct *tsk, + struct pid_namespace *ns) { - return tsk->signal->__session; + return __task_pid_nr_ns(tsk, PIDTYPE_SID, ns); } - pid_t task_session_nr_ns(struct task_struct *tsk, struct pid_namespace *ns); - static inline pid_t task_session_vnr(struct task_struct *tsk) { - return pid_vnr(task_session(tsk)); + return __task_pid_nr_ns(tsk, PIDTYPE_SID, NULL); } + /* obsolete, do not use */ + static inline pid_t task_pgrp_nr(struct task_struct *tsk) + { + return task_pgrp_nr_ns(tsk, &init_pid_ns); + } /** * pid_alive - check that a task structure is not stale @@@ -1672,6 -1681,16 +1683,16 @@@ static inline int set_cpus_allowed(stru return set_cpus_allowed_ptr(p, &new_mask); } + /* + * Architectures can set this to 1 if they have specified + * CONFIG_HAVE_UNSTABLE_SCHED_CLOCK in their arch Kconfig, + * but then during bootup it turns out that sched_clock() + * is reliable after all: + */ + #ifdef CONFIG_HAVE_UNSTABLE_SCHED_CLOCK + extern int sched_clock_stable; + #endif + extern unsigned long long sched_clock(void); extern void sched_clock_init(void); @@@ -1948,7 -1967,8 +1969,8 @@@ extern void mm_release(struct task_stru /* Allocate a new mm structure and copy contents from tsk->mm */ extern struct mm_struct *dup_mm(struct task_struct *tsk); - extern int copy_thread(int, unsigned long, unsigned long, unsigned long, struct task_struct *, struct pt_regs *); + extern int copy_thread(unsigned long, unsigned long, unsigned long, + struct task_struct *, struct pt_regs *); extern void flush_thread(void); extern void exit_thread(void); @@@ -2033,6 -2053,11 +2055,11 @@@ static inline int thread_group_empty(st #define delay_group_leader(p) \ (thread_group_leader(p) && !thread_group_empty(p)) + static inline int task_detached(struct task_struct *p) + { + return p->exit_signal == -1; + } + /* * Protects ->fs, ->files, ->mm, ->group_info, ->comm, keyring * subscriptions and synchronises with wait4(). Also used in procfs. Also @@@ -2089,6 -2114,19 +2116,19 @@@ static inline int object_is_on_stack(vo extern void thread_info_cache_init(void); + #ifdef CONFIG_DEBUG_STACK_USAGE + static inline unsigned long stack_not_used(struct task_struct *p) + { + unsigned long *n = end_of_stack(p); + + do { /* Skip over canary */ + n++; + } while (!*n); + + return (unsigned long)n - (unsigned long)end_of_stack(p); + } + #endif + /* set thread flags in other task's structures * - see asm/thread_info.h for TIF_xxxx flags available */ @@@ -2293,9 -2331,13 +2333,13 @@@ extern long sched_group_rt_runtime(stru extern int sched_group_set_rt_period(struct task_group *tg, long rt_period_us); extern long sched_group_rt_period(struct task_group *tg); + extern int sched_rt_can_attach(struct task_group *tg, struct task_struct *tsk); #endif #endif + extern int task_can_switch_user(struct user_struct *up, + struct task_struct *tsk); + #ifdef CONFIG_TASK_XACCT static inline void add_rchar(struct task_struct *tsk, ssize_t amt) { diff --combined kernel/Makefile index ae6565b3dced,bab1dffe37e9..42423665660a --- a/kernel/Makefile +++ b/kernel/Makefile @@@ -51,6 -51,7 +51,7 @@@ obj-$(CONFIG_UID16) += uid16. obj-$(CONFIG_MODULES) += module.o obj-$(CONFIG_KALLSYMS) += kallsyms.o obj-$(CONFIG_PM) += power/ + obj-$(CONFIG_FREEZER) += power/ obj-$(CONFIG_BSD_PROCESS_ACCT) += acct.o obj-$(CONFIG_KEXEC) += kexec.o obj-$(CONFIG_BACKTRACE_SELF_TEST) += backtracetest.o @@@ -73,7 -74,6 +74,7 @@@ obj-$(CONFIG_AUDIT_TREE) += audit_tree. obj-$(CONFIG_KPROBES) += kprobes.o obj-$(CONFIG_KGDB) += kgdb.o obj-$(CONFIG_DETECT_SOFTLOCKUP) += softlockup.o +obj-$(CONFIG_DETECT_HUNG_TASK) += hung_task.o obj-$(CONFIG_GENERIC_HARDIRQS) += irq/ obj-$(CONFIG_SECCOMP) += seccomp.o obj-$(CONFIG_RCU_TORTURE_TEST) += rcutorture.o @@@ -93,6 -93,7 +94,7 @@@ obj-$(CONFIG_HAVE_GENERIC_DMA_COHERENT obj-$(CONFIG_FUNCTION_TRACER) += trace/ obj-$(CONFIG_TRACING) += trace/ obj-$(CONFIG_SMP) += sched_cpupri.o + obj-$(CONFIG_SLOW_WORK) += slow-work.o ifneq ($(CONFIG_SCHED_OMIT_FRAME_POINTER),y) # According to Alan Modra , the -fno-omit-frame-pointer is diff --combined kernel/fork.c index 3b5dcf9a66aa,660c2b8765bc..989c7c202b3d --- a/kernel/fork.c +++ b/kernel/fork.c @@@ -60,7 -60,9 +60,9 @@@ #include #include #include + #include #include + #include #include #include @@@ -212,6 -214,8 +214,8 @@@ static struct task_struct *dup_task_str { struct task_struct *tsk; struct thread_info *ti; + unsigned long *stackend; + int err; prepare_to_copy(orig); @@@ -237,6 -241,8 +241,8 @@@ goto out; setup_thread_stack(tsk, orig); + stackend = end_of_stack(tsk); + *stackend = STACK_END_MAGIC; /* for overflow detection */ #ifdef CONFIG_CC_STACKPROTECTOR tsk->stack_canary = get_random_int(); @@@ -279,7 -285,7 +285,7 @@@ static int dup_mmap(struct mm_struct *m mm->free_area_cache = oldmm->mmap_base; mm->cached_hole_size = ~0UL; mm->map_count = 0; - cpus_clear(mm->cpu_vm_mask); + cpumask_clear(mm_cpumask(mm)); mm->mm_rb = RB_ROOT; rb_link = &mm->mm_rb.rb_node; rb_parent = NULL; @@@ -639,9 -645,6 +645,9 @@@ static int copy_mm(unsigned long clone_ tsk->min_flt = tsk->maj_flt = 0; tsk->nvcsw = tsk->nivcsw = 0; +#ifdef CONFIG_DETECT_HUNG_TASK + tsk->last_switch_count = tsk->nvcsw + tsk->nivcsw; +#endif tsk->mm = NULL; tsk->active_mm = NULL; @@@ -679,38 -682,21 +685,21 @@@ fail_nomem return retval; } - static struct fs_struct *__copy_fs_struct(struct fs_struct *old) - { - struct fs_struct *fs = kmem_cache_alloc(fs_cachep, GFP_KERNEL); - /* We don't need to lock fs - think why ;-) */ - if (fs) { - atomic_set(&fs->count, 1); - rwlock_init(&fs->lock); - fs->umask = old->umask; - read_lock(&old->lock); - fs->root = old->root; - path_get(&old->root); - fs->pwd = old->pwd; - path_get(&old->pwd); - read_unlock(&old->lock); - } - return fs; - } - - struct fs_struct *copy_fs_struct(struct fs_struct *old) - { - return __copy_fs_struct(old); - } - - EXPORT_SYMBOL_GPL(copy_fs_struct); - static int copy_fs(unsigned long clone_flags, struct task_struct *tsk) { + struct fs_struct *fs = current->fs; if (clone_flags & CLONE_FS) { - atomic_inc(¤t->fs->count); + /* tsk->fs is already what we want */ + write_lock(&fs->lock); + if (fs->in_exec) { + write_unlock(&fs->lock); + return -EAGAIN; + } + fs->users++; + write_unlock(&fs->lock); return 0; } - tsk->fs = __copy_fs_struct(current->fs); + tsk->fs = copy_fs_struct(fs); if (!tsk->fs) return -ENOMEM; return 0; @@@ -839,6 -825,8 +828,8 @@@ static int copy_signal(unsigned long cl atomic_set(&sig->live, 1); init_waitqueue_head(&sig->wait_chldexit); sig->flags = 0; + if (clone_flags & CLONE_NEWPID) + sig->flags |= SIGNAL_UNKILLABLE; sig->group_exit_code = 0; sig->group_exit_task = NULL; sig->group_stop_count = 0; @@@ -1044,6 -1032,11 +1035,6 @@@ static struct task_struct *copy_process p->default_timer_slack_ns = current->timer_slack_ns; -#ifdef CONFIG_DETECT_SOFTLOCKUP - p->last_switch_count = 0; - p->last_switch_timestamp = 0; -#endif - task_io_accounting_init(&p->ioac); acct_clear_integrals(p); @@@ -1118,7 -1111,7 +1109,7 @@@ goto bad_fork_cleanup_mm; if ((retval = copy_io(clone_flags, p))) goto bad_fork_cleanup_namespaces; - retval = copy_thread(0, clone_flags, stack_start, stack_size, p, regs); + retval = copy_thread(clone_flags, stack_start, stack_size, p, regs); if (retval) goto bad_fork_cleanup_io; @@@ -1177,10 -1170,6 +1168,6 @@@ #endif clear_all_latency_tracing(p); - /* Our parent execution domain becomes current domain - These must match for thread signalling to apply */ - p->parent_exec_id = p->self_exec_id; - /* ok, now we should be set up.. */ p->exit_signal = (clone_flags & CLONE_THREAD) ? -1 : (clone_flags & CSIGNAL); p->pdeath_signal = 0; @@@ -1218,10 -1207,13 +1205,13 @@@ set_task_cpu(p, smp_processor_id()); /* CLONE_PARENT re-uses the old parent */ - if (clone_flags & (CLONE_PARENT|CLONE_THREAD)) + if (clone_flags & (CLONE_PARENT|CLONE_THREAD)) { p->real_parent = current->real_parent; - else + p->parent_exec_id = current->parent_exec_id; + } else { p->real_parent = current; + p->parent_exec_id = current->self_exec_id; + } spin_lock(¤t->sighand->siglock); @@@ -1257,8 -1249,6 +1247,6 @@@ p->signal->leader_pid = pid; tty_kref_put(p->signal->tty); p->signal->tty = tty_kref_get(current->signal->tty); - set_task_pgrp(p, task_pgrp_nr(current)); - set_task_session(p, task_session_nr(current)); attach_pid(p, PIDTYPE_PGID, task_pgrp(current)); attach_pid(p, PIDTYPE_SID, task_session(current)); list_add_tail_rcu(&p->tasks, &init_task.tasks); @@@ -1482,6 -1472,7 +1470,7 @@@ void __init proc_caches_init(void mm_cachep = kmem_cache_create("mm_struct", sizeof(struct mm_struct), ARCH_MIN_MMSTRUCT_ALIGN, SLAB_HWCACHE_ALIGN|SLAB_PANIC, NULL); + vm_area_cachep = KMEM_CACHE(vm_area_struct, SLAB_PANIC); mmap_init(); } @@@ -1537,12 -1528,16 +1526,16 @@@ static int unshare_fs(unsigned long uns { struct fs_struct *fs = current->fs; - if ((unshare_flags & CLONE_FS) && - (fs && atomic_read(&fs->count) > 1)) { - *new_fsp = __copy_fs_struct(current->fs); - if (!*new_fsp) - return -ENOMEM; - } + if (!(unshare_flags & CLONE_FS) || !fs) + return 0; + + /* don't need lock here; in the worst case we'll do useless copy */ + if (fs->users == 1) + return 0; + + *new_fsp = copy_fs_struct(fs); + if (!*new_fsp) + return -ENOMEM; return 0; } @@@ -1658,8 -1653,13 +1651,13 @@@ SYSCALL_DEFINE1(unshare, unsigned long if (new_fs) { fs = current->fs; + write_lock(&fs->lock); current->fs = new_fs; - new_fs = fs; + if (--fs->users) + new_fs = NULL; + else + new_fs = fs; + write_unlock(&fs->lock); } if (new_mm) { @@@ -1698,7 -1698,7 +1696,7 @@@ bad_unshare_cleanup_sigh bad_unshare_cleanup_fs: if (new_fs) - put_fs_struct(new_fs); + free_fs_struct(new_fs); bad_unshare_cleanup_thread: bad_unshare_out: diff --combined kernel/sysctl.c index 6d2aeff92b3d,b125e3387568..b1a1b968f745 --- a/kernel/sysctl.c +++ b/kernel/sysctl.c @@@ -48,6 -48,7 +48,7 @@@ #include #include #include + #include #include #include @@@ -90,19 -91,14 +91,14 @@@ extern int rcutorture_runnable #endif /* #ifdef CONFIG_RCU_TORTURE_TEST */ /* Constants used for minimum and maximum */ - #if defined(CONFIG_DETECT_HUNG_TASK) || defined(CONFIG_DETECT_SOFTLOCKUP) || defined(CONFIG_HIGHMEM) - static int one = 1; - #endif #ifdef CONFIG_DETECT_SOFTLOCKUP static int sixty = 60; static int neg_one = -1; #endif - #if defined(CONFIG_MMU) && defined(CONFIG_FILE_LOCKING) - static int two = 2; - #endif - static int zero; + static int __maybe_unused one = 1; + static int __maybe_unused two = 2; static unsigned long one_ul = 1; static int one_hundred = 100; @@@ -817,19 -813,6 +813,19 @@@ static struct ctl_table kern_table[] = .extra1 = &neg_one, .extra2 = &sixty, }, +#endif +#ifdef CONFIG_DETECT_HUNG_TASK + { + .ctl_name = CTL_UNNUMBERED, + .procname = "hung_task_panic", + .data = &sysctl_hung_task_panic, + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = &proc_dointvec_minmax, + .strategy = &sysctl_intvec, + .extra1 = &zero, + .extra2 = &one, + }, { .ctl_name = CTL_UNNUMBERED, .procname = "hung_task_check_count", @@@ -845,7 -828,7 +841,7 @@@ .data = &sysctl_hung_task_timeout_secs, .maxlen = sizeof(unsigned long), .mode = 0644, - .proc_handler = &proc_doulongvec_minmax, + .proc_handler = &proc_dohung_task_timeout_secs, .strategy = &sysctl_intvec, }, { @@@ -915,6 -898,14 +911,14 @@@ .proc_handler = &scan_unevictable_handler, }, #endif + #ifdef CONFIG_SLOW_WORK + { + .ctl_name = CTL_UNNUMBERED, + .procname = "slow-work", + .mode = 0555, + .child = slow_work_sysctls, + }, + #endif /* * NOTE: do not add new entries to this table unless you have read * Documentation/sysctl/ctl_unnumbered.txt @@@ -1025,7 -1016,7 +1029,7 @@@ static struct ctl_table vm_table[] = .data = &dirty_expire_interval, .maxlen = sizeof(dirty_expire_interval), .mode = 0644, - .proc_handler = &proc_dointvec_userhz_jiffies, + .proc_handler = &proc_dointvec, }, { .ctl_name = VM_NR_PDFLUSH_THREADS, @@@ -1388,10 -1379,7 +1392,7 @@@ static struct ctl_table fs_table[] = .data = &lease_break_time, .maxlen = sizeof(int), .mode = 0644, - .proc_handler = &proc_dointvec_minmax, - .strategy = &sysctl_intvec, - .extra1 = &zero, - .extra2 = &two, + .proc_handler = &proc_dointvec, }, #endif #ifdef CONFIG_AIO @@@ -1432,7 -1420,10 +1433,10 @@@ .data = &suid_dumpable, .maxlen = sizeof(int), .mode = 0644, - .proc_handler = &proc_dointvec, + .proc_handler = &proc_dointvec_minmax, + .strategy = &sysctl_intvec, + .extra1 = &zero, + .extra2 = &two, }, #if defined(CONFIG_BINFMT_MISC) || defined(CONFIG_BINFMT_MISC_MODULE) { diff --combined lib/Kconfig.debug index 898e07c33c3c,9638d99644af..c6e854f215fa --- a/lib/Kconfig.debug +++ b/lib/Kconfig.debug @@@ -185,44 -185,6 +185,44 @@@ config BOOTPARAM_SOFTLOCKUP_PANIC_VALU range 0 1 default 0 if !BOOTPARAM_SOFTLOCKUP_PANIC default 1 if BOOTPARAM_SOFTLOCKUP_PANIC + +config DETECT_HUNG_TASK + bool "Detect Hung Tasks" + depends on DEBUG_KERNEL + default DETECT_SOFTLOCKUP + help + Say Y here to enable the kernel to detect "hung tasks", + which are bugs that cause the task to be stuck in + uninterruptible "D" state indefinitiley. + + When a hung task is detected, the kernel will print the + current stack trace (which you should report), but the + task will stay in uninterruptible state. If lockdep is + enabled then all held locks will also be reported. This + feature has negligible overhead. + +config BOOTPARAM_HUNG_TASK_PANIC + bool "Panic (Reboot) On Hung Tasks" + depends on DETECT_HUNG_TASK + help + Say Y here to enable the kernel to panic on "hung tasks", + which are bugs that cause the kernel to leave a task stuck + in uninterruptible "D" state. + + The panic can be used in combination with panic_timeout, + to cause the system to reboot automatically after a + hung task has been detected. This feature is useful for + high-availability systems that have uptime guarantees and + where a hung tasks must be resolved ASAP. + + Say N if unsure. + +config BOOTPARAM_HUNG_TASK_PANIC_VALUE + int + depends on DETECT_HUNG_TASK + range 0 1 + default 0 if !BOOTPARAM_HUNG_TASK_PANIC + default 1 if BOOTPARAM_HUNG_TASK_PANIC config SCHED_DEBUG bool "Collect scheduler debugging info" @@@ -440,7 -402,7 +440,7 @@@ config LOCKDE bool depends on DEBUG_KERNEL && TRACE_IRQFLAGS_SUPPORT && STACKTRACE_SUPPORT && LOCKDEP_SUPPORT select STACKTRACE - select FRAME_POINTER if !X86 && !MIPS && !PPC + select FRAME_POINTER if !X86 && !MIPS && !PPC && !ARM_UNWIND select KALLSYMS select KALLSYMS_ALL @@@ -834,6 -796,7 +834,7 @@@ config SYSCTL_SYSCALL_CHEC to properly maintain and use. This enables checks that help you to keep things correct. + source mm/Kconfig.debug source kernel/trace/Kconfig config PROVIDE_OHCI1394_DMA_INIT @@@ -876,7 -839,7 +877,7 @@@ config FIREWIRE_OHCI_REMOTE_DM If unsure, say N. - menuconfig BUILD_DOCSRC + config BUILD_DOCSRC bool "Build targets in Documentation/ tree" depends on HEADERS_CHECK help @@@ -885,60 -848,81 +886,81 @@@ Say N if you are unsure. - config DYNAMIC_PRINTK_DEBUG - bool "Enable dynamic printk() call support" + config DYNAMIC_DEBUG + bool "Enable dynamic printk() support" default n depends on PRINTK + depends on DEBUG_FS select PRINTK_DEBUG help Compiles debug level messages into the kernel, which would not otherwise be available at runtime. These messages can then be - enabled/disabled on a per module basis. This mechanism implicitly - enables all pr_debug() and dev_dbg() calls. The impact of this - compile option is a larger kernel text size of about 2%. + enabled/disabled based on various levels of scope - per source file, + function, module, format string, and line number. This mechanism + implicitly enables all pr_debug() and dev_dbg() calls. The impact of + this compile option is a larger kernel text size of about 2%. Usage: - Dynamic debugging is controlled by the debugfs file, - dynamic_printk/modules. This file contains a list of the modules that - can be enabled. The format of the file is the module name, followed - by a set of flags that can be enabled. The first flag is always the - 'enabled' flag. For example: + Dynamic debugging is controlled via the 'dynamic_debug/ddebug' file, + which is contained in the 'debugfs' filesystem. Thus, the debugfs + filesystem must first be mounted before making use of this feature. + We refer the control file as: /dynamic_debug/ddebug. This + file contains a list of the debug statements that can be enabled. The + format for each line of the file is: - - . - . - . + filename:lineno [module]function flags format - : Name of the module in which the debug call resides - : whether the messages are enabled or not + filename : source file of the debug statement + lineno : line number of the debug statement + module : module that contains the debug statement + function : function that contains the debug statement + flags : 'p' means the line is turned 'on' for printing + format : the format used for the debug statement From a live system: - snd_hda_intel enabled=0 - fixup enabled=0 - driver enabled=0 + nullarbor:~ # cat /dynamic_debug/ddebug + # filename:lineno [module]function flags format + fs/aio.c:222 [aio]__put_ioctx - "__put_ioctx:\040freeing\040%p\012" + fs/aio.c:248 [aio]ioctx_alloc - "ENOMEM:\040nr_events\040too\040high\012" + fs/aio.c:1770 [aio]sys_io_cancel - "calling\040cancel\012" - Enable a module: + Example usage: - $echo "set enabled=1 " > dynamic_printk/modules + // enable the message at line 1603 of file svcsock.c + nullarbor:~ # echo -n 'file svcsock.c line 1603 +p' > + /dynamic_debug/ddebug - Disable a module: + // enable all the messages in file svcsock.c + nullarbor:~ # echo -n 'file svcsock.c +p' > + /dynamic_debug/ddebug - $echo "set enabled=0 " > dynamic_printk/modules + // enable all the messages in the NFS server module + nullarbor:~ # echo -n 'module nfsd +p' > + /dynamic_debug/ddebug - Enable all modules: + // enable all 12 messages in the function svc_process() + nullarbor:~ # echo -n 'func svc_process +p' > + /dynamic_debug/ddebug - $echo "set enabled=1 all" > dynamic_printk/modules + // disable all 12 messages in the function svc_process() + nullarbor:~ # echo -n 'func svc_process -p' > + /dynamic_debug/ddebug - Disable all modules: + See Documentation/dynamic-debug-howto.txt for additional information. - $echo "set enabled=0 all" > dynamic_printk/modules - - Finally, passing "dynamic_printk" at the command line enables - debugging for all modules. This mode can be turned off via the above - disable command. + config DMA_API_DEBUG + bool "Enable debugging of DMA-API usage" + depends on HAVE_DMA_API_DEBUG + help + Enable this option to debug the use of the DMA API by device drivers. + With this option you will be able to detect common bugs in device + drivers like double-freeing of DMA mappings or freeing mappings that + were never allocated. + This option causes a performance degredation. Use only if you want + to debug device drivers. If unsure, say N. source "samples/Kconfig"