Skip to content
Snippets Groups Projects
Commit d0ec5d38 authored by Rob Herring's avatar Rob Herring
Browse files

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: default avatarAlyssa Rosenzweig <alyssa.rosenzweig@collabora.com>
Reviewed-by: default avatarTomeu Vizoso <tomeu.vizoso@collabora.com>
Signed-off-by: default avatarRob Herring <robh@kernel.org>
parent c45c2d79
No related branches found
No related tags found
Loading
......@@ -23,6 +23,8 @@
* Authors (Collabora):
* Alyssa Rosenzweig <alyssa.rosenzweig@collabora.com>
*/
#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);
......
......@@ -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");
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment