rcu: Make TASKS_RCU handle tasks that are almost done exiting
authorPaul E. McKenney <paulmck@linux.vnet.ibm.com>
Mon, 4 Aug 2014 13:10:23 +0000 (06:10 -0700)
committerPaul E. McKenney <paulmck@linux.vnet.ibm.com>
Sun, 7 Sep 2014 23:27:22 +0000 (16:27 -0700)
commit3f95aa81d265223fdb13ea2b59883766a05adbdf
tree5b6d2c42aaf8b20397bd09c0ac31738618f57046
parent53c6d4edf874d3cbc031a53738c6cba9277faea5
rcu: Make TASKS_RCU handle tasks that are almost done exiting

Once a task has passed exit_notify() in the do_exit() code path, it
is no longer on the task lists, and is therefore no longer visible
to rcu_tasks_kthread().  This means that an almost-exited task might
be preempted while within a trampoline, and this task won't be waited
on by rcu_tasks_kthread().  This commit fixes this bug by adding an
srcu_struct.  An exiting task does srcu_read_lock() just before calling
exit_notify(), and does the corresponding srcu_read_unlock() after
doing the final preempt_disable().  This means that rcu_tasks_kthread()
can do synchronize_srcu() to wait for all mostly-exited tasks to reach
their final preempt_disable() region, and then use synchronize_sched()
to wait for those tasks to finish exiting.

Reported-by: Oleg Nesterov <oleg@redhat.com>
Suggested-by: Lai Jiangshan <laijs@cn.fujitsu.com>
Signed-off-by: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
include/linux/rcupdate.h
kernel/exit.c
kernel/rcu/update.c