• Hugh Dickins's avatar
    memcg: fix oops on NULL lru list · fb59e9f1
    Hugh Dickins authored
    While testing force_empty, during an exit_mmap, __mem_cgroup_remove_list
    called from mem_cgroup_uncharge_page oopsed on a NULL pointer in the lru list.
     I couldn't see what racing tasks on other cpus were doing, but surmise that
    another must have been in mem_cgroup_charge_common on the same page, between
    its unlock_page_cgroup and spin_lock_irqsave near done (thanks to that kzalloc
    which I'd almost changed to a kmalloc).
    
    Normally such a race cannot happen, the ref_cnt prevents it, the final
    uncharge cannot race with the initial charge.  But force_empty buggers the
    ref_cnt, that's what it's all about; and thereafter forced pages are
    vulnerable to races such as this (just think of a shared page also mapped into
    an mm of another mem_cgroup than that just emptied).  And remain vulnerable
    until they're freed indefinitely later.
    
    This patch just fixes the oops by moving the unlock_page_cgroups down below
    adding to and removing from the list (only possible given the previous pat...
    fb59e9f1
memcontrol.c 27.2 KB