diff options
Diffstat (limited to 'kernel/exit.c')
-rw-r--r-- | kernel/exit.c | 31 |
1 files changed, 15 insertions, 16 deletions
diff --git a/kernel/exit.c b/kernel/exit.c index 07dc154fc799..14c9b63a96c3 100644 --- a/kernel/exit.c +++ b/kernel/exit.c | |||
@@ -560,29 +560,28 @@ void exit_files(struct task_struct *tsk) | |||
560 | 560 | ||
561 | #ifdef CONFIG_MM_OWNER | 561 | #ifdef CONFIG_MM_OWNER |
562 | /* | 562 | /* |
563 | * Task p is exiting and it owned mm, lets find a new owner for it | 563 | * A task is exiting. If it owned this mm, find a new owner for the mm. |
564 | */ | 564 | */ |
565 | static inline int | ||
566 | mm_need_new_owner(struct mm_struct *mm, struct task_struct *p) | ||
567 | { | ||
568 | /* | ||
569 | * If there are other users of the mm and the owner (us) is exiting | ||
570 | * we need to find a new owner to take on the responsibility. | ||
571 | */ | ||
572 | if (atomic_read(&mm->mm_users) <= 1) | ||
573 | return 0; | ||
574 | if (mm->owner != p) | ||
575 | return 0; | ||
576 | return 1; | ||
577 | } | ||
578 | |||
579 | void mm_update_next_owner(struct mm_struct *mm) | 565 | void mm_update_next_owner(struct mm_struct *mm) |
580 | { | 566 | { |
581 | struct task_struct *c, *g, *p = current; | 567 | struct task_struct *c, *g, *p = current; |
582 | 568 | ||
583 | retry: | 569 | retry: |
584 | if (!mm_need_new_owner(mm, p)) | 570 | /* |
571 | * If the exiting or execing task is not the owner, it's | ||
572 | * someone else's problem. | ||
573 | */ | ||
574 | if (mm->owner != p) | ||
585 | return; | 575 | return; |
576 | /* | ||
577 | * The current owner is exiting/execing and there are no other | ||
578 | * candidates. Do not leave the mm pointing to a possibly | ||
579 | * freed task structure. | ||
580 | */ | ||
581 | if (atomic_read(&mm->mm_users) <= 1) { | ||
582 | mm->owner = NULL; | ||
583 | return; | ||
584 | } | ||
586 | 585 | ||
587 | read_lock(&tasklist_lock); | 586 | read_lock(&tasklist_lock); |
588 | /* | 587 | /* |