diff options
author | Chris Wilson <chris@chris-wilson.co.uk> | 2017-12-16 10:55:54 +0000 |
---|---|---|
committer | Chris Wilson <chris@chris-wilson.co.uk> | 2017-12-16 10:59:09 +0000 |
commit | af6d8e9e8f546e5cba60e3a62765c2dbd0328e83 (patch) | |
tree | 2dcc98c8e241a823b83e2805fd83183ed2ba6d2a /src | |
parent | 21008aaa1f9f77ef3509a68dd83c7ad41da4ec81 (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.c | 37 |
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); |