diff options
Diffstat (limited to 'kernel/exit.c')
-rw-r--r-- | kernel/exit.c | 185 |
1 files changed, 104 insertions, 81 deletions
diff --git a/kernel/exit.c b/kernel/exit.c index 60d6fdcc9265..5962d7ccf243 100644 --- a/kernel/exit.c +++ b/kernel/exit.c | |||
@@ -49,6 +49,7 @@ | |||
49 | #include <linux/init_task.h> | 49 | #include <linux/init_task.h> |
50 | #include <linux/perf_event.h> | 50 | #include <linux/perf_event.h> |
51 | #include <trace/events/sched.h> | 51 | #include <trace/events/sched.h> |
52 | #include <linux/hw_breakpoint.h> | ||
52 | 53 | ||
53 | #include <asm/uaccess.h> | 54 | #include <asm/uaccess.h> |
54 | #include <asm/unistd.h> | 55 | #include <asm/unistd.h> |
@@ -110,9 +111,9 @@ static void __exit_signal(struct task_struct *tsk) | |||
110 | * We won't ever get here for the group leader, since it | 111 | * We won't ever get here for the group leader, since it |
111 | * will have been the last reference on the signal_struct. | 112 | * will have been the last reference on the signal_struct. |
112 | */ | 113 | */ |
113 | sig->utime = cputime_add(sig->utime, task_utime(tsk)); | 114 | sig->utime = cputime_add(sig->utime, tsk->utime); |
114 | sig->stime = cputime_add(sig->stime, task_stime(tsk)); | 115 | sig->stime = cputime_add(sig->stime, tsk->stime); |
115 | sig->gtime = cputime_add(sig->gtime, task_gtime(tsk)); | 116 | sig->gtime = cputime_add(sig->gtime, tsk->gtime); |
116 | sig->min_flt += tsk->min_flt; | 117 | sig->min_flt += tsk->min_flt; |
117 | sig->maj_flt += tsk->maj_flt; | 118 | sig->maj_flt += tsk->maj_flt; |
118 | sig->nvcsw += tsk->nvcsw; | 119 | sig->nvcsw += tsk->nvcsw; |
@@ -359,10 +360,8 @@ void __set_special_pids(struct pid *pid) | |||
359 | { | 360 | { |
360 | struct task_struct *curr = current->group_leader; | 361 | struct task_struct *curr = current->group_leader; |
361 | 362 | ||
362 | if (task_session(curr) != pid) { | 363 | if (task_session(curr) != pid) |
363 | change_pid(curr, PIDTYPE_SID, pid); | 364 | change_pid(curr, PIDTYPE_SID, pid); |
364 | proc_sid_connector(curr); | ||
365 | } | ||
366 | 365 | ||
367 | if (task_pgrp(curr) != pid) | 366 | if (task_pgrp(curr) != pid) |
368 | change_pid(curr, PIDTYPE_PGID, pid); | 367 | change_pid(curr, PIDTYPE_PGID, pid); |
@@ -934,7 +933,7 @@ NORET_TYPE void do_exit(long code) | |||
934 | * an exiting task cleaning up the robust pi futexes. | 933 | * an exiting task cleaning up the robust pi futexes. |
935 | */ | 934 | */ |
936 | smp_mb(); | 935 | smp_mb(); |
937 | spin_unlock_wait(&tsk->pi_lock); | 936 | raw_spin_unlock_wait(&tsk->pi_lock); |
938 | 937 | ||
939 | if (unlikely(in_atomic())) | 938 | if (unlikely(in_atomic())) |
940 | printk(KERN_INFO "note: %s[%d] exited with preempt_count %d\n", | 939 | printk(KERN_INFO "note: %s[%d] exited with preempt_count %d\n", |
@@ -972,16 +971,18 @@ NORET_TYPE void do_exit(long code) | |||
972 | exit_thread(); | 971 | exit_thread(); |
973 | cgroup_exit(tsk, 1); | 972 | cgroup_exit(tsk, 1); |
974 | 973 | ||
975 | if (group_dead && tsk->signal->leader) | 974 | if (group_dead) |
976 | disassociate_ctty(1); | 975 | disassociate_ctty(1); |
977 | 976 | ||
978 | module_put(task_thread_info(tsk)->exec_domain->module); | 977 | module_put(task_thread_info(tsk)->exec_domain->module); |
979 | if (tsk->binfmt) | ||
980 | module_put(tsk->binfmt->module); | ||
981 | 978 | ||
982 | proc_exit_connector(tsk); | 979 | proc_exit_connector(tsk); |
983 | 980 | ||
984 | /* | 981 | /* |
982 | * FIXME: do that only when needed, using sched_exit tracepoint | ||
983 | */ | ||
984 | flush_ptrace_hw_breakpoint(tsk); | ||
985 | /* | ||
985 | * Flush inherited counters to the parent - before the parent | 986 | * Flush inherited counters to the parent - before the parent |
986 | * gets woken up by child-exit notifications. | 987 | * gets woken up by child-exit notifications. |
987 | */ | 988 | */ |
@@ -993,8 +994,6 @@ NORET_TYPE void do_exit(long code) | |||
993 | tsk->mempolicy = NULL; | 994 | tsk->mempolicy = NULL; |
994 | #endif | 995 | #endif |
995 | #ifdef CONFIG_FUTEX | 996 | #ifdef CONFIG_FUTEX |
996 | if (unlikely(!list_empty(&tsk->pi_state_list))) | ||
997 | exit_pi_state_list(tsk); | ||
998 | if (unlikely(current->pi_state_cache)) | 997 | if (unlikely(current->pi_state_cache)) |
999 | kfree(current->pi_state_cache); | 998 | kfree(current->pi_state_cache); |
1000 | #endif | 999 | #endif |
@@ -1010,7 +1009,7 @@ NORET_TYPE void do_exit(long code) | |||
1010 | tsk->flags |= PF_EXITPIDONE; | 1009 | tsk->flags |= PF_EXITPIDONE; |
1011 | 1010 | ||
1012 | if (tsk->io_context) | 1011 | if (tsk->io_context) |
1013 | exit_io_context(); | 1012 | exit_io_context(tsk); |
1014 | 1013 | ||
1015 | if (tsk->splice_pipe) | 1014 | if (tsk->splice_pipe) |
1016 | __free_pipe_info(tsk->splice_pipe); | 1015 | __free_pipe_info(tsk->splice_pipe); |
@@ -1097,28 +1096,28 @@ struct wait_opts { | |||
1097 | int __user *wo_stat; | 1096 | int __user *wo_stat; |
1098 | struct rusage __user *wo_rusage; | 1097 | struct rusage __user *wo_rusage; |
1099 | 1098 | ||
1099 | wait_queue_t child_wait; | ||
1100 | int notask_error; | 1100 | int notask_error; |
1101 | }; | 1101 | }; |
1102 | 1102 | ||
1103 | static struct pid *task_pid_type(struct task_struct *task, enum pid_type type) | 1103 | static inline |
1104 | struct pid *task_pid_type(struct task_struct *task, enum pid_type type) | ||
1104 | { | 1105 | { |
1105 | struct pid *pid = NULL; | 1106 | if (type != PIDTYPE_PID) |
1106 | if (type == PIDTYPE_PID) | 1107 | task = task->group_leader; |
1107 | pid = task->pids[type].pid; | 1108 | return task->pids[type].pid; |
1108 | else if (type < PIDTYPE_MAX) | ||
1109 | pid = task->group_leader->pids[type].pid; | ||
1110 | return pid; | ||
1111 | } | 1109 | } |
1112 | 1110 | ||
1113 | static int eligible_child(struct wait_opts *wo, struct task_struct *p) | 1111 | static int eligible_pid(struct wait_opts *wo, struct task_struct *p) |
1114 | { | 1112 | { |
1115 | int err; | 1113 | return wo->wo_type == PIDTYPE_MAX || |
1116 | 1114 | task_pid_type(p, wo->wo_type) == wo->wo_pid; | |
1117 | if (wo->wo_type < PIDTYPE_MAX) { | 1115 | } |
1118 | if (task_pid_type(p, wo->wo_type) != wo->wo_pid) | ||
1119 | return 0; | ||
1120 | } | ||
1121 | 1116 | ||
1117 | static int eligible_child(struct wait_opts *wo, struct task_struct *p) | ||
1118 | { | ||
1119 | if (!eligible_pid(wo, p)) | ||
1120 | return 0; | ||
1122 | /* Wait for all children (clone and not) if __WALL is set; | 1121 | /* Wait for all children (clone and not) if __WALL is set; |
1123 | * otherwise, wait for clone children *only* if __WCLONE is | 1122 | * otherwise, wait for clone children *only* if __WCLONE is |
1124 | * set; otherwise, wait for non-clone children *only*. (Note: | 1123 | * set; otherwise, wait for non-clone children *only*. (Note: |
@@ -1128,10 +1127,6 @@ static int eligible_child(struct wait_opts *wo, struct task_struct *p) | |||
1128 | && !(wo->wo_flags & __WALL)) | 1127 | && !(wo->wo_flags & __WALL)) |
1129 | return 0; | 1128 | return 0; |
1130 | 1129 | ||
1131 | err = security_task_wait(p); | ||
1132 | if (err) | ||
1133 | return err; | ||
1134 | |||
1135 | return 1; | 1130 | return 1; |
1136 | } | 1131 | } |
1137 | 1132 | ||
@@ -1144,18 +1139,20 @@ static int wait_noreap_copyout(struct wait_opts *wo, struct task_struct *p, | |||
1144 | 1139 | ||
1145 | put_task_struct(p); | 1140 | put_task_struct(p); |
1146 | infop = wo->wo_info; | 1141 | infop = wo->wo_info; |
1147 | if (!retval) | 1142 | if (infop) { |
1148 | retval = put_user(SIGCHLD, &infop->si_signo); | 1143 | if (!retval) |
1149 | if (!retval) | 1144 | retval = put_user(SIGCHLD, &infop->si_signo); |
1150 | retval = put_user(0, &infop->si_errno); | 1145 | if (!retval) |
1151 | if (!retval) | 1146 | retval = put_user(0, &infop->si_errno); |
1152 | retval = put_user((short)why, &infop->si_code); | 1147 | if (!retval) |
1153 | if (!retval) | 1148 | retval = put_user((short)why, &infop->si_code); |
1154 | retval = put_user(pid, &infop->si_pid); | 1149 | if (!retval) |
1155 | if (!retval) | 1150 | retval = put_user(pid, &infop->si_pid); |
1156 | retval = put_user(uid, &infop->si_uid); | 1151 | if (!retval) |
1157 | if (!retval) | 1152 | retval = put_user(uid, &infop->si_uid); |
1158 | retval = put_user(status, &infop->si_status); | 1153 | if (!retval) |
1154 | retval = put_user(status, &infop->si_status); | ||
1155 | } | ||
1159 | if (!retval) | 1156 | if (!retval) |
1160 | retval = pid; | 1157 | retval = pid; |
1161 | return retval; | 1158 | return retval; |
@@ -1213,6 +1210,7 @@ static int wait_task_zombie(struct wait_opts *wo, struct task_struct *p) | |||
1213 | struct signal_struct *psig; | 1210 | struct signal_struct *psig; |
1214 | struct signal_struct *sig; | 1211 | struct signal_struct *sig; |
1215 | unsigned long maxrss; | 1212 | unsigned long maxrss; |
1213 | cputime_t tgutime, tgstime; | ||
1216 | 1214 | ||
1217 | /* | 1215 | /* |
1218 | * The resource counters for the group leader are in its | 1216 | * The resource counters for the group leader are in its |
@@ -1228,20 +1226,23 @@ static int wait_task_zombie(struct wait_opts *wo, struct task_struct *p) | |||
1228 | * need to protect the access to parent->signal fields, | 1226 | * need to protect the access to parent->signal fields, |
1229 | * as other threads in the parent group can be right | 1227 | * as other threads in the parent group can be right |
1230 | * here reaping other children at the same time. | 1228 | * here reaping other children at the same time. |
1229 | * | ||
1230 | * We use thread_group_times() to get times for the thread | ||
1231 | * group, which consolidates times for all threads in the | ||
1232 | * group including the group leader. | ||
1231 | */ | 1233 | */ |
1234 | thread_group_times(p, &tgutime, &tgstime); | ||
1232 | spin_lock_irq(&p->real_parent->sighand->siglock); | 1235 | spin_lock_irq(&p->real_parent->sighand->siglock); |
1233 | psig = p->real_parent->signal; | 1236 | psig = p->real_parent->signal; |
1234 | sig = p->signal; | 1237 | sig = p->signal; |
1235 | psig->cutime = | 1238 | psig->cutime = |
1236 | cputime_add(psig->cutime, | 1239 | cputime_add(psig->cutime, |
1237 | cputime_add(p->utime, | 1240 | cputime_add(tgutime, |
1238 | cputime_add(sig->utime, | 1241 | sig->cutime)); |
1239 | sig->cutime))); | ||
1240 | psig->cstime = | 1242 | psig->cstime = |
1241 | cputime_add(psig->cstime, | 1243 | cputime_add(psig->cstime, |
1242 | cputime_add(p->stime, | 1244 | cputime_add(tgstime, |
1243 | cputime_add(sig->stime, | 1245 | sig->cstime)); |
1244 | sig->cstime))); | ||
1245 | psig->cgtime = | 1246 | psig->cgtime = |
1246 | cputime_add(psig->cgtime, | 1247 | cputime_add(psig->cgtime, |
1247 | cputime_add(p->gtime, | 1248 | cputime_add(p->gtime, |
@@ -1485,13 +1486,14 @@ static int wait_task_continued(struct wait_opts *wo, struct task_struct *p) | |||
1485 | * then ->notask_error is 0 if @p is an eligible child, | 1486 | * then ->notask_error is 0 if @p is an eligible child, |
1486 | * or another error from security_task_wait(), or still -ECHILD. | 1487 | * or another error from security_task_wait(), or still -ECHILD. |
1487 | */ | 1488 | */ |
1488 | static int wait_consider_task(struct wait_opts *wo, struct task_struct *parent, | 1489 | static int wait_consider_task(struct wait_opts *wo, int ptrace, |
1489 | int ptrace, struct task_struct *p) | 1490 | struct task_struct *p) |
1490 | { | 1491 | { |
1491 | int ret = eligible_child(wo, p); | 1492 | int ret = eligible_child(wo, p); |
1492 | if (!ret) | 1493 | if (!ret) |
1493 | return ret; | 1494 | return ret; |
1494 | 1495 | ||
1496 | ret = security_task_wait(p); | ||
1495 | if (unlikely(ret < 0)) { | 1497 | if (unlikely(ret < 0)) { |
1496 | /* | 1498 | /* |
1497 | * If we have not yet seen any eligible child, | 1499 | * If we have not yet seen any eligible child, |
@@ -1553,7 +1555,7 @@ static int do_wait_thread(struct wait_opts *wo, struct task_struct *tsk) | |||
1553 | * Do not consider detached threads. | 1555 | * Do not consider detached threads. |
1554 | */ | 1556 | */ |
1555 | if (!task_detached(p)) { | 1557 | if (!task_detached(p)) { |
1556 | int ret = wait_consider_task(wo, tsk, 0, p); | 1558 | int ret = wait_consider_task(wo, 0, p); |
1557 | if (ret) | 1559 | if (ret) |
1558 | return ret; | 1560 | return ret; |
1559 | } | 1561 | } |
@@ -1567,7 +1569,7 @@ static int ptrace_do_wait(struct wait_opts *wo, struct task_struct *tsk) | |||
1567 | struct task_struct *p; | 1569 | struct task_struct *p; |
1568 | 1570 | ||
1569 | list_for_each_entry(p, &tsk->ptraced, ptrace_entry) { | 1571 | list_for_each_entry(p, &tsk->ptraced, ptrace_entry) { |
1570 | int ret = wait_consider_task(wo, tsk, 1, p); | 1572 | int ret = wait_consider_task(wo, 1, p); |
1571 | if (ret) | 1573 | if (ret) |
1572 | return ret; | 1574 | return ret; |
1573 | } | 1575 | } |
@@ -1575,15 +1577,38 @@ static int ptrace_do_wait(struct wait_opts *wo, struct task_struct *tsk) | |||
1575 | return 0; | 1577 | return 0; |
1576 | } | 1578 | } |
1577 | 1579 | ||
1580 | static int child_wait_callback(wait_queue_t *wait, unsigned mode, | ||
1581 | int sync, void *key) | ||
1582 | { | ||
1583 | struct wait_opts *wo = container_of(wait, struct wait_opts, | ||
1584 | child_wait); | ||
1585 | struct task_struct *p = key; | ||
1586 | |||
1587 | if (!eligible_pid(wo, p)) | ||
1588 | return 0; | ||
1589 | |||
1590 | if ((wo->wo_flags & __WNOTHREAD) && wait->private != p->parent) | ||
1591 | return 0; | ||
1592 | |||
1593 | return default_wake_function(wait, mode, sync, key); | ||
1594 | } | ||
1595 | |||
1596 | void __wake_up_parent(struct task_struct *p, struct task_struct *parent) | ||
1597 | { | ||
1598 | __wake_up_sync_key(&parent->signal->wait_chldexit, | ||
1599 | TASK_INTERRUPTIBLE, 1, p); | ||
1600 | } | ||
1601 | |||
1578 | static long do_wait(struct wait_opts *wo) | 1602 | static long do_wait(struct wait_opts *wo) |
1579 | { | 1603 | { |
1580 | DECLARE_WAITQUEUE(wait, current); | ||
1581 | struct task_struct *tsk; | 1604 | struct task_struct *tsk; |
1582 | int retval; | 1605 | int retval; |
1583 | 1606 | ||
1584 | trace_sched_process_wait(wo->wo_pid); | 1607 | trace_sched_process_wait(wo->wo_pid); |
1585 | 1608 | ||
1586 | add_wait_queue(¤t->signal->wait_chldexit,&wait); | 1609 | init_waitqueue_func_entry(&wo->child_wait, child_wait_callback); |
1610 | wo->child_wait.private = current; | ||
1611 | add_wait_queue(¤t->signal->wait_chldexit, &wo->child_wait); | ||
1587 | repeat: | 1612 | repeat: |
1588 | /* | 1613 | /* |
1589 | * If there is nothing that can match our critiera just get out. | 1614 | * If there is nothing that can match our critiera just get out. |
@@ -1624,32 +1649,7 @@ notask: | |||
1624 | } | 1649 | } |
1625 | end: | 1650 | end: |
1626 | __set_current_state(TASK_RUNNING); | 1651 | __set_current_state(TASK_RUNNING); |
1627 | remove_wait_queue(¤t->signal->wait_chldexit,&wait); | 1652 | remove_wait_queue(¤t->signal->wait_chldexit, &wo->child_wait); |
1628 | if (wo->wo_info) { | ||
1629 | struct siginfo __user *infop = wo->wo_info; | ||
1630 | |||
1631 | if (retval > 0) | ||
1632 | retval = 0; | ||
1633 | else { | ||
1634 | /* | ||
1635 | * For a WNOHANG return, clear out all the fields | ||
1636 | * we would set so the user can easily tell the | ||
1637 | * difference. | ||
1638 | */ | ||
1639 | if (!retval) | ||
1640 | retval = put_user(0, &infop->si_signo); | ||
1641 | if (!retval) | ||
1642 | retval = put_user(0, &infop->si_errno); | ||
1643 | if (!retval) | ||
1644 | retval = put_user(0, &infop->si_code); | ||
1645 | if (!retval) | ||
1646 | retval = put_user(0, &infop->si_pid); | ||
1647 | if (!retval) | ||
1648 | retval = put_user(0, &infop->si_uid); | ||
1649 | if (!retval) | ||
1650 | retval = put_user(0, &infop->si_status); | ||
1651 | } | ||
1652 | } | ||
1653 | return retval; | 1653 | return retval; |
1654 | } | 1654 | } |
1655 | 1655 | ||
@@ -1694,6 +1694,29 @@ SYSCALL_DEFINE5(waitid, int, which, pid_t, upid, struct siginfo __user *, | |||
1694 | wo.wo_stat = NULL; | 1694 | wo.wo_stat = NULL; |
1695 | wo.wo_rusage = ru; | 1695 | wo.wo_rusage = ru; |
1696 | ret = do_wait(&wo); | 1696 | ret = do_wait(&wo); |
1697 | |||
1698 | if (ret > 0) { | ||
1699 | ret = 0; | ||
1700 | } else if (infop) { | ||
1701 | /* | ||
1702 | * For a WNOHANG return, clear out all the fields | ||
1703 | * we would set so the user can easily tell the | ||
1704 | * difference. | ||
1705 | */ | ||
1706 | if (!ret) | ||
1707 | ret = put_user(0, &infop->si_signo); | ||
1708 | if (!ret) | ||
1709 | ret = put_user(0, &infop->si_errno); | ||
1710 | if (!ret) | ||
1711 | ret = put_user(0, &infop->si_code); | ||
1712 | if (!ret) | ||
1713 | ret = put_user(0, &infop->si_pid); | ||
1714 | if (!ret) | ||
1715 | ret = put_user(0, &infop->si_uid); | ||
1716 | if (!ret) | ||
1717 | ret = put_user(0, &infop->si_status); | ||
1718 | } | ||
1719 | |||
1697 | put_pid(pid); | 1720 | put_pid(pid); |
1698 | 1721 | ||
1699 | /* avoid REGPARM breakage on x86: */ | 1722 | /* avoid REGPARM breakage on x86: */ |