Write Combining (Write Coalescing) on memory mapped I/O on IA64.
Hi,
I have a PCI adapter which does a lot of PIO (sort of network adapter using host CPU to send data). On IA32 architechtures we could enable Write Combining to get large burst on the PCI bus, but on IA64 I get at max 8 byte stores (ld8, st8) at a time.
The driver for this adapter also exports the memory to user-space (with mmap()) and when doing this I do (inside the mmap function) :
int ssci_mmap(struct file *file, struct vm_area_struct *vma) {
.....
#ifdef __ia64__
vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot);
#endif
map_page_range(file, vma, vm_start,physaddr,
contlen, vma->vm_page_prot);
remap_page_range(vma->vm_start,
phys_addr, vma->vm_end - vma->vm_start, vma->vm_page_prot))
....
}
This way we get Write Combining on IA64, but only for userspace mappings. Kernel space clients use ioremap() and don't get Write Combining (ioremap on IA64 use the uncacheable region directly).
To solve this I've tried to make my own __ia64_ioremap() (created arch/ia64/mm/ioremap.c) wich has a 'flags' input paramenter so that I can set the _PAGE_MA_WC attribute. I've taken a look on how other architechtures does this (e.g i386 or s390), and made it nearly identical, but it doesn't seem to work. The mapping gets set up, but if I try to read or write something to this address I get a "Unable to handle kernel paging request at virtual address 0xa00000000015c000" which is the address I'm accessing.
I've attached the patch I made. Please let me know if this is doable on IA64 at all. Feedback greatly appreciated.
Thanks,
Signature · 4 lines
Steffen Persvold Systems Engineer Email : mailto:[email protected] Scali AS (http://www.scali.com) Tlf : (+47) 22 62 89 50 Olaf Helsets vei 6 Fax : (+47) 22 62 89 51 N-0621 Oslo, Norway
arch/ia64/mm/Makefile renamed from arch/ia64/mm/Makefile.~1~ +1 -1
@@ -9,6 +9,6 @@ O_TARGET := mm.o -obj-y := init.o fault.o tlb.o extable.o +obj-y := init.o fault.o ioremap.o tlb.o extable.o include $(TOPDIR)/Rules.make
arch/ia64/mm/ioremap.c renamed from arch/ia64/mm/ioremap.c.~1~ +148 -0
148 lines not on this page · raw message
arch/ia64/kernel/ia64_ksyms.c renamed from arch/ia64/kernel/ia64_ksyms.c.~1~ +2 -0
@@ -39,6 +39,8 @@EXPORT_SYMBOL (ip_fast_csum);#include <asm/io.h> +EXPORT_SYMBOL (__ia64_ioremap); +EXPORT_SYMBOL (__ia64_iounmap);EXPORT_SYMBOL (__ia64_memcpy_fromio);EXPORT_SYMBOL (__ia64_memcpy_toio);EXPORT_SYMBOL (__ia64_memset_c_io);
include/asm-ia64/io.h renamed from include/asm-ia64/io.h.~1~ +3 -0
@@ -386,6 +386,9 @@#define ioremap_nocache (o,s) ioremap(o,s) +extern void *__ia64_ioremap (unsigned long offset,unsigned long size,unsigned long flags); +extern void __ia64_iounmap (void *addr); +# ifdef __KERNEL__/*
Just a repost since I didn't get any feedback. I've also copied some auhtors I found in asm/io.h. I appologize for any inconvenience, but this issue is quite important to us.
Regards,
Signature · 54 lines
Steffen Persvold Systems Engineer Email : mailto:[email protected] Scali AS (http://www.scali.com) Tlf : (+47) 22 62 89 50 Olaf Helsets vei 6 Fax : (+47) 22 62 89 51 N-0621 Oslo, Norway Hi, I have a PCI adapter which does a lot of PIO (sort of network adapter using host CPU to send data). On IA32 architechtures we could enable Write Combining to get large burst on the PCI bus, but on IA64 I get at max 8 byte stores (ld8, st8) at a time. The driver for this adapter also exports the memory to user-space (with mmap()) and when doing this I do (inside the mmap function) : int ssci_mmap(struct file *file, struct vm_area_struct *vma) { ..... #ifdef __ia64__ vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot); #endif map_page_range(file, vma, vm_start,physaddr, contlen, vma->vm_page_prot); remap_page_range(vma->vm_start, phys_addr, vma->vm_end - vma->vm_start, vma->vm_page_prot)) .... } This way we get Write Combining on IA64, but only for userspace mappings. Kernel space clients use ioremap() and don't get Write Combining (ioremap on IA64 use the uncacheable region directly). To solve this I've tried to make my own __ia64_ioremap() (created arch/ia64/mm/ioremap.c) wich has a 'flags' input paramenter so that I can set the _PAGE_MA_WC attribute. I've taken a look on how other architechtures does this (e.g i386 or s390), and made it nearly identical, but it doesn't seem to work. The mapping gets set up, but if I try to read or write something to this address I get a "Unable to handle kernel paging request at virtual address 0xa00000000015c000" which is the address I'm accessing. I've attached the patch I made. Please let me know if this is doable on IA64 at all. Feedback greatly appreciated. Thanks, -- Steffen Persvold Systems Engineer Email : mailto:[email protected] Scali AS (http://www.scali.com) Tlf : (+47) 22 62 89 50 Olaf Helsets vei 6 Fax : (+47) 22 62 89 51 N-0621 Oslo, Norway
arch/ia64/mm/Makefile renamed from arch/ia64/mm/Makefile.~1~ +1 -1
@@ -9,6 +9,6 @@ O_TARGET := mm.o -obj-y := init.o fault.o tlb.o extable.o +obj-y := init.o fault.o ioremap.o tlb.o extable.o include $(TOPDIR)/Rules.make
arch/ia64/mm/ioremap.c renamed from arch/ia64/mm/ioremap.c.~1~ +148 -0
148 lines not on this page · raw message
arch/ia64/kernel/ia64_ksyms.c renamed from arch/ia64/kernel/ia64_ksyms.c.~1~ +2 -0
@@ -39,6 +39,8 @@EXPORT_SYMBOL (ip_fast_csum);#include <asm/io.h> +EXPORT_SYMBOL (__ia64_ioremap); +EXPORT_SYMBOL (__ia64_iounmap);EXPORT_SYMBOL (__ia64_memcpy_fromio);EXPORT_SYMBOL (__ia64_memcpy_toio);EXPORT_SYMBOL (__ia64_memset_c_io);
include/asm-ia64/io.h renamed from include/asm-ia64/io.h.~1~ +3 -0
@@ -386,6 +386,9 @@#define ioremap_nocache (o,s) ioremap(o,s) +extern void *__ia64_ioremap (unsigned long offset,unsigned long size,unsigned long flags); +extern void __ia64_iounmap (void *addr); +# ifdef __KERNEL__/*