From f06809cdcaf2682ebc143fa0c8cbb676a18dae81 Mon Sep 17 00:00:00 2001 From: Alyssa Rosenzweig Date: Thu, 7 Jul 2022 12:02:03 -0400 Subject: [PATCH] panfrost: Evict the BO cache when allocation fails If memory allocation fails, we look for a suitable sized BO in the BO cache and wait until we can use its memory. That usually works, but there's a case when it can fail despite sufficient memory in the system: BOs in the BO cache contributing to memory pressure but none of them being of sufficient size. This case is not just theoretical: it's seen in the OpenCL test_non_uniform_work_group, which puts the system under considerable memory pressure with an unusual allocation pattern. To handle this case, try evicting *everything* from the BO cache and stalling in order to allocate, if the above attempts failed. Fixes the following error: DRM_IOCTL_PANFROST_CREATE_BO failed: No space left on device on the aforementioned OpenCL test. Signed-off-by: Alyssa Rosenzweig Acked-by: Boris Brezillon Part-of: --- src/panfrost/lib/pan_bo.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/panfrost/lib/pan_bo.c b/src/panfrost/lib/pan_bo.c index 26a7b6bf884d..80aaf2695802 100644 --- a/src/panfrost/lib/pan_bo.c +++ b/src/panfrost/lib/pan_bo.c @@ -379,23 +379,23 @@ panfrost_bo_create(struct panfrost_device *dev, size_t size, if (flags & PAN_BO_GROWABLE) assert(flags & PAN_BO_INVISIBLE); - /* Before creating a BO, we first want to check the cache but without - * waiting for BO readiness (BOs in the cache can still be referenced - * by jobs that are not finished yet). - * If the cached allocation fails we fall back on fresh BO allocation, - * and if that fails too, we try one more time to allocate from the - * cache, but this time we accept to wait. + /* Ideally, we get a BO that's ready in the cache, or allocate a fresh + * BO. If allocation fails, we can try waiting for something in the + * cache. But if there's no nothing suitable, we should flush the cache + * to make space for the new allocation. */ bo = panfrost_bo_cache_fetch(dev, size, flags, label, true); if (!bo) bo = panfrost_bo_alloc(dev, size, flags, label); if (!bo) bo = panfrost_bo_cache_fetch(dev, size, flags, label, false); - - assert(bo); + if (!bo) { + panfrost_bo_cache_evict_all(dev); + bo = panfrost_bo_alloc(dev, size, flags, label); + } if (!bo) { - fprintf(stderr, "BO creation failed\n"); + unreachable("BO creation failed. We don't handle that yet."); return NULL; } -- GitLab