>From 7318c963a582833d4556c51fc2e1658e00c14e3e Mon Sep 17 00:00:00 2001 From: Johannes Weiner Date: Thu, 5 Oct 2017 12:32:47 -0400 Subject: [PATCH 1/3] mm: memdelay: fix task flags race condition WARNING: CPU: 35 PID: 2263 at ../include/linux/memcontrol.h:466 This is memcg warning that current->memcg_may_oom is set when it doesn't expect it to. The warning came in new with the memdelay patches. They add another task flag in the same int as memcg_may_oom, but modify it from try_to_wake_up, from a task that isn't current. This isn't safe. Move the flag to the other int holding task flags, whose modifications are serialized through the scheduler locks. Signed-off-by: Johannes Weiner --- include/linux/sched.h | 2 +- kernel/sched/core.c | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/include/linux/sched.h b/include/linux/sched.h index de15e3c8c43a..d1aa8f4c19ab 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h @@ -627,6 +627,7 @@ struct task_struct { unsigned sched_contributes_to_load:1; unsigned sched_migrated:1; unsigned sched_remote_wakeup:1; + unsigned sched_memdelay_requeue:1; /* Force alignment to the next boundary: */ unsigned :0; @@ -651,7 +652,6 @@ struct task_struct { /* disallow userland-initiated cgroup migration */ unsigned no_cgroup_migration:1; #endif - unsigned memdelay_migrate_enqueue:1; unsigned long atomic_flags; /* Flags requiring atomic access. */ diff --git a/kernel/sched/core.c b/kernel/sched/core.c index bf105c870da6..b4fa806bf153 100644 --- a/kernel/sched/core.c +++ b/kernel/sched/core.c @@ -760,10 +760,10 @@ static inline void enqueue_task(struct rq *rq, struct task_struct *p, int flags) if (!(flags & ENQUEUE_RESTORE)) sched_info_queued(rq, p); - WARN_ON_ONCE(!(flags & ENQUEUE_WAKEUP) && p->memdelay_migrate_enqueue); - if (!(flags & ENQUEUE_WAKEUP) || p->memdelay_migrate_enqueue) { + WARN_ON_ONCE(!(flags & ENQUEUE_WAKEUP) && p->sched_memdelay_requeue); + if (!(flags & ENQUEUE_WAKEUP) || p->sched_memdelay_requeue) { memdelay_add_runnable(p); - p->memdelay_migrate_enqueue = 0; + p->sched_memdelay_requeue = 0; } else { memdelay_wakeup(p); } @@ -2065,8 +2065,8 @@ try_to_wake_up(struct task_struct *p, unsigned int state, int wake_flags) rq = __task_rq_lock(p, &rf); memdelay_del_sleeping(p); + p->sched_memdelay_requeue = 1; __task_rq_unlock(rq, &rf); - p->memdelay_migrate_enqueue = 1; set_task_cpu(p, cpu); } -- 2.14.2