freedreno: add madvise support
With a new enough drm/msm, we can let the kernel know about buffers that are in the bo cache, so the kernel can free them under memory pressure. Signed-off-by: Rob Clark <robclark@freedesktop.org>main
parent
0c270df8df
commit
eb846d46bc
|
@ -165,10 +165,18 @@ fd_bo_cache_alloc(struct fd_bo_cache *cache, uint32_t *size, uint32_t flags)
|
|||
bucket = get_bucket(cache, *size);
|
||||
|
||||
/* see if we can be green and recycle: */
|
||||
retry:
|
||||
if (bucket) {
|
||||
*size = bucket->size;
|
||||
bo = find_in_bucket(bucket, flags);
|
||||
if (bo) {
|
||||
if (bo->funcs->madvise(bo, TRUE) <= 0) {
|
||||
/* we've lost the backing pages, delete and try again: */
|
||||
pthread_mutex_lock(&table_lock);
|
||||
bo_del(bo);
|
||||
pthread_mutex_unlock(&table_lock);
|
||||
goto retry;
|
||||
}
|
||||
atomic_set(&bo->refcnt, 1);
|
||||
fd_device_ref(bo->dev);
|
||||
return bo;
|
||||
|
@ -187,6 +195,8 @@ fd_bo_cache_free(struct fd_bo_cache *cache, struct fd_bo *bo)
|
|||
if (bucket) {
|
||||
struct timespec time;
|
||||
|
||||
bo->funcs->madvise(bo, FALSE);
|
||||
|
||||
clock_gettime(CLOCK_MONOTONIC, &time);
|
||||
|
||||
bo->free_time = time.tv_sec;
|
||||
|
|
|
@ -56,7 +56,15 @@ struct fd_device * fd_device_new(int fd)
|
|||
|
||||
if (!strcmp(version->name, "msm")) {
|
||||
DEBUG_MSG("msm DRM device");
|
||||
if (version->version_major != 1) {
|
||||
ERROR_MSG("unsupported version: %u.%u.%u", version->version_major,
|
||||
version->version_minor, version->version_patchlevel);
|
||||
dev = NULL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
dev = msm_device_new(fd);
|
||||
dev->version = version->version_minor;
|
||||
#ifdef HAVE_FREEDRENO_KGSL
|
||||
} else if (!strcmp(version->name, "kgsl")) {
|
||||
DEBUG_MSG("kgsl DRM device");
|
||||
|
@ -66,6 +74,8 @@ struct fd_device * fd_device_new(int fd)
|
|||
ERROR_MSG("unknown device: %s", version->name);
|
||||
dev = NULL;
|
||||
}
|
||||
|
||||
out:
|
||||
drmFreeVersion(version);
|
||||
|
||||
if (!dev)
|
||||
|
|
|
@ -54,6 +54,13 @@
|
|||
#include "freedreno_ringbuffer.h"
|
||||
#include "drm.h"
|
||||
|
||||
#ifndef TRUE
|
||||
# define TRUE 1
|
||||
#endif
|
||||
#ifndef FALSE
|
||||
# define FALSE 0
|
||||
#endif
|
||||
|
||||
struct fd_device_funcs {
|
||||
int (*bo_new_handle)(struct fd_device *dev, uint32_t size,
|
||||
uint32_t flags, uint32_t *handle);
|
||||
|
@ -76,6 +83,7 @@ struct fd_bo_cache {
|
|||
|
||||
struct fd_device {
|
||||
int fd;
|
||||
int version;
|
||||
atomic_t refcnt;
|
||||
|
||||
/* tables to keep track of bo's, to avoid "evil-twin" fd_bo objects:
|
||||
|
@ -139,6 +147,7 @@ struct fd_bo_funcs {
|
|||
int (*offset)(struct fd_bo *bo, uint64_t *offset);
|
||||
int (*cpu_prep)(struct fd_bo *bo, struct fd_pipe *pipe, uint32_t op);
|
||||
void (*cpu_fini)(struct fd_bo *bo);
|
||||
int (*madvise)(struct fd_bo *bo, int willneed);
|
||||
void (*destroy)(struct fd_bo *bo);
|
||||
};
|
||||
|
||||
|
|
|
@ -116,6 +116,11 @@ static void kgsl_bo_cpu_fini(struct fd_bo *bo)
|
|||
{
|
||||
}
|
||||
|
||||
static int kgsl_bo_madvise(struct fd_bo *bo, int willneed)
|
||||
{
|
||||
return willneed; /* not supported by kgsl */
|
||||
}
|
||||
|
||||
static void kgsl_bo_destroy(struct fd_bo *bo)
|
||||
{
|
||||
struct kgsl_bo *kgsl_bo = to_kgsl_bo(bo);
|
||||
|
@ -127,6 +132,7 @@ static const struct fd_bo_funcs funcs = {
|
|||
.offset = kgsl_bo_offset,
|
||||
.cpu_prep = kgsl_bo_cpu_prep,
|
||||
.cpu_fini = kgsl_bo_cpu_fini,
|
||||
.madvise = kgsl_bo_madvise,
|
||||
.destroy = kgsl_bo_destroy,
|
||||
};
|
||||
|
||||
|
|
|
@ -89,6 +89,25 @@ static void msm_bo_cpu_fini(struct fd_bo *bo)
|
|||
drmCommandWrite(bo->dev->fd, DRM_MSM_GEM_CPU_FINI, &req, sizeof(req));
|
||||
}
|
||||
|
||||
static int msm_bo_madvise(struct fd_bo *bo, int willneed)
|
||||
{
|
||||
struct drm_msm_gem_madvise req = {
|
||||
.handle = bo->handle,
|
||||
.madv = willneed ? MSM_MADV_WILLNEED : MSM_MADV_DONTNEED,
|
||||
};
|
||||
int ret;
|
||||
|
||||
/* older kernels do not support this: */
|
||||
if (bo->dev->version < 1)
|
||||
return willneed;
|
||||
|
||||
ret = drmCommandWriteRead(bo->dev->fd, DRM_MSM_GEM_MADVISE, &req, sizeof(req));
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
return req.retained;
|
||||
}
|
||||
|
||||
static void msm_bo_destroy(struct fd_bo *bo)
|
||||
{
|
||||
struct msm_bo *msm_bo = to_msm_bo(bo);
|
||||
|
@ -100,6 +119,7 @@ static const struct fd_bo_funcs funcs = {
|
|||
.offset = msm_bo_offset,
|
||||
.cpu_prep = msm_bo_cpu_prep,
|
||||
.cpu_fini = msm_bo_cpu_fini,
|
||||
.madvise = msm_bo_madvise,
|
||||
.destroy = msm_bo_destroy,
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in New Issue