• Tejun Heo's avatar
    memcg: mem_cgroup_migrate() may be called with irq disabled · d93c4130
    Tejun Heo authored
    mem_cgroup_migrate() uses local_irq_disable/enable() but can be called
    with irq disabled from migrate_page_copy().  This ends up enabling irq
    while holding a irq context lock triggering the following lockdep
    warning.  Fix it by using irq_save/restore instead.
    
      =================================
      [ INFO: inconsistent lock state ]
      4.7.0-rc1+ #52 Tainted: G        W
      ---------------------------------
      inconsistent {IN-SOFTIRQ-W} -> {SOFTIRQ-ON-W} usage.
      kcompactd0/151 [HC0[0]:SC0[0]:HE1:SE1] takes:
       (&(&ctx->completion_lock)->rlock){+.?.-.}, at: [<000000000038fd96>] aio_migratepage+0x156/0x1e8
      {IN-SOFTIRQ-W} state was registered at:
         __lock_acquire+0x5b6/0x1930
         lock_acquire+0xee/0x270
         _raw_spin_lock_irqsave+0x66/0xb0
         aio_complete+0x98/0x328
         dio_complete+0xe4/0x1e0
         blk_update_request+0xd4/0x450
         scsi_end_request+0x48/0x1c8
         scsi_io_completion+0x272/0x698
         blk_done_softirq+0xca/0xe8
         __do_softirq+0xc8/0x518
         irq_exit+0xee/0x110
         do_IRQ+0x6a/0x88
         io_int_handler+0x11a/0x25c
         __mutex_unlock_slowpath+0x144/0x1d8
         __mutex_unlock_slowpath+0x140/0x1d8
         kernfs_iop_permission+0x64/0x80
         __inode_permission+0x9e/0xf0
         link_path_walk+0x6e/0x510
         path_lookupat+0xc4/0x1a8
         filename_lookup+0x9c/0x160
         user_path_at_empty+0x5c/0x70
         SyS_readlinkat+0x68/0x140
         system_call+0xd6/0x270
      irq event stamp: 971410
      hardirqs last  enabled at (971409):  migrate_page_move_mapping+0x3ea/0x588
      hardirqs last disabled at (971410):  _raw_spin_lock_irqsave+0x3c/0xb0
      softirqs last  enabled at (970526):  __do_softirq+0x460/0x518
      softirqs last disabled at (970519):  irq_exit+0xee/0x110
    
      other info that might help us debug this:
       Possible unsafe locking scenario:
    
    	 CPU0
    	 ----
        lock(&(&ctx->completion_lock)->rlock);
        <Interrupt>
          lock(&(&ctx->completion_lock)->rlock);
    
        *** DEADLOCK ***
    
      3 locks held by kcompactd0/151:
       #0:  (&(&mapping->private_lock)->rlock){+.+.-.}, at:  aio_migratepage+0x42/0x1e8
       #1:  (&ctx->ring_lock){+.+.+.}, at:  aio_migratepage+0x5a/0x1e8
       #2:  (&(&ctx->completion_lock)->rlock){+.?.-.}, at:  aio_migratepage+0x156/0x1e8
    
      stack backtrace:
      CPU: 20 PID: 151 Comm: kcompactd0 Tainted: G        W       4.7.0-rc1+ #52
      Call Trace:
        show_trace+0xea/0xf0
        show_stack+0x72/0xf0
        dump_stack+0x9a/0xd8
        print_usage_bug.part.27+0x2d4/0x2e8
        mark_lock+0x17e/0x758
        mark_held_locks+0xa2/0xd0
        trace_hardirqs_on_caller+0x140/0x1c0
        mem_cgroup_migrate+0x266/0x370
        aio_migratepage+0x16a/0x1e8
        move_to_new_page+0xb0/0x260
        migrate_pages+0x8f4/0x9f0
        compact_zone+0x4dc/0xdc8
        kcompactd_do_work+0x1aa/0x358
        kcompactd+0xba/0x2c8
        kthread+0x10a/0x110
        kernel_thread_starter+0x6/0xc
        kernel_thread_starter+0x0/0xc
      INFO: lockdep is turned off.
    
    Link: http://lkml.kernel.org/r/20160620184158.GO3262@mtj.duckdns.org
    Link: http://lkml.kernel.org/g/5767CFE5.7080904@de.ibm.com
    Fixes: 74485cf2 ("mm: migrate: consolidate mem_cgroup_migrate() calls")
    Signed-off-by: default avatarTejun Heo <tj@kernel.org>
    Reported-by: default avatarChristian Borntraeger <borntraeger@de.ibm.com>
    Acked-by: default avatarJohannes Weiner <hannes@cmpxchg.org>
    Acked-by: default avatarMichal Hocko <mhocko@suse.com>
    Reviewed-by: default avatarVladimir Davydov <vdavydov@virtuozzo.com>
    Cc: <stable@vger.kernel.org>	[4.5+]
    Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
    Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
    d93c4130
Name
Last commit
Last update
..
kasan Loading commit data...
Kconfig Loading commit data...
Kconfig.debug Loading commit data...
Makefile Loading commit data...
backing-dev.c Loading commit data...
balloon_compaction.c Loading commit data...
bootmem.c Loading commit data...
cleancache.c Loading commit data...
cma.c Loading commit data...
cma.h Loading commit data...
cma_debug.c Loading commit data...
compaction.c Loading commit data...
debug.c Loading commit data...
debug_page_ref.c Loading commit data...
dmapool.c Loading commit data...
early_ioremap.c Loading commit data...
fadvise.c Loading commit data...
failslab.c Loading commit data...
filemap.c Loading commit data...
frame_vector.c Loading commit data...
frontswap.c Loading commit data...
gup.c Loading commit data...
highmem.c Loading commit data...
huge_memory.c Loading commit data...
hugetlb.c Loading commit data...
hugetlb_cgroup.c Loading commit data...
hwpoison-inject.c Loading commit data...
init-mm.c Loading commit data...
internal.h Loading commit data...
interval_tree.c Loading commit data...
kmemcheck.c Loading commit data...
kmemleak-test.c Loading commit data...
kmemleak.c Loading commit data...
ksm.c Loading commit data...
list_lru.c Loading commit data...
maccess.c Loading commit data...
madvise.c Loading commit data...
memblock.c Loading commit data...
memcontrol.c Loading commit data...
memory-failure.c Loading commit data...
memory.c Loading commit data...
memory_hotplug.c Loading commit data...
mempolicy.c Loading commit data...
mempool.c Loading commit data...
memtest.c Loading commit data...
migrate.c Loading commit data...
mincore.c Loading commit data...
mlock.c Loading commit data...
mm_init.c Loading commit data...
mmap.c Loading commit data...
mmu_context.c Loading commit data...
mmu_notifier.c Loading commit data...
mmzone.c Loading commit data...
mprotect.c Loading commit data...
mremap.c Loading commit data...
msync.c Loading commit data...
nobootmem.c Loading commit data...
nommu.c Loading commit data...
oom_kill.c Loading commit data...
page-writeback.c Loading commit data...
page_alloc.c Loading commit data...
page_counter.c Loading commit data...
page_ext.c Loading commit data...
page_idle.c Loading commit data...
page_io.c Loading commit data...
page_isolation.c Loading commit data...
page_owner.c Loading commit data...
page_poison.c Loading commit data...
pagewalk.c Loading commit data...
percpu-km.c Loading commit data...
percpu-vm.c Loading commit data...
percpu.c Loading commit data...
pgtable-generic.c Loading commit data...
process_vm_access.c Loading commit data...
quicklist.c Loading commit data...
readahead.c Loading commit data...
rmap.c Loading commit data...
shmem.c Loading commit data...
slab.c Loading commit data...
slab.h Loading commit data...
slab_common.c Loading commit data...
slob.c Loading commit data...
slub.c Loading commit data...
sparse-vmemmap.c Loading commit data...
sparse.c Loading commit data...
swap.c Loading commit data...
swap_cgroup.c Loading commit data...
swap_state.c Loading commit data...
swapfile.c Loading commit data...
truncate.c Loading commit data...
userfaultfd.c Loading commit data...
util.c Loading commit data...
vmacache.c Loading commit data...
vmalloc.c Loading commit data...
vmpressure.c Loading commit data...
vmscan.c Loading commit data...
vmstat.c Loading commit data...
workingset.c Loading commit data...
z3fold.c Loading commit data...
zbud.c Loading commit data...
zpool.c Loading commit data...
zsmalloc.c Loading commit data...
zswap.c Loading commit data...