summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorChris Wilson <chris@chris-wilson.co.uk>2017-12-16 10:55:54 +0000
committerChris Wilson <chris@chris-wilson.co.uk>2017-12-16 10:59:09 +0000
commitaf6d8e9e8f546e5cba60e3a62765c2dbd0328e83 (patch)
tree2dcc98c8e241a823b83e2805fd83183ed2ba6d2a /src
parent21008aaa1f9f77ef3509a68dd83c7ad41da4ec81 (diff)
sna: Avoid calling kgem_bo_free() on a still active bo
If we fail to manipulate a bo from the active cache for reuse, then we have to be careful not to immediately close it as it is still referenced from the current batch. Reported-by: Adric Blake <promarbler14@gmail.com> References: https://bugs.freedesktop.org/show_bug.cgi?id=103025#c44 Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Diffstat (limited to 'src')
-rw-r--r--src/sna/kgem.c37
1 files changed, 16 insertions, 21 deletions
diff --git a/src/sna/kgem.c b/src/sna/kgem.c
index 29e09e33..e58db967 100644
--- a/src/sna/kgem.c
+++ b/src/sna/kgem.c
@@ -4729,10 +4729,8 @@ discard:
if (first)
continue;
- if (!kgem_set_tiling(kgem, bo, I915_TILING_NONE, 0)) {
- kgem_bo_free(kgem, bo);
- break;
- }
+ if (!kgem_set_tiling(kgem, bo, I915_TILING_NONE, 0))
+ continue;
}
assert(bo->tiling == I915_TILING_NONE);
bo->pitch = 0;
@@ -5466,7 +5464,8 @@ struct kgem_bo *kgem_create_2d(struct kgem *kgem,
if (!kgem_set_tiling(kgem, bo,
tiling, pitch)) {
- kgem_bo_free(kgem, bo);
+ bo->scanout = false;
+ __kgem_bo_destroy(kgem, bo);
break;
}
}
@@ -5480,7 +5479,8 @@ struct kgem_bo *kgem_create_2d(struct kgem *kgem,
arg.handle = bo->handle;
if (do_ioctl(kgem->fd, DRM_IOCTL_MODE_ADDFB, &arg)) {
- kgem_bo_free(kgem, bo);
+ bo->scanout = false;
+ __kgem_bo_destroy(kgem, bo);
break;
}
@@ -5787,13 +5787,10 @@ search_active:
continue;
if (!kgem_set_tiling(kgem, bo, tiling, pitch)) {
- if (kgem->gen >= 040 && !exact) {
- set_gpu_tiling(kgem, bo,
- tiling, pitch);
- } else {
- kgem_bo_free(kgem, bo);
- break;
- }
+ if (exact || kgem->gen < 040)
+ continue;
+
+ set_gpu_tiling(kgem, bo, tiling, pitch);
}
assert(bo->tiling == tiling);
assert(bo->pitch >= pitch);
@@ -5879,12 +5876,12 @@ search_inactive:
}
if (!kgem_set_tiling(kgem, bo, tiling, pitch)) {
- if (kgem->gen >= 040 && !exact) {
- set_gpu_tiling(kgem, bo, tiling, pitch);
- } else {
+ if (exact || kgem->gen < 040) {
kgem_bo_free(kgem, bo);
break;
}
+
+ set_gpu_tiling(kgem, bo, tiling, pitch);
}
if (bo->purged && !kgem_bo_clear_purgeable(kgem, bo)) {
@@ -5945,12 +5942,10 @@ search_inactive:
__kgem_bo_clear_busy(bo);
if (!kgem_set_tiling(kgem, bo, tiling, pitch)) {
- if (kgem->gen >= 040 && !exact) {
- set_gpu_tiling(kgem, bo, tiling, pitch);
- } else {
- kgem_bo_free(kgem, bo);
+ if (exact || kgem->gen < 040)
goto no_retire;
- }
+
+ set_gpu_tiling(kgem, bo, tiling, pitch);
}
assert(bo->tiling == tiling);
assert(bo->pitch >= pitch);