Commit 7f188251 authored by Aneesh Kumar K.V's avatar Aneesh Kumar K.V Committed by Linus Torvalds

powerpc/mm/iommu: allow large IOMMU page size only for hugetlb backing

THP pages can get split during different code paths.  An incremented
reference count does imply we will not split the compound page.  But the
pmd entry can be converted to level 4 pte entries.  Keep the code
simpler by allowing large IOMMU page size only if the guest ram is
backed by hugetlb pages.

Link: http://lkml.kernel.org/r/20190114095438.32470-6-aneesh.kumar@linux.ibm.comSigned-off-by: default avatarAneesh Kumar K.V <aneesh.kumar@linux.ibm.com>
Cc: Alexey Kardashevskiy <aik@ozlabs.ru>
Cc: Andrea Arcangeli <aarcange@redhat.com>
Cc: David Gibson <david@gibson.dropbear.id.au>
Cc: Michael Ellerman <mpe@ellerman.id.au>
Cc: Michal Hocko <mhocko@kernel.org>
Cc: Mel Gorman <mgorman@techsingularity.net>
Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
parent 678e174c
...@@ -98,8 +98,6 @@ static long mm_iommu_do_alloc(struct mm_struct *mm, unsigned long ua, ...@@ -98,8 +98,6 @@ static long mm_iommu_do_alloc(struct mm_struct *mm, unsigned long ua,
struct mm_iommu_table_group_mem_t *mem; struct mm_iommu_table_group_mem_t *mem;
long i, ret, locked_entries = 0; long i, ret, locked_entries = 0;
unsigned int pageshift; unsigned int pageshift;
unsigned long flags;
unsigned long cur_ua;
mutex_lock(&mem_list_mutex); mutex_lock(&mem_list_mutex);
...@@ -167,22 +165,14 @@ static long mm_iommu_do_alloc(struct mm_struct *mm, unsigned long ua, ...@@ -167,22 +165,14 @@ static long mm_iommu_do_alloc(struct mm_struct *mm, unsigned long ua,
for (i = 0; i < entries; ++i) { for (i = 0; i < entries; ++i) {
struct page *page = mem->hpages[i]; struct page *page = mem->hpages[i];
cur_ua = ua + (i << PAGE_SHIFT); /*
if (mem->pageshift > PAGE_SHIFT && PageCompound(page)) { * Allow to use larger than 64k IOMMU pages. Only do that
pte_t *pte; * if we are backed by hugetlb.
*/
if ((mem->pageshift > PAGE_SHIFT) && PageHuge(page)) {
struct page *head = compound_head(page); struct page *head = compound_head(page);
unsigned int compshift = compound_order(head);
unsigned int pteshift; pageshift = compound_order(head) + PAGE_SHIFT;
local_irq_save(flags); /* disables as well */
pte = find_linux_pte(mm->pgd, cur_ua, NULL, &pteshift);
/* Double check it is still the same pinned page */
if (pte && pte_page(*pte) == head &&
pteshift == compshift + PAGE_SHIFT)
pageshift = max_t(unsigned int, pteshift,
PAGE_SHIFT);
local_irq_restore(flags);
} }
mem->pageshift = min(mem->pageshift, pageshift); mem->pageshift = min(mem->pageshift, pageshift);
/* /*
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment