Commit 8cd9c249128a59e8e833d454a784b0cbd338d468
Committed by
Linus Torvalds
1 parent
999d9fc167
Exists in
master
and in
4 other branches
coredump: simplify core_state->nr_threads calculation
Change zap_process() to return int instead of incrementing mm->core_state->nr_threads directly. Change zap_threads() to set mm->core_state only on success. This patch restores the original size of .text, and more importantly now ->nr_threads is used in two places only. Signed-off-by: Oleg Nesterov <oleg@tv-sign.ru> Cc: Roland McGrath <roland@redhat.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Showing 1 changed file with 16 additions and 17 deletions Side-by-side Diff
fs/exec.c
... | ... | @@ -1502,9 +1502,10 @@ |
1502 | 1502 | return ispipe; |
1503 | 1503 | } |
1504 | 1504 | |
1505 | -static void zap_process(struct task_struct *start) | |
1505 | +static int zap_process(struct task_struct *start) | |
1506 | 1506 | { |
1507 | 1507 | struct task_struct *t; |
1508 | + int nr = 0; | |
1508 | 1509 | |
1509 | 1510 | start->signal->flags = SIGNAL_GROUP_EXIT; |
1510 | 1511 | start->signal->group_stop_count = 0; |
1511 | 1512 | |
1512 | 1513 | |
1513 | 1514 | |
1514 | 1515 | |
1515 | 1516 | |
1516 | 1517 | |
1517 | 1518 | |
1518 | 1519 | |
... | ... | @@ -1512,31 +1513,33 @@ |
1512 | 1513 | t = start; |
1513 | 1514 | do { |
1514 | 1515 | if (t != current && t->mm) { |
1515 | - t->mm->core_state->nr_threads++; | |
1516 | 1516 | sigaddset(&t->pending.signal, SIGKILL); |
1517 | 1517 | signal_wake_up(t, 1); |
1518 | + nr++; | |
1518 | 1519 | } |
1519 | 1520 | } while_each_thread(start, t); |
1521 | + | |
1522 | + return nr; | |
1520 | 1523 | } |
1521 | 1524 | |
1522 | 1525 | static inline int zap_threads(struct task_struct *tsk, struct mm_struct *mm, |
1523 | - int exit_code) | |
1526 | + struct core_state *core_state, int exit_code) | |
1524 | 1527 | { |
1525 | 1528 | struct task_struct *g, *p; |
1526 | 1529 | unsigned long flags; |
1527 | - int err = -EAGAIN; | |
1530 | + int nr = -EAGAIN; | |
1528 | 1531 | |
1529 | 1532 | spin_lock_irq(&tsk->sighand->siglock); |
1530 | 1533 | if (!signal_group_exit(tsk->signal)) { |
1534 | + mm->core_state = core_state; | |
1531 | 1535 | tsk->signal->group_exit_code = exit_code; |
1532 | - zap_process(tsk); | |
1533 | - err = 0; | |
1536 | + nr = zap_process(tsk); | |
1534 | 1537 | } |
1535 | 1538 | spin_unlock_irq(&tsk->sighand->siglock); |
1536 | - if (err) | |
1537 | - return err; | |
1539 | + if (unlikely(nr < 0)) | |
1540 | + return nr; | |
1538 | 1541 | |
1539 | - if (atomic_read(&mm->mm_users) == mm->core_state->nr_threads + 1) | |
1542 | + if (atomic_read(&mm->mm_users) == nr + 1) | |
1540 | 1543 | goto done; |
1541 | 1544 | /* |
1542 | 1545 | * We should find and kill all tasks which use this mm, and we should |
... | ... | @@ -1579,7 +1582,7 @@ |
1579 | 1582 | if (p->mm) { |
1580 | 1583 | if (unlikely(p->mm == mm)) { |
1581 | 1584 | lock_task_sighand(p, &flags); |
1582 | - zap_process(p); | |
1585 | + nr += zap_process(p); | |
1583 | 1586 | unlock_task_sighand(p, &flags); |
1584 | 1587 | } |
1585 | 1588 | break; |
... | ... | @@ -1588,7 +1591,8 @@ |
1588 | 1591 | } |
1589 | 1592 | rcu_read_unlock(); |
1590 | 1593 | done: |
1591 | - return mm->core_state->nr_threads; | |
1594 | + core_state->nr_threads = nr; | |
1595 | + return nr; | |
1592 | 1596 | } |
1593 | 1597 | |
1594 | 1598 | static int coredump_wait(int exit_code) |
... | ... | @@ -1601,12 +1605,7 @@ |
1601 | 1605 | |
1602 | 1606 | init_completion(&mm->core_done); |
1603 | 1607 | init_completion(&core_state.startup); |
1604 | - core_state.nr_threads = 0; | |
1605 | - mm->core_state = &core_state; | |
1606 | - | |
1607 | - core_waiters = zap_threads(tsk, mm, exit_code); | |
1608 | - if (core_waiters < 0) | |
1609 | - mm->core_state = NULL; | |
1608 | + core_waiters = zap_threads(tsk, mm, &core_state, exit_code); | |
1610 | 1609 | up_write(&mm->mmap_sem); |
1611 | 1610 | |
1612 | 1611 | if (unlikely(core_waiters < 0)) |