diff options
Diffstat (limited to 'kernel')
| -rw-r--r-- | kernel/Kconfig.preempt | 3 | ||||
| -rw-r--r-- | kernel/auditsc.c | 1 | ||||
| -rw-r--r-- | kernel/capability.c | 4 | ||||
| -rw-r--r-- | kernel/cpuset.c | 43 | ||||
| -rw-r--r-- | kernel/exit.c | 116 | ||||
| -rw-r--r-- | kernel/fork.c | 18 | ||||
| -rw-r--r-- | kernel/futex.c | 3 | ||||
| -rw-r--r-- | kernel/irq/chip.c | 3 | ||||
| -rw-r--r-- | kernel/irq/manage.c | 31 | ||||
| -rw-r--r-- | kernel/kexec.c | 113 | ||||
| -rw-r--r-- | kernel/ksysfs.c | 10 | ||||
| -rw-r--r-- | kernel/module.c | 130 | ||||
| -rw-r--r-- | kernel/nsproxy.c | 3 | ||||
| -rw-r--r-- | kernel/params.c | 17 | ||||
| -rw-r--r-- | kernel/posix-timers.c | 3 | ||||
| -rw-r--r-- | kernel/printk.c | 52 | ||||
| -rw-r--r-- | kernel/profile.c | 2 | ||||
| -rw-r--r-- | kernel/rcupdate.c | 1 | ||||
| -rw-r--r-- | kernel/rcutorture.c | 10 | ||||
| -rw-r--r-- | kernel/rtmutex-debug.c | 7 | ||||
| -rw-r--r-- | kernel/sched.c | 26 | ||||
| -rw-r--r-- | kernel/signal.c | 24 | ||||
| -rw-r--r-- | kernel/softlockup.c | 54 | ||||
| -rw-r--r-- | kernel/sys_ni.c | 4 | ||||
| -rw-r--r-- | kernel/sysctl.c | 44 | ||||
| -rw-r--r-- | kernel/taskstats.c | 1 | ||||
| -rw-r--r-- | kernel/time.c | 1 | ||||
| -rw-r--r-- | kernel/time/tick-broadcast.c | 17 | ||||
| -rw-r--r-- | kernel/time/tick-sched.c | 2 | ||||
| -rw-r--r-- | kernel/time/timekeeping.c | 5 | ||||
| -rw-r--r-- | kernel/user.c | 12 |
31 files changed, 500 insertions, 260 deletions
diff --git a/kernel/Kconfig.preempt b/kernel/Kconfig.preempt index 6b066632e40c..c64ce9c14207 100644 --- a/kernel/Kconfig.preempt +++ b/kernel/Kconfig.preempt | |||
| @@ -63,6 +63,3 @@ config PREEMPT_BKL | |||
| 63 | Say Y here if you are building a kernel for a desktop system. | 63 | Say Y here if you are building a kernel for a desktop system. |
| 64 | Say N if you are unsure. | 64 | Say N if you are unsure. |
| 65 | 65 | ||
| 66 | config PREEMPT_NOTIFIERS | ||
| 67 | bool | ||
| 68 | |||
diff --git a/kernel/auditsc.c b/kernel/auditsc.c index 0ae703c157ba..938e60a61882 100644 --- a/kernel/auditsc.c +++ b/kernel/auditsc.c | |||
| @@ -45,7 +45,6 @@ | |||
| 45 | #include <linux/init.h> | 45 | #include <linux/init.h> |
| 46 | #include <asm/types.h> | 46 | #include <asm/types.h> |
| 47 | #include <asm/atomic.h> | 47 | #include <asm/atomic.h> |
| 48 | #include <asm/types.h> | ||
| 49 | #include <linux/fs.h> | 48 | #include <linux/fs.h> |
| 50 | #include <linux/namei.h> | 49 | #include <linux/namei.h> |
| 51 | #include <linux/mm.h> | 50 | #include <linux/mm.h> |
diff --git a/kernel/capability.c b/kernel/capability.c index c8d3c7762034..4e350a36ed6a 100644 --- a/kernel/capability.c +++ b/kernel/capability.c | |||
| @@ -17,9 +17,6 @@ | |||
| 17 | unsigned securebits = SECUREBITS_DEFAULT; /* systemwide security settings */ | 17 | unsigned securebits = SECUREBITS_DEFAULT; /* systemwide security settings */ |
| 18 | kernel_cap_t cap_bset = CAP_INIT_EFF_SET; | 18 | kernel_cap_t cap_bset = CAP_INIT_EFF_SET; |
| 19 | 19 | ||
| 20 | EXPORT_SYMBOL(securebits); | ||
| 21 | EXPORT_SYMBOL(cap_bset); | ||
| 22 | |||
| 23 | /* | 20 | /* |
| 24 | * This lock protects task->cap_* for all tasks including current. | 21 | * This lock protects task->cap_* for all tasks including current. |
| 25 | * Locking rule: acquire this prior to tasklist_lock. | 22 | * Locking rule: acquire this prior to tasklist_lock. |
| @@ -244,7 +241,6 @@ int __capable(struct task_struct *t, int cap) | |||
| 244 | } | 241 | } |
| 245 | return 0; | 242 | return 0; |
| 246 | } | 243 | } |
| 247 | EXPORT_SYMBOL(__capable); | ||
| 248 | 244 | ||
| 249 | int capable(int cap) | 245 | int capable(int cap) |
| 250 | { | 246 | { |
diff --git a/kernel/cpuset.c b/kernel/cpuset.c index 0864f4097930..2eb2e50db0d6 100644 --- a/kernel/cpuset.c +++ b/kernel/cpuset.c | |||
| @@ -2506,41 +2506,20 @@ int cpuset_mem_spread_node(void) | |||
| 2506 | EXPORT_SYMBOL_GPL(cpuset_mem_spread_node); | 2506 | EXPORT_SYMBOL_GPL(cpuset_mem_spread_node); |
| 2507 | 2507 | ||
| 2508 | /** | 2508 | /** |
| 2509 | * cpuset_excl_nodes_overlap - Do we overlap @p's mem_exclusive ancestors? | 2509 | * cpuset_mems_allowed_intersects - Does @tsk1's mems_allowed intersect @tsk2's? |
| 2510 | * @p: pointer to task_struct of some other task. | 2510 | * @tsk1: pointer to task_struct of some task. |
| 2511 | * | 2511 | * @tsk2: pointer to task_struct of some other task. |
| 2512 | * Description: Return true if the nearest mem_exclusive ancestor | 2512 | * |
| 2513 | * cpusets of tasks @p and current overlap. Used by oom killer to | 2513 | * Description: Return true if @tsk1's mems_allowed intersects the |
| 2514 | * determine if task @p's memory usage might impact the memory | 2514 | * mems_allowed of @tsk2. Used by the OOM killer to determine if |
| 2515 | * available to the current task. | 2515 | * one of the task's memory usage might impact the memory available |
| 2516 | * | 2516 | * to the other. |
| 2517 | * Call while holding callback_mutex. | ||
| 2518 | **/ | 2517 | **/ |
| 2519 | 2518 | ||
| 2520 | int cpuset_excl_nodes_overlap(const struct task_struct *p) | 2519 | int cpuset_mems_allowed_intersects(const struct task_struct *tsk1, |
| 2520 | const struct task_struct *tsk2) | ||
| 2521 | { | 2521 | { |
| 2522 | const struct cpuset *cs1, *cs2; /* my and p's cpuset ancestors */ | 2522 | return nodes_intersects(tsk1->mems_allowed, tsk2->mems_allowed); |
| 2523 | int overlap = 1; /* do cpusets overlap? */ | ||
| 2524 | |||
| 2525 | task_lock(current); | ||
| 2526 | if (current->flags & PF_EXITING) { | ||
| 2527 | task_unlock(current); | ||
| 2528 | goto done; | ||
| 2529 | } | ||
| 2530 | cs1 = nearest_exclusive_ancestor(current->cpuset); | ||
| 2531 | task_unlock(current); | ||
| 2532 | |||
| 2533 | task_lock((struct task_struct *)p); | ||
| 2534 | if (p->flags & PF_EXITING) { | ||
| 2535 | task_unlock((struct task_struct *)p); | ||
| 2536 | goto done; | ||
| 2537 | } | ||
| 2538 | cs2 = nearest_exclusive_ancestor(p->cpuset); | ||
| 2539 | task_unlock((struct task_struct *)p); | ||
| 2540 | |||
| 2541 | overlap = nodes_intersects(cs1->mems_allowed, cs2->mems_allowed); | ||
| 2542 | done: | ||
| 2543 | return overlap; | ||
| 2544 | } | 2523 | } |
| 2545 | 2524 | ||
| 2546 | /* | 2525 | /* |
diff --git a/kernel/exit.c b/kernel/exit.c index 7f7959de4a87..2c704c86edb3 100644 --- a/kernel/exit.c +++ b/kernel/exit.c | |||
| @@ -44,7 +44,6 @@ | |||
| 44 | #include <linux/resource.h> | 44 | #include <linux/resource.h> |
| 45 | #include <linux/blkdev.h> | 45 | #include <linux/blkdev.h> |
| 46 | #include <linux/task_io_accounting_ops.h> | 46 | #include <linux/task_io_accounting_ops.h> |
| 47 | #include <linux/freezer.h> | ||
| 48 | 47 | ||
| 49 | #include <asm/uaccess.h> | 48 | #include <asm/uaccess.h> |
| 50 | #include <asm/unistd.h> | 49 | #include <asm/unistd.h> |
| @@ -93,10 +92,9 @@ static void __exit_signal(struct task_struct *tsk) | |||
| 93 | * If there is any task waiting for the group exit | 92 | * If there is any task waiting for the group exit |
| 94 | * then notify it: | 93 | * then notify it: |
| 95 | */ | 94 | */ |
| 96 | if (sig->group_exit_task && atomic_read(&sig->count) == sig->notify_count) { | 95 | if (sig->group_exit_task && atomic_read(&sig->count) == sig->notify_count) |
| 97 | wake_up_process(sig->group_exit_task); | 96 | wake_up_process(sig->group_exit_task); |
| 98 | sig->group_exit_task = NULL; | 97 | |
| 99 | } | ||
| 100 | if (tsk == sig->curr_target) | 98 | if (tsk == sig->curr_target) |
| 101 | sig->curr_target = next_thread(tsk); | 99 | sig->curr_target = next_thread(tsk); |
| 102 | /* | 100 | /* |
| @@ -593,17 +591,6 @@ static void exit_mm(struct task_struct * tsk) | |||
| 593 | mmput(mm); | 591 | mmput(mm); |
| 594 | } | 592 | } |
| 595 | 593 | ||
| 596 | static inline void | ||
| 597 | choose_new_parent(struct task_struct *p, struct task_struct *reaper) | ||
| 598 | { | ||
| 599 | /* | ||
| 600 | * Make sure we're not reparenting to ourselves and that | ||
| 601 | * the parent is not a zombie. | ||
| 602 | */ | ||
| 603 | BUG_ON(p == reaper || reaper->exit_state); | ||
| 604 | p->real_parent = reaper; | ||
| 605 | } | ||
| 606 | |||
| 607 | static void | 594 | static void |
| 608 | reparent_thread(struct task_struct *p, struct task_struct *father, int traced) | 595 | reparent_thread(struct task_struct *p, struct task_struct *father, int traced) |
| 609 | { | 596 | { |
| @@ -711,7 +698,7 @@ forget_original_parent(struct task_struct *father, struct list_head *to_release) | |||
| 711 | 698 | ||
| 712 | if (father == p->real_parent) { | 699 | if (father == p->real_parent) { |
| 713 | /* reparent with a reaper, real father it's us */ | 700 | /* reparent with a reaper, real father it's us */ |
| 714 | choose_new_parent(p, reaper); | 701 | p->real_parent = reaper; |
| 715 | reparent_thread(p, father, 0); | 702 | reparent_thread(p, father, 0); |
| 716 | } else { | 703 | } else { |
| 717 | /* reparent ptraced task to its real parent */ | 704 | /* reparent ptraced task to its real parent */ |
| @@ -732,7 +719,7 @@ forget_original_parent(struct task_struct *father, struct list_head *to_release) | |||
| 732 | } | 719 | } |
| 733 | list_for_each_safe(_p, _n, &father->ptrace_children) { | 720 | list_for_each_safe(_p, _n, &father->ptrace_children) { |
| 734 | p = list_entry(_p, struct task_struct, ptrace_list); | 721 | p = list_entry(_p, struct task_struct, ptrace_list); |
| 735 | choose_new_parent(p, reaper); | 722 | p->real_parent = reaper; |
| 736 | reparent_thread(p, father, 1); | 723 | reparent_thread(p, father, 1); |
| 737 | } | 724 | } |
| 738 | } | 725 | } |
| @@ -759,13 +746,11 @@ static void exit_notify(struct task_struct *tsk) | |||
| 759 | * Now we'll wake all the threads in the group just to make | 746 | * Now we'll wake all the threads in the group just to make |
| 760 | * sure someone gets all the pending signals. | 747 | * sure someone gets all the pending signals. |
| 761 | */ | 748 | */ |
| 762 | read_lock(&tasklist_lock); | ||
| 763 | spin_lock_irq(&tsk->sighand->siglock); | 749 | spin_lock_irq(&tsk->sighand->siglock); |
| 764 | for (t = next_thread(tsk); t != tsk; t = next_thread(t)) | 750 | for (t = next_thread(tsk); t != tsk; t = next_thread(t)) |
| 765 | if (!signal_pending(t) && !(t->flags & PF_EXITING)) | 751 | if (!signal_pending(t) && !(t->flags & PF_EXITING)) |
| 766 | recalc_sigpending_and_wake(t); | 752 | recalc_sigpending_and_wake(t); |
| 767 | spin_unlock_irq(&tsk->sighand->siglock); | 753 | spin_unlock_irq(&tsk->sighand->siglock); |
| 768 | read_unlock(&tasklist_lock); | ||
| 769 | } | 754 | } |
| 770 | 755 | ||
| 771 | write_lock_irq(&tasklist_lock); | 756 | write_lock_irq(&tasklist_lock); |
| @@ -793,9 +778,8 @@ static void exit_notify(struct task_struct *tsk) | |||
| 793 | * and we were the only connection outside, so our pgrp | 778 | * and we were the only connection outside, so our pgrp |
| 794 | * is about to become orphaned. | 779 | * is about to become orphaned. |
| 795 | */ | 780 | */ |
| 796 | |||
| 797 | t = tsk->real_parent; | 781 | t = tsk->real_parent; |
| 798 | 782 | ||
| 799 | pgrp = task_pgrp(tsk); | 783 | pgrp = task_pgrp(tsk); |
| 800 | if ((task_pgrp(t) != pgrp) && | 784 | if ((task_pgrp(t) != pgrp) && |
| 801 | (task_session(t) == task_session(tsk)) && | 785 | (task_session(t) == task_session(tsk)) && |
| @@ -842,6 +826,11 @@ static void exit_notify(struct task_struct *tsk) | |||
| 842 | state = EXIT_DEAD; | 826 | state = EXIT_DEAD; |
| 843 | tsk->exit_state = state; | 827 | tsk->exit_state = state; |
| 844 | 828 | ||
| 829 | if (thread_group_leader(tsk) && | ||
| 830 | tsk->signal->notify_count < 0 && | ||
| 831 | tsk->signal->group_exit_task) | ||
| 832 | wake_up_process(tsk->signal->group_exit_task); | ||
| 833 | |||
| 845 | write_unlock_irq(&tasklist_lock); | 834 | write_unlock_irq(&tasklist_lock); |
| 846 | 835 | ||
| 847 | list_for_each_safe(_p, _n, &ptrace_dead) { | 836 | list_for_each_safe(_p, _n, &ptrace_dead) { |
| @@ -883,6 +872,14 @@ static void check_stack_usage(void) | |||
| 883 | static inline void check_stack_usage(void) {} | 872 | static inline void check_stack_usage(void) {} |
| 884 | #endif | 873 | #endif |
| 885 | 874 | ||
| 875 | static inline void exit_child_reaper(struct task_struct *tsk) | ||
| 876 | { | ||
| 877 | if (likely(tsk->group_leader != child_reaper(tsk))) | ||
| 878 | return; | ||
| 879 | |||
| 880 | panic("Attempted to kill init!"); | ||
| 881 | } | ||
| 882 | |||
| 886 | fastcall NORET_TYPE void do_exit(long code) | 883 | fastcall NORET_TYPE void do_exit(long code) |
| 887 | { | 884 | { |
| 888 | struct task_struct *tsk = current; | 885 | struct task_struct *tsk = current; |
| @@ -896,13 +893,6 @@ fastcall NORET_TYPE void do_exit(long code) | |||
| 896 | panic("Aiee, killing interrupt handler!"); | 893 | panic("Aiee, killing interrupt handler!"); |
| 897 | if (unlikely(!tsk->pid)) | 894 | if (unlikely(!tsk->pid)) |
| 898 | panic("Attempted to kill the idle task!"); | 895 | panic("Attempted to kill the idle task!"); |
| 899 | if (unlikely(tsk == child_reaper(tsk))) { | ||
| 900 | if (tsk->nsproxy->pid_ns != &init_pid_ns) | ||
| 901 | tsk->nsproxy->pid_ns->child_reaper = init_pid_ns.child_reaper; | ||
| 902 | else | ||
| 903 | panic("Attempted to kill init!"); | ||
| 904 | } | ||
| 905 | |||
| 906 | 896 | ||
| 907 | if (unlikely(current->ptrace & PT_TRACE_EXIT)) { | 897 | if (unlikely(current->ptrace & PT_TRACE_EXIT)) { |
| 908 | current->ptrace_message = code; | 898 | current->ptrace_message = code; |
| @@ -932,13 +922,13 @@ fastcall NORET_TYPE void do_exit(long code) | |||
| 932 | schedule(); | 922 | schedule(); |
| 933 | } | 923 | } |
| 934 | 924 | ||
| 925 | tsk->flags |= PF_EXITING; | ||
| 935 | /* | 926 | /* |
| 936 | * tsk->flags are checked in the futex code to protect against | 927 | * tsk->flags are checked in the futex code to protect against |
| 937 | * an exiting task cleaning up the robust pi futexes. | 928 | * an exiting task cleaning up the robust pi futexes. |
| 938 | */ | 929 | */ |
| 939 | spin_lock_irq(&tsk->pi_lock); | 930 | smp_mb(); |
| 940 | tsk->flags |= PF_EXITING; | 931 | spin_unlock_wait(&tsk->pi_lock); |
| 941 | spin_unlock_irq(&tsk->pi_lock); | ||
| 942 | 932 | ||
| 943 | if (unlikely(in_atomic())) | 933 | if (unlikely(in_atomic())) |
| 944 | printk(KERN_INFO "note: %s[%d] exited with preempt_count %d\n", | 934 | printk(KERN_INFO "note: %s[%d] exited with preempt_count %d\n", |
| @@ -952,16 +942,19 @@ fastcall NORET_TYPE void do_exit(long code) | |||
| 952 | } | 942 | } |
| 953 | group_dead = atomic_dec_and_test(&tsk->signal->live); | 943 | group_dead = atomic_dec_and_test(&tsk->signal->live); |
| 954 | if (group_dead) { | 944 | if (group_dead) { |
| 945 | exit_child_reaper(tsk); | ||
| 955 | hrtimer_cancel(&tsk->signal->real_timer); | 946 | hrtimer_cancel(&tsk->signal->real_timer); |
| 956 | exit_itimers(tsk->signal); | 947 | exit_itimers(tsk->signal); |
| 957 | } | 948 | } |
| 958 | acct_collect(code, group_dead); | 949 | acct_collect(code, group_dead); |
| 950 | #ifdef CONFIG_FUTEX | ||
| 959 | if (unlikely(tsk->robust_list)) | 951 | if (unlikely(tsk->robust_list)) |
| 960 | exit_robust_list(tsk); | 952 | exit_robust_list(tsk); |
| 961 | #if defined(CONFIG_FUTEX) && defined(CONFIG_COMPAT) | 953 | #ifdef CONFIG_COMPAT |
| 962 | if (unlikely(tsk->compat_robust_list)) | 954 | if (unlikely(tsk->compat_robust_list)) |
| 963 | compat_exit_robust_list(tsk); | 955 | compat_exit_robust_list(tsk); |
| 964 | #endif | 956 | #endif |
| 957 | #endif | ||
| 965 | if (group_dead) | 958 | if (group_dead) |
| 966 | tty_audit_exit(); | 959 | tty_audit_exit(); |
| 967 | if (unlikely(tsk->audit_context)) | 960 | if (unlikely(tsk->audit_context)) |
| @@ -996,6 +989,7 @@ fastcall NORET_TYPE void do_exit(long code) | |||
| 996 | mpol_free(tsk->mempolicy); | 989 | mpol_free(tsk->mempolicy); |
| 997 | tsk->mempolicy = NULL; | 990 | tsk->mempolicy = NULL; |
| 998 | #endif | 991 | #endif |
| 992 | #ifdef CONFIG_FUTEX | ||
| 999 | /* | 993 | /* |
| 1000 | * This must happen late, after the PID is not | 994 | * This must happen late, after the PID is not |
| 1001 | * hashed anymore: | 995 | * hashed anymore: |
| @@ -1004,6 +998,7 @@ fastcall NORET_TYPE void do_exit(long code) | |||
| 1004 | exit_pi_state_list(tsk); | 998 | exit_pi_state_list(tsk); |
| 1005 | if (unlikely(current->pi_state_cache)) | 999 | if (unlikely(current->pi_state_cache)) |
| 1006 | kfree(current->pi_state_cache); | 1000 | kfree(current->pi_state_cache); |
| 1001 | #endif | ||
| 1007 | /* | 1002 | /* |
| 1008 | * Make sure we are holding no locks: | 1003 | * Make sure we are holding no locks: |
| 1009 | */ | 1004 | */ |
| @@ -1168,8 +1163,7 @@ static int wait_task_zombie(struct task_struct *p, int noreap, | |||
| 1168 | int __user *stat_addr, struct rusage __user *ru) | 1163 | int __user *stat_addr, struct rusage __user *ru) |
| 1169 | { | 1164 | { |
| 1170 | unsigned long state; | 1165 | unsigned long state; |
| 1171 | int retval; | 1166 | int retval, status, traced; |
| 1172 | int status; | ||
| 1173 | 1167 | ||
| 1174 | if (unlikely(noreap)) { | 1168 | if (unlikely(noreap)) { |
| 1175 | pid_t pid = p->pid; | 1169 | pid_t pid = p->pid; |
| @@ -1203,15 +1197,11 @@ static int wait_task_zombie(struct task_struct *p, int noreap, | |||
| 1203 | BUG_ON(state != EXIT_DEAD); | 1197 | BUG_ON(state != EXIT_DEAD); |
| 1204 | return 0; | 1198 | return 0; |
| 1205 | } | 1199 | } |
| 1206 | if (unlikely(p->exit_signal == -1 && p->ptrace == 0)) { | ||
| 1207 | /* | ||
| 1208 | * This can only happen in a race with a ptraced thread | ||
| 1209 | * dying on another processor. | ||
| 1210 | */ | ||
| 1211 | return 0; | ||
| 1212 | } | ||
| 1213 | 1200 | ||
| 1214 | if (likely(p->real_parent == p->parent) && likely(p->signal)) { | 1201 | /* traced means p->ptrace, but not vice versa */ |
| 1202 | traced = (p->real_parent != p->parent); | ||
| 1203 | |||
| 1204 | if (likely(!traced)) { | ||
| 1215 | struct signal_struct *psig; | 1205 | struct signal_struct *psig; |
| 1216 | struct signal_struct *sig; | 1206 | struct signal_struct *sig; |
| 1217 | 1207 | ||
| @@ -1298,35 +1288,30 @@ static int wait_task_zombie(struct task_struct *p, int noreap, | |||
| 1298 | retval = put_user(p->pid, &infop->si_pid); | 1288 | retval = put_user(p->pid, &infop->si_pid); |
| 1299 | if (!retval && infop) | 1289 | if (!retval && infop) |
| 1300 | retval = put_user(p->uid, &infop->si_uid); | 1290 | retval = put_user(p->uid, &infop->si_uid); |
| 1301 | if (retval) { | 1291 | if (!retval) |
| 1302 | // TODO: is this safe? | 1292 | retval = p->pid; |
| 1303 | p->exit_state = EXIT_ZOMBIE; | 1293 | |
| 1304 | return retval; | 1294 | if (traced) { |
| 1305 | } | ||
| 1306 | retval = p->pid; | ||
| 1307 | if (p->real_parent != p->parent) { | ||
| 1308 | write_lock_irq(&tasklist_lock); | 1295 | write_lock_irq(&tasklist_lock); |
| 1309 | /* Double-check with lock held. */ | 1296 | /* We dropped tasklist, ptracer could die and untrace */ |
| 1310 | if (p->real_parent != p->parent) { | 1297 | ptrace_unlink(p); |
| 1311 | __ptrace_unlink(p); | 1298 | /* |
| 1312 | // TODO: is this safe? | 1299 | * If this is not a detached task, notify the parent. |
| 1313 | p->exit_state = EXIT_ZOMBIE; | 1300 | * If it's still not detached after that, don't release |
| 1314 | /* | 1301 | * it now. |
| 1315 | * If this is not a detached task, notify the parent. | 1302 | */ |
| 1316 | * If it's still not detached after that, don't release | 1303 | if (p->exit_signal != -1) { |
| 1317 | * it now. | 1304 | do_notify_parent(p, p->exit_signal); |
| 1318 | */ | ||
| 1319 | if (p->exit_signal != -1) { | 1305 | if (p->exit_signal != -1) { |
| 1320 | do_notify_parent(p, p->exit_signal); | 1306 | p->exit_state = EXIT_ZOMBIE; |
| 1321 | if (p->exit_signal != -1) | 1307 | p = NULL; |
| 1322 | p = NULL; | ||
| 1323 | } | 1308 | } |
| 1324 | } | 1309 | } |
| 1325 | write_unlock_irq(&tasklist_lock); | 1310 | write_unlock_irq(&tasklist_lock); |
| 1326 | } | 1311 | } |
| 1327 | if (p != NULL) | 1312 | if (p != NULL) |
| 1328 | release_task(p); | 1313 | release_task(p); |
| 1329 | BUG_ON(!retval); | 1314 | |
| 1330 | return retval; | 1315 | return retval; |
| 1331 | } | 1316 | } |
| 1332 | 1317 | ||
| @@ -1345,7 +1330,7 @@ static int wait_task_stopped(struct task_struct *p, int delayed_group_leader, | |||
| 1345 | if (!p->exit_code) | 1330 | if (!p->exit_code) |
| 1346 | return 0; | 1331 | return 0; |
| 1347 | if (delayed_group_leader && !(p->ptrace & PT_PTRACED) && | 1332 | if (delayed_group_leader && !(p->ptrace & PT_PTRACED) && |
| 1348 | p->signal && p->signal->group_stop_count > 0) | 1333 | p->signal->group_stop_count > 0) |
| 1349 | /* | 1334 | /* |
| 1350 | * A group stop is in progress and this is the group leader. | 1335 | * A group stop is in progress and this is the group leader. |
| 1351 | * We won't report until all threads have stopped. | 1336 | * We won't report until all threads have stopped. |
| @@ -1459,9 +1444,6 @@ static int wait_task_continued(struct task_struct *p, int noreap, | |||
| 1459 | pid_t pid; | 1444 | pid_t pid; |
| 1460 | uid_t uid; | 1445 | uid_t uid; |
| 1461 | 1446 | ||
| 1462 | if (unlikely(!p->signal)) | ||
| 1463 | return 0; | ||
| 1464 | |||
| 1465 | if (!(p->signal->flags & SIGNAL_STOP_CONTINUED)) | 1447 | if (!(p->signal->flags & SIGNAL_STOP_CONTINUED)) |
| 1466 | return 0; | 1448 | return 0; |
| 1467 | 1449 | ||
diff --git a/kernel/fork.c b/kernel/fork.c index 3fc3c1383912..490495a39c7e 100644 --- a/kernel/fork.c +++ b/kernel/fork.c | |||
| @@ -107,6 +107,7 @@ static struct kmem_cache *mm_cachep; | |||
| 107 | 107 | ||
| 108 | void free_task(struct task_struct *tsk) | 108 | void free_task(struct task_struct *tsk) |
| 109 | { | 109 | { |
| 110 | prop_local_destroy_single(&tsk->dirties); | ||
| 110 | free_thread_info(tsk->stack); | 111 | free_thread_info(tsk->stack); |
| 111 | rt_mutex_debug_task_free(tsk); | 112 | rt_mutex_debug_task_free(tsk); |
| 112 | free_task_struct(tsk); | 113 | free_task_struct(tsk); |
| @@ -163,6 +164,7 @@ static struct task_struct *dup_task_struct(struct task_struct *orig) | |||
| 163 | { | 164 | { |
| 164 | struct task_struct *tsk; | 165 | struct task_struct *tsk; |
| 165 | struct thread_info *ti; | 166 | struct thread_info *ti; |
| 167 | int err; | ||
| 166 | 168 | ||
| 167 | prepare_to_copy(orig); | 169 | prepare_to_copy(orig); |
| 168 | 170 | ||
| @@ -178,6 +180,14 @@ static struct task_struct *dup_task_struct(struct task_struct *orig) | |||
| 178 | 180 | ||
| 179 | *tsk = *orig; | 181 | *tsk = *orig; |
| 180 | tsk->stack = ti; | 182 | tsk->stack = ti; |
| 183 | |||
| 184 | err = prop_local_init_single(&tsk->dirties); | ||
| 185 | if (err) { | ||
| 186 | free_thread_info(ti); | ||
| 187 | free_task_struct(tsk); | ||
| 188 | return NULL; | ||
| 189 | } | ||
| 190 | |||
| 181 | setup_thread_stack(tsk, orig); | 191 | setup_thread_stack(tsk, orig); |
| 182 | 192 | ||
| 183 | #ifdef CONFIG_CC_STACKPROTECTOR | 193 | #ifdef CONFIG_CC_STACKPROTECTOR |
| @@ -1069,7 +1079,9 @@ static struct task_struct *copy_process(unsigned long clone_flags, | |||
| 1069 | do_posix_clock_monotonic_gettime(&p->start_time); | 1079 | do_posix_clock_monotonic_gettime(&p->start_time); |
| 1070 | p->real_start_time = p->start_time; | 1080 | p->real_start_time = p->start_time; |
| 1071 | monotonic_to_bootbased(&p->real_start_time); | 1081 | monotonic_to_bootbased(&p->real_start_time); |
| 1082 | #ifdef CONFIG_SECURITY | ||
| 1072 | p->security = NULL; | 1083 | p->security = NULL; |
| 1084 | #endif | ||
| 1073 | p->io_context = NULL; | 1085 | p->io_context = NULL; |
| 1074 | p->io_wait = NULL; | 1086 | p->io_wait = NULL; |
| 1075 | p->audit_context = NULL; | 1087 | p->audit_context = NULL; |
| @@ -1146,13 +1158,14 @@ static struct task_struct *copy_process(unsigned long clone_flags, | |||
| 1146 | * Clear TID on mm_release()? | 1158 | * Clear TID on mm_release()? |
| 1147 | */ | 1159 | */ |
| 1148 | p->clear_child_tid = (clone_flags & CLONE_CHILD_CLEARTID) ? child_tidptr: NULL; | 1160 | p->clear_child_tid = (clone_flags & CLONE_CHILD_CLEARTID) ? child_tidptr: NULL; |
| 1161 | #ifdef CONFIG_FUTEX | ||
| 1149 | p->robust_list = NULL; | 1162 | p->robust_list = NULL; |
| 1150 | #ifdef CONFIG_COMPAT | 1163 | #ifdef CONFIG_COMPAT |
| 1151 | p->compat_robust_list = NULL; | 1164 | p->compat_robust_list = NULL; |
| 1152 | #endif | 1165 | #endif |
| 1153 | INIT_LIST_HEAD(&p->pi_state_list); | 1166 | INIT_LIST_HEAD(&p->pi_state_list); |
| 1154 | p->pi_state_cache = NULL; | 1167 | p->pi_state_cache = NULL; |
| 1155 | 1168 | #endif | |
| 1156 | /* | 1169 | /* |
| 1157 | * sigaltstack should be cleared when sharing the same VM | 1170 | * sigaltstack should be cleared when sharing the same VM |
| 1158 | */ | 1171 | */ |
| @@ -1435,8 +1448,7 @@ long do_fork(unsigned long clone_flags, | |||
| 1435 | #define ARCH_MIN_MMSTRUCT_ALIGN 0 | 1448 | #define ARCH_MIN_MMSTRUCT_ALIGN 0 |
| 1436 | #endif | 1449 | #endif |
| 1437 | 1450 | ||
| 1438 | static void sighand_ctor(void *data, struct kmem_cache *cachep, | 1451 | static void sighand_ctor(struct kmem_cache *cachep, void *data) |
| 1439 | unsigned long flags) | ||
| 1440 | { | 1452 | { |
| 1441 | struct sighand_struct *sighand = data; | 1453 | struct sighand_struct *sighand = data; |
| 1442 | 1454 | ||
diff --git a/kernel/futex.c b/kernel/futex.c index fcc94e7b4086..d725676d84f3 100644 --- a/kernel/futex.c +++ b/kernel/futex.c | |||
| @@ -52,6 +52,7 @@ | |||
| 52 | #include <linux/syscalls.h> | 52 | #include <linux/syscalls.h> |
| 53 | #include <linux/signal.h> | 53 | #include <linux/signal.h> |
| 54 | #include <linux/module.h> | 54 | #include <linux/module.h> |
| 55 | #include <linux/magic.h> | ||
| 55 | #include <asm/futex.h> | 56 | #include <asm/futex.h> |
| 56 | 57 | ||
| 57 | #include "rtmutex_common.h" | 58 | #include "rtmutex_common.h" |
| @@ -2080,7 +2081,7 @@ static int futexfs_get_sb(struct file_system_type *fs_type, | |||
| 2080 | int flags, const char *dev_name, void *data, | 2081 | int flags, const char *dev_name, void *data, |
| 2081 | struct vfsmount *mnt) | 2082 | struct vfsmount *mnt) |
| 2082 | { | 2083 | { |
| 2083 | return get_sb_pseudo(fs_type, "futex", NULL, 0xBAD1DEA, mnt); | 2084 | return get_sb_pseudo(fs_type, "futex", NULL, FUTEXFS_SUPER_MAGIC, mnt); |
| 2084 | } | 2085 | } |
| 2085 | 2086 | ||
| 2086 | static struct file_system_type futex_fs_type = { | 2087 | static struct file_system_type futex_fs_type = { |
diff --git a/kernel/irq/chip.c b/kernel/irq/chip.c index f1a73f0b54e7..9b5dff6b3f6a 100644 --- a/kernel/irq/chip.c +++ b/kernel/irq/chip.c | |||
| @@ -503,7 +503,6 @@ out_unlock: | |||
| 503 | spin_unlock(&desc->lock); | 503 | spin_unlock(&desc->lock); |
| 504 | } | 504 | } |
| 505 | 505 | ||
| 506 | #ifdef CONFIG_SMP | ||
| 507 | /** | 506 | /** |
| 508 | * handle_percpu_IRQ - Per CPU local irq handler | 507 | * handle_percpu_IRQ - Per CPU local irq handler |
| 509 | * @irq: the interrupt number | 508 | * @irq: the interrupt number |
| @@ -529,8 +528,6 @@ handle_percpu_irq(unsigned int irq, struct irq_desc *desc) | |||
| 529 | desc->chip->eoi(irq); | 528 | desc->chip->eoi(irq); |
| 530 | } | 529 | } |
| 531 | 530 | ||
| 532 | #endif /* CONFIG_SMP */ | ||
| 533 | |||
| 534 | void | 531 | void |
| 535 | __set_irq_handler(unsigned int irq, irq_flow_handler_t handle, int is_chained, | 532 | __set_irq_handler(unsigned int irq, irq_flow_handler_t handle, int is_chained, |
| 536 | const char *name) | 533 | const char *name) |
diff --git a/kernel/irq/manage.c b/kernel/irq/manage.c index 7230d914eaa2..80eab7a04205 100644 --- a/kernel/irq/manage.c +++ b/kernel/irq/manage.c | |||
| @@ -405,7 +405,6 @@ void free_irq(unsigned int irq, void *dev_id) | |||
| 405 | struct irq_desc *desc; | 405 | struct irq_desc *desc; |
| 406 | struct irqaction **p; | 406 | struct irqaction **p; |
| 407 | unsigned long flags; | 407 | unsigned long flags; |
| 408 | irqreturn_t (*handler)(int, void *) = NULL; | ||
| 409 | 408 | ||
| 410 | WARN_ON(in_interrupt()); | 409 | WARN_ON(in_interrupt()); |
| 411 | if (irq >= NR_IRQS) | 410 | if (irq >= NR_IRQS) |
| @@ -445,8 +444,21 @@ void free_irq(unsigned int irq, void *dev_id) | |||
| 445 | 444 | ||
| 446 | /* Make sure it's not being used on another CPU */ | 445 | /* Make sure it's not being used on another CPU */ |
| 447 | synchronize_irq(irq); | 446 | synchronize_irq(irq); |
| 448 | if (action->flags & IRQF_SHARED) | 447 | #ifdef CONFIG_DEBUG_SHIRQ |
| 449 | handler = action->handler; | 448 | /* |
| 449 | * It's a shared IRQ -- the driver ought to be | ||
| 450 | * prepared for it to happen even now it's | ||
| 451 | * being freed, so let's make sure.... We do | ||
| 452 | * this after actually deregistering it, to | ||
| 453 | * make sure that a 'real' IRQ doesn't run in | ||
| 454 | * parallel with our fake | ||
| 455 | */ | ||
| 456 | if (action->flags & IRQF_SHARED) { | ||
| 457 | local_irq_save(flags); | ||
| 458 | action->handler(irq, dev_id); | ||
| 459 | local_irq_restore(flags); | ||
| 460 | } | ||
| 461 | #endif | ||
| 450 | kfree(action); | 462 | kfree(action); |
| 451 | return; | 463 | return; |
| 452 | } | 464 | } |
| @@ -454,19 +466,6 @@ void free_irq(unsigned int irq, void *dev_id) | |||
| 454 | spin_unlock_irqrestore(&desc->lock, flags); | 466 | spin_unlock_irqrestore(&desc->lock, flags); |
| 455 | return; | 467 | return; |
| 456 | } | 468 | } |
| 457 | #ifdef CONFIG_DEBUG_SHIRQ | ||
| 458 | if (handler) { | ||
| 459 | /* | ||
| 460 | * It's a shared IRQ -- the driver ought to be prepared for it | ||
| 461 | * to happen even now it's being freed, so let's make sure.... | ||
| 462 | * We do this after actually deregistering it, to make sure that | ||
| 463 | * a 'real' IRQ doesn't run in parallel with our fake | ||
| 464 | */ | ||
| 465 | local_irq_save(flags); | ||
| 466 | handler(irq, dev_id); | ||
| 467 | local_irq_restore(flags); | ||
| 468 | } | ||
| 469 | #endif | ||
| 470 | } | 469 | } |
| 471 | EXPORT_SYMBOL(free_irq); | 470 | EXPORT_SYMBOL(free_irq); |
| 472 | 471 | ||
diff --git a/kernel/kexec.c b/kernel/kexec.c index 25db14b89e82..7885269b0da2 100644 --- a/kernel/kexec.c +++ b/kernel/kexec.c | |||
| @@ -17,21 +17,30 @@ | |||
| 17 | #include <linux/highmem.h> | 17 | #include <linux/highmem.h> |
| 18 | #include <linux/syscalls.h> | 18 | #include <linux/syscalls.h> |
| 19 | #include <linux/reboot.h> | 19 | #include <linux/reboot.h> |
| 20 | #include <linux/syscalls.h> | ||
| 21 | #include <linux/ioport.h> | 20 | #include <linux/ioport.h> |
| 22 | #include <linux/hardirq.h> | 21 | #include <linux/hardirq.h> |
| 23 | #include <linux/elf.h> | 22 | #include <linux/elf.h> |
| 24 | #include <linux/elfcore.h> | 23 | #include <linux/elfcore.h> |
| 24 | #include <linux/utsrelease.h> | ||
| 25 | #include <linux/utsname.h> | ||
| 26 | #include <linux/numa.h> | ||
| 25 | 27 | ||
| 26 | #include <asm/page.h> | 28 | #include <asm/page.h> |
| 27 | #include <asm/uaccess.h> | 29 | #include <asm/uaccess.h> |
| 28 | #include <asm/io.h> | 30 | #include <asm/io.h> |
| 29 | #include <asm/system.h> | 31 | #include <asm/system.h> |
| 30 | #include <asm/semaphore.h> | 32 | #include <asm/semaphore.h> |
| 33 | #include <asm/sections.h> | ||
| 31 | 34 | ||
| 32 | /* Per cpu memory for storing cpu states in case of system crash. */ | 35 | /* Per cpu memory for storing cpu states in case of system crash. */ |
| 33 | note_buf_t* crash_notes; | 36 | note_buf_t* crash_notes; |
| 34 | 37 | ||
| 38 | /* vmcoreinfo stuff */ | ||
| 39 | unsigned char vmcoreinfo_data[VMCOREINFO_BYTES]; | ||
| 40 | u32 vmcoreinfo_note[VMCOREINFO_NOTE_SIZE/4]; | ||
| 41 | size_t vmcoreinfo_size; | ||
| 42 | size_t vmcoreinfo_max_size = sizeof(vmcoreinfo_data); | ||
| 43 | |||
| 35 | /* Location of the reserved area for the crash kernel */ | 44 | /* Location of the reserved area for the crash kernel */ |
| 36 | struct resource crashk_res = { | 45 | struct resource crashk_res = { |
| 37 | .name = "Crash kernel", | 46 | .name = "Crash kernel", |
| @@ -1061,6 +1070,7 @@ void crash_kexec(struct pt_regs *regs) | |||
| 1061 | if (kexec_crash_image) { | 1070 | if (kexec_crash_image) { |
| 1062 | struct pt_regs fixed_regs; | 1071 | struct pt_regs fixed_regs; |
| 1063 | crash_setup_regs(&fixed_regs, regs); | 1072 | crash_setup_regs(&fixed_regs, regs); |
| 1073 | crash_save_vmcoreinfo(); | ||
| 1064 | machine_crash_shutdown(&fixed_regs); | 1074 | machine_crash_shutdown(&fixed_regs); |
| 1065 | machine_kexec(kexec_crash_image); | 1075 | machine_kexec(kexec_crash_image); |
| 1066 | } | 1076 | } |
| @@ -1135,3 +1145,104 @@ static int __init crash_notes_memory_init(void) | |||
| 1135 | return 0; | 1145 | return 0; |
| 1136 | } | 1146 | } |
| 1137 | module_init(crash_notes_memory_init) | 1147 | module_init(crash_notes_memory_init) |
| 1148 | |||
| 1149 | void crash_save_vmcoreinfo(void) | ||
| 1150 | { | ||
| 1151 | u32 *buf; | ||
| 1152 | |||
| 1153 | if (!vmcoreinfo_size) | ||
| 1154 | return; | ||
| 1155 | |||
| 1156 | vmcoreinfo_append_str("CRASHTIME=%ld", get_seconds()); | ||
| 1157 | |||
| 1158 | buf = (u32 *)vmcoreinfo_note; | ||
| 1159 | |||
| 1160 | buf = append_elf_note(buf, VMCOREINFO_NOTE_NAME, 0, vmcoreinfo_data, | ||
| 1161 | vmcoreinfo_size); | ||
| 1162 | |||
| 1163 | final_note(buf); | ||
| 1164 | } | ||
| 1165 | |||
| 1166 | void vmcoreinfo_append_str(const char *fmt, ...) | ||
| 1167 | { | ||
| 1168 | va_list args; | ||
| 1169 | char buf[0x50]; | ||
| 1170 | int r; | ||
| 1171 | |||
| 1172 | va_start(args, fmt); | ||
| 1173 | r = vsnprintf(buf, sizeof(buf), fmt, args); | ||
| 1174 | va_end(args); | ||
| 1175 | |||
| 1176 | if (r + vmcoreinfo_size > vmcoreinfo_max_size) | ||
| 1177 | r = vmcoreinfo_max_size - vmcoreinfo_size; | ||
| 1178 | |||
| 1179 | memcpy(&vmcoreinfo_data[vmcoreinfo_size], buf, r); | ||
| 1180 | |||
| 1181 | vmcoreinfo_size += r; | ||
| 1182 | } | ||
| 1183 | |||
| 1184 | /* | ||
| 1185 | * provide an empty default implementation here -- architecture | ||
| 1186 | * code may override this | ||
| 1187 | */ | ||
| 1188 | void __attribute__ ((weak)) arch_crash_save_vmcoreinfo(void) | ||
| 1189 | {} | ||
| 1190 | |||
| 1191 | unsigned long __attribute__ ((weak)) paddr_vmcoreinfo_note(void) | ||
| 1192 | { | ||
| 1193 | return __pa((unsigned long)(char *)&vmcoreinfo_note); | ||
| 1194 | } | ||
| 1195 | |||
| 1196 | static int __init crash_save_vmcoreinfo_init(void) | ||
| 1197 | { | ||
| 1198 | vmcoreinfo_append_str("OSRELEASE=%s\n", init_uts_ns.name.release); | ||
| 1199 | vmcoreinfo_append_str("PAGESIZE=%ld\n", PAGE_SIZE); | ||
| 1200 | |||
| 1201 | VMCOREINFO_SYMBOL(init_uts_ns); | ||
| 1202 | VMCOREINFO_SYMBOL(node_online_map); | ||
| 1203 | VMCOREINFO_SYMBOL(swapper_pg_dir); | ||
| 1204 | VMCOREINFO_SYMBOL(_stext); | ||
| 1205 | |||
| 1206 | #ifndef CONFIG_NEED_MULTIPLE_NODES | ||
| 1207 | VMCOREINFO_SYMBOL(mem_map); | ||
| 1208 | VMCOREINFO_SYMBOL(contig_page_data); | ||
| 1209 | #endif | ||
| 1210 | #ifdef CONFIG_SPARSEMEM | ||
| 1211 | VMCOREINFO_SYMBOL(mem_section); | ||
| 1212 | VMCOREINFO_LENGTH(mem_section, NR_SECTION_ROOTS); | ||
| 1213 | VMCOREINFO_SIZE(mem_section); | ||
| 1214 | VMCOREINFO_OFFSET(mem_section, section_mem_map); | ||
| 1215 | #endif | ||
| 1216 | VMCOREINFO_SIZE(page); | ||
| 1217 | VMCOREINFO_SIZE(pglist_data); | ||
| 1218 | VMCOREINFO_SIZE(zone); | ||
| 1219 | VMCOREINFO_SIZE(free_area); | ||
| 1220 | VMCOREINFO_SIZE(list_head); | ||
| 1221 | VMCOREINFO_TYPEDEF_SIZE(nodemask_t); | ||
| 1222 | VMCOREINFO_OFFSET(page, flags); | ||
| 1223 | VMCOREINFO_OFFSET(page, _count); | ||
| 1224 | VMCOREINFO_OFFSET(page, mapping); | ||
| 1225 | VMCOREINFO_OFFSET(page, lru); | ||
| 1226 | VMCOREINFO_OFFSET(pglist_data, node_zones); | ||
| 1227 | VMCOREINFO_OFFSET(pglist_data, nr_zones); | ||
| 1228 | #ifdef CONFIG_FLAT_NODE_MEM_MAP | ||
| 1229 | VMCOREINFO_OFFSET(pglist_data, node_mem_map); | ||
| 1230 | #endif | ||
| 1231 | VMCOREINFO_OFFSET(pglist_data, node_start_pfn); | ||
| 1232 | VMCOREINFO_OFFSET(pglist_data, node_spanned_pages); | ||
| 1233 | VMCOREINFO_OFFSET(pglist_data, node_id); | ||
| 1234 | VMCOREINFO_OFFSET(zone, free_area); | ||
| 1235 | VMCOREINFO_OFFSET(zone, vm_stat); | ||
| 1236 | VMCOREINFO_OFFSET(zone, spanned_pages); | ||
| 1237 | VMCOREINFO_OFFSET(free_area, free_list); | ||
| 1238 | VMCOREINFO_OFFSET(list_head, next); | ||
| 1239 | VMCOREINFO_OFFSET(list_head, prev); | ||
| 1240 | VMCOREINFO_LENGTH(zone.free_area, MAX_ORDER); | ||
| 1241 | VMCOREINFO_NUMBER(NR_FREE_PAGES); | ||
| 1242 | |||
| 1243 | arch_crash_save_vmcoreinfo(); | ||
| 1244 | |||
| 1245 | return 0; | ||
| 1246 | } | ||
| 1247 | |||
| 1248 | module_init(crash_save_vmcoreinfo_init) | ||
diff --git a/kernel/ksysfs.c b/kernel/ksysfs.c index 6046939d0804..65daa5373ca6 100644 --- a/kernel/ksysfs.c +++ b/kernel/ksysfs.c | |||
| @@ -61,6 +61,15 @@ static ssize_t kexec_crash_loaded_show(struct kset *kset, char *page) | |||
| 61 | return sprintf(page, "%d\n", !!kexec_crash_image); | 61 | return sprintf(page, "%d\n", !!kexec_crash_image); |
| 62 | } | 62 | } |
| 63 | KERNEL_ATTR_RO(kexec_crash_loaded); | 63 | KERNEL_ATTR_RO(kexec_crash_loaded); |
| 64 | |||
| 65 | static ssize_t vmcoreinfo_show(struct kset *kset, char *page) | ||
| 66 | { | ||
| 67 | return sprintf(page, "%lx %x\n", | ||
| 68 | paddr_vmcoreinfo_note(), | ||
| 69 | (unsigned int)vmcoreinfo_max_size); | ||
| 70 | } | ||
| 71 | KERNEL_ATTR_RO(vmcoreinfo); | ||
| 72 | |||
| 64 | #endif /* CONFIG_KEXEC */ | 73 | #endif /* CONFIG_KEXEC */ |
| 65 | 74 | ||
| 66 | /* | 75 | /* |
| @@ -96,6 +105,7 @@ static struct attribute * kernel_attrs[] = { | |||
| 96 | #ifdef CONFIG_KEXEC | 105 | #ifdef CONFIG_KEXEC |
| 97 | &kexec_loaded_attr.attr, | 106 | &kexec_loaded_attr.attr, |
| 98 | &kexec_crash_loaded_attr.attr, | 107 | &kexec_crash_loaded_attr.attr, |
| 108 | &vmcoreinfo_attr.attr, | ||
| 99 | #endif | 109 | #endif |
| 100 | NULL | 110 | NULL |
| 101 | }; | 111 | }; |
diff --git a/kernel/module.c b/kernel/module.c index db0ead0363e2..a389b423c279 100644 --- a/kernel/module.c +++ b/kernel/module.c | |||
| @@ -20,6 +20,7 @@ | |||
| 20 | #include <linux/moduleloader.h> | 20 | #include <linux/moduleloader.h> |
| 21 | #include <linux/init.h> | 21 | #include <linux/init.h> |
| 22 | #include <linux/kallsyms.h> | 22 | #include <linux/kallsyms.h> |
| 23 | #include <linux/sysfs.h> | ||
| 23 | #include <linux/kernel.h> | 24 | #include <linux/kernel.h> |
| 24 | #include <linux/slab.h> | 25 | #include <linux/slab.h> |
| 25 | #include <linux/vmalloc.h> | 26 | #include <linux/vmalloc.h> |
| @@ -692,8 +693,7 @@ sys_delete_module(const char __user *name_user, unsigned int flags) | |||
| 692 | } | 693 | } |
| 693 | 694 | ||
| 694 | /* If it has an init func, it must have an exit func to unload */ | 695 | /* If it has an init func, it must have an exit func to unload */ |
| 695 | if ((mod->init != NULL && mod->exit == NULL) | 696 | if (mod->init && !mod->exit) { |
| 696 | || mod->unsafe) { | ||
| 697 | forced = try_force_unload(flags); | 697 | forced = try_force_unload(flags); |
| 698 | if (!forced) { | 698 | if (!forced) { |
| 699 | /* This module can't be removed */ | 699 | /* This module can't be removed */ |
| @@ -741,11 +741,6 @@ static void print_unload_info(struct seq_file *m, struct module *mod) | |||
| 741 | seq_printf(m, "%s,", use->module_which_uses->name); | 741 | seq_printf(m, "%s,", use->module_which_uses->name); |
| 742 | } | 742 | } |
| 743 | 743 | ||
| 744 | if (mod->unsafe) { | ||
| 745 | printed_something = 1; | ||
| 746 | seq_printf(m, "[unsafe],"); | ||
| 747 | } | ||
| 748 | |||
| 749 | if (mod->init != NULL && mod->exit == NULL) { | 744 | if (mod->init != NULL && mod->exit == NULL) { |
| 750 | printed_something = 1; | 745 | printed_something = 1; |
| 751 | seq_printf(m, "[permanent],"); | 746 | seq_printf(m, "[permanent],"); |
| @@ -1053,6 +1048,100 @@ static void remove_sect_attrs(struct module *mod) | |||
| 1053 | } | 1048 | } |
| 1054 | } | 1049 | } |
| 1055 | 1050 | ||
| 1051 | /* | ||
| 1052 | * /sys/module/foo/notes/.section.name gives contents of SHT_NOTE sections. | ||
| 1053 | */ | ||
| 1054 | |||
| 1055 | struct module_notes_attrs { | ||
| 1056 | struct kobject *dir; | ||
| 1057 | unsigned int notes; | ||
| 1058 | struct bin_attribute attrs[0]; | ||
| 1059 | }; | ||
| 1060 | |||
| 1061 | static ssize_t module_notes_read(struct kobject *kobj, | ||
| 1062 | struct bin_attribute *bin_attr, | ||
| 1063 | char *buf, loff_t pos, size_t count) | ||
| 1064 | { | ||
| 1065 | /* | ||
| 1066 | * The caller checked the pos and count against our size. | ||
| 1067 | */ | ||
| 1068 | memcpy(buf, bin_attr->private + pos, count); | ||
| 1069 | return count; | ||
| 1070 | } | ||
| 1071 | |||
| 1072 | static void free_notes_attrs(struct module_notes_attrs *notes_attrs, | ||
| 1073 | unsigned int i) | ||
| 1074 | { | ||
| 1075 | if (notes_attrs->dir) { | ||
| 1076 | while (i-- > 0) | ||
| 1077 | sysfs_remove_bin_file(notes_attrs->dir, | ||
| 1078 | ¬es_attrs->attrs[i]); | ||
| 1079 | kobject_del(notes_attrs->dir); | ||
| 1080 | } | ||
| 1081 | kfree(notes_attrs); | ||
| 1082 | } | ||
| 1083 | |||
| 1084 | static void add_notes_attrs(struct module *mod, unsigned int nsect, | ||
| 1085 | char *secstrings, Elf_Shdr *sechdrs) | ||
| 1086 | { | ||
| 1087 | unsigned int notes, loaded, i; | ||
| 1088 | struct module_notes_attrs *notes_attrs; | ||
| 1089 | struct bin_attribute *nattr; | ||
| 1090 | |||
| 1091 | /* Count notes sections and allocate structures. */ | ||
| 1092 | notes = 0; | ||
| 1093 | for (i = 0; i < nsect; i++) | ||
| 1094 | if ((sechdrs[i].sh_flags & SHF_ALLOC) && | ||
| 1095 | (sechdrs[i].sh_type == SHT_NOTE)) | ||
| 1096 | ++notes; | ||
| 1097 | |||
| 1098 | if (notes == 0) | ||
| 1099 | return; | ||
| 1100 | |||
| 1101 | notes_attrs = kzalloc(sizeof(*notes_attrs) | ||
| 1102 | + notes * sizeof(notes_attrs->attrs[0]), | ||
| 1103 | GFP_KERNEL); | ||
| 1104 | if (notes_attrs == NULL) | ||
| 1105 | return; | ||
| 1106 | |||
| 1107 | notes_attrs->notes = notes; | ||
| 1108 | nattr = ¬es_attrs->attrs[0]; | ||
| 1109 | for (loaded = i = 0; i < nsect; ++i) { | ||
| 1110 | if (!(sechdrs[i].sh_flags & SHF_ALLOC)) | ||
| 1111 | continue; | ||
| 1112 | if (sechdrs[i].sh_type == SHT_NOTE) { | ||
| 1113 | nattr->attr.name = mod->sect_attrs->attrs[loaded].name; | ||
| 1114 | nattr->attr.mode = S_IRUGO; | ||
| 1115 | nattr->size = sechdrs[i].sh_size; | ||
| 1116 | nattr->private = (void *) sechdrs[i].sh_addr; | ||
| 1117 | nattr->read = module_notes_read; | ||
| 1118 | ++nattr; | ||
| 1119 | } | ||
| 1120 | ++loaded; | ||
| 1121 | } | ||
| 1122 | |||
| 1123 | notes_attrs->dir = kobject_add_dir(&mod->mkobj.kobj, "notes"); | ||
| 1124 | if (!notes_attrs->dir) | ||
| 1125 | goto out; | ||
| 1126 | |||
| 1127 | for (i = 0; i < notes; ++i) | ||
| 1128 | if (sysfs_create_bin_file(notes_attrs->dir, | ||
| 1129 | ¬es_attrs->attrs[i])) | ||
| 1130 | goto out; | ||
| 1131 | |||
| 1132 | mod->notes_attrs = notes_attrs; | ||
| 1133 | return; | ||
| 1134 | |||
| 1135 | out: | ||
| 1136 | free_notes_attrs(notes_attrs, i); | ||
| 1137 | } | ||
| 1138 | |||
| 1139 | static void remove_notes_attrs(struct module *mod) | ||
| 1140 | { | ||
| 1141 | if (mod->notes_attrs) | ||
| 1142 | free_notes_attrs(mod->notes_attrs, mod->notes_attrs->notes); | ||
| 1143 | } | ||
| 1144 | |||
| 1056 | #else | 1145 | #else |
| 1057 | 1146 | ||
| 1058 | static inline void add_sect_attrs(struct module *mod, unsigned int nsect, | 1147 | static inline void add_sect_attrs(struct module *mod, unsigned int nsect, |
| @@ -1063,6 +1152,15 @@ static inline void add_sect_attrs(struct module *mod, unsigned int nsect, | |||
| 1063 | static inline void remove_sect_attrs(struct module *mod) | 1152 | static inline void remove_sect_attrs(struct module *mod) |
| 1064 | { | 1153 | { |
| 1065 | } | 1154 | } |
| 1155 | |||
| 1156 | static inline void add_notes_attrs(struct module *mod, unsigned int nsect, | ||
| 1157 | char *sectstrings, Elf_Shdr *sechdrs) | ||
| 1158 | { | ||
| 1159 | } | ||
| 1160 | |||
| 1161 | static inline void remove_notes_attrs(struct module *mod) | ||
| 1162 | { | ||
| 1163 | } | ||
| 1066 | #endif /* CONFIG_KALLSYMS */ | 1164 | #endif /* CONFIG_KALLSYMS */ |
| 1067 | 1165 | ||
| 1068 | #ifdef CONFIG_SYSFS | 1166 | #ifdef CONFIG_SYSFS |
| @@ -1197,6 +1295,7 @@ static void free_module(struct module *mod) | |||
| 1197 | { | 1295 | { |
| 1198 | /* Delete from various lists */ | 1296 | /* Delete from various lists */ |
| 1199 | stop_machine_run(__unlink_module, mod, NR_CPUS); | 1297 | stop_machine_run(__unlink_module, mod, NR_CPUS); |
| 1298 | remove_notes_attrs(mod); | ||
| 1200 | remove_sect_attrs(mod); | 1299 | remove_sect_attrs(mod); |
| 1201 | mod_kobject_remove(mod); | 1300 | mod_kobject_remove(mod); |
| 1202 | 1301 | ||
| @@ -1782,7 +1881,8 @@ static struct module *load_module(void __user *umod, | |||
| 1782 | module_unload_init(mod); | 1881 | module_unload_init(mod); |
| 1783 | 1882 | ||
| 1784 | /* Initialize kobject, so we can reference it. */ | 1883 | /* Initialize kobject, so we can reference it. */ |
| 1785 | if (mod_sysfs_init(mod) != 0) | 1884 | err = mod_sysfs_init(mod); |
| 1885 | if (err) | ||
| 1786 | goto cleanup; | 1886 | goto cleanup; |
| 1787 | 1887 | ||
| 1788 | /* Set up license info based on the info section */ | 1888 | /* Set up license info based on the info section */ |
| @@ -1924,6 +2024,7 @@ static struct module *load_module(void __user *umod, | |||
| 1924 | if (err < 0) | 2024 | if (err < 0) |
| 1925 | goto arch_cleanup; | 2025 | goto arch_cleanup; |
| 1926 | add_sect_attrs(mod, hdr->e_shnum, secstrings, sechdrs); | 2026 | add_sect_attrs(mod, hdr->e_shnum, secstrings, sechdrs); |
| 2027 | add_notes_attrs(mod, hdr->e_shnum, secstrings, sechdrs); | ||
| 1927 | 2028 | ||
| 1928 | /* Size of section 0 is 0, so this works well if no unwind info. */ | 2029 | /* Size of section 0 is 0, so this works well if no unwind info. */ |
| 1929 | mod->unwind_info = unwind_add_table(mod, | 2030 | mod->unwind_info = unwind_add_table(mod, |
| @@ -2011,15 +2112,10 @@ sys_init_module(void __user *umod, | |||
| 2011 | buggy refcounters. */ | 2112 | buggy refcounters. */ |
| 2012 | mod->state = MODULE_STATE_GOING; | 2113 | mod->state = MODULE_STATE_GOING; |
| 2013 | synchronize_sched(); | 2114 | synchronize_sched(); |
| 2014 | if (mod->unsafe) | 2115 | module_put(mod); |
| 2015 | printk(KERN_ERR "%s: module is now stuck!\n", | 2116 | mutex_lock(&module_mutex); |
| 2016 | mod->name); | 2117 | free_module(mod); |
| 2017 | else { | 2118 | mutex_unlock(&module_mutex); |
| 2018 | module_put(mod); | ||
| 2019 | mutex_lock(&module_mutex); | ||
| 2020 | free_module(mod); | ||
| 2021 | mutex_unlock(&module_mutex); | ||
| 2022 | } | ||
| 2023 | return ret; | 2119 | return ret; |
| 2024 | } | 2120 | } |
| 2025 | 2121 | ||
diff --git a/kernel/nsproxy.c b/kernel/nsproxy.c index f1decd21a534..049e7c0ac566 100644 --- a/kernel/nsproxy.c +++ b/kernel/nsproxy.c | |||
| @@ -203,8 +203,7 @@ int unshare_nsproxy_namespaces(unsigned long unshare_flags, | |||
| 203 | 203 | ||
| 204 | static int __init nsproxy_cache_init(void) | 204 | static int __init nsproxy_cache_init(void) |
| 205 | { | 205 | { |
| 206 | nsproxy_cachep = kmem_cache_create("nsproxy", sizeof(struct nsproxy), | 206 | nsproxy_cachep = KMEM_CACHE(nsproxy, SLAB_PANIC); |
| 207 | 0, SLAB_PANIC, NULL); | ||
| 208 | return 0; | 207 | return 0; |
| 209 | } | 208 | } |
| 210 | 209 | ||
diff --git a/kernel/params.c b/kernel/params.c index 4e57732fcfb4..1d6aca288cdc 100644 --- a/kernel/params.c +++ b/kernel/params.c | |||
| @@ -252,8 +252,9 @@ int param_get_bool(char *buffer, struct kernel_param *kp) | |||
| 252 | int param_set_invbool(const char *val, struct kernel_param *kp) | 252 | int param_set_invbool(const char *val, struct kernel_param *kp) |
| 253 | { | 253 | { |
| 254 | int boolval, ret; | 254 | int boolval, ret; |
| 255 | struct kernel_param dummy = { .arg = &boolval }; | 255 | struct kernel_param dummy; |
| 256 | 256 | ||
| 257 | dummy.arg = &boolval; | ||
| 257 | ret = param_set_bool(val, &dummy); | 258 | ret = param_set_bool(val, &dummy); |
| 258 | if (ret == 0) | 259 | if (ret == 0) |
| 259 | *(int *)kp->arg = !boolval; | 260 | *(int *)kp->arg = !boolval; |
| @@ -262,11 +263,7 @@ int param_set_invbool(const char *val, struct kernel_param *kp) | |||
| 262 | 263 | ||
| 263 | int param_get_invbool(char *buffer, struct kernel_param *kp) | 264 | int param_get_invbool(char *buffer, struct kernel_param *kp) |
| 264 | { | 265 | { |
| 265 | int val; | 266 | return sprintf(buffer, "%c", (*(int *)kp->arg) ? 'N' : 'Y'); |
| 266 | struct kernel_param dummy = { .arg = &val }; | ||
| 267 | |||
| 268 | val = !*(int *)kp->arg; | ||
| 269 | return param_get_bool(buffer, &dummy); | ||
| 270 | } | 267 | } |
| 271 | 268 | ||
| 272 | /* We break the rule and mangle the string. */ | 269 | /* We break the rule and mangle the string. */ |
| @@ -325,7 +322,7 @@ static int param_array(const char *name, | |||
| 325 | 322 | ||
| 326 | int param_array_set(const char *val, struct kernel_param *kp) | 323 | int param_array_set(const char *val, struct kernel_param *kp) |
| 327 | { | 324 | { |
| 328 | struct kparam_array *arr = kp->arg; | 325 | const struct kparam_array *arr = kp->arr; |
| 329 | unsigned int temp_num; | 326 | unsigned int temp_num; |
| 330 | 327 | ||
| 331 | return param_array(kp->name, val, 1, arr->max, arr->elem, | 328 | return param_array(kp->name, val, 1, arr->max, arr->elem, |
| @@ -335,7 +332,7 @@ int param_array_set(const char *val, struct kernel_param *kp) | |||
| 335 | int param_array_get(char *buffer, struct kernel_param *kp) | 332 | int param_array_get(char *buffer, struct kernel_param *kp) |
| 336 | { | 333 | { |
| 337 | int i, off, ret; | 334 | int i, off, ret; |
| 338 | struct kparam_array *arr = kp->arg; | 335 | const struct kparam_array *arr = kp->arr; |
| 339 | struct kernel_param p; | 336 | struct kernel_param p; |
| 340 | 337 | ||
| 341 | p = *kp; | 338 | p = *kp; |
| @@ -354,7 +351,7 @@ int param_array_get(char *buffer, struct kernel_param *kp) | |||
| 354 | 351 | ||
| 355 | int param_set_copystring(const char *val, struct kernel_param *kp) | 352 | int param_set_copystring(const char *val, struct kernel_param *kp) |
| 356 | { | 353 | { |
| 357 | struct kparam_string *kps = kp->arg; | 354 | const struct kparam_string *kps = kp->str; |
| 358 | 355 | ||
| 359 | if (!val) { | 356 | if (!val) { |
| 360 | printk(KERN_ERR "%s: missing param set value\n", kp->name); | 357 | printk(KERN_ERR "%s: missing param set value\n", kp->name); |
| @@ -371,7 +368,7 @@ int param_set_copystring(const char *val, struct kernel_param *kp) | |||
| 371 | 368 | ||
| 372 | int param_get_string(char *buffer, struct kernel_param *kp) | 369 | int param_get_string(char *buffer, struct kernel_param *kp) |
| 373 | { | 370 | { |
| 374 | struct kparam_string *kps = kp->arg; | 371 | const struct kparam_string *kps = kp->str; |
| 375 | return strlcpy(buffer, kps->string, kps->maxlen); | 372 | return strlcpy(buffer, kps->string, kps->maxlen); |
| 376 | } | 373 | } |
| 377 | 374 | ||
diff --git a/kernel/posix-timers.c b/kernel/posix-timers.c index 57efe0400bc2..d71ed09fe1dd 100644 --- a/kernel/posix-timers.c +++ b/kernel/posix-timers.c | |||
| @@ -241,7 +241,8 @@ static __init int init_posix_timers(void) | |||
| 241 | register_posix_clock(CLOCK_MONOTONIC, &clock_monotonic); | 241 | register_posix_clock(CLOCK_MONOTONIC, &clock_monotonic); |
| 242 | 242 | ||
| 243 | posix_timers_cache = kmem_cache_create("posix_timers_cache", | 243 | posix_timers_cache = kmem_cache_create("posix_timers_cache", |
| 244 | sizeof (struct k_itimer), 0, 0, NULL); | 244 | sizeof (struct k_itimer), 0, SLAB_PANIC, |
| 245 | NULL); | ||
| 245 | idr_init(&posix_timers_id); | 246 | idr_init(&posix_timers_id); |
| 246 | return 0; | 247 | return 0; |
| 247 | } | 248 | } |
diff --git a/kernel/printk.c b/kernel/printk.c index b2b5c3a22a36..52493474f0ab 100644 --- a/kernel/printk.c +++ b/kernel/printk.c | |||
| @@ -220,6 +220,58 @@ static inline void boot_delay_msec(void) | |||
| 220 | #endif | 220 | #endif |
| 221 | 221 | ||
| 222 | /* | 222 | /* |
| 223 | * Return the number of unread characters in the log buffer. | ||
| 224 | */ | ||
| 225 | int log_buf_get_len(void) | ||
| 226 | { | ||
| 227 | return logged_chars; | ||
| 228 | } | ||
| 229 | |||
| 230 | /* | ||
| 231 | * Copy a range of characters from the log buffer. | ||
| 232 | */ | ||
| 233 | int log_buf_copy(char *dest, int idx, int len) | ||
| 234 | { | ||
| 235 | int ret, max; | ||
| 236 | bool took_lock = false; | ||
| 237 | |||
| 238 | if (!oops_in_progress) { | ||
| 239 | spin_lock_irq(&logbuf_lock); | ||
| 240 | took_lock = true; | ||
| 241 | } | ||
| 242 | |||
| 243 | max = log_buf_get_len(); | ||
| 244 | if (idx < 0 || idx >= max) { | ||
| 245 | ret = -1; | ||
| 246 | } else { | ||
| 247 | if (len > max) | ||
| 248 | len = max; | ||
| 249 | ret = len; | ||
| 250 | idx += (log_end - max); | ||
| 251 | while (len-- > 0) | ||
| 252 | dest[len] = LOG_BUF(idx + len); | ||
| 253 | } | ||
| 254 | |||
| 255 | if (took_lock) | ||
| 256 | spin_unlock_irq(&logbuf_lock); | ||
| 257 | |||
| 258 | return ret; | ||
| 259 | } | ||
| 260 | |||
| 261 | /* | ||
| 262 | * Extract a single character from the log buffer. | ||
| 263 | */ | ||
| 264 | int log_buf_read(int idx) | ||
| 265 | { | ||
| 266 | char ret; | ||
| 267 | |||
| 268 | if (log_buf_copy(&ret, idx, 1) == 1) | ||
| 269 | return ret; | ||
| 270 | else | ||
| 271 | return -1; | ||
| 272 | } | ||
| 273 | |||
| 274 | /* | ||
| 223 | * Commands to do_syslog: | 275 | * Commands to do_syslog: |
| 224 | * | 276 | * |
| 225 | * 0 -- Close the log. Currently a NOP. | 277 | * 0 -- Close the log. Currently a NOP. |
diff --git a/kernel/profile.c b/kernel/profile.c index 6f69bf792d96..631b75c25d7e 100644 --- a/kernel/profile.c +++ b/kernel/profile.c | |||
| @@ -37,7 +37,7 @@ struct profile_hit { | |||
| 37 | #define NR_PROFILE_GRP (NR_PROFILE_HIT/PROFILE_GRPSZ) | 37 | #define NR_PROFILE_GRP (NR_PROFILE_HIT/PROFILE_GRPSZ) |
| 38 | 38 | ||
| 39 | /* Oprofile timer tick hook */ | 39 | /* Oprofile timer tick hook */ |
| 40 | int (*timer_hook)(struct pt_regs *) __read_mostly; | 40 | static int (*timer_hook)(struct pt_regs *) __read_mostly; |
| 41 | 41 | ||
| 42 | static atomic_t *prof_buffer; | 42 | static atomic_t *prof_buffer; |
| 43 | static unsigned long prof_len, prof_shift; | 43 | static unsigned long prof_len, prof_shift; |
diff --git a/kernel/rcupdate.c b/kernel/rcupdate.c index 130214f3d229..a66d4d1615f7 100644 --- a/kernel/rcupdate.c +++ b/kernel/rcupdate.c | |||
| @@ -45,7 +45,6 @@ | |||
| 45 | #include <linux/moduleparam.h> | 45 | #include <linux/moduleparam.h> |
| 46 | #include <linux/percpu.h> | 46 | #include <linux/percpu.h> |
| 47 | #include <linux/notifier.h> | 47 | #include <linux/notifier.h> |
| 48 | #include <linux/rcupdate.h> | ||
| 49 | #include <linux/cpu.h> | 48 | #include <linux/cpu.h> |
| 50 | #include <linux/mutex.h> | 49 | #include <linux/mutex.h> |
| 51 | 50 | ||
diff --git a/kernel/rcutorture.c b/kernel/rcutorture.c index ddff33247785..c3e165c2318f 100644 --- a/kernel/rcutorture.c +++ b/kernel/rcutorture.c | |||
| @@ -35,14 +35,12 @@ | |||
| 35 | #include <linux/sched.h> | 35 | #include <linux/sched.h> |
| 36 | #include <asm/atomic.h> | 36 | #include <asm/atomic.h> |
| 37 | #include <linux/bitops.h> | 37 | #include <linux/bitops.h> |
| 38 | #include <linux/module.h> | ||
| 39 | #include <linux/completion.h> | 38 | #include <linux/completion.h> |
| 40 | #include <linux/moduleparam.h> | 39 | #include <linux/moduleparam.h> |
| 41 | #include <linux/percpu.h> | 40 | #include <linux/percpu.h> |
| 42 | #include <linux/notifier.h> | 41 | #include <linux/notifier.h> |
| 43 | #include <linux/freezer.h> | 42 | #include <linux/freezer.h> |
| 44 | #include <linux/cpu.h> | 43 | #include <linux/cpu.h> |
| 45 | #include <linux/random.h> | ||
| 46 | #include <linux/delay.h> | 44 | #include <linux/delay.h> |
| 47 | #include <linux/byteorder/swabb.h> | 45 | #include <linux/byteorder/swabb.h> |
| 48 | #include <linux/stat.h> | 46 | #include <linux/stat.h> |
| @@ -166,16 +164,14 @@ struct rcu_random_state { | |||
| 166 | 164 | ||
| 167 | /* | 165 | /* |
| 168 | * Crude but fast random-number generator. Uses a linear congruential | 166 | * Crude but fast random-number generator. Uses a linear congruential |
| 169 | * generator, with occasional help from get_random_bytes(). | 167 | * generator, with occasional help from cpu_clock(). |
| 170 | */ | 168 | */ |
| 171 | static unsigned long | 169 | static unsigned long |
| 172 | rcu_random(struct rcu_random_state *rrsp) | 170 | rcu_random(struct rcu_random_state *rrsp) |
| 173 | { | 171 | { |
| 174 | long refresh; | ||
| 175 | |||
| 176 | if (--rrsp->rrs_count < 0) { | 172 | if (--rrsp->rrs_count < 0) { |
| 177 | get_random_bytes(&refresh, sizeof(refresh)); | 173 | rrsp->rrs_state += |
| 178 | rrsp->rrs_state += refresh; | 174 | (unsigned long)cpu_clock(raw_smp_processor_id()); |
| 179 | rrsp->rrs_count = RCU_RANDOM_REFRESH; | 175 | rrsp->rrs_count = RCU_RANDOM_REFRESH; |
| 180 | } | 176 | } |
| 181 | rrsp->rrs_state = rrsp->rrs_state * RCU_RANDOM_MULT + RCU_RANDOM_ADD; | 177 | rrsp->rrs_state = rrsp->rrs_state * RCU_RANDOM_MULT + RCU_RANDOM_ADD; |
diff --git a/kernel/rtmutex-debug.c b/kernel/rtmutex-debug.c index 5aedbee014df..6b0703db152d 100644 --- a/kernel/rtmutex-debug.c +++ b/kernel/rtmutex-debug.c | |||
| @@ -82,12 +82,7 @@ do { \ | |||
| 82 | * into the tracing code when doing error printk or | 82 | * into the tracing code when doing error printk or |
| 83 | * executing a BUG(): | 83 | * executing a BUG(): |
| 84 | */ | 84 | */ |
| 85 | int rt_trace_on = 1; | 85 | static int rt_trace_on = 1; |
| 86 | |||
| 87 | void deadlock_trace_off(void) | ||
| 88 | { | ||
| 89 | rt_trace_on = 0; | ||
| 90 | } | ||
| 91 | 86 | ||
| 92 | static void printk_task(struct task_struct *p) | 87 | static void printk_task(struct task_struct *p) |
| 93 | { | 88 | { |
diff --git a/kernel/sched.c b/kernel/sched.c index 0ec9521a8e70..92721d1534b8 100644 --- a/kernel/sched.c +++ b/kernel/sched.c | |||
| @@ -5075,6 +5075,17 @@ wait_to_die: | |||
| 5075 | } | 5075 | } |
| 5076 | 5076 | ||
| 5077 | #ifdef CONFIG_HOTPLUG_CPU | 5077 | #ifdef CONFIG_HOTPLUG_CPU |
| 5078 | |||
| 5079 | static int __migrate_task_irq(struct task_struct *p, int src_cpu, int dest_cpu) | ||
| 5080 | { | ||
| 5081 | int ret; | ||
| 5082 | |||
| 5083 | local_irq_disable(); | ||
| 5084 | ret = __migrate_task(p, src_cpu, dest_cpu); | ||
| 5085 | local_irq_enable(); | ||
| 5086 | return ret; | ||
| 5087 | } | ||
| 5088 | |||
| 5078 | /* | 5089 | /* |
| 5079 | * Figure out where task on dead CPU should go, use force if neccessary. | 5090 | * Figure out where task on dead CPU should go, use force if neccessary. |
| 5080 | * NOTE: interrupts should be disabled by the caller | 5091 | * NOTE: interrupts should be disabled by the caller |
| @@ -5113,7 +5124,7 @@ static void move_task_off_dead_cpu(int dead_cpu, struct task_struct *p) | |||
| 5113 | "longer affine to cpu%d\n", | 5124 | "longer affine to cpu%d\n", |
| 5114 | p->pid, p->comm, dead_cpu); | 5125 | p->pid, p->comm, dead_cpu); |
| 5115 | } | 5126 | } |
| 5116 | } while (!__migrate_task(p, dead_cpu, dest_cpu)); | 5127 | } while (!__migrate_task_irq(p, dead_cpu, dest_cpu)); |
| 5117 | } | 5128 | } |
| 5118 | 5129 | ||
| 5119 | /* | 5130 | /* |
| @@ -5141,7 +5152,7 @@ static void migrate_live_tasks(int src_cpu) | |||
| 5141 | { | 5152 | { |
| 5142 | struct task_struct *p, *t; | 5153 | struct task_struct *p, *t; |
| 5143 | 5154 | ||
| 5144 | write_lock_irq(&tasklist_lock); | 5155 | read_lock(&tasklist_lock); |
| 5145 | 5156 | ||
| 5146 | do_each_thread(t, p) { | 5157 | do_each_thread(t, p) { |
| 5147 | if (p == current) | 5158 | if (p == current) |
| @@ -5151,7 +5162,7 @@ static void migrate_live_tasks(int src_cpu) | |||
| 5151 | move_task_off_dead_cpu(src_cpu, p); | 5162 | move_task_off_dead_cpu(src_cpu, p); |
| 5152 | } while_each_thread(t, p); | 5163 | } while_each_thread(t, p); |
| 5153 | 5164 | ||
| 5154 | write_unlock_irq(&tasklist_lock); | 5165 | read_unlock(&tasklist_lock); |
| 5155 | } | 5166 | } |
| 5156 | 5167 | ||
| 5157 | /* | 5168 | /* |
| @@ -5229,11 +5240,10 @@ static void migrate_dead(unsigned int dead_cpu, struct task_struct *p) | |||
| 5229 | * Drop lock around migration; if someone else moves it, | 5240 | * Drop lock around migration; if someone else moves it, |
| 5230 | * that's OK. No task can be added to this CPU, so iteration is | 5241 | * that's OK. No task can be added to this CPU, so iteration is |
| 5231 | * fine. | 5242 | * fine. |
| 5232 | * NOTE: interrupts should be left disabled --dev@ | ||
| 5233 | */ | 5243 | */ |
| 5234 | spin_unlock(&rq->lock); | 5244 | spin_unlock_irq(&rq->lock); |
| 5235 | move_task_off_dead_cpu(dead_cpu, p); | 5245 | move_task_off_dead_cpu(dead_cpu, p); |
| 5236 | spin_lock(&rq->lock); | 5246 | spin_lock_irq(&rq->lock); |
| 5237 | 5247 | ||
| 5238 | put_task_struct(p); | 5248 | put_task_struct(p); |
| 5239 | } | 5249 | } |
| @@ -5471,14 +5481,14 @@ migration_call(struct notifier_block *nfb, unsigned long action, void *hcpu) | |||
| 5471 | kthread_stop(rq->migration_thread); | 5481 | kthread_stop(rq->migration_thread); |
| 5472 | rq->migration_thread = NULL; | 5482 | rq->migration_thread = NULL; |
| 5473 | /* Idle task back to normal (off runqueue, low prio) */ | 5483 | /* Idle task back to normal (off runqueue, low prio) */ |
| 5474 | rq = task_rq_lock(rq->idle, &flags); | 5484 | spin_lock_irq(&rq->lock); |
| 5475 | update_rq_clock(rq); | 5485 | update_rq_clock(rq); |
| 5476 | deactivate_task(rq, rq->idle, 0); | 5486 | deactivate_task(rq, rq->idle, 0); |
| 5477 | rq->idle->static_prio = MAX_PRIO; | 5487 | rq->idle->static_prio = MAX_PRIO; |
| 5478 | __setscheduler(rq, rq->idle, SCHED_NORMAL, 0); | 5488 | __setscheduler(rq, rq->idle, SCHED_NORMAL, 0); |
| 5479 | rq->idle->sched_class = &idle_sched_class; | 5489 | rq->idle->sched_class = &idle_sched_class; |
| 5480 | migrate_dead_tasks(cpu); | 5490 | migrate_dead_tasks(cpu); |
| 5481 | task_rq_unlock(rq, &flags); | 5491 | spin_unlock_irq(&rq->lock); |
| 5482 | migrate_nr_uninterruptible(rq); | 5492 | migrate_nr_uninterruptible(rq); |
| 5483 | BUG_ON(rq->nr_running != 0); | 5493 | BUG_ON(rq->nr_running != 0); |
| 5484 | 5494 | ||
diff --git a/kernel/signal.c b/kernel/signal.c index 792952381092..2124ffadcfde 100644 --- a/kernel/signal.c +++ b/kernel/signal.c | |||
| @@ -909,8 +909,7 @@ __group_complete_signal(int sig, struct task_struct *p) | |||
| 909 | do { | 909 | do { |
| 910 | sigaddset(&t->pending.signal, SIGKILL); | 910 | sigaddset(&t->pending.signal, SIGKILL); |
| 911 | signal_wake_up(t, 1); | 911 | signal_wake_up(t, 1); |
| 912 | t = next_thread(t); | 912 | } while_each_thread(p, t); |
| 913 | } while (t != p); | ||
| 914 | return; | 913 | return; |
| 915 | } | 914 | } |
| 916 | 915 | ||
| @@ -928,13 +927,11 @@ __group_complete_signal(int sig, struct task_struct *p) | |||
| 928 | rm_from_queue(SIG_KERNEL_STOP_MASK, &p->signal->shared_pending); | 927 | rm_from_queue(SIG_KERNEL_STOP_MASK, &p->signal->shared_pending); |
| 929 | p->signal->group_stop_count = 0; | 928 | p->signal->group_stop_count = 0; |
| 930 | p->signal->group_exit_task = t; | 929 | p->signal->group_exit_task = t; |
| 931 | t = p; | 930 | p = t; |
| 932 | do { | 931 | do { |
| 933 | p->signal->group_stop_count++; | 932 | p->signal->group_stop_count++; |
| 934 | signal_wake_up(t, 0); | 933 | signal_wake_up(t, t == p); |
| 935 | t = next_thread(t); | 934 | } while_each_thread(p, t); |
| 936 | } while (t != p); | ||
| 937 | wake_up_process(p->signal->group_exit_task); | ||
| 938 | return; | 935 | return; |
| 939 | } | 936 | } |
| 940 | 937 | ||
| @@ -985,9 +982,6 @@ void zap_other_threads(struct task_struct *p) | |||
| 985 | p->signal->flags = SIGNAL_GROUP_EXIT; | 982 | p->signal->flags = SIGNAL_GROUP_EXIT; |
| 986 | p->signal->group_stop_count = 0; | 983 | p->signal->group_stop_count = 0; |
| 987 | 984 | ||
| 988 | if (thread_group_empty(p)) | ||
| 989 | return; | ||
| 990 | |||
| 991 | for (t = next_thread(p); t != p; t = next_thread(t)) { | 985 | for (t = next_thread(p); t != p; t = next_thread(t)) { |
| 992 | /* | 986 | /* |
| 993 | * Don't bother with already dead threads | 987 | * Don't bother with already dead threads |
| @@ -2300,15 +2294,6 @@ int do_sigaction(int sig, struct k_sigaction *act, struct k_sigaction *oact) | |||
| 2300 | k = ¤t->sighand->action[sig-1]; | 2294 | k = ¤t->sighand->action[sig-1]; |
| 2301 | 2295 | ||
| 2302 | spin_lock_irq(¤t->sighand->siglock); | 2296 | spin_lock_irq(¤t->sighand->siglock); |
| 2303 | if (signal_pending(current)) { | ||
| 2304 | /* | ||
| 2305 | * If there might be a fatal signal pending on multiple | ||
| 2306 | * threads, make sure we take it before changing the action. | ||
| 2307 | */ | ||
| 2308 | spin_unlock_irq(¤t->sighand->siglock); | ||
| 2309 | return -ERESTARTNOINTR; | ||
| 2310 | } | ||
| 2311 | |||
| 2312 | if (oact) | 2297 | if (oact) |
| 2313 | *oact = *k; | 2298 | *oact = *k; |
| 2314 | 2299 | ||
| @@ -2335,7 +2320,6 @@ int do_sigaction(int sig, struct k_sigaction *act, struct k_sigaction *oact) | |||
| 2335 | rm_from_queue_full(&mask, &t->signal->shared_pending); | 2320 | rm_from_queue_full(&mask, &t->signal->shared_pending); |
| 2336 | do { | 2321 | do { |
| 2337 | rm_from_queue_full(&mask, &t->pending); | 2322 | rm_from_queue_full(&mask, &t->pending); |
| 2338 | recalc_sigpending_and_wake(t); | ||
| 2339 | t = next_thread(t); | 2323 | t = next_thread(t); |
| 2340 | } while (t != current); | 2324 | } while (t != current); |
| 2341 | } | 2325 | } |
diff --git a/kernel/softlockup.c b/kernel/softlockup.c index 708d4882c0c3..edeeef3a6a32 100644 --- a/kernel/softlockup.c +++ b/kernel/softlockup.c | |||
| @@ -15,13 +15,16 @@ | |||
| 15 | #include <linux/notifier.h> | 15 | #include <linux/notifier.h> |
| 16 | #include <linux/module.h> | 16 | #include <linux/module.h> |
| 17 | 17 | ||
| 18 | #include <asm/irq_regs.h> | ||
| 19 | |||
| 18 | static DEFINE_SPINLOCK(print_lock); | 20 | static DEFINE_SPINLOCK(print_lock); |
| 19 | 21 | ||
| 20 | static DEFINE_PER_CPU(unsigned long, touch_timestamp); | 22 | static DEFINE_PER_CPU(unsigned long, touch_timestamp); |
| 21 | static DEFINE_PER_CPU(unsigned long, print_timestamp); | 23 | static DEFINE_PER_CPU(unsigned long, print_timestamp); |
| 22 | static DEFINE_PER_CPU(struct task_struct *, watchdog_task); | 24 | static DEFINE_PER_CPU(struct task_struct *, watchdog_task); |
| 23 | 25 | ||
| 24 | static int did_panic = 0; | 26 | static int did_panic; |
| 27 | int softlockup_thresh = 10; | ||
| 25 | 28 | ||
| 26 | static int | 29 | static int |
| 27 | softlock_panic(struct notifier_block *this, unsigned long event, void *ptr) | 30 | softlock_panic(struct notifier_block *this, unsigned long event, void *ptr) |
| @@ -40,14 +43,16 @@ static struct notifier_block panic_block = { | |||
| 40 | * resolution, and we don't need to waste time with a big divide when | 43 | * resolution, and we don't need to waste time with a big divide when |
| 41 | * 2^30ns == 1.074s. | 44 | * 2^30ns == 1.074s. |
| 42 | */ | 45 | */ |
| 43 | static unsigned long get_timestamp(void) | 46 | static unsigned long get_timestamp(int this_cpu) |
| 44 | { | 47 | { |
| 45 | return sched_clock() >> 30; /* 2^30 ~= 10^9 */ | 48 | return cpu_clock(this_cpu) >> 30; /* 2^30 ~= 10^9 */ |
| 46 | } | 49 | } |
| 47 | 50 | ||
| 48 | void touch_softlockup_watchdog(void) | 51 | void touch_softlockup_watchdog(void) |
| 49 | { | 52 | { |
| 50 | __raw_get_cpu_var(touch_timestamp) = get_timestamp(); | 53 | int this_cpu = raw_smp_processor_id(); |
| 54 | |||
| 55 | __raw_get_cpu_var(touch_timestamp) = get_timestamp(this_cpu); | ||
| 51 | } | 56 | } |
| 52 | EXPORT_SYMBOL(touch_softlockup_watchdog); | 57 | EXPORT_SYMBOL(touch_softlockup_watchdog); |
| 53 | 58 | ||
| @@ -70,6 +75,7 @@ void softlockup_tick(void) | |||
| 70 | int this_cpu = smp_processor_id(); | 75 | int this_cpu = smp_processor_id(); |
| 71 | unsigned long touch_timestamp = per_cpu(touch_timestamp, this_cpu); | 76 | unsigned long touch_timestamp = per_cpu(touch_timestamp, this_cpu); |
| 72 | unsigned long print_timestamp; | 77 | unsigned long print_timestamp; |
| 78 | struct pt_regs *regs = get_irq_regs(); | ||
| 73 | unsigned long now; | 79 | unsigned long now; |
| 74 | 80 | ||
| 75 | if (touch_timestamp == 0) { | 81 | if (touch_timestamp == 0) { |
| @@ -80,10 +86,11 @@ void softlockup_tick(void) | |||
| 80 | print_timestamp = per_cpu(print_timestamp, this_cpu); | 86 | print_timestamp = per_cpu(print_timestamp, this_cpu); |
| 81 | 87 | ||
| 82 | /* report at most once a second */ | 88 | /* report at most once a second */ |
| 83 | if (print_timestamp < (touch_timestamp + 1) || | 89 | if ((print_timestamp >= touch_timestamp && |
| 84 | did_panic || | 90 | print_timestamp < (touch_timestamp + 1)) || |
| 85 | !per_cpu(watchdog_task, this_cpu)) | 91 | did_panic || !per_cpu(watchdog_task, this_cpu)) { |
| 86 | return; | 92 | return; |
| 93 | } | ||
| 87 | 94 | ||
| 88 | /* do not print during early bootup: */ | 95 | /* do not print during early bootup: */ |
| 89 | if (unlikely(system_state != SYSTEM_RUNNING)) { | 96 | if (unlikely(system_state != SYSTEM_RUNNING)) { |
| @@ -91,28 +98,33 @@ void softlockup_tick(void) | |||
| 91 | return; | 98 | return; |
| 92 | } | 99 | } |
| 93 | 100 | ||
| 94 | now = get_timestamp(); | 101 | now = get_timestamp(this_cpu); |
| 95 | 102 | ||
| 96 | /* Wake up the high-prio watchdog task every second: */ | 103 | /* Wake up the high-prio watchdog task every second: */ |
| 97 | if (now > (touch_timestamp + 1)) | 104 | if (now > (touch_timestamp + 1)) |
| 98 | wake_up_process(per_cpu(watchdog_task, this_cpu)); | 105 | wake_up_process(per_cpu(watchdog_task, this_cpu)); |
| 99 | 106 | ||
| 100 | /* Warn about unreasonable 10+ seconds delays: */ | 107 | /* Warn about unreasonable 10+ seconds delays: */ |
| 101 | if (now > (touch_timestamp + 10)) { | 108 | if (now <= (touch_timestamp + softlockup_thresh)) |
| 102 | per_cpu(print_timestamp, this_cpu) = touch_timestamp; | 109 | return; |
| 103 | 110 | ||
| 104 | spin_lock(&print_lock); | 111 | per_cpu(print_timestamp, this_cpu) = touch_timestamp; |
| 105 | printk(KERN_ERR "BUG: soft lockup detected on CPU#%d!\n", | 112 | |
| 106 | this_cpu); | 113 | spin_lock(&print_lock); |
| 114 | printk(KERN_ERR "BUG: soft lockup - CPU#%d stuck for %lus! [%s:%d]\n", | ||
| 115 | this_cpu, now - touch_timestamp, | ||
| 116 | current->comm, current->pid); | ||
| 117 | if (regs) | ||
| 118 | show_regs(regs); | ||
| 119 | else | ||
| 107 | dump_stack(); | 120 | dump_stack(); |
| 108 | spin_unlock(&print_lock); | 121 | spin_unlock(&print_lock); |
| 109 | } | ||
| 110 | } | 122 | } |
| 111 | 123 | ||
| 112 | /* | 124 | /* |
| 113 | * The watchdog thread - runs every second and touches the timestamp. | 125 | * The watchdog thread - runs every second and touches the timestamp. |
| 114 | */ | 126 | */ |
| 115 | static int watchdog(void * __bind_cpu) | 127 | static int watchdog(void *__bind_cpu) |
| 116 | { | 128 | { |
| 117 | struct sched_param param = { .sched_priority = MAX_RT_PRIO-1 }; | 129 | struct sched_param param = { .sched_priority = MAX_RT_PRIO-1 }; |
| 118 | 130 | ||
| @@ -150,13 +162,13 @@ cpu_callback(struct notifier_block *nfb, unsigned long action, void *hcpu) | |||
| 150 | BUG_ON(per_cpu(watchdog_task, hotcpu)); | 162 | BUG_ON(per_cpu(watchdog_task, hotcpu)); |
| 151 | p = kthread_create(watchdog, hcpu, "watchdog/%d", hotcpu); | 163 | p = kthread_create(watchdog, hcpu, "watchdog/%d", hotcpu); |
| 152 | if (IS_ERR(p)) { | 164 | if (IS_ERR(p)) { |
| 153 | printk("watchdog for %i failed\n", hotcpu); | 165 | printk(KERN_ERR "watchdog for %i failed\n", hotcpu); |
| 154 | return NOTIFY_BAD; | 166 | return NOTIFY_BAD; |
| 155 | } | 167 | } |
| 156 | per_cpu(touch_timestamp, hotcpu) = 0; | 168 | per_cpu(touch_timestamp, hotcpu) = 0; |
| 157 | per_cpu(watchdog_task, hotcpu) = p; | 169 | per_cpu(watchdog_task, hotcpu) = p; |
| 158 | kthread_bind(p, hotcpu); | 170 | kthread_bind(p, hotcpu); |
| 159 | break; | 171 | break; |
| 160 | case CPU_ONLINE: | 172 | case CPU_ONLINE: |
| 161 | case CPU_ONLINE_FROZEN: | 173 | case CPU_ONLINE_FROZEN: |
| 162 | wake_up_process(per_cpu(watchdog_task, hotcpu)); | 174 | wake_up_process(per_cpu(watchdog_task, hotcpu)); |
| @@ -176,7 +188,7 @@ cpu_callback(struct notifier_block *nfb, unsigned long action, void *hcpu) | |||
| 176 | kthread_stop(p); | 188 | kthread_stop(p); |
| 177 | break; | 189 | break; |
| 178 | #endif /* CONFIG_HOTPLUG_CPU */ | 190 | #endif /* CONFIG_HOTPLUG_CPU */ |
| 179 | } | 191 | } |
| 180 | return NOTIFY_OK; | 192 | return NOTIFY_OK; |
| 181 | } | 193 | } |
| 182 | 194 | ||
diff --git a/kernel/sys_ni.c b/kernel/sys_ni.c index b0ec498a18d9..52c7a151e298 100644 --- a/kernel/sys_ni.c +++ b/kernel/sys_ni.c | |||
| @@ -4,6 +4,10 @@ | |||
| 4 | 4 | ||
| 5 | #include <asm/unistd.h> | 5 | #include <asm/unistd.h> |
| 6 | 6 | ||
| 7 | /* we can't #include <linux/syscalls.h> here, | ||
| 8 | but tell gcc to not warn with -Wmissing-prototypes */ | ||
| 9 | asmlinkage long sys_ni_syscall(void); | ||
| 10 | |||
| 7 | /* | 11 | /* |
| 8 | * Non-implemented system calls get redirected here. | 12 | * Non-implemented system calls get redirected here. |
| 9 | */ | 13 | */ |
diff --git a/kernel/sysctl.c b/kernel/sysctl.c index 96efbb859997..dde3d53e8adc 100644 --- a/kernel/sysctl.c +++ b/kernel/sysctl.c | |||
| @@ -63,6 +63,7 @@ extern int print_fatal_signals; | |||
| 63 | extern int sysctl_overcommit_memory; | 63 | extern int sysctl_overcommit_memory; |
| 64 | extern int sysctl_overcommit_ratio; | 64 | extern int sysctl_overcommit_ratio; |
| 65 | extern int sysctl_panic_on_oom; | 65 | extern int sysctl_panic_on_oom; |
| 66 | extern int sysctl_oom_kill_allocating_task; | ||
| 66 | extern int max_threads; | 67 | extern int max_threads; |
| 67 | extern int core_uses_pid; | 68 | extern int core_uses_pid; |
| 68 | extern int suid_dumpable; | 69 | extern int suid_dumpable; |
| @@ -79,6 +80,19 @@ extern int maps_protect; | |||
| 79 | extern int sysctl_stat_interval; | 80 | extern int sysctl_stat_interval; |
| 80 | extern int audit_argv_kb; | 81 | extern int audit_argv_kb; |
| 81 | 82 | ||
| 83 | /* Constants used for minimum and maximum */ | ||
| 84 | #ifdef CONFIG_DETECT_SOFTLOCKUP | ||
| 85 | static int one = 1; | ||
| 86 | static int sixty = 60; | ||
| 87 | #endif | ||
| 88 | |||
| 89 | #ifdef CONFIG_MMU | ||
| 90 | static int two = 2; | ||
| 91 | #endif | ||
| 92 | |||
| 93 | static int zero; | ||
| 94 | static int one_hundred = 100; | ||
| 95 | |||
| 82 | /* this is needed for the proc_dointvec_minmax for [fs_]overflow UID and GID */ | 96 | /* this is needed for the proc_dointvec_minmax for [fs_]overflow UID and GID */ |
| 83 | static int maxolduid = 65535; | 97 | static int maxolduid = 65535; |
| 84 | static int minolduid; | 98 | static int minolduid; |
| @@ -710,6 +724,19 @@ static ctl_table kern_table[] = { | |||
| 710 | .proc_handler = &proc_dointvec, | 724 | .proc_handler = &proc_dointvec, |
| 711 | }, | 725 | }, |
| 712 | #endif | 726 | #endif |
| 727 | #ifdef CONFIG_DETECT_SOFTLOCKUP | ||
| 728 | { | ||
| 729 | .ctl_name = CTL_UNNUMBERED, | ||
| 730 | .procname = "softlockup_thresh", | ||
| 731 | .data = &softlockup_thresh, | ||
| 732 | .maxlen = sizeof(int), | ||
| 733 | .mode = 0644, | ||
| 734 | .proc_handler = &proc_dointvec_minmax, | ||
| 735 | .strategy = &sysctl_intvec, | ||
| 736 | .extra1 = &one, | ||
| 737 | .extra2 = &sixty, | ||
| 738 | }, | ||
| 739 | #endif | ||
| 713 | #ifdef CONFIG_COMPAT | 740 | #ifdef CONFIG_COMPAT |
| 714 | { | 741 | { |
| 715 | .ctl_name = KERN_COMPAT_LOG, | 742 | .ctl_name = KERN_COMPAT_LOG, |
| @@ -756,13 +783,6 @@ static ctl_table kern_table[] = { | |||
| 756 | { .ctl_name = 0 } | 783 | { .ctl_name = 0 } |
| 757 | }; | 784 | }; |
| 758 | 785 | ||
| 759 | /* Constants for minimum and maximum testing in vm_table. | ||
| 760 | We use these as one-element integer vectors. */ | ||
| 761 | static int zero; | ||
| 762 | static int two = 2; | ||
| 763 | static int one_hundred = 100; | ||
| 764 | |||
| 765 | |||
| 766 | static ctl_table vm_table[] = { | 786 | static ctl_table vm_table[] = { |
| 767 | { | 787 | { |
| 768 | .ctl_name = VM_OVERCOMMIT_MEMORY, | 788 | .ctl_name = VM_OVERCOMMIT_MEMORY, |
| @@ -781,6 +801,14 @@ static ctl_table vm_table[] = { | |||
| 781 | .proc_handler = &proc_dointvec, | 801 | .proc_handler = &proc_dointvec, |
| 782 | }, | 802 | }, |
| 783 | { | 803 | { |
| 804 | .ctl_name = CTL_UNNUMBERED, | ||
| 805 | .procname = "oom_kill_allocating_task", | ||
| 806 | .data = &sysctl_oom_kill_allocating_task, | ||
| 807 | .maxlen = sizeof(sysctl_oom_kill_allocating_task), | ||
| 808 | .mode = 0644, | ||
| 809 | .proc_handler = &proc_dointvec, | ||
| 810 | }, | ||
| 811 | { | ||
| 784 | .ctl_name = VM_OVERCOMMIT_RATIO, | 812 | .ctl_name = VM_OVERCOMMIT_RATIO, |
| 785 | .procname = "overcommit_ratio", | 813 | .procname = "overcommit_ratio", |
| 786 | .data = &sysctl_overcommit_ratio, | 814 | .data = &sysctl_overcommit_ratio, |
| @@ -813,7 +841,7 @@ static ctl_table vm_table[] = { | |||
| 813 | .data = &vm_dirty_ratio, | 841 | .data = &vm_dirty_ratio, |
| 814 | .maxlen = sizeof(vm_dirty_ratio), | 842 | .maxlen = sizeof(vm_dirty_ratio), |
| 815 | .mode = 0644, | 843 | .mode = 0644, |
| 816 | .proc_handler = &proc_dointvec_minmax, | 844 | .proc_handler = &dirty_ratio_handler, |
| 817 | .strategy = &sysctl_intvec, | 845 | .strategy = &sysctl_intvec, |
| 818 | .extra1 = &zero, | 846 | .extra1 = &zero, |
| 819 | .extra2 = &one_hundred, | 847 | .extra2 = &one_hundred, |
diff --git a/kernel/taskstats.c b/kernel/taskstats.c index 059431ed67db..7d4d7f9c1bb2 100644 --- a/kernel/taskstats.c +++ b/kernel/taskstats.c | |||
| @@ -20,7 +20,6 @@ | |||
| 20 | #include <linux/taskstats_kern.h> | 20 | #include <linux/taskstats_kern.h> |
| 21 | #include <linux/tsacct_kern.h> | 21 | #include <linux/tsacct_kern.h> |
| 22 | #include <linux/delayacct.h> | 22 | #include <linux/delayacct.h> |
| 23 | #include <linux/tsacct_kern.h> | ||
| 24 | #include <linux/cpumask.h> | 23 | #include <linux/cpumask.h> |
| 25 | #include <linux/percpu.h> | 24 | #include <linux/percpu.h> |
| 26 | #include <net/genetlink.h> | 25 | #include <net/genetlink.h> |
diff --git a/kernel/time.c b/kernel/time.c index 1afcc78dc3b1..2d5b6a682138 100644 --- a/kernel/time.c +++ b/kernel/time.c | |||
| @@ -34,7 +34,6 @@ | |||
| 34 | #include <linux/syscalls.h> | 34 | #include <linux/syscalls.h> |
| 35 | #include <linux/security.h> | 35 | #include <linux/security.h> |
| 36 | #include <linux/fs.h> | 36 | #include <linux/fs.h> |
| 37 | #include <linux/module.h> | ||
| 38 | 37 | ||
| 39 | #include <asm/uaccess.h> | 38 | #include <asm/uaccess.h> |
| 40 | #include <asm/unistd.h> | 39 | #include <asm/unistd.h> |
diff --git a/kernel/time/tick-broadcast.c b/kernel/time/tick-broadcast.c index fc3fc79b3d59..fab9dd8bbd6b 100644 --- a/kernel/time/tick-broadcast.c +++ b/kernel/time/tick-broadcast.c | |||
| @@ -274,21 +274,12 @@ out: | |||
| 274 | */ | 274 | */ |
| 275 | void tick_broadcast_on_off(unsigned long reason, int *oncpu) | 275 | void tick_broadcast_on_off(unsigned long reason, int *oncpu) |
| 276 | { | 276 | { |
| 277 | int cpu = get_cpu(); | 277 | if (!cpu_isset(*oncpu, cpu_online_map)) |
| 278 | |||
| 279 | if (!cpu_isset(*oncpu, cpu_online_map)) { | ||
| 280 | printk(KERN_ERR "tick-braodcast: ignoring broadcast for " | 278 | printk(KERN_ERR "tick-braodcast: ignoring broadcast for " |
| 281 | "offline CPU #%d\n", *oncpu); | 279 | "offline CPU #%d\n", *oncpu); |
| 282 | } else { | 280 | else |
| 283 | 281 | smp_call_function_single(*oncpu, tick_do_broadcast_on_off, | |
| 284 | if (cpu == *oncpu) | 282 | &reason, 1, 1); |
| 285 | tick_do_broadcast_on_off(&reason); | ||
| 286 | else | ||
| 287 | smp_call_function_single(*oncpu, | ||
| 288 | tick_do_broadcast_on_off, | ||
| 289 | &reason, 1, 1); | ||
| 290 | } | ||
| 291 | put_cpu(); | ||
| 292 | } | 283 | } |
| 293 | 284 | ||
| 294 | /* | 285 | /* |
diff --git a/kernel/time/tick-sched.c b/kernel/time/tick-sched.c index 8c3fef1db09c..ce89ffb474d0 100644 --- a/kernel/time/tick-sched.c +++ b/kernel/time/tick-sched.c | |||
| @@ -570,7 +570,7 @@ void tick_setup_sched_timer(void) | |||
| 570 | /* Get the next period (per cpu) */ | 570 | /* Get the next period (per cpu) */ |
| 571 | ts->sched_timer.expires = tick_init_jiffy_update(); | 571 | ts->sched_timer.expires = tick_init_jiffy_update(); |
| 572 | offset = ktime_to_ns(tick_period) >> 1; | 572 | offset = ktime_to_ns(tick_period) >> 1; |
| 573 | do_div(offset, NR_CPUS); | 573 | do_div(offset, num_possible_cpus()); |
| 574 | offset *= smp_processor_id(); | 574 | offset *= smp_processor_id(); |
| 575 | ts->sched_timer.expires = ktime_add_ns(ts->sched_timer.expires, offset); | 575 | ts->sched_timer.expires = ktime_add_ns(ts->sched_timer.expires, offset); |
| 576 | 576 | ||
diff --git a/kernel/time/timekeeping.c b/kernel/time/timekeeping.c index 7e8983aecf83..e5e466b27598 100644 --- a/kernel/time/timekeeping.c +++ b/kernel/time/timekeeping.c | |||
| @@ -24,9 +24,7 @@ | |||
| 24 | * This read-write spinlock protects us from races in SMP while | 24 | * This read-write spinlock protects us from races in SMP while |
| 25 | * playing with xtime and avenrun. | 25 | * playing with xtime and avenrun. |
| 26 | */ | 26 | */ |
| 27 | __attribute__((weak)) __cacheline_aligned_in_smp DEFINE_SEQLOCK(xtime_lock); | 27 | __cacheline_aligned_in_smp DEFINE_SEQLOCK(xtime_lock); |
| 28 | |||
| 29 | EXPORT_SYMBOL(xtime_lock); | ||
| 30 | 28 | ||
| 31 | 29 | ||
| 32 | /* | 30 | /* |
| @@ -47,7 +45,6 @@ EXPORT_SYMBOL(xtime_lock); | |||
| 47 | struct timespec xtime __attribute__ ((aligned (16))); | 45 | struct timespec xtime __attribute__ ((aligned (16))); |
| 48 | struct timespec wall_to_monotonic __attribute__ ((aligned (16))); | 46 | struct timespec wall_to_monotonic __attribute__ ((aligned (16))); |
| 49 | static unsigned long total_sleep_time; /* seconds */ | 47 | static unsigned long total_sleep_time; /* seconds */ |
| 50 | EXPORT_SYMBOL(xtime); | ||
| 51 | 48 | ||
| 52 | static struct timespec xtime_cache __attribute__ ((aligned (16))); | 49 | static struct timespec xtime_cache __attribute__ ((aligned (16))); |
| 53 | static inline void update_xtime_cache(u64 nsec) | 50 | static inline void update_xtime_cache(u64 nsec) |
diff --git a/kernel/user.c b/kernel/user.c index 7e8215d87b40..e91331c457e2 100644 --- a/kernel/user.c +++ b/kernel/user.c | |||
| @@ -44,7 +44,6 @@ struct user_struct root_user = { | |||
| 44 | .processes = ATOMIC_INIT(1), | 44 | .processes = ATOMIC_INIT(1), |
| 45 | .files = ATOMIC_INIT(0), | 45 | .files = ATOMIC_INIT(0), |
| 46 | .sigpending = ATOMIC_INIT(0), | 46 | .sigpending = ATOMIC_INIT(0), |
| 47 | .mq_bytes = 0, | ||
| 48 | .locked_shm = 0, | 47 | .locked_shm = 0, |
| 49 | #ifdef CONFIG_KEYS | 48 | #ifdef CONFIG_KEYS |
| 50 | .uid_keyring = &root_user_keyring, | 49 | .uid_keyring = &root_user_keyring, |
| @@ -58,19 +57,17 @@ struct user_struct root_user = { | |||
| 58 | /* | 57 | /* |
| 59 | * These routines must be called with the uidhash spinlock held! | 58 | * These routines must be called with the uidhash spinlock held! |
| 60 | */ | 59 | */ |
| 61 | static inline void uid_hash_insert(struct user_struct *up, | 60 | static void uid_hash_insert(struct user_struct *up, struct hlist_head *hashent) |
| 62 | struct hlist_head *hashent) | ||
| 63 | { | 61 | { |
| 64 | hlist_add_head(&up->uidhash_node, hashent); | 62 | hlist_add_head(&up->uidhash_node, hashent); |
| 65 | } | 63 | } |
| 66 | 64 | ||
| 67 | static inline void uid_hash_remove(struct user_struct *up) | 65 | static void uid_hash_remove(struct user_struct *up) |
| 68 | { | 66 | { |
| 69 | hlist_del_init(&up->uidhash_node); | 67 | hlist_del_init(&up->uidhash_node); |
| 70 | } | 68 | } |
| 71 | 69 | ||
| 72 | static inline struct user_struct *uid_hash_find(uid_t uid, | 70 | static struct user_struct *uid_hash_find(uid_t uid, struct hlist_head *hashent) |
| 73 | struct hlist_head *hashent) | ||
| 74 | { | 71 | { |
| 75 | struct user_struct *user; | 72 | struct user_struct *user; |
| 76 | struct hlist_node *h; | 73 | struct hlist_node *h; |
| @@ -350,8 +347,9 @@ struct user_struct * alloc_uid(struct user_namespace *ns, uid_t uid) | |||
| 350 | atomic_set(&new->inotify_watches, 0); | 347 | atomic_set(&new->inotify_watches, 0); |
| 351 | atomic_set(&new->inotify_devs, 0); | 348 | atomic_set(&new->inotify_devs, 0); |
| 352 | #endif | 349 | #endif |
| 353 | 350 | #ifdef CONFIG_POSIX_MQUEUE | |
| 354 | new->mq_bytes = 0; | 351 | new->mq_bytes = 0; |
| 352 | #endif | ||
| 355 | new->locked_shm = 0; | 353 | new->locked_shm = 0; |
| 356 | 354 | ||
| 357 | if (alloc_uid_keyring(new, current) < 0) { | 355 | if (alloc_uid_keyring(new, current) < 0) { |
