Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

parisc: Update huge TLB page support to use per-pagetable spinlock

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>

authored by

John David Anglin and committed by
Helge Deller
11c03dc8 b37d1c18

+10 -9
+10 -9
arch/parisc/mm/hugetlbpage.c
··· 139 139 { 140 140 unsigned long flags; 141 141 142 - purge_tlb_start(flags); 142 + spin_lock_irqsave(pgd_spinlock((mm)->pgd), flags); 143 143 __set_huge_pte_at(mm, addr, ptep, entry); 144 - purge_tlb_end(flags); 144 + spin_unlock_irqrestore(pgd_spinlock((mm)->pgd), flags); 145 145 } 146 146 147 147 ··· 151 151 unsigned long flags; 152 152 pte_t entry; 153 153 154 - purge_tlb_start(flags); 154 + spin_lock_irqsave(pgd_spinlock((mm)->pgd), flags); 155 155 entry = *ptep; 156 156 __set_huge_pte_at(mm, addr, ptep, __pte(0)); 157 - purge_tlb_end(flags); 157 + spin_unlock_irqrestore(pgd_spinlock((mm)->pgd), flags); 158 158 159 159 return entry; 160 160 } ··· 166 166 unsigned long flags; 167 167 pte_t old_pte; 168 168 169 - purge_tlb_start(flags); 169 + spin_lock_irqsave(pgd_spinlock((mm)->pgd), flags); 170 170 old_pte = *ptep; 171 171 __set_huge_pte_at(mm, addr, ptep, pte_wrprotect(old_pte)); 172 - purge_tlb_end(flags); 172 + spin_unlock_irqrestore(pgd_spinlock((mm)->pgd), flags); 173 173 } 174 174 175 175 int huge_ptep_set_access_flags(struct vm_area_struct *vma, ··· 178 178 { 179 179 unsigned long flags; 180 180 int changed; 181 + struct mm_struct *mm = vma->vm_mm; 181 182 182 - purge_tlb_start(flags); 183 + spin_lock_irqsave(pgd_spinlock((mm)->pgd), flags); 183 184 changed = !pte_same(*ptep, pte); 184 185 if (changed) { 185 - __set_huge_pte_at(vma->vm_mm, addr, ptep, pte); 186 + __set_huge_pte_at(mm, addr, ptep, pte); 186 187 } 187 - purge_tlb_end(flags); 188 + spin_unlock_irqrestore(pgd_spinlock((mm)->pgd), flags); 188 189 return changed; 189 190 } 190 191