consistent_alloc() revisited
A little while back Tom Rini suggested that we implement the various tricks ARM uses in its version of consistent_alloc() in our version. I've made a start on that, but there are some complications. There are basically two things that ARM does and we don't: 1. Frees unused pages in the allocation, if the requested size isn't a power of two pages 2. Marks the pages Reserved In addition, the following seem to me like desirable (to a greater or lesser extent) properties for consistent_alloc(): a. one of the return values can be used as a single handle so that consistent_free() only needs one parameter. b. works on both cache coherent and non cache coherent machines c. be able to use highmem pages (1) is certainly desirable and the attached patch implements it (for 2.5). I think the patch may also correct some potential bugs in the current implementation - I'm not 100% convinced the current implementation can't leak memory if map_page() fails at the wrong time. I'll commit this if no-one has objections. (2) is a little more complicated. The reason asserted in the comments in the ARM code is so that remap_page_range() works. However, the only code I can see that would call remap_page_range() on memory which came from consistent_alloc() (actually from pci_alloc_consistent()) is in some (apparently x86 specific) sound drivers. [actually these are broken on PPC (2.5) anyway since they use virt_to_bus() on the virtual address returned by pci_alloc_consistent() but that's easily fixed]. These drivers set and clear PageReserved themselves, so they're clearly not expecting pci_alloc_consistent() to return Reserved pages. Arguably setting PageReserved is the Right Thing, since consistent_alloc() memory obviously shouldn't be swapped or paged. However, it's only relevant if the memory is mapped into userspace, and then a driver can set VM_IO on the vma to prevent this. Furthermore, at the moment it is diffuclt for a general driver to correctly map consistent_alloc() memory into userspace, since it must set the flags on the new mappings correctly to disable caching on machines which aren't DMA consistent. At the moment that means the driver must be (a) arch-specific and (b) have an ifdef on CONFIG_NOT_COHERENT_CACHE or various different options for some of the other archs. Therefore, I think a _PAGE_DMA_CONSISTENT page flag would be a useful thing. Patches probably forthcoming. We currently have (a) by use of vfree() on the virtual address, we don't have (b) or (c). Some earlier patches of mine added (b), but at the expense of (a). paulus pointer out however, that we can add (b) while keeping (a) by having consistent_alloc() remap the memory even on cache coherent machines - it will just omit the cache flush and the _PAGE_NO_CACHE flag. A _PAGE_DMA_CONSISTENT would make this even easier. As a bonus, having this remapping gives us (c) almost for free. Comments? Objections? -- David Gibson| For every complex problem there is a david at gibson.dropbear.id.au | solution which is simple, neat and | wrong. http://www.ozlabs.org/people/dgibson -- next part -- diff -urN /home/dgibson/kernel/linuxppc-2.5/arch/ppc/mm/cachemap.c linux-bluefish/arch/ppc/mm/cachemap.c --- /home/dgibson/kernel/linuxppc-2.5/arch/ppc/mm/cachemap.cFri Jun 28 10:40:59 2002 +++ linux-bluefish/arch/ppc/mm/cachemap.c Mon Jul 15 16:20:39 2002 @@ -61,57 +61,69 @@ */ void *consistent_alloc(int gfp, size_t size, dma_addr_t *dma_handle) { - int order, err, i; - unsigned long page, va, pa, flags; - struct vm_struct *area; - void *ret; + int order, err; + struct page *page, *free, *end; + unsigned long pa, flags, offset; + struct vm_struct *area = NULL; + unsigned long va = 0; - if (in_interrupt()) - BUG(); + BUG_ON(in_interrupt()); - /* Only allocate page size areas. - */ + /* Only allocate page size areas */ size = PAGE_ALIGN(size); order = get_order(size); - page = __get_free_pages(gfp, order); - if (!page) { - BUG(); + free = page = alloc_pages(gfp, order); + if (! page) return NULL; - } + + pa = page_to_phys(page); + *dma_handle = page_to_bus(page); + end = page + (1 order); /* * we need to ensure that there are no cachelines in use, * or worse dirty in this area. */ - invalidate_dcache_range(page, page + size); + invalidate_dcache_range((unsigned long)page_address(page), + (unsigned long)page_address(page) + size); - /* Allocate some common virtual space to map the new pages. - */ + /* +* alloc_pages() expects the block to be handled as a unit, so +* it only sets the page count on the first page.
Poor 8xx SCC Ethernet mode performence..
Hi . I was testing SCC ethernet performance at our 850 custom board and found somting interesting. 1. Tested FTP Transfer about 20MB file with 10T hub I got about 250 k bps (someting poor ..) 2. and I found the hhl20 arch/ppc/8xx_io/enet.c source code NOT enable full duplex .. and I had pmsr added SCC_PMSR_FDE | SCC_PMSR_LPB .. and compiling , tested FTP Transfer again. I got about 200 Kbps! I do not understand what is happen? Has anyone experience this? ** Sent via the linuxppc-embedded mail list. See http://lists.linuxppc.org/
ioremap on powerpc question
[...] However, on powerpc, as soon as I try to do, for example: *buf = '\0'; // write one char to virt addr returned by ioremap It blows up with a machine check. You are hitting a 440GP specific feature. ioremap is trapping ranges of addresses and fixing them up with the proper ERPN. Unfortunately, I left the default on a no match as an ERPN=1 which will ioremap 1 0400 . That's why you get a bus error. Try this patch: Thanks! That appears to work. and thanks for explaining the rationale on the readb/writeb requirement. -- steve ** Sent via the linuxppc-embedded mail list. See http://lists.linuxppc.org/
consistent_alloc() revisited
David Gibson wrote: In addition, the following seem to me like desirable (to a greater or lesser extent) properties for consistent_alloc(): a. one of the return values can be used as a single handle so that consistent_free() only needs one parameter. We want the implementation API to be identical across all architectures. Until there is a consistent way of handling devices that are on local processor busses, platforms with these types of devices may call these functions directly.This is particularly true of some host USB controllers on embedded systems that don't have PCI busses. b. works on both cache coherent and non cache coherent machines The original purpose of the consistent_* functions was to provide support for processors that aren't cache coherent. The pci_* (and any other functions) can call these if appropriate, but I still believe the decision should be made at a higher level. Obviously, these consistent_* functions will be implemented differently on non- or cache coherent processors, and across different architectures. The PCI functions (or others) should still do their thing as they always have, and call these consistent_* functions when appropriate. c. be able to use highmem pages You think there will be non-coherent processors with this much memory? :-) - if (in_interrupt()) - BUG(); + BUG_ON(in_interrupt()); We should be able to call these functions from interrupt, let's push the remainder of the changes though get_free_pages() to make this happen. Thanks. -- Dan ** Sent via the linuxppc-embedded mail list. See http://lists.linuxppc.org/
consistent_alloc() revisited
On Tue, Jul 16, 2002 at 10:09:03AM -0400, Dan Malek wrote: David Gibson wrote: -if (in_interrupt()) -BUG(); +BUG_ON(in_interrupt()); We should be able to call these functions from interrupt, let's push the remainder of the changes though get_free_pages() to make this happen. I think the only reason we should keep that like it is, for now, is that fixing that requires other generic changes. Which Paul was going to ask Dave M about doing. Paul, any word back from him yet? -- Tom Rini (TR1265) http://gate.crashing.org/~trini/ ** Sent via the linuxppc-embedded mail list. See http://lists.linuxppc.org/
consistent_alloc() revisited
On Tue, Jul 16, 2002 at 10:09:03AM -0400, Dan Malek wrote: David Gibson wrote: c. be able to use highmem pages You think there will be non-coherent processors with this much memory? :-) I guess you're kidding, but to be clear to everybody, the 440GP does handle up to 2GB of DDR. I run my ref platform with 1GB using highmem. To be fair, I don't like this proliferation of non-coherent processors (especially in the high-end PPC application space) any better than you do. :-/ Regards, -- Matt Porter porter at cox.net This is Linux Country. On a quiet night, you can hear Windows reboot. ** Sent via the linuxppc-embedded mail list. See http://lists.linuxppc.org/
consistent_alloc() revisited
On Tue, Jul 16, 2002 at 10:09:03AM -0400, Dan Malek wrote: David Gibson wrote: - if (in_interrupt()) - BUG(); + BUG_ON(in_interrupt()); We should be able to call these functions from interrupt, let's push the remainder of the changes though get_free_pages() to make this happen. Yes, not just should, but must. They must be callable from an interrupt since many generic drivers follow the rules as they have been laid down and allocate from an interrupt context. Regards, -- Matt Porter porter at cox.net This is Linux Country. On a quiet night, you can hear Windows reboot. ** Sent via the linuxppc-embedded mail list. See http://lists.linuxppc.org/
consistent_alloc() revisited
Dan and Matt I agree with you 100% Chip -- Forwarded by Ralph Blach/Raleigh/IBM on 07/16/2002 12:13 PM --- Matt Porter porter at cox.net@lists.linuxppc.org on 07/16/2002 11:27:26 AM Sent by:owner-linuxppc-embedded at lists.linuxppc.org To:Dan Malek dan at embeddededge.com cc:David Gibson david at gibson.dropbear.id.au, linuxppc-embedded at lists.linuxppc.org Subject:Re: consistent_alloc() revisited On Tue, Jul 16, 2002 at 10:09:03AM -0400, Dan Malek wrote: David Gibson wrote: - if (in_interrupt()) - BUG(); + BUG_ON(in_interrupt()); We should be able to call these functions from interrupt, let's push the remainder of the changes though get_free_pages() to make this happen. Yes, not just should, but must. They must be callable from an interrupt since many generic drivers follow the rules as they have been laid down and allocate from an interrupt context. Regards, -- Matt Porter porter at cox.net This is Linux Country. On a quiet night, you can hear Windows reboot. ** Sent via the linuxppc-embedded mail list. See http://lists.linuxppc.org/
Poor 8xx SCC Ethernet mode performence..
Jim Lin wrote: Hi . I was testing SCC ethernet performance at our 850 custom board and found somting interesting. 1. Tested FTP Transfer about 20MB file with 10T hub I got about 250 k bps (someting poor ..) 2. and I found the hhl20 arch/ppc/8xx_io/enet.c source code NOT enable full duplex .. and I had pmsr added SCC_PMSR_FDE | SCC_PMSR_LPB .. and compiling , tested FTP Transfer again. I got about 200 Kbps! I do not understand what is happen? Has anyone experience this? I know for a fact that the 850 can do 10Mbits . Check and see what the download rate is from your ftp host using a different computer. Your 850 board should be about the same speed. If your 850 board isn't try looking at the Tx and Rx ethernet data lines with an oscilliscope. If the activity on the lines seems to corespond to the with the datarate you have a software problem. If the activity is signifigantly greater you probably have a analog problem. Double check the turns ratio on your magnet and make sure it is what your phy needs. Good luck Conn -- * If you live at home long enough, your parents will move out. (Warning they may try to sell their house out from under you.) * Conn Clark Engineering Stooge clark at esteem.com Electronic Systems Technology Inc. www.esteem.com ** Sent via the linuxppc-embedded mail list. See http://lists.linuxppc.org/