summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEric Anholt <[email protected]>2015-11-04 13:27:16 -0800
committerEmil Velikov <[email protected]>2015-11-07 15:17:49 +0000
commitc323f97963dbbf069352fb40a7daa4a031aa87ba (patch)
tree56ae9a4940a9dab4ba58f8907941b958a0f4448e
parent7cfd87ce84f259f928efaaa4d2a5e340634ed058 (diff)
vc4: When the create ioctl fails, free our cache and try again.
This greatly increases the pressure you can put on the driver before create fails. Ultimately we need to let the kernel take control of our cached BOs and just take them from us (and other clients) directly, but this is a very easy patch for the moment. Cc: "11.0" <[email protected]> (cherry picked from commit 6d3a24bce80a32063aedfe568efd5532aea4c875)
-rw-r--r--src/gallium/drivers/vc4/vc4_bufmgr.c29
1 files changed, 24 insertions, 5 deletions
diff --git a/src/gallium/drivers/vc4/vc4_bufmgr.c b/src/gallium/drivers/vc4/vc4_bufmgr.c
index f7b41f5816d..4766f2e304d 100644
--- a/src/gallium/drivers/vc4/vc4_bufmgr.c
+++ b/src/gallium/drivers/vc4/vc4_bufmgr.c
@@ -37,6 +37,9 @@
static bool dump_stats = false;
static void
+vc4_bo_cache_free_all(struct vc4_bo_cache *cache);
+
+static void
vc4_bo_dump_stats(struct vc4_screen *screen)
{
struct vc4_bo_cache *cache = &screen->bo_cache;
@@ -136,6 +139,8 @@ vc4_bo_alloc(struct vc4_screen *screen, uint32_t size, const char *name)
bo->name = name;
bo->private = true;
+ bool cleared_and_retried = false;
+retry:
if (!using_vc4_simulator) {
struct drm_vc4_create_bo create;
memset(&create, 0, sizeof(create));
@@ -157,6 +162,12 @@ vc4_bo_alloc(struct vc4_screen *screen, uint32_t size, const char *name)
assert(create.size >= size);
}
if (ret != 0) {
+ if (!list_empty(&screen->bo_cache.time_list) &&
+ !cleared_and_retried) {
+ cleared_and_retried = true;
+ vc4_bo_cache_free_all(&screen->bo_cache);
+ goto retry;
+ }
fprintf(stderr, "create ioctl failure\n");
abort();
}
@@ -248,6 +259,18 @@ free_stale_bos(struct vc4_screen *screen, time_t time)
}
}
+static void
+vc4_bo_cache_free_all(struct vc4_bo_cache *cache)
+{
+ pipe_mutex_lock(cache->lock);
+ list_for_each_entry_safe(struct vc4_bo, bo, &cache->time_list,
+ time_list) {
+ vc4_bo_remove_from_cache(cache, bo);
+ vc4_bo_free(bo);
+ }
+ pipe_mutex_unlock(cache->lock);
+}
+
void
vc4_bo_last_unreference_locked_timed(struct vc4_bo *bo, time_t time)
{
@@ -600,11 +623,7 @@ vc4_bufmgr_destroy(struct pipe_screen *pscreen)
struct vc4_screen *screen = vc4_screen(pscreen);
struct vc4_bo_cache *cache = &screen->bo_cache;
- list_for_each_entry_safe(struct vc4_bo, bo, &cache->time_list,
- time_list) {
- vc4_bo_remove_from_cache(cache, bo);
- vc4_bo_free(bo);
- }
+ vc4_bo_cache_free_all(cache);
if (dump_stats) {
fprintf(stderr, "BO stats after screen destroy:\n");