diff options
| author | Arnd Bergmann <arnd@arndb.de> | 2012-03-24 15:13:59 -0400 |
|---|---|---|
| committer | Arnd Bergmann <arnd@arndb.de> | 2012-03-24 15:13:59 -0400 |
| commit | 83fe628e16d84efc8df2731bc403eae4e4f53801 (patch) | |
| tree | 9a51c292235621d0f4f632c2a55ddb5a6ab582af /kernel | |
| parent | 853a0231e057c04255a848f6998f84faaa635c58 (diff) | |
| parent | 426f1af947c61dee48a9267f84bff227e503a547 (diff) | |
Merge branch 'renesas/soc' into next/soc2
Diffstat (limited to 'kernel')
| -rw-r--r-- | kernel/fork.c | 60 | ||||
| -rw-r--r-- | kernel/hung_task.c | 11 | ||||
| -rw-r--r-- | kernel/irq/manage.c | 44 | ||||
| -rw-r--r-- | kernel/kprobes.c | 12 | ||||
| -rw-r--r-- | kernel/printk.c | 6 | ||||
| -rw-r--r-- | kernel/sched/core.c | 4 | ||||
| -rw-r--r-- | kernel/workqueue.c | 7 |
7 files changed, 105 insertions, 39 deletions
diff --git a/kernel/fork.c b/kernel/fork.c index e2cd3e2a5ae8..26a7a6707fa7 100644 --- a/kernel/fork.c +++ b/kernel/fork.c | |||
| @@ -668,6 +668,38 @@ struct mm_struct *mm_access(struct task_struct *task, unsigned int mode) | |||
| 668 | return mm; | 668 | return mm; |
| 669 | } | 669 | } |
| 670 | 670 | ||
| 671 | static void complete_vfork_done(struct task_struct *tsk) | ||
| 672 | { | ||
| 673 | struct completion *vfork; | ||
| 674 | |||
| 675 | task_lock(tsk); | ||
| 676 | vfork = tsk->vfork_done; | ||
| 677 | if (likely(vfork)) { | ||
| 678 | tsk->vfork_done = NULL; | ||
| 679 | complete(vfork); | ||
| 680 | } | ||
| 681 | task_unlock(tsk); | ||
| 682 | } | ||
| 683 | |||
| 684 | static int wait_for_vfork_done(struct task_struct *child, | ||
| 685 | struct completion *vfork) | ||
| 686 | { | ||
| 687 | int killed; | ||
| 688 | |||
| 689 | freezer_do_not_count(); | ||
| 690 | killed = wait_for_completion_killable(vfork); | ||
| 691 | freezer_count(); | ||
| 692 | |||
| 693 | if (killed) { | ||
| 694 | task_lock(child); | ||
| 695 | child->vfork_done = NULL; | ||
| 696 | task_unlock(child); | ||
| 697 | } | ||
| 698 | |||
| 699 | put_task_struct(child); | ||
| 700 | return killed; | ||
| 701 | } | ||
| 702 | |||
| 671 | /* Please note the differences between mmput and mm_release. | 703 | /* Please note the differences between mmput and mm_release. |
| 672 | * mmput is called whenever we stop holding onto a mm_struct, | 704 | * mmput is called whenever we stop holding onto a mm_struct, |
| 673 | * error success whatever. | 705 | * error success whatever. |
| @@ -683,8 +715,6 @@ struct mm_struct *mm_access(struct task_struct *task, unsigned int mode) | |||
| 683 | */ | 715 | */ |
| 684 | void mm_release(struct task_struct *tsk, struct mm_struct *mm) | 716 | void mm_release(struct task_struct *tsk, struct mm_struct *mm) |
| 685 | { | 717 | { |
| 686 | struct completion *vfork_done = tsk->vfork_done; | ||
| 687 | |||
| 688 | /* Get rid of any futexes when releasing the mm */ | 718 | /* Get rid of any futexes when releasing the mm */ |
| 689 | #ifdef CONFIG_FUTEX | 719 | #ifdef CONFIG_FUTEX |
| 690 | if (unlikely(tsk->robust_list)) { | 720 | if (unlikely(tsk->robust_list)) { |
| @@ -704,17 +734,15 @@ void mm_release(struct task_struct *tsk, struct mm_struct *mm) | |||
| 704 | /* Get rid of any cached register state */ | 734 | /* Get rid of any cached register state */ |
| 705 | deactivate_mm(tsk, mm); | 735 | deactivate_mm(tsk, mm); |
| 706 | 736 | ||
| 707 | /* notify parent sleeping on vfork() */ | 737 | if (tsk->vfork_done) |
| 708 | if (vfork_done) { | 738 | complete_vfork_done(tsk); |
| 709 | tsk->vfork_done = NULL; | ||
| 710 | complete(vfork_done); | ||
| 711 | } | ||
| 712 | 739 | ||
| 713 | /* | 740 | /* |
| 714 | * If we're exiting normally, clear a user-space tid field if | 741 | * If we're exiting normally, clear a user-space tid field if |
| 715 | * requested. We leave this alone when dying by signal, to leave | 742 | * requested. We leave this alone when dying by signal, to leave |
| 716 | * the value intact in a core dump, and to save the unnecessary | 743 | * the value intact in a core dump, and to save the unnecessary |
| 717 | * trouble otherwise. Userland only wants this done for a sys_exit. | 744 | * trouble, say, a killed vfork parent shouldn't touch this mm. |
| 745 | * Userland only wants this done for a sys_exit. | ||
| 718 | */ | 746 | */ |
| 719 | if (tsk->clear_child_tid) { | 747 | if (tsk->clear_child_tid) { |
| 720 | if (!(tsk->flags & PF_SIGNALED) && | 748 | if (!(tsk->flags & PF_SIGNALED) && |
| @@ -1018,7 +1046,6 @@ static void copy_flags(unsigned long clone_flags, struct task_struct *p) | |||
| 1018 | 1046 | ||
| 1019 | new_flags &= ~(PF_SUPERPRIV | PF_WQ_WORKER); | 1047 | new_flags &= ~(PF_SUPERPRIV | PF_WQ_WORKER); |
| 1020 | new_flags |= PF_FORKNOEXEC; | 1048 | new_flags |= PF_FORKNOEXEC; |
| 1021 | new_flags |= PF_STARTING; | ||
| 1022 | p->flags = new_flags; | 1049 | p->flags = new_flags; |
| 1023 | } | 1050 | } |
| 1024 | 1051 | ||
| @@ -1548,16 +1575,9 @@ long do_fork(unsigned long clone_flags, | |||
| 1548 | if (clone_flags & CLONE_VFORK) { | 1575 | if (clone_flags & CLONE_VFORK) { |
| 1549 | p->vfork_done = &vfork; | 1576 | p->vfork_done = &vfork; |
| 1550 | init_completion(&vfork); | 1577 | init_completion(&vfork); |
| 1578 | get_task_struct(p); | ||
| 1551 | } | 1579 | } |
| 1552 | 1580 | ||
| 1553 | /* | ||
| 1554 | * We set PF_STARTING at creation in case tracing wants to | ||
| 1555 | * use this to distinguish a fully live task from one that | ||
| 1556 | * hasn't finished SIGSTOP raising yet. Now we clear it | ||
| 1557 | * and set the child going. | ||
| 1558 | */ | ||
| 1559 | p->flags &= ~PF_STARTING; | ||
| 1560 | |||
| 1561 | wake_up_new_task(p); | 1581 | wake_up_new_task(p); |
| 1562 | 1582 | ||
| 1563 | /* forking complete and child started to run, tell ptracer */ | 1583 | /* forking complete and child started to run, tell ptracer */ |
| @@ -1565,10 +1585,8 @@ long do_fork(unsigned long clone_flags, | |||
| 1565 | ptrace_event(trace, nr); | 1585 | ptrace_event(trace, nr); |
| 1566 | 1586 | ||
| 1567 | if (clone_flags & CLONE_VFORK) { | 1587 | if (clone_flags & CLONE_VFORK) { |
| 1568 | freezer_do_not_count(); | 1588 | if (!wait_for_vfork_done(p, &vfork)) |
| 1569 | wait_for_completion(&vfork); | 1589 | ptrace_event(PTRACE_EVENT_VFORK_DONE, nr); |
| 1570 | freezer_count(); | ||
| 1571 | ptrace_event(PTRACE_EVENT_VFORK_DONE, nr); | ||
| 1572 | } | 1590 | } |
| 1573 | } else { | 1591 | } else { |
| 1574 | nr = PTR_ERR(p); | 1592 | nr = PTR_ERR(p); |
diff --git a/kernel/hung_task.c b/kernel/hung_task.c index 2e48ec0c2e91..c21449f85a2a 100644 --- a/kernel/hung_task.c +++ b/kernel/hung_task.c | |||
| @@ -119,15 +119,20 @@ static void check_hung_task(struct task_struct *t, unsigned long timeout) | |||
| 119 | * For preemptible RCU it is sufficient to call rcu_read_unlock in order | 119 | * For preemptible RCU it is sufficient to call rcu_read_unlock in order |
| 120 | * to exit the grace period. For classic RCU, a reschedule is required. | 120 | * to exit the grace period. For classic RCU, a reschedule is required. |
| 121 | */ | 121 | */ |
| 122 | static void rcu_lock_break(struct task_struct *g, struct task_struct *t) | 122 | static bool rcu_lock_break(struct task_struct *g, struct task_struct *t) |
| 123 | { | 123 | { |
| 124 | bool can_cont; | ||
| 125 | |||
| 124 | get_task_struct(g); | 126 | get_task_struct(g); |
| 125 | get_task_struct(t); | 127 | get_task_struct(t); |
| 126 | rcu_read_unlock(); | 128 | rcu_read_unlock(); |
| 127 | cond_resched(); | 129 | cond_resched(); |
| 128 | rcu_read_lock(); | 130 | rcu_read_lock(); |
| 131 | can_cont = pid_alive(g) && pid_alive(t); | ||
| 129 | put_task_struct(t); | 132 | put_task_struct(t); |
| 130 | put_task_struct(g); | 133 | put_task_struct(g); |
| 134 | |||
| 135 | return can_cont; | ||
| 131 | } | 136 | } |
| 132 | 137 | ||
| 133 | /* | 138 | /* |
| @@ -154,9 +159,7 @@ static void check_hung_uninterruptible_tasks(unsigned long timeout) | |||
| 154 | goto unlock; | 159 | goto unlock; |
| 155 | if (!--batch_count) { | 160 | if (!--batch_count) { |
| 156 | batch_count = HUNG_TASK_BATCHING; | 161 | batch_count = HUNG_TASK_BATCHING; |
| 157 | rcu_lock_break(g, t); | 162 | if (!rcu_lock_break(g, t)) |
| 158 | /* Exit if t or g was unhashed during refresh. */ | ||
| 159 | if (t->state == TASK_DEAD || g->state == TASK_DEAD) | ||
| 160 | goto unlock; | 163 | goto unlock; |
| 161 | } | 164 | } |
| 162 | /* use "==" to skip the TASK_KILLABLE tasks waiting on NFS */ | 165 | /* use "==" to skip the TASK_KILLABLE tasks waiting on NFS */ |
diff --git a/kernel/irq/manage.c b/kernel/irq/manage.c index 32313c084442..0f0d4704ddd8 100644 --- a/kernel/irq/manage.c +++ b/kernel/irq/manage.c | |||
| @@ -985,6 +985,11 @@ __setup_irq(unsigned int irq, struct irq_desc *desc, struct irqaction *new) | |||
| 985 | 985 | ||
| 986 | /* add new interrupt at end of irq queue */ | 986 | /* add new interrupt at end of irq queue */ |
| 987 | do { | 987 | do { |
| 988 | /* | ||
| 989 | * Or all existing action->thread_mask bits, | ||
| 990 | * so we can find the next zero bit for this | ||
| 991 | * new action. | ||
| 992 | */ | ||
| 988 | thread_mask |= old->thread_mask; | 993 | thread_mask |= old->thread_mask; |
| 989 | old_ptr = &old->next; | 994 | old_ptr = &old->next; |
| 990 | old = *old_ptr; | 995 | old = *old_ptr; |
| @@ -993,14 +998,41 @@ __setup_irq(unsigned int irq, struct irq_desc *desc, struct irqaction *new) | |||
| 993 | } | 998 | } |
| 994 | 999 | ||
| 995 | |||
