From 8634d461bd9e5a3d3f75b0efc11db87b8d3e1245 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Wed, 8 Feb 2012 09:13:27 +0000 Subject: [PATCH] sna: Limit max CPU bo size to prevent aperture thrashing on upload Copying between two objects that consume more than the available GATT space is a painful experience due to the forced use of an intermediatory and eviction on every batch. The tiled upload paths are in comparison remarkably efficient, so favour their use when handling extremely large buffers. This reverses the previous idea in that we now prefer large GPU bo rather than large CPU bo, as the render pipeline is far more flexible for handling those than the blitter is for handling the CPU bo (at least for gen4+). Signed-off-by: Chris Wilson --- src/sna/kgem.c | 34 +++++++++++++++++++++------------- 1 file changed, 21 insertions(+), 13 deletions(-) diff --git a/src/sna/kgem.c b/src/sna/kgem.c index 94b6c184..1c233204 100644 --- a/src/sna/kgem.c +++ b/src/sna/kgem.c @@ -575,6 +575,7 @@ void kgem_init(struct kgem *kgem, int fd, struct pci_device *dev, int gen) { struct drm_i915_gem_get_aperture aperture; size_t totalram; + unsigned half_gpu_max; unsigned int i, j; memset(kgem, 0, sizeof(*kgem)); @@ -679,7 +680,6 @@ void kgem_init(struct kgem *kgem, int fd, struct pci_device *dev, int gen) kgem->min_alignment = 64; kgem->max_object_size = 2 * kgem->aperture_total / 3; - kgem->max_cpu_size = kgem->max_object_size; kgem->max_gpu_size = kgem->max_object_size; if (!kgem->has_llc) kgem->max_gpu_size = MAX_CACHE_SIZE; @@ -691,16 +691,6 @@ void kgem_init(struct kgem *kgem, int fd, struct pci_device *dev, int gen) if (kgem->max_gpu_size > kgem->aperture_low) kgem->max_gpu_size = kgem->aperture_low; } - if (kgem->max_gpu_size > kgem->max_cpu_size) - kgem->max_gpu_size = kgem->max_cpu_size; - - kgem->max_upload_tile_size = kgem->aperture_mappable / 2; - if (kgem->max_upload_tile_size > kgem->max_gpu_size / 2) - kgem->max_upload_tile_size = kgem->max_gpu_size / 2; - - kgem->max_copy_tile_size = (MAX_CACHE_SIZE + 1)/2; - if (kgem->max_copy_tile_size > kgem->max_gpu_size / 2) - kgem->max_copy_tile_size = kgem->max_gpu_size / 2; totalram = total_ram_size(); if (totalram == 0) { @@ -708,14 +698,32 @@ void kgem_init(struct kgem *kgem, int fd, struct pci_device *dev, int gen) __FUNCTION__)); totalram = kgem->aperture_total; } + DBG(("%s: total ram=%ld\n", __FUNCTION__, (long)totalram)); if (kgem->max_object_size > totalram / 2) kgem->max_object_size = totalram / 2; - if (kgem->max_cpu_size > totalram / 2) - kgem->max_cpu_size = totalram / 2; if (kgem->max_gpu_size > totalram / 4) kgem->max_gpu_size = totalram / 4; + half_gpu_max = kgem->max_gpu_size / 2; + if (kgem->gen >= 40) + kgem->max_cpu_size = half_gpu_max; + else + kgem->max_cpu_size = kgem->max_object_size; + + kgem->max_copy_tile_size = (MAX_CACHE_SIZE + 1)/2; + if (kgem->max_copy_tile_size > half_gpu_max) + kgem->max_copy_tile_size = half_gpu_max; + + if (kgem->has_llc) + kgem->max_upload_tile_size = kgem->max_copy_tile_size; + else + kgem->max_upload_tile_size = kgem->aperture_mappable / 4; + if (kgem->max_upload_tile_size > half_gpu_max) + kgem->max_upload_tile_size = half_gpu_max; + kgem->large_object_size = MAX_CACHE_SIZE; + if (kgem->large_object_size > kgem->max_cpu_size) + kgem->large_object_size = kgem->max_cpu_size; if (kgem->large_object_size > kgem->max_gpu_size) kgem->large_object_size = kgem->max_gpu_size;