diff options
Diffstat (limited to 'kernel/exit.c')
-rw-r--r-- | kernel/exit.c | 141 |
1 files changed, 103 insertions, 38 deletions
diff --git a/kernel/exit.c b/kernel/exit.c index 8dd874181542..f2b321bae440 100644 --- a/kernel/exit.c +++ b/kernel/exit.c | |||
@@ -561,29 +561,28 @@ void exit_files(struct task_struct *tsk) | |||
561 | 561 | ||
562 | #ifdef CONFIG_MM_OWNER | 562 | #ifdef CONFIG_MM_OWNER |
563 | /* | 563 | /* |
564 | * Task p is exiting and it owned mm, lets find a new owner for it | 564 | * A task is exiting. If it owned this mm, find a new owner for the mm. |
565 | */ | 565 | */ |
566 | static inline int | ||
567 | mm_need_new_owner(struct mm_struct *mm, struct task_struct *p) | ||
568 | { | ||
569 | /* | ||
570 | * If there are other users of the mm and the owner (us) is exiting | ||
571 | * we need to find a new owner to take on the responsibility. | ||
572 | */ | ||
573 | if (atomic_read(&mm->mm_users) <= 1) | ||
574 | return 0; | ||
575 | if (mm->owner != p) | ||
576 | return 0; | ||
577 | return 1; | ||
578 | } | ||
579 | |||
580 | void mm_update_next_owner(struct mm_struct *mm) | 566 | void mm_update_next_owner(struct mm_struct *mm) |
581 | { | 567 | { |
582 | struct task_struct *c, *g, *p = current; | 568 | struct task_struct *c, *g, *p = current; |
583 | 569 | ||
584 | retry: | 570 | retry: |
585 | if (!mm_need_new_owner(mm, p)) | 571 | /* |
572 | * If the exiting or execing task is not the owner, it's | ||
573 | * someone else's problem. | ||
574 | */ | ||
575 | if (mm->owner != p) | ||
586 | return; | 576 | return; |
577 | /* | ||
578 | * The current owner is exiting/execing and there are no other | ||
579 | * candidates. Do not leave the mm pointing to a possibly | ||
580 | * freed task structure. | ||
581 | */ | ||
582 | if (atomic_read(&mm->mm_users) <= 1) { | ||
583 | mm->owner = NULL; | ||
584 | return; | ||
585 | } | ||
587 | 586 | ||
588 | read_lock(&tasklist_lock); | 587 | read_lock(&tasklist_lock); |
589 | /* | 588 | /* |
@@ -1377,11 +1376,23 @@ static int *task_stopped_code(struct task_struct *p, bool ptrace) | |||
1377 | return NULL; | 1376 | return NULL; |
1378 | } | 1377 | } |
1379 | 1378 | ||
1380 | /* | 1379 | /** |
1381 | * Handle sys_wait4 work for one task in state TASK_STOPPED. We hold | 1380 | * wait_task_stopped - Wait for %TASK_STOPPED or %TASK_TRACED |
1382 | * read_lock(&tasklist_lock) on entry. If we return zero, we still hold | 1381 | * @wo: wait options |
1383 | * the lock and this task is uninteresting. If we return nonzero, we have | 1382 | * @ptrace: is the wait for ptrace |
1384 | * released the lock and the system call should return. | 1383 | * @p: task to wait for |
1384 | * | ||
1385 | * Handle sys_wait4() work for %p in state %TASK_STOPPED or %TASK_TRACED. | ||
1386 | * | ||
1387 | * CONTEXT: | ||
1388 | * read_lock(&tasklist_lock), which is released if return value is | ||
1389 | * non-zero. Also, grabs and releases @p->sighand->siglock. | ||
1390 | * | ||
1391 | * RETURNS: | ||
1392 | * 0 if wait condition didn't exist and search for other wait conditions | ||
1393 | * should continue. Non-zero return, -errno on failure and @p's pid on | ||
1394 | * success, implies that tasklist_lock is released and wait condition | ||
1395 | * search should terminate. | ||
1385 | */ | 1396 | */ |
1386 | static int wait_task_stopped(struct wait_opts *wo, | 1397 | static int wait_task_stopped(struct wait_opts *wo, |
1387 | int ptrace, struct task_struct *p) | 1398 | int ptrace, struct task_struct *p) |
@@ -1397,6 +1408,9 @@ static int wait_task_stopped(struct wait_opts *wo, | |||
1397 | if (!ptrace && !(wo->wo_flags & WUNTRACED)) | 1408 | if (!ptrace && !(wo->wo_flags & WUNTRACED)) |
1398 | return 0; | 1409 | return 0; |
1399 | 1410 | ||
1411 | if (!task_stopped_code(p, ptrace)) | ||
1412 | return 0; | ||
1413 | |||
1400 | exit_code = 0; | 1414 | exit_code = 0; |
1401 | spin_lock_irq(&p->sighand->siglock); | 1415 | spin_lock_irq(&p->sighand->siglock); |
1402 | 1416 | ||
@@ -1538,33 +1552,84 @@ static int wait_consider_task(struct wait_opts *wo, int ptrace, | |||
1538 | return 0; | 1552 | return 0; |
1539 | } | 1553 | } |
1540 | 1554 | ||
1541 | if (likely(!ptrace) && unlikely(task_ptrace(p))) { | 1555 | /* dead body doesn't have much to contribute */ |
1556 | if (p->exit_state == EXIT_DEAD) | ||
1557 | return 0; | ||
1558 | |||
1559 | /* slay zombie? */ | ||
1560 | if (p->exit_state == EXIT_ZOMBIE) { | ||
1561 | /* | ||
1562 | * A zombie ptracee is only visible to its ptracer. | ||
1563 | * Notification and reaping will be cascaded to the real | ||
1564 | * parent when the ptracer detaches. | ||
1565 | */ | ||
1566 | if (likely(!ptrace) && unlikely(task_ptrace(p))) { | ||
1567 | /* it will become visible, clear notask_error */ | ||
1568 | wo->notask_error = 0; | ||
1569 | return 0; | ||
1570 | } | ||
1571 | |||
1572 | /* we don't reap group leaders with subthreads */ | ||
1573 | if (!delay_group_leader(p)) | ||
1574 | return wait_task_zombie(wo, p); | ||
1575 | |||
1542 | /* | 1576 | /* |
1543 | * This child is hidden by ptrace. | 1577 | * Allow access to stopped/continued state via zombie by |
1544 | * We aren't allowed to see it now, but eventually we will. | 1578 | * falling through. Clearing of notask_error is complex. |
1579 | * | ||
1580 | * When !@ptrace: | ||
1581 | * | ||
1582 | * If WEXITED is set, notask_error should naturally be | ||
1583 | * cleared. If not, subset of WSTOPPED|WCONTINUED is set, | ||
1584 | * so, if there are live subthreads, there are events to | ||
1585 | * wait for. If all subthreads are dead, it's still safe | ||
1586 | * to clear - this function will be called again in finite | ||
1587 | * amount time once all the subthreads are released and | ||
1588 | * will then return without clearing. | ||
1589 | * | ||
1590 | * When @ptrace: | ||
1591 | * | ||
1592 | * Stopped state is per-task and thus can't change once the | ||
1593 | * target task dies. Only continued and exited can happen. | ||
1594 | * Clear notask_error if WCONTINUED | WEXITED. | ||
1595 | */ | ||
1596 | if (likely(!ptrace) || (wo->wo_flags & (WCONTINUED | WEXITED))) | ||
1597 | wo->notask_error = 0; | ||
1598 | } else { | ||
1599 | /* | ||
1600 | * If @p is ptraced by a task in its real parent's group, | ||
1601 | * hide group stop/continued state when looking at @p as | ||
1602 | * the real parent; otherwise, a single stop can be | ||
1603 | * reported twice as group and ptrace stops. | ||
1604 | * | ||
1605 | * If a ptracer wants to distinguish the two events for its | ||
1606 | * own children, it should create a separate process which | ||
1607 | * takes the role of real parent. | ||
1608 | */ | ||
1609 | if (likely(!ptrace) && task_ptrace(p) && | ||
1610 | same_thread_group(p->parent, p->real_parent)) | ||
1611 | return 0; | ||
1612 | |||
1613 | /* | ||
1614 | * @p is alive and it's gonna stop, continue or exit, so | ||
1615 | * there always is something to wait for. | ||
1545 | */ | 1616 | */ |
1546 | wo->notask_error = 0; | 1617 | wo->notask_error = 0; |
1547 | return 0; | ||
1548 | } | 1618 | } |
1549 | 1619 | ||
1550 | if (p->exit_state == EXIT_DEAD) | ||
1551 | return 0; | ||
1552 | |||
1553 | /* | 1620 | /* |
1554 | * We don't reap group leaders with subthreads. | 1621 | * Wait for stopped. Depending on @ptrace, different stopped state |
1622 | * is used and the two don't interact with each other. | ||
1555 | */ | 1623 | */ |
1556 | if (p->exit_state == EXIT_ZOMBIE && !delay_group_leader(p)) | 1624 | ret = wait_task_stopped(wo, ptrace, p); |
1557 | return wait_task_zombie(wo, p); | 1625 | if (ret) |
1626 | return ret; | ||
1558 | 1627 | ||
1559 | /* | 1628 | /* |
1560 | * It's stopped or running now, so it might | 1629 | * Wait for continued. There's only one continued state and the |
1561 | * later continue, exit, or stop again. | 1630 | * ptracer can consume it which can confuse the real parent. Don't |
1631 | * use WCONTINUED from ptracer. You don't need or want it. | ||
1562 | */ | 1632 | */ |
1563 | wo->notask_error = 0; | ||
1564 | |||
1565 | if (task_stopped_code(p, ptrace)) | ||
1566 | return wait_task_stopped(wo, ptrace, p); | ||
1567 | |||
1568 | return wait_task_continued(wo, p); | 1633 | return wait_task_continued(wo, p); |
1569 | } | 1634 | } |
1570 | 1635 | ||