• Vlastimil Babka's avatar
    mm, compaction: make capture control handling safe wrt interrupts · b9e20f0d
    Vlastimil Babka authored
    Hugh reports:
    
     "While stressing compaction, one run oopsed on NULL capc->cc in
      __free_one_page()'s task_capc(zone): compact_zone_order() had been
      interrupted, and a page was being freed in the return from interrupt.
    
      Though you would not expect it from the source, both gccs I was using
      (4.8.1 and 7.5.0) had chosen to compile compact_zone_order() with the
      ".cc = &cc" implemented by mov %rbx,-0xb0(%rbp) immediately before
      callq compact_zone - long after the "current->capture_control =
      &capc". An interrupt in between those finds capc->cc NULL (zeroed by
      an earlier rep stos).
    
      This could presumably be fixed by a barrier() before setting
      current->capture_control in compact_zone_order(); but would also need
      more care on return from compact_zone(), in order not to risk leaking
      a page captured by interrupt just before capture_control is reset.
    
      Maybe that is the preferable fix, but I felt safer for task_capc() to
      exclude the rather surprising possibility of capture at interrupt
      time"
    
    I have checked that gcc10 also behaves the same.
    
    The advantage of fix in compact_zone_order() is that we don't add
    another test in the page freeing hot path, and that it might prevent
    future problems if we stop exposing pointers to uninitialized structures
    in current task.
    
    So this patch implements the suggestion for compact_zone_order() with
    barrier() (and WRITE_ONCE() to prevent store tearing) for setting
    current->capture_control, and prevents page leaking with
    WRITE_ONCE/READ_ONCE in the proper order.
    
    Link: http://lkml.kernel.org/r/20200616082649.27173-1-vbabka@suse.cz
    Fixes: 5e1f0f09 ("mm, compaction: capture a page under direct compaction")
    Signed-off-by: default avatarVlastimil Babka <vbabka@suse.cz>
    Reported-by: default avatarHugh Dickins <hughd@google.com>
    Suggested-by: default avatarHugh Dickins <hughd@google.com>
    Acked-by: default avatarHugh Dickins <hughd@google.com>
    Cc: Alex Shi <alex.shi@linux.alibaba.com>
    Cc: Li Wang <liwang@redhat.com>
    Cc: Mel Gorman <mgorman@techsingularity.net>
    Cc: <stable@vger.kernel.org>	[5.1+]
    Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
    Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
    b9e20f0d
compaction.c 75.6 KB