Behaviour of consistent_{alloc|free}

Frank Haverkamp f.haverkamp at web.de
Wed Apr 23 23:55:55 EST 2003


Hi,

I am working with a PowerPC 405 based asic having PCI_DRAM_OFFSET to be defined not to be zero.
I was using consistent_alloc to get a memory area to be used by my ethernet driver for its descriptor tables.

consistent_alloc returned a virtual address and the address on my pci bus. The address on the bus was
returned correctly, but the mapping consistent_alloc was working was not like I expected it.
It maps the virtual address to an address on the bus and not to the real address of my DRAM.
A mapping to the real address in DRAM is, what I wanted to have. I tried to do a virt_to_phys
on the virtual address, but got, again, the address on the bus. And a bus_to_phys I could not find ;-)

Now I wondered, how consistent_free could work, since consistent_alloc did a get_free_pages, but did not store the physical address of that buffer somewhere. Instead it stored the bus address. I did the following experiment:

TEST TEST TEST ...
DESCR: virt_addr=0xc7b82000 bus_addr=0xf6e6b000
       phys_addr=0xf6e6b000 pci_dram_offset=0xf4000000
DESCR: virt_addr=0xc7b82000 bus_addr=0xf6e6a000
       phys_addr=0xf6e6a000 pci_dram_offset=0xf4000000
DESCR: virt_addr=0xc7b82000 bus_addr=0xf6e91000
       phys_addr=0xf6e91000 pci_dram_offset=0xf4000000
DESCR: virt_addr=0xc7b82000 bus_addr=0xf6e90000
       phys_addr=0xf6e90000 pci_dram_offset=0xf4000000
DESCR: virt_addr=0xc7b82000 bus_addr=0xf6e29000
       phys_addr=0xf6e29000 pci_dram_offset=0xf4000000
DESCR: virt_addr=0xc7b82000 bus_addr=0xf6e28000
       phys_addr=0xf6e28000 pci_dram_offset=0xf4000000

I was wondering if that can be correct, since I am allocating the same amount of memory all the time and returning it immediatly after doing that. So I would expect, that the function returns the same physical and bus addresses again, since I expect it to be deterministic.

After thinking about it I modified consistent_alloc in the following way:

        ....
        /* Allocate some common virtual space to map the new pages.
        */
        area = get_vm_area(size, VM_ALLOC);
        if (area == 0) {
                free_pages(page, order);
                return NULL;
        }
        va = VMALLOC_VMADDR(area->addr);
        ret = (void *)va;

        /* This gives us the real physical address of the first page.
        */
#if defined(WITH_MY_FIX)
        *dma_handle = virt_to_bus(page);
        pa = virt_to_phys(page);
#else
        *dma_handle = pa = virt_to_bus(page);
#endif

        flags = _PAGE_KERNEL | _PAGE_NO_CACHE;

        err = 0;
        for (i = 0; i < size && err == 0; i += PAGE_SIZE)
                err = map_page(va+i, pa+i, flags);
        ....

Now the returned mapping done to the physical memory instead of the bus addresses, which I cannot access directly on my system. Now my system can perform the consistent_free function correctly and it prints:

DESCR: virt_addr=0xc7b82000 bus_addr=0xf6e53000
       phys_addr=0x02e53000 pci_dram_offset=0xf4000000
DESCR: virt_addr=0xc7b82000 bus_addr=0xf6e53000
       phys_addr=0x02e53000 pci_dram_offset=0xf4000000
DESCR: virt_addr=0xc7b82000 bus_addr=0xf6e53000
       phys_addr=0x02e53000 pci_dram_offset=0xf4000000
DESCR: virt_addr=0xc7b82000 bus_addr=0xf6e53000
       phys_addr=0x02e53000 pci_dram_offset=0xf4000000
DESCR: virt_addr=0xc7b82000 bus_addr=0xf6e53000
       phys_addr=0x02e53000 pci_dram_offset=0xf4000000
DESCR: virt_addr=0xc7b82000 bus_addr=0xf6e53000
       phys_addr=0x02e53000 pci_dram_offset=0xf4000000

Which I consider to be ok. If I observed that correctly, consistent_alloc has a memory leak and strange things may happen if consistent_free is called. Any opinions on that?


Frank Haverkamp

--
Frank Haverkamp
f.haverkamp at web.de
______________________________________________________________________________
UNICEF bittet um Spenden für die Kinder im Irak! Hier online an
UNICEF spenden: https://spenden.web.de/unicef/special/?mc=021101


** Sent via the linuxppc-embedded mail list. See http://lists.linuxppc.org/





More information about the Linuxppc-embedded mailing list