[PATCH 1/3] mm: memdelay: fix task flags race condition

From: Johannes Weiner
Date: Thu Oct 05 2017 - 12:32:47 EST


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 <hannes@xxxxxxxxxxx>
---
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


--0F1p//8PRICkK4MW
Content-Type: text/x-diff; charset=us-ascii
Content-Disposition: attachment; filename="0002-mm-memdelay-idle-time-is-not-productive-time.patch"