parisc: Update huge TLB page support to use per-pagetable spinlock
authorJohn David Anglin <dave.anglin@bell.net>
Sat, 27 Apr 2019 18:15:38 +0000 (14:15 -0400)
committerHelge Deller <deller@gmx.de>
Fri, 3 May 2019 21:47:41 +0000 (23:47 +0200)
This patch updates the parisc huge TLB page support to use per-pagetable spinlocks.

This patch requires Mikulas' per-pagetable spinlock patch and the revised TLB
serialization patch from Helge and myself.  With Mikulas' patch, we need to use
the per-pagetable spinlock for page table updates.  The TLB lock is only used
to serialize TLB flushes on machines with the Merced bus.

Signed-off-by: John David Anglin <dave.anglin@bell.net>
Signed-off-by: Helge Deller <deller@gmx.de>
arch/parisc/mm/hugetlbpage.c

index d77479a..d578809 100644 (file)
@@ -139,9 +139,9 @@ void set_huge_pte_at(struct mm_struct *mm, unsigned long addr,
 {
        unsigned long flags;
 
-       purge_tlb_start(flags);
+       spin_lock_irqsave(pgd_spinlock((mm)->pgd), flags);
        __set_huge_pte_at(mm, addr, ptep, entry);
-       purge_tlb_end(flags);
+       spin_unlock_irqrestore(pgd_spinlock((mm)->pgd), flags);
 }
 
 
@@ -151,10 +151,10 @@ pte_t huge_ptep_get_and_clear(struct mm_struct *mm, unsigned long addr,
        unsigned long flags;
        pte_t entry;
 
-       purge_tlb_start(flags);
+       spin_lock_irqsave(pgd_spinlock((mm)->pgd), flags);
        entry = *ptep;
        __set_huge_pte_at(mm, addr, ptep, __pte(0));
-       purge_tlb_end(flags);
+       spin_unlock_irqrestore(pgd_spinlock((mm)->pgd), flags);
 
        return entry;
 }
@@ -166,10 +166,10 @@ void huge_ptep_set_wrprotect(struct mm_struct *mm,
        unsigned long flags;
        pte_t old_pte;
 
-       purge_tlb_start(flags);
+       spin_lock_irqsave(pgd_spinlock((mm)->pgd), flags);
        old_pte = *ptep;
        __set_huge_pte_at(mm, addr, ptep, pte_wrprotect(old_pte));
-       purge_tlb_end(flags);
+       spin_unlock_irqrestore(pgd_spinlock((mm)->pgd), flags);
 }
 
 int huge_ptep_set_access_flags(struct vm_area_struct *vma,
@@ -178,13 +178,14 @@ int huge_ptep_set_access_flags(struct vm_area_struct *vma,
 {
        unsigned long flags;
        int changed;
+       struct mm_struct *mm = vma->vm_mm;
 
-       purge_tlb_start(flags);
+       spin_lock_irqsave(pgd_spinlock((mm)->pgd), flags);
        changed = !pte_same(*ptep, pte);
        if (changed) {
-               __set_huge_pte_at(vma->vm_mm, addr, ptep, pte);
+               __set_huge_pte_at(mm, addr, ptep, pte);
        }
-       purge_tlb_end(flags);
+       spin_unlock_irqrestore(pgd_spinlock((mm)->pgd), flags);
        return changed;
 }