17 Jul, 2009

3 commits

  • is_current_single_threaded() can safely miss a freshly forked CLONE_VM
    task, but in this case it must not miss its parent. That is why we take
    mm->mmap_sem for writing to make sure a thread/task with the same ->mm
    can't pass exit_mm() and disappear.

    However we can avoid ->mmap_sem and rely on rcu/barriers:

    - if we do not see the exiting parent on thread/process list
    we see the result of list_del_rcu(), in this case we must
    also see the result of list_add_rcu() which does wmb().

    - if we do see the parent but its ->mm == NULL, we need rmb()
    to make sure we can't miss the child.

    Signed-off-by: Oleg Nesterov
    Acked-by: David Howells
    Signed-off-by: James Morris

    Oleg Nesterov
     
  • - is_single_threaded(task) is not safe unless task == current,
    we can't use task->signal or task->mm.

    - it doesn't make sense unless task == current, the task can
    fork right after the check.

    Rename it to current_is_single_threaded() and kill the argument.

    Signed-off-by: Oleg Nesterov
    Acked-by: David Howells
    Signed-off-by: James Morris

    Oleg Nesterov
     
  • - Fix the comment, is_single_threaded(p) actually means that nobody shares
    ->mm with p.

    I think this helper should be renamed, and it should not have arguments.
    With or without this patch it must not be used unless p == current,
    otherwise we can't safely use p->signal or p->mm.

    - "if (atomic_read(&p->signal->count) != 1)" is not right when we have a
    zombie group leader, use signal->live instead.

    - Add PF_KTHREAD check to skip kernel threads which may borrow p->mm,
    otherwise we can return the wrong "false".

    - Use for_each_process() instead of do_each_thread(), all threads must use
    the same ->mm.

    - Use down_write(mm->mmap_sem) + rcu_read_lock() instead of tasklist_lock
    to iterate over the process list. If there is another CLONE_VM process
    it can't pass exit_mm() which takes the same mm->mmap_sem. We can miss
    a freshly forked CLONE_VM task, but this doesn't matter because we must
    see its parent and return false.

    Signed-off-by: Oleg Nesterov
    Cc: David Howells
    Cc: James Morris
    Cc: Roland McGrath
    Cc: Stephen Smalley
    Signed-off-by: Andrew Morton
    Signed-off-by: James Morris

    Oleg Nesterov
     

14 Nov, 2008

1 commit