diff options
-rw-r--r-- | mm/khugepaged.c | 12 |
1 files changed, 12 insertions, 0 deletions
diff --git a/mm/khugepaged.c b/mm/khugepaged.c index f37be43f8cae..30553d7df402 100644 --- a/mm/khugepaged.c +++ b/mm/khugepaged.c @@ -820,6 +820,18 @@ static struct page *khugepaged_alloc_hugepage(bool *wait) static bool khugepaged_prealloc_page(struct page **hpage, bool *wait) { + /* + * If the hpage allocated earlier was briefly exposed in page cache + * before collapse_file() failed, it is possible that racing lookups + * have not yet completed, and would then be unpleasantly surprised by + * finding the hpage reused for the same mapping at a different offset. + * Just release the previous allocation if there is any danger of that. + */ + if (*hpage && page_count(*hpage) > 1) { + put_page(*hpage); + *hpage = NULL; + } + if (!*hpage) *hpage = khugepaged_alloc_hugepage(wait); |