Skip to content

Commit f8dae00

Browse files
danglin44hdeller
authored andcommitted
parisc: Ensure full cache coherency for kmap/kunmap
Helge Deller noted a few weeks ago problems with the AIO support on parisc. This change is the result of numerous iterations on how best to deal with this problem. The solution adopted here is to provide full cache coherency in a uniform manner on all parisc systems. This involves calling flush_dcache_page() on kmap operations and flush_kernel_dcache_page() on kunmap operations. As a result, the copy_user_page() and clear_user_page() functions can be removed and the overall code is simpler. The change ensures that both userspace and kernel aliases to a mapped page are invalidated and flushed. This is necessary for the correct operation of PA8800 and PA8900 based systems which do not support inequivalent aliases. With this change, I have observed no cache related issues on c8000 and rp3440. It is now possible for example to do kernel builds with "-j64" on four way systems. On systems using XFS file systems, the patch recently posted by Mikulas Patocka to "fix crash using XFS on loopback" is needed to avoid a hang caused by an uninitialized lock passed to flush_dcache_page() in the page struct. Signed-off-by: John David Anglin <[email protected]> Cc: [email protected] # v3.9+ Signed-off-by: Helge Deller <[email protected]>
1 parent ceb3b02 commit f8dae00

File tree

3 files changed

+6
-46
lines changed

3 files changed

+6
-46
lines changed

arch/parisc/include/asm/cacheflush.h

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -125,42 +125,38 @@ flush_anon_page(struct vm_area_struct *vma, struct page *page, unsigned long vma
125125
void mark_rodata_ro(void);
126126
#endif
127127

128-
#ifdef CONFIG_PA8X00
129-
/* Only pa8800, pa8900 needs this */
130-
131128
#include <asm/kmap_types.h>
132129

133130
#define ARCH_HAS_KMAP
134131

135-
void kunmap_parisc(void *addr);
136-
137132
static inline void *kmap(struct page *page)
138133
{
139134
might_sleep();
135+
flush_dcache_page(page);
140136
return page_address(page);
141137
}
142138

143139
static inline void kunmap(struct page *page)
144140
{
145-
kunmap_parisc(page_address(page));
141+
flush_kernel_dcache_page_addr(page_address(page));
146142
}
147143

148144
static inline void *kmap_atomic(struct page *page)
149145
{
150146
pagefault_disable();
147+
flush_dcache_page(page);
151148
return page_address(page);
152149
}
153150

154151
static inline void __kunmap_atomic(void *addr)
155152
{
156-
kunmap_parisc(addr);
153+
flush_kernel_dcache_page_addr(addr);
157154
pagefault_enable();
158155
}
159156

160157
#define kmap_atomic_prot(page, prot) kmap_atomic(page)
161158
#define kmap_atomic_pfn(pfn) kmap_atomic(pfn_to_page(pfn))
162159
#define kmap_atomic_to_page(ptr) virt_to_page(ptr)
163-
#endif
164160

165161
#endif /* _PARISC_CACHEFLUSH_H */
166162

arch/parisc/include/asm/page.h

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,9 +28,8 @@ struct page;
2828

2929
void clear_page_asm(void *page);
3030
void copy_page_asm(void *to, void *from);
31-
void clear_user_page(void *vto, unsigned long vaddr, struct page *pg);
32-
void copy_user_page(void *vto, void *vfrom, unsigned long vaddr,
33-
struct page *pg);
31+
#define clear_user_page(vto, vaddr, page) clear_page_asm(vto)
32+
#define copy_user_page(vto, vfrom, vaddr, page) copy_page_asm(vto, vfrom)
3433

3534
/* #define CONFIG_PARISC_TMPALIAS */
3635

arch/parisc/kernel/cache.c

Lines changed: 0 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -388,41 +388,6 @@ void flush_kernel_dcache_page_addr(void *addr)
388388
}
389389
EXPORT_SYMBOL(flush_kernel_dcache_page_addr);
390390

391-
void clear_user_page(void *vto, unsigned long vaddr, struct page *page)
392-
{
393-
clear_page_asm(vto);
394-
if (!parisc_requires_coherency())
395-
flush_kernel_dcache_page_asm(vto);
396-
}
397-
EXPORT_SYMBOL(clear_user_page);
398-
399-
void copy_user_page(void *vto, void *vfrom, unsigned long vaddr,
400-
struct page *pg)
401-
{
402-
/* Copy using kernel mapping. No coherency is needed
403-
(all in kmap/kunmap) on machines that don't support
404-
non-equivalent aliasing. However, the `from' page
405-
needs to be flushed before it can be accessed through
406-
the kernel mapping. */
407-
preempt_disable();
408-
flush_dcache_page_asm(__pa(vfrom), vaddr);
409-
preempt_enable();
410-
copy_page_asm(vto, vfrom);
411-
if (!parisc_requires_coherency())
412-
flush_kernel_dcache_page_asm(vto);
413-
}
414-
EXPORT_SYMBOL(copy_user_page);
415-
416-
#ifdef CONFIG_PA8X00
417-
418-
void kunmap_parisc(void *addr)
419-
{
420-
if (parisc_requires_coherency())
421-
flush_kernel_dcache_page_addr(addr);
422-
}
423-
EXPORT_SYMBOL(kunmap_parisc);
424-
#endif
425-
426391
void purge_tlb_entries(struct mm_struct *mm, unsigned long addr)
427392
{
428393
unsigned long flags;

0 commit comments

Comments
 (0)