diff options
Diffstat (limited to 'kernel/exit.c')
| -rw-r--r-- | kernel/exit.c | 164 |
1 files changed, 95 insertions, 69 deletions
diff --git a/kernel/exit.c b/kernel/exit.c index ae5d8660ddff..5859f598c951 100644 --- a/kernel/exit.c +++ b/kernel/exit.c | |||
| @@ -47,7 +47,7 @@ | |||
| 47 | #include <linux/tracehook.h> | 47 | #include <linux/tracehook.h> |
| 48 | #include <linux/fs_struct.h> | 48 | #include <linux/fs_struct.h> |
| 49 | #include <linux/init_task.h> | 49 | #include <linux/init_task.h> |
| 50 | #include <linux/perf_counter.h> | 50 | #include <linux/perf_event.h> |
| 51 | #include <trace/events/sched.h> | 51 | #include <trace/events/sched.h> |
| 52 | 52 | ||
| 53 | #include <asm/uaccess.h> | 53 | #include <asm/uaccess.h> |
| @@ -154,8 +154,8 @@ static void delayed_put_task_struct(struct rcu_head *rhp) | |||
| 154 | { | 154 | { |
| 155 | struct task_struct *tsk = container_of(rhp, struct task_struct, rcu); | 155 | struct task_struct *tsk = container_of(rhp, struct task_struct, rcu); |
| 156 | 156 | ||
| 157 | #ifdef CONFIG_PERF_COUNTERS | 157 | #ifdef CONFIG_PERF_EVENTS |
| 158 | WARN_ON_ONCE(tsk->perf_counter_ctxp); | 158 | WARN_ON_ONCE(tsk->perf_event_ctxp); |
| 159 | #endif | 159 | #endif |
| 160 | trace_sched_process_free(tsk); | 160 | trace_sched_process_free(tsk); |
| 161 | put_task_struct(tsk); | 161 | put_task_struct(tsk); |
| @@ -359,8 +359,10 @@ void __set_special_pids(struct pid *pid) | |||
| 359 | { | 359 | { |
| 360 | struct task_struct *curr = current->group_leader; | 360 | struct task_struct *curr = current->group_leader; |
| 361 | 361 | ||
| 362 | if (task_session(curr) != pid) | 362 | if (task_session(curr) != pid) { |
| 363 | change_pid(curr, PIDTYPE_SID, pid); | 363 | change_pid(curr, PIDTYPE_SID, pid); |
| 364 | proc_sid_connector(curr); | ||
| 365 | } | ||
| 364 | 366 | ||
| 365 | if (task_pgrp(curr) != pid) | 367 | if (task_pgrp(curr) != pid) |
| 366 | change_pid(curr, PIDTYPE_PGID, pid); | 368 | change_pid(curr, PIDTYPE_PGID, pid); |
| @@ -945,6 +947,8 @@ NORET_TYPE void do_exit(long code) | |||
| 945 | if (group_dead) { | 947 | if (group_dead) { |
| 946 | hrtimer_cancel(&tsk->signal->real_timer); | 948 | hrtimer_cancel(&tsk->signal->real_timer); |
| 947 | exit_itimers(tsk->signal); | 949 | exit_itimers(tsk->signal); |
| 950 | if (tsk->mm) | ||
| 951 | setmax_mm_hiwater_rss(&tsk->signal->maxrss, tsk->mm); | ||
| 948 | } | 952 | } |
| 949 | acct_collect(code, group_dead); | 953 | acct_collect(code, group_dead); |
| 950 | if (group_dead) | 954 | if (group_dead) |
| @@ -972,8 +976,6 @@ NORET_TYPE void do_exit(long code) | |||
| 972 | disassociate_ctty(1); | 976 | disassociate_ctty(1); |
| 973 | 977 | ||
| 974 | module_put(task_thread_info(tsk)->exec_domain->module); | 978 | module_put(task_thread_info(tsk)->exec_domain->module); |
| 975 | if (tsk->binfmt) | ||
| 976 | module_put(tsk->binfmt->module); | ||
| 977 | 979 | ||
| 978 | proc_exit_connector(tsk); | 980 | proc_exit_connector(tsk); |
| 979 | 981 | ||
| @@ -981,7 +983,7 @@ NORET_TYPE void do_exit(long code) | |||
| 981 | * Flush inherited counters to the parent - before the parent | 983 | * Flush inherited counters to the parent - before the parent |
| 982 | * gets woken up by child-exit notifications. | 984 | * gets woken up by child-exit notifications. |
| 983 | */ | 985 | */ |
| 984 | perf_counter_exit_task(tsk); | 986 | perf_event_exit_task(tsk); |
| 985 | 987 | ||
| 986 | exit_notify(tsk, group_dead); | 988 | exit_notify(tsk, group_dead); |
| 987 | #ifdef CONFIG_NUMA | 989 | #ifdef CONFIG_NUMA |
| @@ -1093,28 +1095,28 @@ struct wait_opts { | |||
| 1093 | int __user *wo_stat; | 1095 | int __user *wo_stat; |
| 1094 | struct rusage __user *wo_rusage; | 1096 | struct rusage __user *wo_rusage; |
| 1095 | 1097 | ||
| 1098 | wait_queue_t child_wait; | ||
| 1096 | int notask_error; | 1099 | int notask_error; |
| 1097 | }; | 1100 | }; |
| 1098 | 1101 | ||
| 1099 | static struct pid *task_pid_type(struct task_struct *task, enum pid_type type) | 1102 | static inline |
| 1103 | struct pid *task_pid_type(struct task_struct *task, enum pid_type type) | ||
| 1100 | { | 1104 | { |
| 1101 | struct pid *pid = NULL; | 1105 | if (type != PIDTYPE_PID) |
| 1102 | if (type == PIDTYPE_PID) | 1106 | task = task->group_leader; |
| 1103 | pid = task->pids[type].pid; | 1107 | return task->pids[type].pid; |
| 1104 | else if (type < PIDTYPE_MAX) | ||
| 1105 | pid = task->group_leader->pids[type].pid; | ||
| 1106 | return pid; | ||
| 1107 | } | 1108 | } |
| 1108 | 1109 | ||
| 1109 | static int eligible_child(struct wait_opts *wo, struct task_struct *p) | 1110 | static int eligible_pid(struct wait_opts *wo, struct task_struct *p) |
| 1110 | { | 1111 | { |
| 1111 | int err; | 1112 | return wo->wo_type == PIDTYPE_MAX || |
| 1112 | 1113 | task_pid_type(p, wo->wo_type) == wo->wo_pid; | |
| 1113 | if (wo->wo_type < PIDTYPE_MAX) { | 1114 | } |
| 1114 | if (task_pid_type(p, wo->wo_type) != wo->wo_pid) | ||
| 1115 | return 0; | ||
| 1116 | } | ||
| 1117 | 1115 | ||
| 1116 | static int eligible_child(struct wait_opts *wo, struct task_struct *p) | ||
| 1117 | { | ||
| 1118 | if (!eligible_pid(wo, p)) | ||
| 1119 | return 0; | ||
| 1118 | /* Wait for all children (clone and not) if __WALL is set; | 1120 | /* Wait for all children (clone and not) if __WALL is set; |
| 1119 | * otherwise, wait for clone children *only* if __WCLONE is | 1121 | * otherwise, wait for clone children *only* if __WCLONE is |
| 1120 | * set; otherwise, wait for non-clone children *only*. (Note: | 1122 | * set; otherwise, wait for non-clone children *only*. (Note: |
| @@ -1124,10 +1126,6 @@ static int eligible_child(struct wait_opts *wo, struct task_struct *p) | |||
| 1124 | && !(wo->wo_flags & __WALL)) | 1126 | && !(wo->wo_flags & __WALL)) |
| 1125 | return 0; | 1127 | return 0; |
| 1126 | 1128 | ||
| 1127 | err = security_task_wait(p); | ||
| 1128 | if (err) | ||
| 1129 | return err; | ||
| 1130 | |||
| 1131 | return 1; | 1129 | return 1; |
| 1132 | } | 1130 | } |
| 1133 | 1131 | ||
| @@ -1140,18 +1138,20 @@ static int wait_noreap_copyout(struct wait_opts *wo, struct task_struct *p, | |||
| 1140 | 1138 | ||
| 1141 | put_task_struct(p); | 1139 | put_task_struct(p); |
| 1142 | infop = wo->wo_info; | 1140 | infop = wo->wo_info; |
| 1143 | if (!retval) | 1141 | if (infop) { |
| 1144 | retval = put_user(SIGCHLD, &infop->si_signo); | 1142 | if (!retval) |
| 1145 | if (!retval) | 1143 | retval = put_user(SIGCHLD, &infop->si_signo); |
| 1146 | retval = put_user(0, &infop->si_errno); | 1144 | if (!retval) |
| 1147 | if (!retval) | 1145 | retval = put_user(0, &infop->si_errno); |
| 1148 | retval = put_user((short)why, &infop->si_code); | 1146 | if (!retval) |
| 1149 | if (!retval) | 1147 | retval = put_user((short)why, &infop->si_code); |
| 1150 | retval = put_user(pid, &infop->si_pid); | 1148 | if (!retval) |
| 1151 | if (!retval) | 1149 | retval = put_user(pid, &infop->si_pid); |
| 1152 | retval = put_user(uid, &infop->si_uid); | 1150 | if (!retval) |
| 1153 | if (!retval) | 1151 | retval = put_user(uid, &infop->si_uid); |
| 1154 | retval = put_user(status, &infop->si_status); | 1152 | if (!retval) |
| 1153 | retval = put_user(status, &infop->si_status); | ||
| 1154 | } | ||
| 1155 | if (!retval) | 1155 | if (!retval) |
| 1156 | retval = pid; | 1156 | retval = pid; |
| 1157 | return retval; | 1157 | return retval; |
| @@ -1208,6 +1208,7 @@ static int wait_task_zombie(struct wait_opts *wo, struct task_struct *p) | |||
| 1208 | if (likely(!traced) && likely(!task_detached(p))) { | 1208 | if (likely(!traced) && likely(!task_detached(p))) { |
| 1209 | struct signal_struct *psig; | 1209 | struct signal_struct *psig; |
| 1210 | struct signal_struct *sig; | 1210 | struct signal_struct *sig; |
| 1211 | unsigned long maxrss; | ||
| 1211 | 1212 | ||
| 1212 | /* | 1213 | /* |
| 1213 | * The resource counters for the group leader are in its | 1214 | * The resource counters for the group leader are in its |
| @@ -1256,6 +1257,9 @@ static int wait_task_zombie(struct wait_opts *wo, struct task_struct *p) | |||
| 1256 | psig->coublock += | 1257 | psig->coublock += |
| 1257 | task_io_get_oublock(p) + | 1258 | task_io_get_oublock(p) + |
| 1258 | sig->oublock + sig->coublock; | 1259 | sig->oublock + sig->coublock; |
| 1260 | maxrss = max(sig->maxrss, sig->cmaxrss); | ||
| 1261 | if (psig->cmaxrss < maxrss) | ||
| 1262 | psig->cmaxrss = maxrss; | ||
| 1259 | task_io_accounting_add(&psig->ioac, &p->ioac); | 1263 | task_io_accounting_add(&psig->ioac, &p->ioac); |
| 1260 | task_io_accounting_add(&psig->ioac, &sig->ioac); | 1264 | task_io_accounting_add(&psig->ioac, &sig->ioac); |
| 1261 | spin_unlock_irq(&p->real_parent->sighand->siglock); | 1265 | spin_unlock_irq(&p->real_parent->sighand->siglock); |
| @@ -1477,13 +1481,14 @@ static int wait_task_continued(struct wait_opts *wo, struct task_struct *p) | |||
| 1477 | * then ->notask_error is 0 if @p is an eligible child, | 1481 | * then ->notask_error is 0 if @p is an eligible child, |
| 1478 | * or another error from security_task_wait(), or still -ECHILD. | 1482 | * or another error from security_task_wait(), or still -ECHILD. |
| 1479 | */ | 1483 | */ |
| 1480 | static int wait_consider_task(struct wait_opts *wo, struct task_struct *parent, | 1484 | static int wait_consider_task(struct wait_opts *wo, int ptrace, |
| 1481 | int ptrace, struct task_struct *p) | 1485 | struct task_struct *p) |
| 1482 | { | 1486 | { |
| 1483 | int ret = eligible_child(wo, p); | 1487 | int ret = eligible_child(wo, p); |
| 1484 | if (!ret) | 1488 | if (!ret) |
| 1485 | return ret; | 1489 | return ret; |
| 1486 | 1490 | ||
| 1491 | ret = security_task_wait(p); | ||
| 1487 | if (unlikely(ret < 0)) { | 1492 | if (unlikely(ret < 0)) { |
| 1488 | /* | 1493 | /* |
| 1489 | * If we have not yet seen any eligible child, | 1494 | * If we have not yet seen any eligible child, |
| @@ -1545,7 +1550,7 @@ static int do_wait_thread(struct wait_opts *wo, struct task_struct *tsk) | |||
| 1545 | * Do not consider detached threads. | 1550 | * Do not consider detached threads. |
| 1546 | */ | 1551 | */ |
| 1547 | if (!task_detached(p)) { | 1552 | if (!task_detached(p)) { |
| 1548 | int ret = wait_consider_task(wo, tsk, 0, p); | 1553 | int ret = wait_consider_task(wo, 0, p); |
| 1549 | if (ret) | 1554 | if (ret) |
| 1550 | return ret; | 1555 | return ret; |
| 1551 | } | 1556 | } |
| @@ -1559,7 +1564,7 @@ static int ptrace_do_wait(struct wait_opts *wo, struct task_struct *tsk) | |||
| 1559 | struct task_struct *p; | 1564 | struct task_struct *p; |
| 1560 | 1565 | ||
| 1561 | list_for_each_entry(p, &tsk->ptraced, ptrace_entry) { | 1566 | list_for_each_entry(p, &tsk->ptraced, ptrace_entry) { |
| 1562 | int ret = wait_consider_task(wo, tsk, 1, p); | 1567 | int ret = wait_consider_task(wo, 1, p); |
| 1563 | if (ret) | 1568 | if (ret) |
| 1564 | return ret; | 1569 | return ret; |
| 1565 | } | 1570 | } |
| @@ -1567,15 +1572,38 @@ static int ptrace_do_wait(struct wait_opts *wo, struct task_struct *tsk) | |||
| 1567 | return 0; | 1572 | return 0; |
| 1568 | } | 1573 | } |
| 1569 | 1574 | ||
| 1575 | static int child_wait_callback(wait_queue_t *wait, unsigned mode, | ||
| 1576 | int sync, void *key) | ||
| 1577 | { | ||
| 1578 | struct wait_opts *wo = container_of(wait, struct wait_opts, | ||
| 1579 | child_wait); | ||
| 1580 | struct task_struct *p = key; | ||
| 1581 | |||
| 1582 | if (!eligible_pid(wo, p)) | ||
| 1583 | return 0; | ||
| 1584 | |||
| 1585 | if ((wo->wo_flags & __WNOTHREAD) && wait->private != p->parent) | ||
| 1586 | return 0; | ||
| 1587 | |||
| 1588 | return default_wake_function(wait, mode, sync, key); | ||
| 1589 | } | ||
| 1590 | |||
| 1591 | void __wake_up_parent(struct task_struct *p, struct task_struct *parent) | ||
| 1592 | { | ||
| 1593 | __wake_up_sync_key(&parent->signal->wait_chldexit, | ||
| 1594 | TASK_INTERRUPTIBLE, 1, p); | ||
| 1595 | } | ||
| 1596 | |||
| 1570 | static long do_wait(struct wait_opts *wo) | 1597 | static long do_wait(struct wait_opts *wo) |
| 1571 | { | 1598 | { |
| 1572 | DECLARE_WAITQUEUE(wait, current); | ||
| 1573 | struct task_struct *tsk; | 1599 | struct task_struct *tsk; |
| 1574 | int retval; | 1600 | int retval; |
| 1575 | 1601 | ||
| 1576 | trace_sched_process_wait(wo->wo_pid); | 1602 | trace_sched_process_wait(wo->wo_pid); |
| 1577 | 1603 | ||
| 1578 | add_wait_queue(¤t->signal->wait_chldexit,&wait); | 1604 | init_waitqueue_func_entry(&wo->child_wait, child_wait_callback); |
| 1605 | wo->child_wait.private = current; | ||
| 1606 | add_wait_queue(¤t->signal->wait_chldexit, &wo->child_wait); | ||
| 1579 | repeat: | 1607 | repeat: |
| 1580 | /* | 1608 | /* |
| 1581 | * If there is nothing that can match our critiera just get out. | 1609 | * If there is nothing that can match our critiera just get out. |
| @@ -1616,32 +1644,7 @@ notask: | |||
| 1616 | } | 1644 | } |
| 1617 | end: | 1645 | end: |
| 1618 | __set_current_state(TASK_RUNNING); | 1646 | __set_current_state(TASK_RUNNING); |
| 1619 | remove_wait_queue(¤t->signal->wait_chldexit,&wait); | 1647 | remove_wait_queue(¤t->signal->wait_chldexit, &wo->child_wait); |
| 1620 | if (wo->wo_info) { | ||
| 1621 | struct siginfo __user *infop = wo->wo_info; | ||
| 1622 | |||
| 1623 | if (retval > 0) | ||
| 1624 | retval = 0; | ||
| 1625 | else { | ||
| 1626 | /* | ||
| 1627 | * For a WNOHANG return, clear out all the fields | ||
| 1628 | * we would set so the user can easily tell the | ||
| 1629 | * difference. | ||
| 1630 | */ | ||
| 1631 | if (!retval) | ||
| 1632 | retval = put_user(0, &infop->si_signo); | ||
| 1633 | if (!retval) | ||
| 1634 | retval = put_user(0, &infop->si_errno); | ||
| 1635 | if (!retval) | ||
| 1636 | retval = put_user(0, &infop->si_code); | ||
| 1637 | if (!retval) | ||
| 1638 | retval = put_user(0, &infop->si_pid); | ||
| 1639 | if (!retval) | ||
| 1640 | retval = put_user(0, &infop->si_uid); | ||
| 1641 | if (!retval) | ||
| 1642 | retval = put_user(0, &infop->si_status); | ||
| 1643 | } | ||
| 1644 | } | ||
| 1645 | return retval; | 1648 | return retval; |
| 1646 | } | 1649 | } |
| 1647 | 1650 | ||
| @@ -1686,6 +1689,29 @@ SYSCALL_DEFINE5(waitid, int, which, pid_t, upid, struct siginfo __user *, | |||
| 1686 | wo.wo_stat = NULL; | 1689 | wo.wo_stat = NULL; |
| 1687 | wo.wo_rusage = ru; | 1690 | wo.wo_rusage = ru; |
| 1688 | ret = do_wait(&wo); | 1691 | ret = do_wait(&wo); |
| 1692 | |||
| 1693 | if (ret > 0) { | ||
| 1694 | ret = 0; | ||
| 1695 | } else if (infop) { | ||
| 1696 | /* | ||
| 1697 | * For a WNOHANG return, clear out all the fields | ||
| 1698 | * we would set so the user can easily tell the | ||
| 1699 | * difference. | ||
| 1700 | */ | ||
| 1701 | if (!ret) | ||
| 1702 | ret = put_user(0, &infop->si_signo); | ||
| 1703 | if (!ret) | ||
| 1704 | ret = put_user(0, &infop->si_errno); | ||
| 1705 | if (!ret) | ||
| 1706 | ret = put_user(0, &infop->si_code); | ||
| 1707 | if (!ret) | ||
| 1708 | ret = put_user(0, &infop->si_pid); | ||
| 1709 | if (!ret) | ||
| 1710 | ret = put_user(0, &infop->si_uid); | ||
| 1711 | if (!ret) | ||
| 1712 | ret = put_user(0, &infop->si_status); | ||
| 1713 | } | ||
| 1714 | |||
| 1689 | put_pid(pid); | 1715 | put_pid(pid); |
| 1690 | 1716 | ||
| 1691 | /* avoid REGPARM breakage on x86: */ | 1717 | /* avoid REGPARM breakage on x86: */ |
