WARNING - OLD ARCHIVES

This is an archived copy of the Xen.org mailing list, which we have preserved to ensure that existing links to archives are not broken. The live archive, which contains the latest emails, can be found at http://lists.xen.org/
   
 
 
Xen 
 
Home Products Support Community News
 
   
 

xen-devel

[Xen-devel] Re: ATI radeon fails with "iommu=soft swiotlb=force" (seen o

To: Konrad Rzeszutek Wilk <konrad.wilk@xxxxxxxxxx>
Subject: [Xen-devel] Re: ATI radeon fails with "iommu=soft swiotlb=force" (seen on RV730/RV740 and RS780/RS800)
From: Jeremy Fitzhardinge <jeremy@xxxxxxxx>
Date: Thu, 01 Oct 2009 12:37:32 -0700
Cc: dri-devel@xxxxxxxxxxxxxxxxxxxxx, xen-devel@xxxxxxxxxxxxxxxxxxx, JBeulich@xxxxxxxxxx
Delivery-date: Thu, 01 Oct 2009 12:37:59 -0700
Envelope-to: www-data@xxxxxxxxxxxxxxxxxxx
In-reply-to: <4AC4FDEA.3070909@xxxxxxxx>
List-help: <mailto:xen-devel-request@lists.xensource.com?subject=help>
List-id: Xen developer discussion <xen-devel.lists.xensource.com>
List-post: <mailto:xen-devel@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/mailman/listinfo/xen-devel>, <mailto:xen-devel-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/mailman/listinfo/xen-devel>, <mailto:xen-devel-request@lists.xensource.com?subject=unsubscribe>
References: <20090930152149.GA29603@xxxxxxxxxxxxxxxxxxx> <20091001173558.GA1921@xxxxxxxxxxxxxxxxxxx> <4AC4FDEA.3070909@xxxxxxxx>
Sender: xen-devel-bounces@xxxxxxxxxxxxxxxxxxx
User-agent: Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.1.1) Gecko/20090814 Fedora/3.0-2.6.b3.fc11 Lightning/1.0pre Thunderbird/3.0b3
On 10/01/09 12:07, Jeremy Fitzhardinge wrote:
> Could modify drm_vmalloc_dma to do the vmalloc "manually":
>
>    1. call __get_vm_area to reserve a chunk of vmalloc address space
>    2. allocate a bunch of individual pages with dma_alloc_coherent
>    3. insert them into the vmalloc mapping with map_vm_area
>
> That will guarantee a normal-looking vmalloc area with device-friendly
> pages that subsequent pci_map_page operations will use as-is.
>   

Like this (untested):

diff --git a/drivers/gpu/drm/drm_scatter.c b/drivers/gpu/drm/drm_scatter.c
index c7823c8..73bfa63 100644
--- a/drivers/gpu/drm/drm_scatter.c
+++ b/drivers/gpu/drm/drm_scatter.c
@@ -32,16 +32,60 @@
  */
 
 #include <linux/vmalloc.h>
+#include <linux/mm.h>
 #include "drmP.h"
 
 #define DEBUG_SCATTER 0
 
-static inline void *drm_vmalloc_dma(unsigned long size)
+static inline void *drm_vmalloc_dma(struct drm_device *drmdev, unsigned long 
size)
 {
 #if defined(__powerpc__) && defined(CONFIG_NOT_COHERENT_CACHE)
        return __vmalloc(size, GFP_KERNEL, PAGE_KERNEL | _PAGE_NO_CACHE);
 #else
-       return vmalloc_32(size);
+       struct device *dev = &drmdev->pdev->dev;
+       struct vm_struct *vma;
+       struct page **pages;
+       const int npages = PFN_UP(size);
+       int i;
+
+       pages = kmalloc(npages * sizeof(*pages), GFP_KERNEL);
+       if (!pages)
+               goto out_free_pagearr;
+
+       vma = __get_vm_area(size, VM_ALLOC, VMALLOC_START, VMALLOC_END);
+       if (!vma)
+               goto out_release_vma;
+
+       for (i = 0; i < npages; i++) {
+               dma_addr_t phys;
+               void *addr;
+               addr = dma_alloc_coherent(dev, PAGE_SIZE, &phys, GFP_KERNEL);
+               if (addr == NULL)
+                       goto out_free_pages;
+
+               pages[i] = virt_to_page(addr);
+       }
+
+       if (map_vm_area(vma, PAGE_KERNEL, &pages))
+               goto out_free_pages;
+
+       kfree(pages);
+
+       return vma->addr;
+
+out_free_pages:
+       while(i > 0) {
+               void *addr = page_address(pages[--i]);
+               dma_free_coherent(dev, PAGE_SIZE, addr, virt_to_bus(addr));
+       }
+
+out_release_vma:
+       vunmap(vma->addr);
+
+out_free_pagearr:
+       kfree(pages);
+
+       return NULL;
 #endif
 }
 
@@ -107,7 +151,7 @@ int drm_sg_alloc(struct drm_device *dev, struct 
drm_scatter_gather * request)
        }
        memset((void *)entry->busaddr, 0, pages * sizeof(*entry->busaddr));
 
-       entry->virtual = drm_vmalloc_dma(pages << PAGE_SHIFT);
+       entry->virtual = drm_vmalloc_dma(dev, pages << PAGE_SHIFT);
        if (!entry->virtual) {
                kfree(entry->busaddr);
                kfree(entry->pagelist);



_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-devel

<Prev in Thread] Current Thread [Next in Thread>