diff options
author | Chris Wilson <chris@chris-wilson.co.uk> | 2013-02-22 21:09:52 +0000 |
---|---|---|
committer | Chris Wilson <chris@chris-wilson.co.uk> | 2013-02-22 21:49:42 +0000 |
commit | cbd8f16ea0e3b1b7eae57edfe343a332ae42373c (patch) | |
tree | e064a2b188514c1739c6d3c48a324372b0e65539 | |
parent | 7a264792772512528a4d6138e09b4ee1ace7f322 (diff) |
sna: Refuse to create larger than max temporary upload bo
The maximum size is determined by available RAM, if we exceed it we
greatly increase the risk of swap thrashing.
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
-rw-r--r-- | src/sna/kgem.c | 15 | ||||
-rw-r--r-- | src/sna/sna_render.c | 10 |
2 files changed, 17 insertions, 8 deletions
diff --git a/src/sna/kgem.c b/src/sna/kgem.c index c4ad5faf..324df6da 100644 --- a/src/sna/kgem.c +++ b/src/sna/kgem.c @@ -2959,10 +2959,13 @@ search_linear_cache(struct kgem *kgem, unsigned int num_pages, unsigned flags) bool use_active = (flags & CREATE_INACTIVE) == 0; struct list *cache; - DBG(("%s: num_pages=%d, flags=%x, use_active? %d\n", - __FUNCTION__, num_pages, flags, use_active)); + DBG(("%s: num_pages=%d, flags=%x, use_active? %d, use_large=%d [max=%d]\n", + __FUNCTION__, num_pages, flags, use_active, + num_pages >= MAX_CACHE_SIZE / PAGE_SIZE, + MAX_CACHE_SIZE / PAGE_SIZE)); if (num_pages >= MAX_CACHE_SIZE / PAGE_SIZE) { + DBG(("%s: searching large buffers\n", __FUNCTION__)); retry_large: cache = use_active ? &kgem->large : &kgem->large_inactive; list_for_each_entry_safe(bo, first, cache, list) { @@ -2986,7 +2989,7 @@ retry_large: } if (bo->purged && !kgem_bo_clear_purgeable(kgem, bo)) - continue; + goto discard; list_del(&bo->list); if (bo->rq == (void *)kgem) @@ -2996,7 +2999,8 @@ retry_large: return bo; discard: - kgem_bo_free(kgem, bo); + if (!use_active) + kgem_bo_free(kgem, bo); } if (use_active) { @@ -5470,6 +5474,9 @@ struct kgem_bo *kgem_upload_source_image(struct kgem *kgem, struct kgem_bo *bo; void *dst; + if (!kgem_can_create_2d(kgem, width, height, bpp)) + return NULL; + DBG(("%s : (%d, %d), (%d, %d), stride=%d, bpp=%d\n", __FUNCTION__, box->x1, box->y1, box->x2, box->y2, stride, bpp)); diff --git a/src/sna/sna_render.c b/src/sna/sna_render.c index 4bc1fad3..512be950 100644 --- a/src/sna/sna_render.c +++ b/src/sna/sna_render.c @@ -1008,11 +1008,14 @@ sna_render_picture_partial(struct sna *sna, if (use_cpu_bo(sna, pixmap, &box, false)) { bo = sna_pixmap(pixmap)->cpu_bo; } else { - if (!sna_pixmap_force_to_gpu(pixmap, - MOVE_READ | MOVE_SOURCE_HINT)) + struct sna_pixmap *priv; + + priv = sna_pixmap_force_to_gpu(pixmap, + MOVE_READ | MOVE_SOURCE_HINT); + if (priv == NULL) return 0; - bo = sna_pixmap(pixmap)->gpu_bo; + bo = priv->gpu_bo; } if (bo->pitch > sna->render.max_3d_pitch) @@ -1188,7 +1191,6 @@ sna_render_picture_extract(struct sna *sna, pixmap->devKind, pixmap->drawable.bitsPerPixel); if (bo != NULL && - pixmap->usage_hint == 0 && box.x2 - box.x1 == pixmap->drawable.width && box.y2 - box.y1 == pixmap->drawable.height) { struct sna_pixmap *priv = sna_pixmap(pixmap); |