#include <linux/freezer.h>
#include <linux/ptrace.h>
#include <linux/uaccess.h>
+#include <linux/cgroup.h>
#include <trace/events/sched.h>
static DEFINE_SPINLOCK(kthread_create_lock);
ret = -EINTR;
if (!test_bit(KTHREAD_SHOULD_STOP, &self->flags)) {
+ cgroup_kthread_ready();
__kthread_parkme(self);
ret = threadfn(data);
}
* new kernel thread.
*/
if (unlikely(wait_for_completion_killable(&done))) {
+ int i = 0;
+
+ /*
+ * I got SIGKILL, but wait for 10 more seconds for completion
+ * unless chosen by the OOM killer. This delay is there as a
+ * workaround for boot failure caused by SIGKILL upon device
+ * driver initialization timeout.
+ */
+ while (i++ < 10 && !test_tsk_thread_flag(current, TIF_MEMDIE))
+ if (wait_for_completion_timeout(&done, HZ))
+ goto ready;
/*
* If I was SIGKILLed before kthreadd (or new kernel thread)
* calls complete(), leave the cleanup of this structure to
*/
wait_for_completion(&done);
}
+ready:
task = create->result;
if (!IS_ERR(task)) {
static const struct sched_param param = { .sched_priority = 0 };
set_mems_allowed(node_states[N_MEMORY]);
current->flags |= PF_NOFREEZE;
+ cgroup_init_kthreadd();
for (;;) {
set_current_state(TASK_INTERRUPTIBLE);