• Johannes Weiner's avatar
    mm: vmscan: clear kswapd's special reclaim powers before exiting · e70d6e73
    Johannes Weiner authored
    commit 71abdc15 upstream.
    
    When kswapd exits, it can end up taking locks that were previously held
    by allocating tasks while they waited for reclaim.  Lockdep currently
    warns about this:
    
    On Wed, May 28, 2014 at 06:06:34PM +0800, Gu Zheng wrote:
    >  inconsistent {RECLAIM_FS-ON-W} -> {IN-RECLAIM_FS-R} usage.
    >  kswapd2/1151 [HC0[0]:SC0[0]:HE1:SE1] takes:
    >   (&sig->group_rwsem){+++++?}, at: exit_signals+0x24/0x130
    >  {RECLAIM_FS-ON-W} state was registered at:
    >     mark_held_locks+0xb9/0x140
    >     lockdep_trace_alloc+0x7a/0xe0
    >     kmem_cache_alloc_trace+0x37/0x240
    >     flex_array_alloc+0x99/0x1a0
    >     cgroup_attach_task+0x63/0x430
    >     attach_task_by_pid+0x210/0x280
    >     cgroup_procs_write+0x16/0x20
    >     cgroup_file_write+0x120/0x2c0
    >     vfs_write+0xc0/0x1f0
    >     SyS_write+0x4c/0xa0
    >     tracesys+0xdd/0xe2
    >  irq event stamp: 49
    >  hardirqs last  enabled at (49):  _raw_spin_unlock_irqrestore+0x36/0x70
    >  hardirqs last disabled at (48):  _raw_spin_lock_irqsave+0x2b/0xa0
    >  softirqs last  enabled at (0):  copy_process.part.24+0x627/0x15f0
    >  softirqs last disabled at (0):            (null)
    >
    >  other info that might help us debug this:
    >   Possible unsafe locking scenario:
    >
    >         CPU0
    >         ----
    >    lock(&sig->group_rwsem);
    >    <Interrupt>
    >      lock(&sig->group_rwsem);
    >
    >   *** DEADLOCK ***
    >
    >  no locks held by kswapd2/1151.
    >
    >  stack backtrace:
    >  CPU: 30 PID: 1151 Comm: kswapd2 Not tainted 3.10.39+ #4
    >  Call Trace:
    >    dump_stack+0x19/0x1b
    >    print_usage_bug+0x1f7/0x208
    >    mark_lock+0x21d/0x2a0
    >    __lock_acquire+0x52a/0xb60
    >    lock_acquire+0xa2/0x140
    >    down_read+0x51/0xa0
    >    exit_signals+0x24/0x130
    >    do_exit+0xb5/0xa50
    >    kthread+0xdb/0x100
    >    ret_from_fork+0x7c/0xb0
    
    This is because the kswapd thread is still marked as a reclaimer at the
    time of exit.  But because it is exiting, nobody is actually waiting on
    it to make reclaim progress anymore, and it's nothing but a regular
    thread at this point.  Be tidy and strip it of all its powers
    (PF_MEMALLOC, PF_SWAPWRITE, PF_KSWAPD, and the lockdep reclaim state)
    before returning from the thread function.
    Signed-off-by: default avatarJohannes Weiner <hannes@cmpxchg.org>
    Reported-by: default avatarGu Zheng <guz.fnst@cn.fujitsu.com>
    Cc: Yasuaki Ishimatsu <isimatu.yasuaki@jp.fujitsu.com>
    Cc: Tang Chen <tangchen@cn.fujitsu.com>
    Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
    Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
    Signed-off-by: default avatarBen Hutchings <ben@decadent.org.uk>
    e70d6e73
vmscan.c 99.9 KB