Revision b1dd693e5b9348bd68a80e679e03cf9c0973b01b authored by Daisuke Nishimura on 24 November 2010, 20:57:06 UTC, committed by Linus Torvalds on 24 November 2010, 21:50:44 UTC
__mem_cgroup_try_charge() can be called under down_write(&mmap_sem)(e.g.
mlock does it). This means it can cause deadlock if it races with move charge:

Ex.1)
                move charge             |        try charge
  --------------------------------------+------------------------------
    mem_cgroup_can_attach()             |  down_write(&mmap_sem)
      mc.moving_task = current          |    ..
      mem_cgroup_precharge_mc()         |  __mem_cgroup_try_charge()
        mem_cgroup_count_precharge()    |    prepare_to_wait()
          down_read(&mmap_sem)          |    if (mc.moving_task)
          -> cannot aquire the lock     |    -> true
                                        |      schedule()

Ex.2)
                move charge             |        try charge
  --------------------------------------+------------------------------
    mem_cgroup_can_attach()             |
      mc.moving_task = current          |
      mem_cgroup_precharge_mc()         |
        mem_cgroup_count_precharge()    |
          down_read(&mmap_sem)          |
          ..                            |
          up_read(&mmap_sem)            |
                                        |  down_write(&mmap_sem)
    mem_cgroup_move_task()              |    ..
      mem_cgroup_move_charge()          |  __mem_cgroup_try_charge()
        down_read(&mmap_sem)            |    prepare_to_wait()
        -> cannot aquire the lock       |    if (mc.moving_task)
                                        |    -> true
                                        |      schedule()

To avoid this deadlock, we do all the move charge works (both can_attach() and
attach()) under one mmap_sem section.
And after this patch, we set/clear mc.moving_task outside mc.lock, because we
use the lock only to check mc.from/to.

Signed-off-by: Daisuke Nishimura <nishimura@mxp.nes.nec.co.jp>
Cc: Balbir Singh <balbir@linux.vnet.ibm.com>
Acked-by: KAMEZAWA Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com>
Cc: <stable@kernel.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
1 parent 11e7946
History
File Mode Size
Kconfig -rw-r--r-- 9.9 KB
Kconfig.debug -rw-r--r-- 1014 bytes
Makefile -rw-r--r-- 1.6 KB
backing-dev.c -rw-r--r-- 20.9 KB
bootmem.c -rw-r--r-- 24.4 KB
bounce.c -rw-r--r-- 6.5 KB
compaction.c -rw-r--r-- 16.2 KB
debug-pagealloc.c -rw-r--r-- 2.5 KB
dmapool.c -rw-r--r-- 13.0 KB
fadvise.c -rw-r--r-- 3.5 KB
failslab.c -rw-r--r-- 1.6 KB
filemap.c -rw-r--r-- 66.4 KB
filemap_xip.c -rw-r--r-- 11.0 KB
fremap.c -rw-r--r-- 6.7 KB
highmem.c -rw-r--r-- 10.3 KB
hugetlb.c -rw-r--r-- 76.9 KB
hwpoison-inject.c -rw-r--r-- 3.3 KB
init-mm.c -rw-r--r-- 647 bytes
internal.h -rw-r--r-- 7.1 KB
kmemcheck.c -rw-r--r-- 2.8 KB
kmemleak-test.c -rw-r--r-- 3.3 KB
kmemleak.c -rw-r--r-- 49.6 KB
ksm.c -rw-r--r-- 52.5 KB
maccess.c -rw-r--r-- 1.6 KB
madvise.c -rw-r--r-- 11.3 KB
memblock.c -rw-r--r-- 22.5 KB
memcontrol.c -rw-r--r-- 126.3 KB
memory-failure.c -rw-r--r-- 38.6 KB
memory.c -rw-r--r-- 97.5 KB
memory_hotplug.c -rw-r--r-- 21.8 KB
mempolicy.c -rw-r--r-- 67.4 KB
mempool.c -rw-r--r-- 8.9 KB
migrate.c -rw-r--r-- 31.0 KB
mincore.c -rw-r--r-- 7.6 KB
mlock.c -rw-r--r-- 15.5 KB
mm_init.c -rw-r--r-- 3.7 KB
mmap.c -rw-r--r-- 69.4 KB
mmu_context.c -rw-r--r-- 1.4 KB
mmu_notifier.c -rw-r--r-- 8.8 KB
mmzone.c -rw-r--r-- 2.5 KB
mprotect.c -rw-r--r-- 7.6 KB
mremap.c -rw-r--r-- 13.0 KB
msync.c -rw-r--r-- 2.4 KB
nommu.c -rw-r--r-- 49.7 KB
oom_kill.c -rw-r--r-- 21.2 KB
page-writeback.c -rw-r--r-- 39.0 KB
page_alloc.c -rw-r--r-- 152.4 KB
page_cgroup.c -rw-r--r-- 11.4 KB
page_io.c -rw-r--r-- 3.2 KB
page_isolation.c -rw-r--r-- 3.6 KB
pagewalk.c -rw-r--r-- 4.7 KB
percpu-km.c -rw-r--r-- 2.8 KB
percpu-vm.c -rw-r--r-- 13.0 KB
percpu.c -rw-r--r-- 55.5 KB
prio_tree.c -rw-r--r-- 6.3 KB
quicklist.c -rw-r--r-- 2.4 KB
readahead.c -rw-r--r-- 15.4 KB
rmap.c -rw-r--r-- 45.4 KB
shmem.c -rw-r--r-- 71.6 KB
slab.c -rw-r--r-- 118.3 KB
slob.c -rw-r--r-- 17.2 KB
slub.c -rw-r--r-- 110.6 KB
sparse-vmemmap.c -rw-r--r-- 5.9 KB
sparse.c -rw-r--r-- 20.5 KB
swap.c -rw-r--r-- 13.0 KB
swap_state.c -rw-r--r-- 10.4 KB
swapfile.c -rw-r--r-- 65.3 KB
thrash.c -rw-r--r-- 1.9 KB
truncate.c -rw-r--r-- 16.4 KB
util.c -rw-r--r-- 7.3 KB
vmalloc.c -rw-r--r-- 62.4 KB
vmscan.c -rw-r--r-- 84.0 KB
vmstat.c -rw-r--r-- 29.3 KB

back to top