• Huang Ying's avatar
    mm: fix races between swapoff and flush dcache · cb9f753a
    Huang Ying authored
    Thanks to commit 4b3ef9da ("mm/swap: split swap cache into 64MB
    trunks"), after swapoff the address_space associated with the swap
    device will be freed.  So page_mapping() users which may touch the
    address_space need some kind of mechanism to prevent the address_space
    from being freed during accessing.
    
    The dcache flushing functions (flush_dcache_page(), etc) in architecture
    specific code may access the address_space of swap device for anonymous
    pages in swap cache via page_mapping() function.  But in some cases
    there are no mechanisms to prevent the swap device from being swapoff,
    for example,
    
      CPU1					CPU2
      __get_user_pages()			swapoff()
        flush_dcache_page()
          mapping = page_mapping()
            ...				  exit_swap_address_space()
            ...				    kvfree(spaces)
            mapping_mapped(mapping)
    
    The address space may be accessed after being freed.
    
    But from cachetlb.txt and Russell King, flush_dcache_page() only care
    about file cache pages, for anonymous pages, flush_anon_page() should be
    used.  The implementation of flush_dcache_page() in all architectures
    follows this too.  They will check whether page_mapping() is NULL and
    whether mapping_mapped() is true to determine whether to flush the
    dcache immediately.  And they will use interval tree (mapping->i_mmap)
    to find all user space mappings.  While mapping_mapped() and
    mapping->i_mmap isn't used by anonymous pages in swap cache at all.
    
    So, to fix the race between swapoff and flush dcache, __page_mapping()
    is add to return the address_space for file cache pages and NULL
    otherwise.  All page_mapping() invoking in flush dcache functions are
    replaced with page_mapping_file().
    
    [akpm@linux-foundation.org: simplify page_mapping_file(), per Mike]
    Link: http://lkml.kernel.org/r/20180305083634.15174-1-ying.huang@intel.comSigned-off-by: default avatar"Huang, Ying" <ying.huang@intel.com>
    Reviewed-by: default avatarAndrew Morton <akpm@linux-foundation.org>
    Cc: Minchan Kim <minchan@kernel.org>
    Cc: Michal Hocko <mhocko@suse.com>
    Cc: Johannes Weiner <hannes@cmpxchg.org>
    Cc: Mel Gorman <mgorman@techsingularity.net>
    Cc: Dave Hansen <dave.hansen@intel.com>
    Cc: Chen Liqin <liqin.linux@gmail.com>
    Cc: Russell King <linux@armlinux.org.uk>
    Cc: Yoshinori Sato <ysato@users.sourceforge.jp>
    Cc: "James E.J. Bottomley" <jejb@parisc-linux.org>
    Cc: Guan Xuetao <gxt@mprc.pku.edu.cn>
    Cc: "David S. Miller" <davem@davemloft.net>
    Cc: Chris Zankel <chris@zankel.net>
    Cc: Vineet Gupta <vgupta@synopsys.com>
    Cc: Ley Foon Tan <lftan@altera.com>
    Cc: Ralf Baechle <ralf@linux-mips.org>
    Cc: Andi Kleen <ak@linux.intel.com>
    Cc: Mike Rapoport <rppt@linux.vnet.ibm.com>
    Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
    Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
    cb9f753a
Name
Last commit
Last update
..
boot Loading commit data...
configs Loading commit data...
include Loading commit data...
kernel Loading commit data...
lib Loading commit data...
mm Loading commit data...
platform Loading commit data...
Kconfig Loading commit data...
Kconfig.debug Loading commit data...
Makefile Loading commit data...