hugetlbfs page faults can race with truncate and hole punch operations.
Current code in the page fault path attempts to handle this by 'backing
out' operations if we encounter the race. One obvious omission in the
current code is removing a page newly added to the page cache. This is
pretty straight forward to address, but there is a more subtle and
difficult issue of backing out hugetlb reservations. To handle this
correctly, the 'reservation state' before page allocation needs to be
noted so that it can be properly backed out. There are four distinct
possibilities for reservation state: shared/reserved, shared/no-resv,
private/reserved and private/no-resv. Backing out a reservation may
require memory allocation which could fail so that needs to be taken into
account as well.
Instead of writing the required complicated code for this rare occurrence,
just eliminate the race. i_mmap_rwsem is now held in read mode for the
duration of page fault processing. Hold i_mmap_rwsem longer in truncation
and hold punch code to cover the call to remove_inode_hugepages.
With this modification, code in remove_inode_hugepages checking for races
becomes 'dead' as it can not longer happen. Remove the dead code and
expand comments to explain reasoning. Similarly, checks for races with
truncation in the page fault path can be simplified and removed.
[firstname.lastname@example.org: incorporat suggestions from Kirill]
Fixes: ebed4bfc ("hugetlb: fix absurd HugePages_Rsvd")
Signed-off-by: Mike Kravetz <email@example.com>
Acked-by: Kirill A. Shutemov <firstname.lastname@example.org>
Cc: Michal Hocko <email@example.com>
Cc: Hugh Dickins <firstname.lastname@example.org>
Cc: Naoya Horiguchi <email@example.com>
Cc: "Aneesh Kumar K . V" <firstname.lastname@example.org>
Cc: Andrea Arcangeli <email@example.com>
Cc: Davidlohr Bueso <firstname.lastname@example.org>
Cc: Prakash Sangappa <email@example.com>
Signed-off-by: Andrew Morton <firstname.lastname@example.org>
Signed-off-by: Linus Torvalds <email@example.com>