s390/mm: handle PTE-mapped tail pages in fast gup
With the THP refcounting rework it is possible to see THP compound tail pages mapped with PTEs during a THP split. This needs to be considered when using page_cache_get_speculative(), which will always fail on tail pages because ->_count is always zero. commit7aef4172
"mm: handle PTE-mapped tail pages in gerneric fast gup implementaiton" fixed it for the generic fast gup code by using compound_head(page) instead of page, but not for s390. This patch is a 1:1 adaption of commit7aef4172
for the s390 fast gup code. Without this fix, gup will fall back to the slow path or fail in the unlikely scenario that we hit a THP under splitting in-between the page table split and the compound page split. Cc: stable@vger.kernel.org # v4.5 Signed-off-by: Gerald Schaefer <gerald.schaefer@de.ibm.com> Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
This commit is contained in:
Родитель
91d3721176
Коммит
fc897c95e9
|
@ -20,9 +20,9 @@
|
|||
static inline int gup_pte_range(pmd_t *pmdp, pmd_t pmd, unsigned long addr,
|
||||
unsigned long end, int write, struct page **pages, int *nr)
|
||||
{
|
||||
struct page *head, *page;
|
||||
unsigned long mask;
|
||||
pte_t *ptep, pte;
|
||||
struct page *page;
|
||||
|
||||
mask = (write ? _PAGE_PROTECT : 0) | _PAGE_INVALID | _PAGE_SPECIAL;
|
||||
|
||||
|
@ -37,12 +37,14 @@ static inline int gup_pte_range(pmd_t *pmdp, pmd_t pmd, unsigned long addr,
|
|||
return 0;
|
||||
VM_BUG_ON(!pfn_valid(pte_pfn(pte)));
|
||||
page = pte_page(pte);
|
||||
if (!page_cache_get_speculative(page))
|
||||
head = compound_head(page);
|
||||
if (!page_cache_get_speculative(head))
|
||||
return 0;
|
||||
if (unlikely(pte_val(pte) != pte_val(*ptep))) {
|
||||
put_page(page);
|
||||
put_page(head);
|
||||
return 0;
|
||||
}
|
||||
VM_BUG_ON_PAGE(compound_head(page) != head, page);
|
||||
pages[*nr] = page;
|
||||
(*nr)++;
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче