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
netfilter
Kconfig -rw-r--r-- 6.9 KB
Makefile -rw-r--r-- 1.4 KB
addrconf.c -rw-r--r-- 113.1 KB
addrconf_core.c -rw-r--r-- 2.4 KB
addrlabel.c -rw-r--r-- 13.8 KB
af_inet6.c -rw-r--r-- 30.1 KB
ah6.c -rw-r--r-- 17.5 KB
anycast.c -rw-r--r-- 11.5 KB
datagram.c -rw-r--r-- 20.0 KB
esp6.c -rw-r--r-- 13.8 KB
exthdrs.c -rw-r--r-- 21.2 KB
exthdrs_core.c -rw-r--r-- 3.2 KB
fib6_rules.c -rw-r--r-- 6.8 KB
icmp.c -rw-r--r-- 21.3 KB
inet6_connection_sock.c -rw-r--r-- 6.2 KB
inet6_hashtables.c -rw-r--r-- 8.0 KB
ip6_fib.c -rw-r--r-- 32.8 KB
ip6_flowlabel.c -rw-r--r-- 17.3 KB
ip6_input.c -rw-r--r-- 7.6 KB
ip6_output.c -rw-r--r-- 38.7 KB
ip6_tunnel.c -rw-r--r-- 36.3 KB
ip6mr.c -rw-r--r-- 49.0 KB
ipcomp6.c -rw-r--r-- 5.4 KB
ipv6_sockglue.c -rw-r--r-- 27.2 KB
mcast.c -rw-r--r-- 62.5 KB
mip6.c -rw-r--r-- 13.2 KB
ndisc.c -rw-r--r-- 45.4 KB
netfilter.c -rw-r--r-- 4.4 KB
proc.c -rw-r--r-- 10.3 KB
protocol.c -rw-r--r-- 1.6 KB
raw.c -rw-r--r-- 30.8 KB
reassembly.c -rw-r--r-- 18.9 KB
route.c -rw-r--r-- 68.2 KB
sit.c -rw-r--r-- 28.8 KB
syncookies.c -rw-r--r-- 7.3 KB
sysctl_net_ipv6.c -rw-r--r-- 3.4 KB
tcp_ipv6.c -rw-r--r-- 55.9 KB
tunnel6.c -rw-r--r-- 4.6 KB
udp.c -rw-r--r-- 37.2 KB
udp_impl.h -rw-r--r-- 1.4 KB
udplite.c -rw-r--r-- 3.1 KB
xfrm6_input.c -rw-r--r-- 3.0 KB
xfrm6_mode_beet.c -rw-r--r-- 3.5 KB
xfrm6_mode_ro.c -rw-r--r-- 2.3 KB
xfrm6_mode_transport.c -rw-r--r-- 2.3 KB
xfrm6_mode_tunnel.c -rw-r--r-- 3.1 KB
xfrm6_output.c -rw-r--r-- 2.1 KB
xfrm6_policy.c -rw-r--r-- 8.1 KB
xfrm6_state.c -rw-r--r-- 4.5 KB
xfrm6_tunnel.c -rw-r--r-- 9.9 KB

back to top