diff options
author | Paul Mundt <lethal@linux-sh.org> | 2009-12-04 01:14:52 -0500 |
---|---|---|
committer | Paul Mundt <lethal@linux-sh.org> | 2009-12-04 01:14:52 -0500 |
commit | 7e01c949989b984c074469e04ab99c47367c7187 (patch) | |
tree | 86b505a69cbbffb8319466453a0e945f771e19ae /arch/sh/mm/cache.c | |
parent | 8144a7dd51712ab58d052f4df4420768ec5489ef (diff) |
sh: Partial revert of copy/clear_user_highpage() optimizations.
These still require more testing, so revert them for now. We keep the
off-by-1 in the fixmap colouring and drop the rest.
Signed-off-by: Paul Mundt <lethal@linux-sh.org>
Diffstat (limited to 'arch/sh/mm/cache.c')
-rw-r--r-- | arch/sh/mm/cache.c | 66 |
1 files changed, 13 insertions, 53 deletions
diff --git a/arch/sh/mm/cache.c b/arch/sh/mm/cache.c index 997c7e42b1e1..e9415d3ea94a 100644 --- a/arch/sh/mm/cache.c +++ b/arch/sh/mm/cache.c | |||
@@ -46,18 +46,6 @@ static inline void cacheop_on_each_cpu(void (*func) (void *info), void *info, | |||
46 | preempt_enable(); | 46 | preempt_enable(); |
47 | } | 47 | } |
48 | 48 | ||
49 | /* | ||
50 | * copy_to_user_page | ||
51 | * @vma: vm_area_struct holding the pages | ||
52 | * @page: struct page | ||
53 | * @vaddr: user space address | ||
54 | * @dst: address of page in kernel space (possibly from kmap) | ||
55 | * @src: source address in kernel logical memory | ||
56 | * @len: length of data in bytes (may be less than PAGE_SIZE) | ||
57 | * | ||
58 | * Copy data into the address space of a process other than the current | ||
59 | * process (eg for ptrace). | ||
60 | */ | ||
61 | void copy_to_user_page(struct vm_area_struct *vma, struct page *page, | 49 | void copy_to_user_page(struct vm_area_struct *vma, struct page *page, |
62 | unsigned long vaddr, void *dst, const void *src, | 50 | unsigned long vaddr, void *dst, const void *src, |
63 | unsigned long len) | 51 | unsigned long len) |
@@ -93,49 +81,28 @@ void copy_from_user_page(struct vm_area_struct *vma, struct page *page, | |||
93 | } | 81 | } |
94 | } | 82 | } |
95 | 83 | ||
96 | /* | ||
97 | * copy_user_highpage | ||
98 | * @to: destination page | ||
99 | * @from: source page | ||
100 | * @vaddr: address of pages in user address space | ||
101 | * @vma: vm_area_struct holding the pages | ||
102 | * | ||
103 | * This is used in COW implementation to copy data from page @from to | ||
104 | * page @to. @from was previousl mapped at @vaddr, and @to will be. | ||
105 | * As this is used only in the COW implementation, this means that the | ||
106 | * source is unmodified, and so we don't have to worry about cache | ||
107 | * aliasing on that side. | ||
108 | */ | ||
109 | #ifdef CONFIG_HIGHMEM | ||
110 | /* | ||
111 | * If we ever have a real highmem system, this code will need fixing | ||
112 | * (as will clear_user/clear_user_highmem), because the kmap potentitally | ||
113 | * creates another alias risk. | ||
114 | */ | ||
115 | #error This code is broken with real HIGHMEM | ||
116 | #endif | ||
117 | void copy_user_highpage(struct page *to, struct page *from, | 84 | void copy_user_highpage(struct page *to, struct page *from, |
118 | unsigned long vaddr, struct vm_area_struct *vma) | 85 | unsigned long vaddr, struct vm_area_struct *vma) |
119 | { | 86 | { |
120 | void *vfrom, *vto; | 87 | void *vfrom, *vto; |
121 | 88 | ||
122 | vto = kmap_atomic(to, KM_USER1); | 89 | vto = kmap_atomic(to, KM_USER1); |
123 | vfrom = kmap_atomic(from, KM_USER0); | ||
124 | |||
125 | if (pages_do_alias((unsigned long)vto, vaddr & PAGE_MASK)) | ||
126 | __flush_invalidate_region(vto, PAGE_SIZE); | ||
127 | 90 | ||
128 | if (boot_cpu_data.dcache.n_aliases && page_mapped(from) && | 91 | if (boot_cpu_data.dcache.n_aliases && page_mapped(from) && |
129 | !test_bit(PG_dcache_dirty, &from->flags)) { | 92 | !test_bit(PG_dcache_dirty, &from->flags)) { |
130 | void *vto_coloured = kmap_coherent(to, vaddr); | 93 | vfrom = kmap_coherent(from, vaddr); |
131 | copy_page(vto_coloured, vfrom); | ||
132 | kunmap_coherent(vto_coloured); | ||
133 | } else | ||
134 | copy_page(vto, vfrom); | 94 | copy_page(vto, vfrom); |
95 | kunmap_coherent(vfrom); | ||
96 | } else { | ||
97 | vfrom = kmap_atomic(from, KM_USER0); | ||
98 | copy_page(vto, vfrom); | ||
99 | kunmap_atomic(vfrom, KM_USER0); | ||
100 | } | ||
135 | 101 | ||
136 | kunmap_atomic(vfrom, KM_USER0); | 102 | if (pages_do_alias((unsigned long)vto, vaddr & PAGE_MASK)) |
137 | kunmap_atomic(vto, KM_USER1); | 103 | __flush_purge_region(vto, PAGE_SIZE); |
138 | 104 | ||
105 | kunmap_atomic(vto, KM_USER1); | ||
139 | /* Make sure this page is cleared on other CPU's too before using it */ | 106 | /* Make sure this page is cleared on other CPU's too before using it */ |
140 | smp_wmb(); | 107 | smp_wmb(); |
141 | } | 108 | } |
@@ -145,17 +112,10 @@ void clear_user_highpage(struct page *page, unsigned long vaddr) | |||
145 | { | 112 | { |
146 | void *kaddr = kmap_atomic(page, KM_USER0); | 113 | void *kaddr = kmap_atomic(page, KM_USER0); |
147 | 114 | ||
148 | if (pages_do_alias((unsigned long)kaddr, vaddr & PAGE_MASK)) { | 115 | clear_page(kaddr); |
149 | void *vto; | ||
150 | 116 | ||
151 | /* Kernel alias may have modified data in the cache. */ | 117 | if (pages_do_alias((unsigned long)kaddr, vaddr & PAGE_MASK)) |
152 | __flush_invalidate_region(kaddr, PAGE_SIZE); | 118 | __flush_purge_region(kaddr, PAGE_SIZE); |
153 | |||
154 | vto = kmap_coherent(page, vaddr); | ||
155 | clear_page(vto); | ||
156 | kunmap_coherent(vto); | ||
157 | } else | ||
158 | clear_page(kaddr); | ||
159 | 119 | ||
160 | kunmap_atomic(kaddr, KM_USER0); | 120 | kunmap_atomic(kaddr, KM_USER0); |
161 | } | 121 | } |