summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris Wilson <chris@chris-wilson.co.uk>2010-05-12 09:57:27 +0100
committerChris Wilson <chris@chris-wilson.co.uk>2010-05-12 12:50:31 +0100
commit0c6372a77fd8c051534c1b420a02a8737aa1dd01 (patch)
tree35ab5a7c9c4d642bf3f9a631478a49d3f0e705ac
parent244b7cbfffdcda4761948eaa37ed2a30ca81f107 (diff)
i830: Prevent allocation of bo larger than half the aperture
We need to prevent overcommitting the aperture, and in particular if we allocate a buffer larger than available space we will fail to mmap it in and rendering will fail. Trying to allocate multiple large buffers in the aperture, often the case when falling back, causes thrashes and eviction of useful buffers. So from the outset simply do not allocate a bo if the the required size is more than half the available aperture space. Fixes allocation failure in ocitymap.trace for instance. Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
-rw-r--r--src/i830.h1
-rw-r--r--src/i830_memory.c63
-rw-r--r--src/i830_uxa.c15
3 files changed, 40 insertions, 39 deletions
diff --git a/src/i830.h b/src/i830.h
index aa7fedc0..fdaa47ee 100644
--- a/src/i830.h
+++ b/src/i830.h
@@ -296,6 +296,7 @@ typedef struct intel_screen_private {
int accel_pixmap_offset_alignment;
int accel_max_x;
int accel_max_y;
+ int max_bo_size;
int max_gtt_map_size;
int max_tiling_size;
diff --git a/src/i830_memory.c b/src/i830_memory.c
index 6a73bf6c..611b5485 100644
--- a/src/i830_memory.c
+++ b/src/i830_memory.c
@@ -274,50 +274,55 @@ drm_intel_bo *i830_allocate_framebuffer(ScrnInfoPtr scrn)
return front_buffer;
}
-static void i830_set_max_gtt_map_size(ScrnInfoPtr scrn)
+static void i830_set_max_bo_size(intel_screen_private *intel,
+ const struct drm_i915_gem_get_aperture *aperture)
{
- intel_screen_private *intel = intel_get_screen_private(scrn);
- struct drm_i915_gem_get_aperture aperture;
- int ret;
-
- /* Default low value in case it gets used during server init. */
- intel->max_gtt_map_size = 16 * 1024 * 1024;
+ if (aperture->aper_available_size)
+ /* Large BOs will tend to hit SW fallbacks frequently, and also will
+ * tend to fail to successfully map when doing SW fallbacks because we
+ * overcommit address space for BO access, or worse cause aperture
+ * thrashing.
+ */
+ intel->max_bo_size = aperture->aper_available_size / 2;
+ else
+ intel->max_bo_size = 64 * 1024 * 1024;
+}
- ret =
- ioctl(intel->drmSubFD, DRM_IOCTL_I915_GEM_GET_APERTURE, &aperture);
- if (ret == 0) {
+static void i830_set_max_gtt_map_size(intel_screen_private *intel,
+ const struct drm_i915_gem_get_aperture *aperture)
+{
+ if (aperture->aper_available_size)
/* Let objects up get bound up to the size where only 2 would fit in
* the aperture, but then leave slop to account for alignment like
* libdrm does.
*/
intel->max_gtt_map_size =
- aperture.aper_available_size * 3 / 4 / 2;
- }
+ aperture->aper_available_size * 3 / 4 / 2;
+ else
+ intel->max_gtt_map_size = 16 * 1024 * 1024;
}
-static void i830_set_max_tiling_size(ScrnInfoPtr scrn)
+static void i830_set_max_tiling_size(intel_screen_private *intel,
+ const struct drm_i915_gem_get_aperture *aperture)
{
- intel_screen_private *intel = intel_get_screen_private(scrn);
- struct drm_i915_gem_get_aperture aperture;
- int ret;
-
- /* Default low value in case it gets used during server init. */
- intel->max_tiling_size = 4 * 1024 * 1024;
-
- ret =
- ioctl(intel->drmSubFD, DRM_IOCTL_I915_GEM_GET_APERTURE, &aperture);
- if (ret == 0) {
+ if (aperture->aper_available_size)
/* Let objects be tiled up to the size where only 4 would fit in
* the aperture, presuming worst case alignment.
*/
- intel->max_tiling_size = aperture.aper_available_size / 4;
- if (!IS_I965G(intel))
- intel->max_tiling_size /= 2;
- }
+ intel->max_tiling_size = aperture->aper_available_size / 4;
+ else
+ intel->max_tiling_size = 4 * 1024 * 1024;
}
void i830_set_gem_max_sizes(ScrnInfoPtr scrn)
{
- i830_set_max_gtt_map_size(scrn);
- i830_set_max_tiling_size(scrn);
+ intel_screen_private *intel = intel_get_screen_private(scrn);
+ struct drm_i915_gem_get_aperture aperture;
+
+ aperture.aper_available_size = 0;
+ ioctl(intel->drmSubFD, DRM_IOCTL_I915_GEM_GET_APERTURE, &aperture);
+
+ i830_set_max_bo_size(intel, &aperture);
+ i830_set_max_gtt_map_size(intel, &aperture);
+ i830_set_max_tiling_size(intel, &aperture);
}
diff --git a/src/i830_uxa.c b/src/i830_uxa.c
index b5fc6b88..3f9610e4 100644
--- a/src/i830_uxa.c
+++ b/src/i830_uxa.c
@@ -944,18 +944,13 @@ i830_uxa_create_pixmap(ScreenPtr screen, int w, int h, int depth,
}
size = i830_uxa_pixmap_compute_size(pixmap, w, h, &tiling, &stride);
- /* Fail very large allocations on 32-bit systems. Large BOs will
- * tend to hit SW fallbacks frequently, and also will tend to fail
- * to successfully map when doing SW fallbacks because we overcommit
- * address space for BO access.
- *
- * Note that size should fit in 32 bits. We throw out >32767x32767x4,
- * and pitch alignment could get us up to 32768x32767x4.
+ /* Fail very large allocations. Large BOs will tend to hit SW fallbacks
+ * frequently, and also will tend to fail to successfully map when doing
+ * SW fallbacks because we overcommit address space for BO access.
*/
- if (sizeof(unsigned long) == 4 &&
- size > (unsigned int)(1024 * 1024 * 1024)) {
+ if (size > intel->max_bo_size) {
fbDestroyPixmap(pixmap);
- return NullPixmap;
+ return fbCreatePixmap(screen, w, h, depth, usage);
}
/* Perform a preliminary search for an in-flight bo */