diff --git a/kernel/exit.c b/kernel/exit.c index c536da8538731763523b1ac7d382e0e75884b90c..1ddcc422bccd46396c6ef9332a6e0daeabce2abf 100644 --- a/kernel/exit.c +++ b/kernel/exit.c @@ -710,10 +710,17 @@ static void forget_original_parent(struct task_struct *father, static void exit_notify(struct task_struct *tsk, int group_dead) { bool autoreap; + unsigned long flags; struct task_struct *p, *n; LIST_HEAD(dead); - write_lock_irq(&tasklist_lock); +retry: + if (!write_trylock_irqsave(&tasklist_lock, flags)) { + if (!in_atomic() && !irqs_disabled()) + cond_resched(); + goto retry; + } + forget_original_parent(tsk, &dead); if (group_dead) diff --git a/kernel/fork.c b/kernel/fork.c index 23302e2bc7bf1b685be1698899928fd5c2430d5b..4fd1f435ce86bfe562070eecc2d07c922cee7c81 100644 --- a/kernel/fork.c +++ b/kernel/fork.c @@ -1658,6 +1658,7 @@ static __latent_entropy struct task_struct *copy_process( int retval; struct task_struct *p; struct multiprocess_signals delayed; + unsigned long flags; /* * Don't allow sharing the root directory with processes in a different @@ -1986,7 +1987,11 @@ static __latent_entropy struct task_struct *copy_process( * Make it visible to the rest of the system, but dont wake it up yet. * Need tasklist lock for parent etc handling! */ - write_lock_irq(&tasklist_lock); +retry: + if (!write_trylock_irqsave(&tasklist_lock, flags)) { + cond_resched(); + goto retry; + } /* CLONE_PARENT re-uses the old parent */ if (clone_flags & (CLONE_PARENT|CLONE_THREAD)) {