• Santosh Shilimkar's avatar
    mm: fix the page_swap_info() BUG_ON check · c8de641b
    Santosh Shilimkar authored
    Commit 62c230bc ("mm: add support for a filesystem to activate
    swap files and use direct_IO for writing swap pages") replaced the
    swap_aops dirty hook from __set_page_dirty_no_writeback() with
    For normal cases without these special SWP flags code path falls back to
    __set_page_dirty_no_writeback() so the behaviour is expected to be the
    same as before.
    But swap_set_page_dirty() makes use of the page_swap_info() helper to
    get the swap_info_struct to check for the flags like SWP_FILE,
    SWP_BLKDEV etc as desired for those features.  This helper has
    BUG_ON(!PageSwapCache(page)) which is racy and safe only for the
    set_page_dirty_lock() path.
    For the set_page_dirty() path which is often needed for cases to be
    called from irq context, kswapd() can toggle the flag behind the back
    while the call is getting executed when system is low on memory and
    heavy swapping is ongoing.
    This ends up with undesired kernel panic.
    This patch just moves the check outside the helper to its users
    appropriately to fix kernel panic for the described path.  Couple of
    users of helpers already take care of SwapCache condition so I skipped
    Link: http://lkml.kernel.org/r/1473460718-31013-1-git-send-email-santosh.shilimkar@oracle.comSigned-off-by: default avatarSantosh Shilimkar <santosh.shilimkar@oracle.com>
    Cc: Mel Gorman <mgorman@suse.de>
    Cc: Joe Perches <joe@perches.com>
    Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
    Cc: Rik van Riel <riel@redhat.com>
    Cc: David S. Miller <davem@davemloft.net>
    Cc: Jens Axboe <axboe@fb.com>
    Cc: Michal Hocko <mhocko@suse.com>
    Cc: Hugh Dickins <hughd@google.com>
    Cc: Al Viro <viro@zeniv.linux.org.uk>
    Cc: <stable@vger.kernel.org>	[4.7.x]
    Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
    Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
swapfile.c 77.6 KB