diff options
Diffstat (limited to 'freedreno')
-rw-r--r-- | freedreno/freedreno_bo_cache.c | 10 | ||||
-rw-r--r-- | freedreno/freedreno_device.c | 10 | ||||
-rw-r--r-- | freedreno/freedreno_priv.h | 9 | ||||
-rw-r--r-- | freedreno/kgsl/kgsl_bo.c | 6 | ||||
-rw-r--r-- | freedreno/msm/msm_bo.c | 20 |
5 files changed, 55 insertions, 0 deletions
diff --git a/freedreno/freedreno_bo_cache.c b/freedreno/freedreno_bo_cache.c index 17199d27..58d171eb 100644 --- a/freedreno/freedreno_bo_cache.c +++ b/freedreno/freedreno_bo_cache.c | |||
@@ -165,10 +165,18 @@ fd_bo_cache_alloc(struct fd_bo_cache *cache, uint32_t *size, uint32_t flags) | |||
165 | bucket = get_bucket(cache, *size); | 165 | bucket = get_bucket(cache, *size); |
166 | 166 | ||
167 | /* see if we can be green and recycle: */ | 167 | /* see if we can be green and recycle: */ |
168 | retry: | ||
168 | if (bucket) { | 169 | if (bucket) { |
169 | *size = bucket->size; | 170 | *size = bucket->size; |
170 | bo = find_in_bucket(bucket, flags); | 171 | bo = find_in_bucket(bucket, flags); |
171 | if (bo) { | 172 | if (bo) { |
173 | if (bo->funcs->madvise(bo, TRUE) <= 0) { | ||
174 | /* we've lost the backing pages, delete and try again: */ | ||
175 | pthread_mutex_lock(&table_lock); | ||
176 | bo_del(bo); | ||
177 | pthread_mutex_unlock(&table_lock); | ||
178 | goto retry; | ||
179 | } | ||
172 | atomic_set(&bo->refcnt, 1); | 180 | atomic_set(&bo->refcnt, 1); |
173 | fd_device_ref(bo->dev); | 181 | fd_device_ref(bo->dev); |
174 | return bo; | 182 | return bo; |
@@ -187,6 +195,8 @@ fd_bo_cache_free(struct fd_bo_cache *cache, struct fd_bo *bo) | |||
187 | if (bucket) { | 195 | if (bucket) { |
188 | struct timespec time; | 196 | struct timespec time; |
189 | 197 | ||
198 | bo->funcs->madvise(bo, FALSE); | ||
199 | |||
190 | clock_gettime(CLOCK_MONOTONIC, &time); | 200 | clock_gettime(CLOCK_MONOTONIC, &time); |
191 | 201 | ||
192 | bo->free_time = time.tv_sec; | 202 | bo->free_time = time.tv_sec; |
diff --git a/freedreno/freedreno_device.c b/freedreno/freedreno_device.c index 15e41f0e..027414ec 100644 --- a/freedreno/freedreno_device.c +++ b/freedreno/freedreno_device.c | |||
@@ -56,7 +56,15 @@ struct fd_device * fd_device_new(int fd) | |||
56 | 56 | ||
57 | if (!strcmp(version->name, "msm")) { | 57 | if (!strcmp(version->name, "msm")) { |
58 | DEBUG_MSG("msm DRM device"); | 58 | DEBUG_MSG("msm DRM device"); |
59 | if (version->version_major != 1) { | ||
60 | ERROR_MSG("unsupported version: %u.%u.%u", version->version_major, | ||
61 | version->version_minor, version->version_patchlevel); | ||
62 | dev = NULL; | ||
63 | goto out; | ||
64 | } | ||
65 | |||
59 | dev = msm_device_new(fd); | 66 | dev = msm_device_new(fd); |
67 | dev->version = version->version_minor; | ||
60 | #ifdef HAVE_FREEDRENO_KGSL | 68 | #ifdef HAVE_FREEDRENO_KGSL |
61 | } else if (!strcmp(version->name, "kgsl")) { | 69 | } else if (!strcmp(version->name, "kgsl")) { |
62 | DEBUG_MSG("kgsl DRM device"); | 70 | DEBUG_MSG("kgsl DRM device"); |
@@ -66,6 +74,8 @@ struct fd_device * fd_device_new(int fd) | |||
66 | ERROR_MSG("unknown device: %s", version->name); | 74 | ERROR_MSG("unknown device: %s", version->name); |
67 | dev = NULL; | 75 | dev = NULL; |
68 | } | 76 | } |
77 | |||
78 | out: | ||
69 | drmFreeVersion(version); | 79 | drmFreeVersion(version); |
70 | 80 | ||
71 | if (!dev) | 81 | if (!dev) |
diff --git a/freedreno/freedreno_priv.h b/freedreno/freedreno_priv.h index 4159e526..f3ddd77d 100644 --- a/freedreno/freedreno_priv.h +++ b/freedreno/freedreno_priv.h | |||
@@ -54,6 +54,13 @@ | |||
54 | #include "freedreno_ringbuffer.h" | 54 | #include "freedreno_ringbuffer.h" |
55 | #include "drm.h" | 55 | #include "drm.h" |
56 | 56 | ||
57 | #ifndef TRUE | ||
58 | # define TRUE 1 | ||
59 | #endif | ||
60 | #ifndef FALSE | ||
61 | # define FALSE 0 | ||
62 | #endif | ||
63 | |||
57 | struct fd_device_funcs { | 64 | struct fd_device_funcs { |
58 | int (*bo_new_handle)(struct fd_device *dev, uint32_t size, | 65 | int (*bo_new_handle)(struct fd_device *dev, uint32_t size, |
59 | uint32_t flags, uint32_t *handle); | 66 | uint32_t flags, uint32_t *handle); |
@@ -76,6 +83,7 @@ struct fd_bo_cache { | |||
76 | 83 | ||
77 | struct fd_device { | 84 | struct fd_device { |
78 | int fd; | 85 | int fd; |
86 | int version; | ||
79 | atomic_t refcnt; | 87 | atomic_t refcnt; |
80 | 88 | ||
81 | /* tables to keep track of bo's, to avoid "evil-twin" fd_bo objects: | 89 | /* tables to keep track of bo's, to avoid "evil-twin" fd_bo objects: |
@@ -139,6 +147,7 @@ struct fd_bo_funcs { | |||
139 | int (*offset)(struct fd_bo *bo, uint64_t *offset); | 147 | int (*offset)(struct fd_bo *bo, uint64_t *offset); |
140 | int (*cpu_prep)(struct fd_bo *bo, struct fd_pipe *pipe, uint32_t op); | 148 | int (*cpu_prep)(struct fd_bo *bo, struct fd_pipe *pipe, uint32_t op); |
141 | void (*cpu_fini)(struct fd_bo *bo); | 149 | void (*cpu_fini)(struct fd_bo *bo); |
150 | int (*madvise)(struct fd_bo *bo, int willneed); | ||
142 | void (*destroy)(struct fd_bo *bo); | 151 | void (*destroy)(struct fd_bo *bo); |
143 | }; | 152 | }; |
144 | 153 | ||
diff --git a/freedreno/kgsl/kgsl_bo.c b/freedreno/kgsl/kgsl_bo.c index 2b45b5e2..ab3485e3 100644 --- a/freedreno/kgsl/kgsl_bo.c +++ b/freedreno/kgsl/kgsl_bo.c | |||
@@ -116,6 +116,11 @@ static void kgsl_bo_cpu_fini(struct fd_bo *bo) | |||
116 | { | 116 | { |
117 | } | 117 | } |
118 | 118 | ||
119 | static int kgsl_bo_madvise(struct fd_bo *bo, int willneed) | ||
120 | { | ||
121 | return willneed; /* not supported by kgsl */ | ||
122 | } | ||
123 | |||
119 | static void kgsl_bo_destroy(struct fd_bo *bo) | 124 | static void kgsl_bo_destroy(struct fd_bo *bo) |
120 | { | 125 | { |
121 | struct kgsl_bo *kgsl_bo = to_kgsl_bo(bo); | 126 | struct kgsl_bo *kgsl_bo = to_kgsl_bo(bo); |
@@ -127,6 +132,7 @@ static const struct fd_bo_funcs funcs = { | |||
127 | .offset = kgsl_bo_offset, | 132 | .offset = kgsl_bo_offset, |
128 | .cpu_prep = kgsl_bo_cpu_prep, | 133 | .cpu_prep = kgsl_bo_cpu_prep, |
129 | .cpu_fini = kgsl_bo_cpu_fini, | 134 | .cpu_fini = kgsl_bo_cpu_fini, |
135 | .madvise = kgsl_bo_madvise, | ||
130 | .destroy = kgsl_bo_destroy, | 136 | .destroy = kgsl_bo_destroy, |
131 | }; | 137 | }; |
132 | 138 | ||
diff --git a/freedreno/msm/msm_bo.c b/freedreno/msm/msm_bo.c index cd05a6cd..cfaec827 100644 --- a/freedreno/msm/msm_bo.c +++ b/freedreno/msm/msm_bo.c | |||
@@ -89,6 +89,25 @@ static void msm_bo_cpu_fini(struct fd_bo *bo) | |||
89 | drmCommandWrite(bo->dev->fd, DRM_MSM_GEM_CPU_FINI, &req, sizeof(req)); | 89 | drmCommandWrite(bo->dev->fd, DRM_MSM_GEM_CPU_FINI, &req, sizeof(req)); |
90 | } | 90 | } |
91 | 91 | ||
92 | static int msm_bo_madvise(struct fd_bo *bo, int willneed) | ||
93 | { | ||
94 | struct drm_msm_gem_madvise req = { | ||
95 | .handle = bo->handle, | ||
96 | .madv = willneed ? MSM_MADV_WILLNEED : MSM_MADV_DONTNEED, | ||
97 | }; | ||
98 | int ret; | ||
99 | |||
100 | /* older kernels do not support this: */ | ||
101 | if (bo->dev->version < 1) | ||
102 | return willneed; | ||
103 | |||
104 | ret = drmCommandWriteRead(bo->dev->fd, DRM_MSM_GEM_MADVISE, &req, sizeof(req)); | ||
105 | if (ret) | ||
106 | return ret; | ||
107 | |||
108 | return req.retained; | ||
109 | } | ||
110 | |||
92 | static void msm_bo_destroy(struct fd_bo *bo) | 111 | static void msm_bo_destroy(struct fd_bo *bo) |
93 | { | 112 | { |
94 | struct msm_bo *msm_bo = to_msm_bo(bo); | 113 | struct msm_bo *msm_bo = to_msm_bo(bo); |
@@ -100,6 +119,7 @@ static const struct fd_bo_funcs funcs = { | |||
100 | .offset = msm_bo_offset, | 119 | .offset = msm_bo_offset, |
101 | .cpu_prep = msm_bo_cpu_prep, | 120 | .cpu_prep = msm_bo_cpu_prep, |
102 | .cpu_fini = msm_bo_cpu_fini, | 121 | .cpu_fini = msm_bo_cpu_fini, |
122 | .madvise = msm_bo_madvise, | ||
103 | .destroy = msm_bo_destroy, | 123 | .destroy = msm_bo_destroy, |
104 | }; | 124 | }; |
105 | 125 | ||