 
	
| [Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] RE: [Xen-devel] high memory dma update: up against a wall
 Scott Parish wrote:
> I've been slowly working on the dma problem i ran into; thought i was
> making progress, but i think i'm up against a wall, so more discussion
> and ideas might be helpful.
I think porting swiotlb (arch/ia64/lib/swiotlb.c) is one of other
approaches for EM64T as we are using it in the native x86_64 Linux. We
need at least 64MB physically contiguous memory below 4GB for that. For
dom0, I think we can find such area at boot time. 
We have a plan to work on that, but it will be after OLS...
Basically, the io_tlb_start is the starting address of the buffer. You
need to ensure that the memory is physically contiguous in machine
physical. I think it's easy to find such an area in dom0.
alloc_bootmem_low_pages() may not work, so you may need to write a new
(simple) function.
swiotlb_init_with_default_size (size_t default_size)
{
        unsigned long i;
        if (!io_tlb_nslabs) {
                io_tlb_nslabs = (default_size >> PAGE_SHIFT);
                io_tlb_nslabs = ALIGN(io_tlb_nslabs, IO_TLB_SEGSIZE);
        }
        /*
         * Get IO TLB memory from the low pages
         */
        io_tlb_start = alloc_bootmem_low_pages(io_tlb_nslabs *
                                               (1 << IO_TLB_SHIFT));
Other thing is to use virt_to_bus() not virt_to_phys(). See below.
void *
swiotlb_alloc_coherent(struct device *hwdev, size_t size,
                       dma_addr_t *dma_handle, int flags)
{
        unsigned long dev_addr;
        void *ret;
        int order = get_order(size);
        /*
         * XXX fix me: the DMA API should pass us an explicit DMA mask
         * instead, or use ZONE_DMA32 (ia64 overloads ZONE_DMA to be a
~32
         * bit range instead of a 16MB one).
         */
        flags |= GFP_DMA;
        ret = (void *)__get_free_pages(flags, order);
        if (ret && address_needs_mapping(hwdev, virt_to_phys(ret))) {
                /*
                 * The allocated memory isn't reachable by the device.
                 * Fall back on swiotlb_map_single().
                 */
            free_pages((unsigned long) ret, order);
                ret = NULL;
        }
The baisc idea of swiotlb is if the memory allocate is lower than 4GB,
then just use it. If not, allocate memory chunk from the buffer:
        if (!ret) {
                /*
                 * We are either out of memory or the device can't DMA
                 * to GFP_DMA memory; fall back on
                 * swiotlb_map_single(), which will grab memory from
                 * the lowest available address range.
                 */
                dma_addr_t handle;
                handle = swiotlb_map_single(NULL, NULL, size,
DMA_FROM_DEVICE);
                if (dma_mapping_error(handle))
                        return NULL;
                ret = phys_to_virt(handle);
        }
Jun
---
Intel Open Source Technology Center
_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-devel
 | 
|  | Lists.xenproject.org is hosted with RackSpace, monitoring our |