aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRob Clark2017-03-21 18:44:57 -0500
committerRob Clark2017-03-23 14:22:30 -0500
commitd0dae26ca4e743933f50c1bf4a742e0db8e1994b (patch)
tree89b06b5466f9bcfc0291c3c19b56e4f7215a5ec3
parentb983b054d4f1a6be67105e90f0ae2064f91a762c (diff)
downloadexternal-libdrm-d0dae26ca4e743933f50c1bf4a742e0db8e1994b.tar.gz
external-libdrm-d0dae26ca4e743933f50c1bf4a742e0db8e1994b.tar.xz
external-libdrm-d0dae26ca4e743933f50c1bf4a742e0db8e1994b.zip
freedreno: valgrind support
Signed-off-by: Rob Clark <robclark@freedesktop.org>
-rw-r--r--freedreno/Makefile.am1
-rw-r--r--freedreno/freedreno_bo.c12
-rw-r--r--freedreno/freedreno_bo_cache.c4
-rw-r--r--freedreno/freedreno_priv.h56
-rw-r--r--freedreno/kgsl/kgsl_device.c2
-rw-r--r--freedreno/msm/msm_device.c2
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
10libdrm_freedreno_la_LTLIBRARIES = libdrm_freedreno.la 11libdrm_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
121out_unlock: 125out_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
150out_unlock: 156out_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
183out_unlock: 191out_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 */
214drm_private void bo_del(struct fd_bo *bo) 222drm_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
37drm_private void bo_del(struct fd_bo *bo); 36drm_private void bo_del(struct fd_bo *bo);
38drm_private extern pthread_mutex_t table_lock; 37drm_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
107drm_private void fd_bo_cache_init(struct fd_bo_cache *cache, int coarse); 110drm_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 */
209static 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
216static 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 */
231static 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}
239static 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
248static inline void VG_BO_ALLOC(struct fd_bo *bo) {}
249static inline void VG_BO_FREE(struct fd_bo *bo) {}
250static inline void VG_BO_RELEASE(struct fd_bo *bo) {}
251static 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}