aboutsummaryrefslogtreecommitdiffstats
path: root/arch/s390/include
diff options
context:
space:
mode:
authorMartin Schwidefsky <schwidefsky@de.ibm.com>2010-10-25 10:10:11 -0400
committerMartin Schwidefsky <sky@mschwide.boeblingen.de.ibm.com>2010-10-25 10:10:15 -0400
commit80217147a3d80c8a4e48f06e2f6e965455f3fe2a (patch)
treeb419ae9ee3ab0e5b92c0ed2a30ff59b76d6a4978 /arch/s390/include
parent87799ebab760dd1460f6e4193d4f71ba416d1451 (diff)
[S390] lockless get_user_pages_fast()
Implement get_user_pages_fast without locking in the fastpath on s390. Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
Diffstat (limited to 'arch/s390/include')
-rw-r--r--arch/s390/include/asm/pgalloc.h4
-rw-r--r--arch/s390/include/asm/pgtable.h1
-rw-r--r--arch/s390/include/asm/tlb.h13
3 files changed, 12 insertions, 6 deletions
diff --git a/arch/s390/include/asm/pgalloc.h b/arch/s390/include/asm/pgalloc.h
index 68940d0bad91..082eb4e50e8b 100644
--- a/arch/s390/include/asm/pgalloc.h
+++ b/arch/s390/include/asm/pgalloc.h
@@ -21,9 +21,11 @@
21 21
22unsigned long *crst_table_alloc(struct mm_struct *, int); 22unsigned long *crst_table_alloc(struct mm_struct *, int);
23void crst_table_free(struct mm_struct *, unsigned long *); 23void crst_table_free(struct mm_struct *, unsigned long *);
24void crst_table_free_rcu(struct mm_struct *, unsigned long *);
24 25
25unsigned long *page_table_alloc(struct mm_struct *); 26unsigned long *page_table_alloc(struct mm_struct *);
26void page_table_free(struct mm_struct *, unsigned long *); 27void page_table_free(struct mm_struct *, unsigned long *);
28void page_table_free_rcu(struct mm_struct *, unsigned long *);
27void disable_noexec(struct mm_struct *, struct task_struct *); 29void disable_noexec(struct mm_struct *, struct task_struct *);
28 30
29static inline void clear_table(unsigned long *s, unsigned long val, size_t n) 31static inline void clear_table(unsigned long *s, unsigned long val, size_t n)
@@ -176,4 +178,6 @@ static inline void pmd_populate(struct mm_struct *mm,
176#define pte_free_kernel(mm, pte) page_table_free(mm, (unsigned long *) pte) 178#define pte_free_kernel(mm, pte) page_table_free(mm, (unsigned long *) pte)
177#define pte_free(mm, pte) page_table_free(mm, (unsigned long *) pte) 179#define pte_free(mm, pte) page_table_free(mm, (unsigned long *) pte)
178 180
181extern void rcu_table_freelist_finish(void);
182
179#endif /* _S390_PGALLOC_H */ 183#endif /* _S390_PGALLOC_H */
diff --git a/arch/s390/include/asm/pgtable.h b/arch/s390/include/asm/pgtable.h
index 22a294571000..785229ae39cb 100644
--- a/arch/s390/include/asm/pgtable.h
+++ b/arch/s390/include/asm/pgtable.h
@@ -316,6 +316,7 @@ extern unsigned long VMALLOC_START;
316 316
317/* Bits in the segment table entry */ 317/* Bits in the segment table entry */
318#define _SEGMENT_ENTRY_ORIGIN 0x7fffffc0UL /* page table origin */ 318#define _SEGMENT_ENTRY_ORIGIN 0x7fffffc0UL /* page table origin */
319#define _SEGMENT_ENTRY_RO 0x200 /* page protection bit */
319#define _SEGMENT_ENTRY_INV 0x20 /* invalid segment table entry */ 320#define _SEGMENT_ENTRY_INV 0x20 /* invalid segment table entry */
320#define _SEGMENT_ENTRY_COMMON 0x10 /* common segment bit */ 321#define _SEGMENT_ENTRY_COMMON 0x10 /* common segment bit */
321#define _SEGMENT_ENTRY_PTL 0x0f /* page table length */ 322#define _SEGMENT_ENTRY_PTL 0x0f /* page table length */
diff --git a/arch/s390/include/asm/tlb.h b/arch/s390/include/asm/tlb.h
index fd1c00d08bf5..f1f644f2240a 100644
--- a/arch/s390/include/asm/tlb.h
+++ b/arch/s390/include/asm/tlb.h
@@ -64,10 +64,9 @@ static inline void tlb_flush_mmu(struct mmu_gather *tlb,
64 if (!tlb->fullmm && (tlb->nr_ptes > 0 || tlb->nr_pxds < TLB_NR_PTRS)) 64 if (!tlb->fullmm && (tlb->nr_ptes > 0 || tlb->nr_pxds < TLB_NR_PTRS))
65 __tlb_flush_mm(tlb->mm); 65 __tlb_flush_mm(tlb->mm);
66 while (tlb->nr_ptes > 0) 66 while (tlb->nr_ptes > 0)
67 pte_free(tlb->mm, tlb->array[--tlb->nr_ptes]); 67 page_table_free_rcu(tlb->mm, tlb->array[--tlb->nr_ptes]);
68 while (tlb->nr_pxds < TLB_NR_PTRS) 68 while (tlb->nr_pxds < TLB_NR_PTRS)
69 /* pgd_free frees the pointer as region or segment table */ 69 crst_table_free_rcu(tlb->mm, tlb->array[tlb->nr_pxds++]);
70 pgd_free(tlb->mm, tlb->array[tlb->nr_pxds++]);
71} 70}
72 71
73static inline void tlb_finish_mmu(struct mmu_gather *tlb, 72static inline void tlb_finish_mmu(struct mmu_gather *tlb,
@@ -75,6 +74,8 @@ static inline void tlb_finish_mmu(struct mmu_gather *tlb,
75{ 74{
76 tlb_flush_mmu(tlb, start, end); 75 tlb_flush_mmu(tlb, start, end);
77 76
77 rcu_table_freelist_finish();
78
78 /* keep the page table cache within bounds */ 79 /* keep the page table cache within bounds */
79 check_pgt_cache(); 80 check_pgt_cache();
80 81
@@ -103,7 +104,7 @@ static inline void pte_free_tlb(struct mmu_gather *tlb, pgtable_t pte,
103 if (tlb->nr_ptes >= tlb->nr_pxds) 104 if (tlb->nr_ptes >= tlb->nr_pxds)
104 tlb_flush_mmu(tlb, 0, 0); 105 tlb_flush_mmu(tlb, 0, 0);
105 } else 106 } else
106 pte_free(tlb->mm, pte); 107 page_table_free(tlb->mm, (unsigned long *) pte);
107} 108}
108 109
109/* 110/*
@@ -124,7 +125,7 @@ static inline void pmd_free_tlb(struct mmu_gather *tlb, pmd_t *pmd,
124 if (tlb->nr_ptes >= tlb->nr_pxds) 125 if (tlb->nr_ptes >= tlb->nr_pxds)
125 tlb_flush_mmu(tlb, 0, 0); 126 tlb_flush_mmu(tlb, 0, 0);
126 } else 127 } else
127 pmd_free(tlb->mm, pmd); 128 crst_table_free(tlb->mm, (unsigned long *) pmd);
128#endif 129#endif
129} 130}
130 131
@@ -146,7 +147,7 @@ static inline void pud_free_tlb(struct mmu_gather *tlb, pud_t *pud,
146 if (tlb->nr_ptes >= tlb->nr_pxds) 147 if (tlb->nr_ptes >= tlb->nr_pxds)
147 tlb_flush_mmu(tlb, 0, 0); 148 tlb_flush_mmu(tlb, 0, 0);
148 } else 149 } else
149 pud_free(tlb->mm, pud); 150 crst_table_free(tlb->mm, (unsigned long *) pud);
150#endif 151#endif
151} 152}
152 153