[Intel-gfx] [PATCH] drm/agp: agp-intel/i915: trim stolen space to 16M

Jesse Barnes jbarnes at virtuousgeek.org
Mon Mar 22 19:17:46 CET 2010


On my SDV, the BIOS allocates 128M of stolen space no matter what
settings I use.  This leaves very little aperture space available (at
least relatively so given my 30" + 24" desktop setup) for mapping
buffers in execbuf.

I've been using this patch for awhile to work around the problem, and
think it's a reasonable thing to apply.  We generally only need a small
amount of stolen space for the few things that need contiguous space,
the compressed frame buffer being the biggest.

I think I have an idea of how to reclaim the space and give it back to
linux, but I haven't tested that yet; I'll post a follow-up patch on
top of this one when I have it working (basically changing the memory
back to WB using MTRR and/or set_memory_* calls and using memory
hotplug's add_memory() call to return it to the system).

Signed-off-by: Jesse Barnes <jbarnes at virtuousgeek.org>

diff --git a/drivers/char/agp/intel-agp.c b/drivers/char/agp/intel-agp.c
index c1c07a2..5a2be66 100644
--- a/drivers/char/agp/intel-agp.c
+++ b/drivers/char/agp/intel-agp.c
@@ -13,6 +13,10 @@
 int intel_agp_enabled;
 EXPORT_SYMBOL(intel_agp_enabled);
 
+/* Max amount of stolen space, anything above will be returned to Linux */
+int intel_max_stolen = 16 * 1024 * 1024;
+EXPORT_SYMBOL(intel_max_stolen);
+
 /*
  * If we have Intel graphics, we're not going to have anything other than
  * an Intel IOMMU. So make the correct use of the PCI DMA API contingent
@@ -869,7 +873,13 @@ static void intel_i830_init_gtt_entries(void)
 			break;
 		}
 	}
-	if (gtt_entries > 0) {
+
+	if (!local && gtt_entries > intel_max_stolen) {
+		dev_info(&agp_bridge->dev->dev,
+			 "detected %dK stolen memory, trimming to %dK\n",
+			 gtt_entries / KB(1), intel_max_stolen / KB(1));
+		gtt_entries = intel_max_stolen / KB(4);
+	} else if (gtt_entries > 0) {
 		dev_info(&agp_bridge->dev->dev, "detected %dK %s memory\n",
 		       gtt_entries / KB(1), local ? "local" : "stolen");
 		gtt_entries /= KB(4);
diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c
index b63638a..6a428b2 100644
--- a/drivers/gpu/drm/i915/i915_dma.c
+++ b/drivers/gpu/drm/i915/i915_dma.c
@@ -38,6 +38,8 @@
 #include <linux/acpi.h>
 #include <linux/pnp.h>
 
+extern int intel_max_stolen; /* from AGP driver */
+
 /* Really want an OS-independent resettable timer.  Would like to have
  * this loop run for (eg) 3 sec, but have the timer reset every time
  * the head pointer changes, so that EBUSY only happens if the ring
@@ -1608,6 +1610,12 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags)
 	if (ret)
 		goto out_iomapfree;
 
+	if (prealloc_size > intel_max_stolen) {
+		DRM_INFO("detected %dM stolen memory, trimming to %dM\n",
+			 prealloc_size >> 20, intel_max_stolen >> 20);
+		prealloc_size = intel_max_stolen;
+	}
+
 	dev_priv->wq = create_singlethread_workqueue("i915");
 	if (dev_priv->wq == NULL) {
 		DRM_ERROR("Failed to create our workqueue.\n");



More information about the Intel-gfx mailing list