diff options
author | Chris Wilson <chris@chris-wilson.co.uk> | 2010-05-12 09:57:27 +0100 |
---|---|---|
committer | Chris Wilson <chris@chris-wilson.co.uk> | 2010-05-12 12:50:31 +0100 |
commit | 0c6372a77fd8c051534c1b420a02a8737aa1dd01 (patch) | |
tree | 35ab5a7c9c4d642bf3f9a631478a49d3f0e705ac | |
parent | 244b7cbfffdcda4761948eaa37ed2a30ca81f107 (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.h | 1 | ||||
-rw-r--r-- | src/i830_memory.c | 63 | ||||
-rw-r--r-- | src/i830_uxa.c | 15 |
3 files changed, 40 insertions, 39 deletions
@@ -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 */ |