diff options
-rw-r--r-- | freedreno/Makefile.am | 1 | ||||
-rw-r--r-- | freedreno/freedreno_bo.c | 12 | ||||
-rw-r--r-- | freedreno/freedreno_bo_cache.c | 4 | ||||
-rw-r--r-- | freedreno/freedreno_priv.h | 56 | ||||
-rw-r--r-- | freedreno/kgsl/kgsl_device.c | 2 | ||||
-rw-r--r-- | freedreno/msm/msm_device.c | 2 |
6 files changed, 75 insertions, 2 deletions
diff --git a/freedreno/Makefile.am b/freedreno/Makefile.am index 0771d146..cbb0d031 100644 --- a/freedreno/Makefile.am +++ b/freedreno/Makefile.am | |||
@@ -5,6 +5,7 @@ AM_CFLAGS = \ | |||
5 | $(WARN_CFLAGS) \ | 5 | $(WARN_CFLAGS) \ |
6 | -I$(top_srcdir) \ | 6 | -I$(top_srcdir) \ |
7 | $(PTHREADSTUBS_CFLAGS) \ | 7 | $(PTHREADSTUBS_CFLAGS) \ |
8 | $(VALGRIND_CFLAGS) \ | ||
8 | -I$(top_srcdir)/include/drm | 9 | -I$(top_srcdir)/include/drm |
9 | 10 | ||
10 | libdrm_freedreno_la_LTLIBRARIES = libdrm_freedreno.la | 11 | libdrm_freedreno_la_LTLIBRARIES = libdrm_freedreno.la |
diff --git a/freedreno/freedreno_bo.c b/freedreno/freedreno_bo.c index 996d6b95..10949ebf 100644 --- a/freedreno/freedreno_bo.c +++ b/freedreno/freedreno_bo.c | |||
@@ -102,6 +102,8 @@ fd_bo_new(struct fd_device *dev, uint32_t size, uint32_t flags) | |||
102 | bo->bo_reuse = TRUE; | 102 | bo->bo_reuse = TRUE; |
103 | pthread_mutex_unlock(&table_lock); | 103 | pthread_mutex_unlock(&table_lock); |
104 | 104 | ||
105 | VG_BO_ALLOC(bo); | ||
106 | |||
105 | return bo; | 107 | return bo; |
106 | } | 108 | } |
107 | 109 | ||
@@ -118,6 +120,8 @@ fd_bo_from_handle(struct fd_device *dev, uint32_t handle, uint32_t size) | |||
118 | 120 | ||
119 | bo = bo_from_handle(dev, size, handle); | 121 | bo = bo_from_handle(dev, size, handle); |
120 | 122 | ||
123 | VG_BO_ALLOC(bo); | ||
124 | |||
121 | out_unlock: | 125 | out_unlock: |
122 | pthread_mutex_unlock(&table_lock); | 126 | pthread_mutex_unlock(&table_lock); |
123 | 127 | ||
@@ -147,6 +151,8 @@ fd_bo_from_dmabuf(struct fd_device *dev, int fd) | |||
147 | 151 | ||
148 | bo = bo_from_handle(dev, size, handle); | 152 | bo = bo_from_handle(dev, size, handle); |
149 | 153 | ||
154 | VG_BO_ALLOC(bo); | ||
155 | |||
150 | out_unlock: | 156 | out_unlock: |
151 | pthread_mutex_unlock(&table_lock); | 157 | pthread_mutex_unlock(&table_lock); |
152 | 158 | ||
@@ -177,8 +183,10 @@ struct fd_bo * fd_bo_from_name(struct fd_device *dev, uint32_t name) | |||
177 | goto out_unlock; | 183 | goto out_unlock; |
178 | 184 | ||
179 | bo = bo_from_handle(dev, req.size, req.handle); | 185 | bo = bo_from_handle(dev, req.size, req.handle); |
180 | if (bo) | 186 | if (bo) { |
181 | set_name(bo, name); | 187 | set_name(bo, name); |
188 | VG_BO_ALLOC(bo); | ||
189 | } | ||
182 | 190 | ||
183 | out_unlock: | 191 | out_unlock: |
184 | pthread_mutex_unlock(&table_lock); | 192 | pthread_mutex_unlock(&table_lock); |
@@ -213,6 +221,8 @@ out: | |||
213 | /* Called under table_lock */ | 221 | /* Called under table_lock */ |
214 | drm_private void bo_del(struct fd_bo *bo) | 222 | drm_private void bo_del(struct fd_bo *bo) |
215 | { | 223 | { |
224 | VG_BO_FREE(bo); | ||
225 | |||
216 | if (bo->map) | 226 | if (bo->map) |
217 | drm_munmap(bo->map, bo->size); | 227 | drm_munmap(bo->map, bo->size); |
218 | 228 | ||
diff --git a/freedreno/freedreno_bo_cache.c b/freedreno/freedreno_bo_cache.c index 7becb0d6..d922f3a9 100644 --- a/freedreno/freedreno_bo_cache.c +++ b/freedreno/freedreno_bo_cache.c | |||
@@ -33,7 +33,6 @@ | |||
33 | #include "freedreno_drmif.h" | 33 | #include "freedreno_drmif.h" |
34 | #include "freedreno_priv.h" | 34 | #include "freedreno_priv.h" |
35 | 35 | ||
36 | |||
37 | drm_private void bo_del(struct fd_bo *bo); | 36 | drm_private void bo_del(struct fd_bo *bo); |
38 | drm_private extern pthread_mutex_t table_lock; | 37 | drm_private extern pthread_mutex_t table_lock; |
39 | 38 | ||
@@ -102,6 +101,7 @@ fd_bo_cache_cleanup(struct fd_bo_cache *cache, time_t time) | |||
102 | if (time && ((time - bo->free_time) <= 1)) | 101 | if (time && ((time - bo->free_time) <= 1)) |
103 | break; | 102 | break; |
104 | 103 | ||
104 | VG_BO_OBTAIN(bo); | ||
105 | list_del(&bo->list); | 105 | list_del(&bo->list); |
106 | bo_del(bo); | 106 | bo_del(bo); |
107 | } | 107 | } |
@@ -177,6 +177,7 @@ retry: | |||
177 | *size = bucket->size; | 177 | *size = bucket->size; |
178 | bo = find_in_bucket(bucket, flags); | 178 | bo = find_in_bucket(bucket, flags); |
179 | if (bo) { | 179 | if (bo) { |
180 | VG_BO_OBTAIN(bo); | ||
180 | if (bo->funcs->madvise(bo, TRUE) <= 0) { | 181 | if (bo->funcs->madvise(bo, TRUE) <= 0) { |
181 | /* we've lost the backing pages, delete and try again: */ | 182 | /* we've lost the backing pages, delete and try again: */ |
182 | pthread_mutex_lock(&table_lock); | 183 | pthread_mutex_lock(&table_lock); |
@@ -207,6 +208,7 @@ fd_bo_cache_free(struct fd_bo_cache *cache, struct fd_bo *bo) | |||
207 | clock_gettime(CLOCK_MONOTONIC, &time); | 208 | clock_gettime(CLOCK_MONOTONIC, &time); |
208 | 209 | ||
209 | bo->free_time = time.tv_sec; | 210 | bo->free_time = time.tv_sec; |
211 | VG_BO_RELEASE(bo); | ||
210 | list_addtail(&bo->list, &bucket->list); | 212 | list_addtail(&bo->list, &bucket->list); |
211 | fd_bo_cache_cleanup(cache, time.tv_sec); | 213 | fd_bo_cache_cleanup(cache, time.tv_sec); |
212 | 214 | ||
diff --git a/freedreno/freedreno_priv.h b/freedreno/freedreno_priv.h index 32170391..8dd3ee69 100644 --- a/freedreno/freedreno_priv.h +++ b/freedreno/freedreno_priv.h | |||
@@ -102,6 +102,9 @@ struct fd_device { | |||
102 | struct fd_bo_cache bo_cache; | 102 | struct fd_bo_cache bo_cache; |
103 | 103 | ||
104 | int closefd; /* call close(fd) upon destruction */ | 104 | int closefd; /* call close(fd) upon destruction */ |
105 | |||
106 | /* just for valgrind: */ | ||
107 | int bo_size; | ||
105 | }; | 108 | }; |
106 | 109 | ||
107 | drm_private void fd_bo_cache_init(struct fd_bo_cache *cache, int coarse); | 110 | drm_private void fd_bo_cache_init(struct fd_bo_cache *cache, int coarse); |
@@ -196,4 +199,57 @@ offset_bytes(void *end, void *start) | |||
196 | return ((char *)end) - ((char *)start); | 199 | return ((char *)end) - ((char *)start); |
197 | } | 200 | } |
198 | 201 | ||
202 | #ifdef HAVE_VALGRIND | ||
203 | # include <memcheck.h> | ||
204 | |||
205 | /* | ||
206 | * For tracking the backing memory (if valgrind enabled, we force a mmap | ||
207 | * for the purposes of tracking) | ||
208 | */ | ||
209 | static inline void VG_BO_ALLOC(struct fd_bo *bo) | ||
210 | { | ||
211 | if (bo && RUNNING_ON_VALGRIND) { | ||
212 | VALGRIND_MALLOCLIKE_BLOCK(fd_bo_map(bo), bo->size, 0, 1); | ||
213 | } | ||
214 | } | ||
215 | |||
216 | static inline void VG_BO_FREE(struct fd_bo *bo) | ||
217 | { | ||
218 | VALGRIND_FREELIKE_BLOCK(bo->map, 0); | ||
219 | } | ||
220 | |||
221 | /* | ||
222 | * For tracking bo structs that are in the buffer-cache, so that valgrind | ||
223 | * doesn't attribute ownership to the first one to allocate the recycled | ||
224 | * bo. | ||
225 | * | ||
226 | * Note that the list_head in fd_bo is used to track the buffers in cache | ||
227 | * so disable error reporting on the range while they are in cache so | ||
228 | * valgrind doesn't squawk about list traversal. | ||
229 | * | ||
230 | */ | ||
231 | static inline void VG_BO_RELEASE(struct fd_bo *bo) | ||
232 | { | ||
233 | if (RUNNING_ON_VALGRIND) { | ||
234 | VALGRIND_DISABLE_ADDR_ERROR_REPORTING_IN_RANGE(bo, bo->dev->bo_size); | ||
235 | VALGRIND_MAKE_MEM_NOACCESS(bo, bo->dev->bo_size); | ||
236 | VALGRIND_FREELIKE_BLOCK(bo->map, 0); | ||
237 | } | ||
238 | } | ||
239 | static inline void VG_BO_OBTAIN(struct fd_bo *bo) | ||
240 | { | ||
241 | if (RUNNING_ON_VALGRIND) { | ||
242 | VALGRIND_MAKE_MEM_DEFINED(bo, bo->dev->bo_size); | ||
243 | VALGRIND_ENABLE_ADDR_ERROR_REPORTING_IN_RANGE(bo, bo->dev->bo_size); | ||
244 | VALGRIND_MALLOCLIKE_BLOCK(bo->map, bo->size, 0, 1); | ||
245 | } | ||
246 | } | ||
247 | #else | ||
248 | static inline void VG_BO_ALLOC(struct fd_bo *bo) {} | ||
249 | static inline void VG_BO_FREE(struct fd_bo *bo) {} | ||
250 | static inline void VG_BO_RELEASE(struct fd_bo *bo) {} | ||
251 | static inline void VG_BO_OBTAIN(struct fd_bo *bo) {} | ||
252 | #endif | ||
253 | |||
254 | |||
199 | #endif /* FREEDRENO_PRIV_H_ */ | 255 | #endif /* FREEDRENO_PRIV_H_ */ |
diff --git a/freedreno/kgsl/kgsl_device.c b/freedreno/kgsl/kgsl_device.c index 175e8378..958e8a72 100644 --- a/freedreno/kgsl/kgsl_device.c +++ b/freedreno/kgsl/kgsl_device.c | |||
@@ -61,5 +61,7 @@ drm_private struct fd_device * kgsl_device_new(int fd) | |||
61 | dev = &kgsl_dev->base; | 61 | dev = &kgsl_dev->base; |
62 | dev->funcs = &funcs; | 62 | dev->funcs = &funcs; |
63 | 63 | ||
64 | dev->bo_size = sizeof(struct kgsl_bo); | ||
65 | |||
64 | return dev; | 66 | return dev; |
65 | } | 67 | } |
diff --git a/freedreno/msm/msm_device.c b/freedreno/msm/msm_device.c index 727baa44..c454938d 100644 --- a/freedreno/msm/msm_device.c +++ b/freedreno/msm/msm_device.c | |||
@@ -64,5 +64,7 @@ drm_private struct fd_device * msm_device_new(int fd) | |||
64 | 64 | ||
65 | fd_bo_cache_init(&msm_dev->ring_cache, TRUE); | 65 | fd_bo_cache_init(&msm_dev->ring_cache, TRUE); |
66 | 66 | ||
67 | dev->bo_size = sizeof(struct msm_bo); | ||
68 | |||
67 | return dev; | 69 | return dev; |
68 | } | 70 | } |