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: */ |