sparc32: mm: Only call ctor()/dtor() functions for first and last user
The SRMMU page-table allocator allocates multiple PTE tables per page,
since they are only 1K in size. However, this means that calls to
pgtable_pte_page_{ctor,dtor}() must be serialised and performed only by
the first and last page-table allocation for the page respectively.
Use the page reference count to track how many PTE tables we have
allocated for a given page returned by the SRMMU allocator and only
call the ctor()/dtor() functions for the first and last user respectively.
Cc: David S. Miller <davem@davemloft.net>
Fixes: 8c8f3156dd
("sparc32: mm: Reduce allocation size for PMD and PTE tables")
Signed-off-by: Will Deacon <will@kernel.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
60bccaa671
commit
1996d47a0d
|
@ -364,9 +364,13 @@ pgtable_t pte_alloc_one(struct mm_struct *mm)
|
|||
if ((ptep = pte_alloc_one_kernel(mm)) == 0)
|
||||
return NULL;
|
||||
page = pfn_to_page(__nocache_pa((unsigned long)ptep) >> PAGE_SHIFT);
|
||||
if (!pgtable_pte_page_ctor(page)) {
|
||||
return NULL;
|
||||
spin_lock(&mm->page_table_lock);
|
||||
if (page_ref_inc_return(page) == 2 && !pgtable_pte_page_ctor(page)) {
|
||||
page_ref_dec(page);
|
||||
ptep = NULL;
|
||||
}
|
||||
spin_unlock(&mm->page_table_lock);
|
||||
|
||||
return ptep;
|
||||
}
|
||||
|
||||
|
@ -375,7 +379,11 @@ void pte_free(struct mm_struct *mm, pgtable_t ptep)
|
|||
struct page *page;
|
||||
|
||||
page = pfn_to_page(__nocache_pa((unsigned long)ptep) >> PAGE_SHIFT);
|
||||
pgtable_pte_page_dtor(page);
|
||||
spin_lock(&mm->page_table_lock);
|
||||
if (page_ref_dec_return(page) == 1)
|
||||
pgtable_pte_page_dtor(page);
|
||||
spin_unlock(&mm->page_table_lock);
|
||||
|
||||
srmmu_free_nocache(ptep, SRMMU_PTE_TABLE_SIZE);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue