summaryrefslogtreecommitdiffstats
path: root/src/gallium/drivers/panfrost
diff options
context:
space:
mode:
authorRob Herring <[email protected]>2019-07-31 23:28:37 +0000
committerRob Herring <[email protected]>2019-08-19 19:33:20 -0500
commitd0ec5d38f6cff2e61d9e526423c0a016cc830d14 (patch)
treed51ab040b6dfcf6e4c793a56e83bf61582a12224 /src/gallium/drivers/panfrost
parentc45c2d79605b27022975ff1635f9df8f5d01806a (diff)
panfrost: Add madvise support to BO cache
The kernel now supports madvise ioctl to indicate which BOs can be freed when there is memory pressure. Mark BOs purgeable when they are in the BO cache. The BOs must also be munmapped when they are in the cache or they cannot be purged. We could optimize avoiding the madvise ioctl on older kernels once the driver version bump lands, but probably not worth it given the other driver features also being added. Reviewed-by: Alyssa Rosenzweig <[email protected]> Reviewed-by: Tomeu Vizoso <[email protected]> Signed-off-by: Rob Herring <[email protected]>
Diffstat (limited to 'src/gallium/drivers/panfrost')
-rw-r--r--src/gallium/drivers/panfrost/pan_bo_cache.c21
-rw-r--r--src/gallium/drivers/panfrost/pan_drm.c4
2 files changed, 23 insertions, 2 deletions
diff --git a/src/gallium/drivers/panfrost/pan_bo_cache.c b/src/gallium/drivers/panfrost/pan_bo_cache.c
index 7378d0a8abe..9dd6b694b72 100644
--- a/src/gallium/drivers/panfrost/pan_bo_cache.c
+++ b/src/gallium/drivers/panfrost/pan_bo_cache.c
@@ -23,6 +23,8 @@
* Authors (Collabora):
* Alyssa Rosenzweig <[email protected]>
*/
+#include <xf86drm.h>
+#include "drm-uapi/panfrost_drm.h"
#include "pan_screen.h"
#include "util/u_math.h"
@@ -88,9 +90,21 @@ panfrost_bo_cache_fetch(
list_for_each_entry_safe(struct panfrost_bo, entry, bucket, link) {
if (entry->size >= size &&
entry->flags == flags) {
+ int ret;
+ struct drm_panfrost_madvise madv;
+
/* This one works, splice it out of the cache */
list_del(&entry->link);
+ madv.handle = entry->gem_handle;
+ madv.madv = PANFROST_MADV_WILLNEED;
+ madv.retained = 0;
+
+ ret = drmIoctl(screen->fd, DRM_IOCTL_PANFROST_MADVISE, &madv);
+ if (!ret && !madv.retained) {
+ panfrost_drm_release_bo(screen, entry, false);
+ continue;
+ }
/* Let's go! */
return entry;
}
@@ -109,6 +123,13 @@ panfrost_bo_cache_put(
struct panfrost_bo *bo)
{
struct list_head *bucket = pan_bucket(screen, bo->size);
+ struct drm_panfrost_madvise madv;
+
+ madv.handle = bo->gem_handle;
+ madv.madv = PANFROST_MADV_DONTNEED;
+ madv.retained = 0;
+
+ drmIoctl(screen->fd, DRM_IOCTL_PANFROST_MADVISE, &madv);
/* Add us to the bucket */
list_addtail(&bo->link, bucket);
diff --git a/src/gallium/drivers/panfrost/pan_drm.c b/src/gallium/drivers/panfrost/pan_drm.c
index 36a6b975680..28a4287202b 100644
--- a/src/gallium/drivers/panfrost/pan_drm.c
+++ b/src/gallium/drivers/panfrost/pan_drm.c
@@ -163,6 +163,8 @@ panfrost_drm_release_bo(struct panfrost_screen *screen, struct panfrost_bo *bo,
/* Rather than freeing the BO now, we'll cache the BO for later
* allocations if we're allowed to */
+ panfrost_drm_munmap_bo(screen, bo);
+
if (cacheable) {
bool cached = panfrost_bo_cache_put(screen, bo);
@@ -172,8 +174,6 @@ panfrost_drm_release_bo(struct panfrost_screen *screen, struct panfrost_bo *bo,
/* Otherwise, if the BO wasn't cached, we'll legitimately free the BO */
- panfrost_drm_munmap_bo(screen, bo);
-
ret = drmIoctl(screen->fd, DRM_IOCTL_GEM_CLOSE, &gem_close);
if (ret) {
fprintf(stderr, "DRM_IOCTL_GEM_CLOSE failed: %m\n");