* [PATCH 1/3] parisc: Disable huge pages on Mako machines @ 2015-12-06 20:43 Helge Deller 2015-12-06 20:43 ` [PATCH 2/3] parisc: Disable tlb flush optimization with huge pages Helge Deller ` (2 more replies) 0 siblings, 3 replies; 6+ messages in thread From: Helge Deller @ 2015-12-06 20:43 UTC (permalink / raw) To: linux-parisc; +Cc: James Bottomley, John David Anglin Mako-based machines (PA8800 and PA8900 CPUs) don't allow aliasing on non-equaivalent addresses. Signed-off-by: Helge Deller <deller@gmx.de> --- arch/parisc/include/asm/pgtable.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/arch/parisc/include/asm/pgtable.h b/arch/parisc/include/asm/pgtable.h index d8534f9..291cee2 100644 --- a/arch/parisc/include/asm/pgtable.h +++ b/arch/parisc/include/asm/pgtable.h @@ -372,7 +372,8 @@ static inline pte_t pte_mkspecial(pte_t pte) { return pte; } */ #ifdef CONFIG_HUGETLB_PAGE #define pte_huge(pte) (pte_val(pte) & _PAGE_HUGE) -#define pte_mkhuge(pte) (__pte(pte_val(pte) | _PAGE_HUGE)) +#define pte_mkhuge(pte) (__pte(pte_val(pte) | \ + (parisc_requires_coherency() ? 0 : _PAGE_HUGE))) #else #define pte_huge(pte) (0) #define pte_mkhuge(pte) (pte) -- 2.1.0 ^ permalink raw reply related [flat|nested] 6+ messages in thread
* [PATCH 2/3] parisc: Disable tlb flush optimization with huge pages 2015-12-06 20:43 [PATCH 1/3] parisc: Disable huge pages on Mako machines Helge Deller @ 2015-12-06 20:43 ` Helge Deller 2015-12-06 20:43 ` [PATCH 3/3] parisc: protect huge pte changes with spinlocks Helge Deller 2015-12-07 15:13 ` [PATCH 1/3] parisc: Disable huge pages on Mako machines John David Anglin 2 siblings, 0 replies; 6+ messages in thread From: Helge Deller @ 2015-12-06 20:43 UTC (permalink / raw) To: linux-parisc; +Cc: James Bottomley, John David Anglin It seems calling flush_tlb_all() doesn't reliable flush the tlb on all CPUs. Disable it when used with huge pages. Signed-off-by: Helge Deller <deller@gmx.de> --- arch/parisc/kernel/cache.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/arch/parisc/kernel/cache.c b/arch/parisc/kernel/cache.c index cda6dbb..aee27e1 100644 --- a/arch/parisc/kernel/cache.c +++ b/arch/parisc/kernel/cache.c @@ -442,13 +442,15 @@ EXPORT_SYMBOL(copy_user_page); int __flush_tlb_range(unsigned long sid, unsigned long start, unsigned long end) { - unsigned long flags, size; + unsigned long flags; - size = (end - start); +#if !defined(CONFIG_HUGETLB_PAGE) + unsigned long size = (end - start); if (size >= parisc_tlb_flush_threshold) { flush_tlb_all(); return 1; } +#endif /* Purge TLB entries for small ranges using the pdtlb and pitlb instructions. These instructions execute locally -- 2.1.0 ^ permalink raw reply related [flat|nested] 6+ messages in thread
* [PATCH 3/3] parisc: protect huge pte changes with spinlocks 2015-12-06 20:43 [PATCH 1/3] parisc: Disable huge pages on Mako machines Helge Deller 2015-12-06 20:43 ` [PATCH 2/3] parisc: Disable tlb flush optimization with huge pages Helge Deller @ 2015-12-06 20:43 ` Helge Deller 2015-12-07 15:13 ` [PATCH 1/3] parisc: Disable huge pages on Mako machines John David Anglin 2 siblings, 0 replies; 6+ messages in thread From: Helge Deller @ 2015-12-06 20:43 UTC (permalink / raw) To: linux-parisc; +Cc: James Bottomley, John David Anglin Protect all changes of huge page pte entries with purge_tlb_start() and purge_tlb_end() spinlocks. Signed-off-by: Helge Deller <deller@gmx.de> --- arch/parisc/include/asm/hugetlb.h | 20 +++---------- arch/parisc/mm/hugetlbpage.c | 60 +++++++++++++++++++++++++++++++-------- 2 files changed, 52 insertions(+), 28 deletions(-) diff --git a/arch/parisc/include/asm/hugetlb.h b/arch/parisc/include/asm/hugetlb.h index 7d56a9c..a65d888 100644 --- a/arch/parisc/include/asm/hugetlb.h +++ b/arch/parisc/include/asm/hugetlb.h @@ -54,24 +54,12 @@ static inline pte_t huge_pte_wrprotect(pte_t pte) return pte_wrprotect(pte); } -static inline void huge_ptep_set_wrprotect(struct mm_struct *mm, - unsigned long addr, pte_t *ptep) -{ - pte_t old_pte = *ptep; - set_huge_pte_at(mm, addr, ptep, pte_wrprotect(old_pte)); -} +void huge_ptep_set_wrprotect(struct mm_struct *mm, + unsigned long addr, pte_t *ptep); -static inline int huge_ptep_set_access_flags(struct vm_area_struct *vma, +int huge_ptep_set_access_flags(struct vm_area_struct *vma, unsigned long addr, pte_t *ptep, - pte_t pte, int dirty) -{ - int changed = !pte_same(*ptep, pte); - if (changed) { - set_huge_pte_at(vma->vm_mm, addr, ptep, pte); - flush_tlb_page(vma, addr); - } - return changed; -} + pte_t pte, int dirty); static inline pte_t huge_ptep_get(pte_t *ptep) { diff --git a/arch/parisc/mm/hugetlbpage.c b/arch/parisc/mm/hugetlbpage.c index f6fdc77..54ba392 100644 --- a/arch/parisc/mm/hugetlbpage.c +++ b/arch/parisc/mm/hugetlbpage.c @@ -105,15 +105,13 @@ static inline void purge_tlb_entries_huge(struct mm_struct *mm, unsigned long ad addr |= _HUGE_PAGE_SIZE_ENCODING_DEFAULT; for (i = 0; i < (1 << (HPAGE_SHIFT-REAL_HPAGE_SHIFT)); i++) { - mtsp(mm->context, 1); - pdtlb(addr); - if (unlikely(split_tlb)) - pitlb(addr); + purge_tlb_entries(mm, addr); addr += (1UL << REAL_HPAGE_SHIFT); } } -void set_huge_pte_at(struct mm_struct *mm, unsigned long addr, +/* __set_huge_pte_at() must be called holding the pa_tlb_lock. */ +static void __set_huge_pte_at(struct mm_struct *mm, unsigned long addr, pte_t *ptep, pte_t entry) { unsigned long addr_start; @@ -123,14 +121,9 @@ void set_huge_pte_at(struct mm_struct *mm, unsigned long addr, addr_start = addr; for (i = 0; i < (1 << HUGETLB_PAGE_ORDER); i++) { - /* Directly write pte entry. We could call set_pte_at(mm, addr, ptep, entry) - * instead, but then we get double locking on pa_tlb_lock. */ - *ptep = entry; + set_pte(ptep, entry); ptep++; - /* Drop the PAGE_SIZE/non-huge tlb entry */ - purge_tlb_entries(mm, addr); - addr += PAGE_SIZE; pte_val(entry) += PAGE_SIZE; } @@ -138,18 +131,61 @@ void set_huge_pte_at(struct mm_struct *mm, unsigned long addr, purge_tlb_entries_huge(mm, addr_start); } +void set_huge_pte_at(struct mm_struct *mm, unsigned long addr, + pte_t *ptep, pte_t entry) +{ + unsigned long flags; + + purge_tlb_start(flags); + __set_huge_pte_at(mm, addr, ptep, entry); + purge_tlb_end(flags); +} + pte_t huge_ptep_get_and_clear(struct mm_struct *mm, unsigned long addr, pte_t *ptep) { + unsigned long flags; pte_t entry; + purge_tlb_start(flags); entry = *ptep; - set_huge_pte_at(mm, addr, ptep, __pte(0)); + __set_huge_pte_at(mm, addr, ptep, __pte(0)); + purge_tlb_end(flags); return entry; } + +void huge_ptep_set_wrprotect(struct mm_struct *mm, + unsigned long addr, pte_t *ptep) +{ + unsigned long flags; + pte_t old_pte; + + purge_tlb_start(flags); + old_pte = *ptep; + __set_huge_pte_at(mm, addr, ptep, pte_wrprotect(old_pte)); + purge_tlb_end(flags); +} + +int huge_ptep_set_access_flags(struct vm_area_struct *vma, + unsigned long addr, pte_t *ptep, + pte_t pte, int dirty) +{ + unsigned long flags; + int changed; + + purge_tlb_start(flags); + changed = !pte_same(*ptep, pte); + if (changed) { + __set_huge_pte_at(vma->vm_mm, addr, ptep, pte); + } + purge_tlb_end(flags); + return changed; +} + + int pmd_huge(pmd_t pmd) { return 0; -- 2.1.0 ^ permalink raw reply related [flat|nested] 6+ messages in thread
* Re: [PATCH 1/3] parisc: Disable huge pages on Mako machines 2015-12-06 20:43 [PATCH 1/3] parisc: Disable huge pages on Mako machines Helge Deller 2015-12-06 20:43 ` [PATCH 2/3] parisc: Disable tlb flush optimization with huge pages Helge Deller 2015-12-06 20:43 ` [PATCH 3/3] parisc: protect huge pte changes with spinlocks Helge Deller @ 2015-12-07 15:13 ` John David Anglin 2015-12-07 21:19 ` Helge Deller 2 siblings, 1 reply; 6+ messages in thread From: John David Anglin @ 2015-12-07 15:13 UTC (permalink / raw) To: Helge Deller, linux-parisc; +Cc: James Bottomley On 2015-12-06 3:43 PM, Helge Deller wrote: > Mako-based machines (PA8800 and PA8900 CPUs) don't allow aliasing on > non-equaivalent addresses. Where do the non equivalent addresses come from? When non equivalent mappings are used in the kernel, we try pretty hard to ensure that the user mappings are flushed prior to using the kernel mapping and then we flush the kernel mapping. There's also the copy_user_page_asm and clear_user_page_asm routines that do copies and clear operations using equivalent addresses. I have some notes on the flushing needed using these routines. One source of non equivalent addresses is the boundary between text and data in user applications. At one time, we had data immediately after the text and non equivalent addresses. Now, the start of data is rounded up so it starts on a 4K page boundary. This may need adjustment for huge pages, but that implies a rebuild of user space. I tend to think flush_tlb_all() doesn't work because the aliasing rules are being broken. Disabling it causes a significant increase in time to flush the tlb. Dave -- John David Anglin dave.anglin@bell.net ^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH 1/3] parisc: Disable huge pages on Mako machines 2015-12-07 15:13 ` [PATCH 1/3] parisc: Disable huge pages on Mako machines John David Anglin @ 2015-12-07 21:19 ` Helge Deller 2015-12-08 2:03 ` John David Anglin 0 siblings, 1 reply; 6+ messages in thread From: Helge Deller @ 2015-12-07 21:19 UTC (permalink / raw) To: John David Anglin, linux-parisc; +Cc: James Bottomley Hi Dave, On 07.12.2015 16:13, John David Anglin wrote: > On 2015-12-06 3:43 PM, Helge Deller wrote: >> Mako-based machines (PA8800 and PA8900 CPUs) don't allow aliasing on >> non-equaivalent addresses. > Where do the non equivalent addresses come from? I think the main problem is the gateway page. It's mapped at address 0 into userspace, but needs to jump into kernel space too. This somehow breaks the huge page mapping. > When non equivalent mappings are > used in the kernel, we try pretty hard to ensure that the user mappings are flushed prior > to using the kernel mapping and then we flush the kernel mapping. There's also the > copy_user_page_asm and clear_user_page_asm routines that do copies and clear operations > using equivalent addresses. I have some notes on the flushing needed using these routines. Yes. > One source of non equivalent addresses is the boundary between text and data in user > applications. At one time, we had data immediately after the text and non equivalent > addresses. Now, the start of data is rounded up so it starts on a 4K page boundary. > This may need adjustment for huge pages, but that implies a rebuild of user space. No, userspace is not mapped in huge pages (but it could if someone gets libhugetlbfs working). Right now, only hugepages would only be used for mmap() or shmget() memory if the flags are given. > I tend to think flush_tlb_all() doesn't work because the aliasing rules are being broken. > Disabling it causes a significant increase in time to flush the tlb. Yes. Right now the patches I sent don't seem to work as I expected them to do. So, it's not what I currently tend to commit. I'm still working on it, but my time is very limited, so it will need some time. My current top goal is to push patches for kernel v4.4 which fixes the boot crash on Mako machines. Helge ^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH 1/3] parisc: Disable huge pages on Mako machines 2015-12-07 21:19 ` Helge Deller @ 2015-12-08 2:03 ` John David Anglin 0 siblings, 0 replies; 6+ messages in thread From: John David Anglin @ 2015-12-08 2:03 UTC (permalink / raw) To: Helge Deller; +Cc: linux-parisc, James Bottomley On 2015-12-07, at 4:19 PM, Helge Deller wrote: >> Where do the non equivalent addresses come from? > > I think the main problem is the gateway page. > It's mapped at address 0 into userspace, but needs to jump into kernel space too. > This somehow breaks the huge page mapping. With latest debian kernel, I see: 000000004015d000 <linux_gateway_page>: ... 000000004015d0b0 <lws_entry>: Possibly, this needs to be aligned to huge page boundary. Dave -- John David Anglin dave.anglin@bell.net ^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2015-12-08 2:03 UTC | newest] Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2015-12-06 20:43 [PATCH 1/3] parisc: Disable huge pages on Mako machines Helge Deller 2015-12-06 20:43 ` [PATCH 2/3] parisc: Disable tlb flush optimization with huge pages Helge Deller 2015-12-06 20:43 ` [PATCH 3/3] parisc: protect huge pte changes with spinlocks Helge Deller 2015-12-07 15:13 ` [PATCH 1/3] parisc: Disable huge pages on Mako machines John David Anglin 2015-12-07 21:19 ` Helge Deller 2015-12-08 2:03 ` John David Anglin
This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.