Commit 801460d0cf5c5288153b722565773059b0f44348
Committed by
Linus Torvalds
1 parent
2fa4341074
Exists in
master
and in
4 other branches
task_struct cleanup: move binfmt field to mm_struct
Because the binfmt is not different between threads in the same process, it can be moved from task_struct to mm_struct. And binfmt moudle is handled per mm_struct instead of task_struct. Signed-off-by: Hiroshi Shimamoto <h-shimamoto@ct.jp.nec.com> Acked-by: Oleg Nesterov <oleg@redhat.com> Cc: Rusty Russell <rusty@rustcorp.com.au> Acked-by: Roland McGrath <roland@redhat.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Showing 5 changed files with 15 additions and 13 deletions Side-by-side Diff
fs/exec.c
... | ... | @@ -1397,10 +1397,12 @@ |
1397 | 1397 | |
1398 | 1398 | void set_binfmt(struct linux_binfmt *new) |
1399 | 1399 | { |
1400 | - if (current->binfmt) | |
1401 | - module_put(current->binfmt->module); | |
1400 | + struct mm_struct *mm = current->mm; | |
1402 | 1401 | |
1403 | - current->binfmt = new; | |
1402 | + if (mm->binfmt) | |
1403 | + module_put(mm->binfmt->module); | |
1404 | + | |
1405 | + mm->binfmt = new; | |
1404 | 1406 | if (new) |
1405 | 1407 | __module_get(new->module); |
1406 | 1408 | } |
... | ... | @@ -1770,7 +1772,7 @@ |
1770 | 1772 | |
1771 | 1773 | audit_core_dumps(signr); |
1772 | 1774 | |
1773 | - binfmt = current->binfmt; | |
1775 | + binfmt = mm->binfmt; | |
1774 | 1776 | if (!binfmt || !binfmt->core_dump) |
1775 | 1777 | goto fail; |
1776 | 1778 |
include/linux/mm_types.h
include/linux/sched.h
kernel/exit.c
kernel/fork.c
... | ... | @@ -518,6 +518,8 @@ |
518 | 518 | spin_unlock(&mmlist_lock); |
519 | 519 | } |
520 | 520 | put_swap_token(mm); |
521 | + if (mm->binfmt) | |
522 | + module_put(mm->binfmt->module); | |
521 | 523 | mmdrop(mm); |
522 | 524 | } |
523 | 525 | } |
524 | 526 | |
... | ... | @@ -643,9 +645,14 @@ |
643 | 645 | mm->hiwater_rss = get_mm_rss(mm); |
644 | 646 | mm->hiwater_vm = mm->total_vm; |
645 | 647 | |
648 | + if (mm->binfmt && !try_module_get(mm->binfmt->module)) | |
649 | + goto free_pt; | |
650 | + | |
646 | 651 | return mm; |
647 | 652 | |
648 | 653 | free_pt: |
654 | + /* don't put binfmt in mmput, we haven't got module yet */ | |
655 | + mm->binfmt = NULL; | |
649 | 656 | mmput(mm); |
650 | 657 | |
651 | 658 | fail_nomem: |
... | ... | @@ -1037,9 +1044,6 @@ |
1037 | 1044 | if (!try_module_get(task_thread_info(p)->exec_domain->module)) |
1038 | 1045 | goto bad_fork_cleanup_count; |
1039 | 1046 | |
1040 | - if (p->binfmt && !try_module_get(p->binfmt->module)) | |
1041 | - goto bad_fork_cleanup_put_domain; | |
1042 | - | |
1043 | 1047 | p->did_exec = 0; |
1044 | 1048 | delayacct_tsk_init(p); /* Must remain after dup_task_struct() */ |
1045 | 1049 | copy_flags(clone_flags, p); |
... | ... | @@ -1327,9 +1331,6 @@ |
1327 | 1331 | #endif |
1328 | 1332 | cgroup_exit(p, cgroup_callbacks_done); |
1329 | 1333 | delayacct_tsk_free(p); |
1330 | - if (p->binfmt) | |
1331 | - module_put(p->binfmt->module); | |
1332 | -bad_fork_cleanup_put_domain: | |
1333 | 1334 | module_put(task_thread_info(p)->exec_domain->module); |
1334 | 1335 | bad_fork_cleanup_count: |
1335 | 1336 | atomic_dec(&p->cred->user->processes); |