core kernel fixes for v3.7
Subsystems (2)
Linus,
Please pull the latest core-urgent-for-linus git tree from:
git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git core-urgent-for-linus
HEAD: f784e8a7989c0da3062d04bfea3db90f41e8f738 task_work: Simplify the usage in ptrace_notify() and get_signal_to_deliver()
This is a complex task_work series from Oleg that fixes the bug that this VFS commit tried to fix:
d35abdb28824 hold task_lock around checks in keyctl
but solves the problem without the lockup regression that d35abdb28824 introduced in v3.6.
This series came late in v3.6 and I did not feel confident about it so late in the cycle. Might be worth backporting to -stable if it proves itself upstream.
Thanks,
Ingo
------------------>
Oleg Nesterov (4):
task_work: Make task_work_add() lockless
task_work: task_work_add() should not succeed after exit_task_work()
task_work: Revert "hold task_lock around checks in keyctl"
task_work: Simplify the usage in ptrace_notify() and get_signal_to_deliver()
include/linux/task_work.h | 3 +- kernel/signal.c | 18 ++------ kernel/task_work.c | 111 +++++++++++++++++++++++++--------------------- security/keys/keyctl.c | 2 - 4 files changed, 66 insertions(+), 68 deletions(-)
include/linux/task_work.h +1 -2
@@ -18,8 +18,7 @@ void task_work_run(void);static inline void exit_task_work (struct task_struct *task) { -if (unlikely (task->task_works)) -task_work_run (); +task_work_run (); }#endif /* _LINUX_TASK_WORK_H */
kernel/signal.c +4 -14
@@ -1971,13 +1971,8 @@ static void ptrace_do_notify(int signr, int exit_code, int why)void ptrace_notify (int exit_code) {BUG_ON ((exit_code & (0x7f | ~0xffff )) !=SIGTRAP ); -if (unlikely (current->task_works)) { -if (test_and_clear_ti_thread_flag (current_thread_info (), -TIF_NOTIFY_RESUME )) { -smp_mb__after_clear_bit (); -task_work_run (); - } - } +if (unlikely (current->task_works)) +task_work_run ();spin_lock_irq (¤t->sighand->siglock);ptrace_do_notify (SIGTRAP , exit_code,CLD_TRAPPED );
@@ -2198,13 +2193,8 @@ int get_signal_to_deliver(siginfo_t *info, struct k_sigaction *return_ka,struct signal_struct *signal = current->signal;int signr; -if (unlikely (current->task_works)) { -if (test_and_clear_ti_thread_flag (current_thread_info (), -TIF_NOTIFY_RESUME )) { -smp_mb__after_clear_bit (); -task_work_run (); - } - } +if (unlikely (current->task_works)) +task_work_run ();if (unlikely (uprobe_deny_signal ()))return 0 ;
kernel/task_work.c +61 -50
139 lines not on this page · raw message
security/keys/keyctl.c +0 -2
@@ -1486,7 +1486,6 @@ long keyctl_session_to_parent(void) oldwork =NULL ; parent = me->real_parent; -task_lock (parent);/* the parent mustn't be init and mustn't be a kernel thread */ if (parent->pid <=1 || !parent->mm) goto unlock;
@@ -1530,7 +1529,6 @@ long keyctl_session_to_parent(void)if (!ret) newwork =NULL ; unlock: -task_unlock (parent);write_unlock_irq (&tasklist_lock);rcu_read_unlock ();if (oldwork)