• E
    [PATCH] task: RCU protect task->usage · 8c7904a0
    Eric W. Biederman 提交于
    A big problem with rcu protected data structures that are also reference
    counted is that you must jump through several hoops to increase the reference
    count.  I think someone finally implemented atomic_inc_not_zero(&count) to
    automate the common case.  Unfortunately this means you must special case the
    rcu access case.
    
    When data structures are only visible via rcu in a manner that is not
    determined by the reference count on the object (i.e.  tasks are visible until
    their zombies are reaped) there is a much simpler technique we can employ.
    Simply delaying the decrement of the reference count until the rcu interval is
    over.
    
    What that means is that the proc code that looks up a task and later
    wants to sleep can now do:
    
    rcu_read_lock();
    task = find_task_by_pid(some_pid);
    if (task) {
    	get_task_struct(task);
    }
    rcu_read_unlock();
    
    The effect on the rest of the kernel is that put_task_struct becomes cheaper
    and immediate, and in the case where the task has been reaped it frees the
    task immediate instead of unnecessarily waiting an until the rcu interval is
    over.
    
    Cleanup of task_struct does not happen when its reference count drops to
    zero, instead cleanup happens when release_task is called.  Tasks can only
    be looked up via rcu before release_task is called.  All rcu protected
    members of task_struct are freed by release_task.
    
    Therefore we can move call_rcu from put_task_struct into release_task.  And
    we can modify release_task to not immediately release the reference count
    but instead have it call put_task_struct from the function it gives to
    call_rcu.
    
    The end result:
    
    - get_task_struct is safe in an rcu context where we have just looked
      up the task.
    
    - put_task_struct() simplifies into its old pre rcu self.
    
    This reorganization also makes put_task_struct uncallable from modules as
    it is not exported but it does not appear to be called from any modules so
    this should not be an issue, and is trivially fixed.
    Signed-off-by: NEric W. Biederman <ebiederm@xmission.com>
    Signed-off-by: NAndrew Morton <akpm@osdl.org>
    Signed-off-by: NLinus Torvalds <torvalds@osdl.org>
    8c7904a0
sched.h 45.3 KB