Explorar el Código

drm/i915: Allow DMA pagetables to use highmem

As we never need to directly access the pages we allocate for scratch and
the pagetables, and always remap them into the GTT through the dma
remapper, we do not need to limit the allocations to lowmem i.e. we can
pass in the __GFP_HIGHMEM flag to the page allocation.

For backwards compatibility, e.g. certain old GPUs not liking highmem
for certain functions that may be accidentally mapped to the scratch
page by userspace, keep the GMCH probe as only allocating from DMA32.

Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Link: http://patchwork.freedesktop.org/patch/msgid/20160822074431.26872-3-chris@chris-wilson.co.uk
Reviewed-by: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
Chris Wilson hace 9 años
padre
commit
bb8f9cffad
Se han modificado 1 ficheros con 12 adiciones y 6 borrados
  1. 12 6
      drivers/gpu/drm/i915/i915_gem_gtt.c

+ 12 - 6
drivers/gpu/drm/i915/i915_gem_gtt.c

@@ -32,6 +32,8 @@
 #include "i915_trace.h"
 #include "i915_trace.h"
 #include "intel_drv.h"
 #include "intel_drv.h"
 
 
+#define I915_GFP_DMA (GFP_KERNEL | __GFP_HIGHMEM)
+
 /**
 /**
  * DOC: Global GTT views
  * DOC: Global GTT views
  *
  *
@@ -345,7 +347,7 @@ static int __setup_page_dma(struct drm_device *dev,
 
 
 static int setup_page_dma(struct drm_device *dev, struct i915_page_dma *p)
 static int setup_page_dma(struct drm_device *dev, struct i915_page_dma *p)
 {
 {
-	return __setup_page_dma(dev, p, GFP_KERNEL);
+	return __setup_page_dma(dev, p, I915_GFP_DMA);
 }
 }
 
 
 static void cleanup_page_dma(struct drm_device *dev, struct i915_page_dma *p)
 static void cleanup_page_dma(struct drm_device *dev, struct i915_page_dma *p)
@@ -410,9 +412,11 @@ static void fill_page_dma_32(struct drm_device *dev, struct i915_page_dma *p,
 }
 }
 
 
 static int
 static int
-setup_scratch_page(struct drm_device *dev, struct i915_page_dma *scratch)
+setup_scratch_page(struct drm_device *dev,
+		   struct i915_page_dma *scratch,
+		   gfp_t gfp)
 {
 {
-	return __setup_page_dma(dev, scratch, GFP_DMA32 | __GFP_ZERO);
+	return __setup_page_dma(dev, scratch, gfp | __GFP_ZERO);
 }
 }
 
 
 static void cleanup_scratch_page(struct drm_device *dev,
 static void cleanup_scratch_page(struct drm_device *dev,
@@ -867,7 +871,7 @@ static int gen8_init_scratch(struct i915_address_space *vm)
 	struct drm_device *dev = vm->dev;
 	struct drm_device *dev = vm->dev;
 	int ret;
 	int ret;
 
 
-	ret = setup_scratch_page(dev, &vm->scratch_page);
+	ret = setup_scratch_page(dev, &vm->scratch_page, I915_GFP_DMA);
 	if (ret)
 	if (ret)
 		return ret;
 		return ret;
 
 
@@ -1934,7 +1938,7 @@ static int gen6_init_scratch(struct i915_address_space *vm)
 	struct drm_device *dev = vm->dev;
 	struct drm_device *dev = vm->dev;
 	int ret;
 	int ret;
 
 
-	ret = setup_scratch_page(dev, &vm->scratch_page);
+	ret = setup_scratch_page(dev, &vm->scratch_page, I915_GFP_DMA);
 	if (ret)
 	if (ret)
 		return ret;
 		return ret;
 
 
@@ -2902,7 +2906,9 @@ static int ggtt_probe_common(struct i915_ggtt *ggtt, u64 size)
 		return -ENOMEM;
 		return -ENOMEM;
 	}
 	}
 
 
-	ret = setup_scratch_page(ggtt->base.dev, &ggtt->base.scratch_page);
+	ret = setup_scratch_page(ggtt->base.dev,
+				 &ggtt->base.scratch_page,
+				 GFP_DMA32);
 	if (ret) {
 	if (ret) {
 		DRM_ERROR("Scratch setup failed\n");
 		DRM_ERROR("Scratch setup failed\n");
 		/* iounmap will also get called at remove, but meh */
 		/* iounmap will also get called at remove, but meh */