[AIO] fix reference counting of aio mm references in the presense of threads With helper threads as a fallback for file descriptors that do not implement aio methods, the reference counting method used by aio to determine when to perform an exit_aio() fails, as the threads have elevated the mm's reference count. Work around this by making use of the counter in the default_kioctx to know when the user processes have exited, thus triggering the exit_aio() codepath which will cancel the outstanding iocbs. Signed-off-by: Benjamin LaHaise diff -purN --exclude=description 82_aio_threads/include/linux/sched.h 83_fix_refcounting/include/linux/sched.h --- 82_aio_threads/include/linux/sched.h 2005-08-08 17:16:00.000000000 -0400 +++ 83_fix_refcounting/include/linux/sched.h 2005-08-16 14:02:21.000000000 -0400 @@ -637,6 +637,7 @@ struct task_struct { struct list_head ptrace_list; struct mm_struct *mm, *active_mm; + struct mm_struct *aio_mm; /* task state */ struct linux_binfmt *binfmt; diff -purN --exclude=description 82_aio_threads/kernel/exit.c 83_fix_refcounting/kernel/exit.c --- 82_aio_threads/kernel/exit.c 2005-08-08 15:45:49.000000000 -0400 +++ 83_fix_refcounting/kernel/exit.c 2005-08-16 14:02:21.000000000 -0400 @@ -485,6 +485,8 @@ static void exit_mm(struct task_struct * { struct mm_struct *mm = tsk->mm; + if (tsk->aio_mm && atomic_dec_and_test(&mm->default_kioctx.users)) + exit_aio(mm); mm_release(tsk, mm); if (!mm) return; diff -purN --exclude=description 82_aio_threads/kernel/fork.c 83_fix_refcounting/kernel/fork.c --- 82_aio_threads/kernel/fork.c 2005-08-08 17:15:57.000000000 -0400 +++ 83_fix_refcounting/kernel/fork.c 2005-08-16 14:02:21.000000000 -0400 @@ -370,7 +370,6 @@ void fastcall __mmdrop(struct mm_struct void mmput(struct mm_struct *mm) { if (atomic_dec_and_test(&mm->mm_users)) { - exit_aio(mm); exit_mmap(mm); if (!list_empty(&mm->mmlist)) { spin_lock(&mmlist_lock); @@ -457,6 +456,7 @@ static int copy_mm(unsigned long clone_f tsk->mm = NULL; tsk->active_mm = NULL; + tsk->aio_mm = NULL; /* * Are we cloning a kernel thread? @@ -469,6 +469,7 @@ static int copy_mm(unsigned long clone_f if (clone_flags & CLONE_VM) { atomic_inc(&oldmm->mm_users); + atomic_inc(&oldmm->default_kioctx.users); mm = oldmm; /* * There are cases where the PTL is held to ensure no @@ -502,6 +503,7 @@ static int copy_mm(unsigned long clone_f good_mm: tsk->mm = mm; + tsk->aio_mm = mm; tsk->active_mm = mm; return 0;