• David Rientjes's avatar
    oom: fix race while temporarily setting current's oom_score_adj · 43362a49
    David Rientjes authored
    test_set_oom_score_adj() was introduced in 72788c38 ("oom: replace
    PF_OOM_ORIGIN with toggling oom_score_adj") to temporarily elevate
    current's oom_score_adj for ksm and swapoff without requiring an
    additional per-process flag.
    
    Using that function to both set oom_score_adj to OOM_SCORE_ADJ_MAX and
    then reinstate the previous value is racy since it's possible that
    userspace can set the value to something else itself before the old value
    is reinstated.  That results in userspace setting current's oom_score_adj
    to a different value and then the kernel immediately setting it back to
    its previous value without notification.
    
    To fix this, a new compare_swap_oom_score_adj() function is introduced
    with the same semantics as the compare and swap CAS instruction, or
    CMPXCHG on x86.  It is used to reinstate the previous value of
    oom_score_adj if and only if the present value is the same as the old
    value.
    Signed-off-by: default avatarDavid Rientjes <rientjes@google.com>
    Cc: Oleg Nesterov <oleg@redhat.com>
    Cc: Ying Han <yinghan@google.com>
    Cc: KOSAKI Motohiro <kosaki.motohiro@jp.fujitsu.com>
    Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
    Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
    43362a49
ksm.c 54.7 KB