drm: Branch 'master' - 2 commits

[email protected] (Rob Clark)
Newsgroups gmane.comp.video.dri.patches
Message-ID <[email protected]>
 freedreno/Makefile.am          |    1 
 freedreno/freedreno_bo.c       |   12 ++++++++
 freedreno/freedreno_bo_cache.c |    4 ++
 freedreno/freedreno_device.c   |    3 +-
 freedreno/freedreno_priv.h     |   56 +++++++++++++++++++++++++++++++++++++++++
 freedreno/kgsl/kgsl_device.c   |    2 +
 freedreno/msm/msm_device.c     |    2 +
 7 files changed, 77 insertions(+), 3 deletions(-)

New commits:
commit a07ae97c75ca45c08327b53df5d8d53e56a46a8a
Author: Rob Clark <[email protected]>
Date:   Thu Mar 23 14:58:38 2017 -0400

    freedreno: fix device close issues
    
    Move closing the fd to after subclass ->destroy() (since it might want
    to delete gem bo's, etc), and actually free() the fd_device object.
    
    Signed-off-by: Rob Clark <[email protected]>

diff --git a/freedreno/freedreno_device.c b/freedreno/freedreno_device.c
index fcbf1402..dba7ec47 100644
--- a/freedreno/freedreno_device.c
+++ b/freedreno/freedreno_device.c
@@ -115,9 +115,10 @@ static void fd_device_del_impl(struct fd_device *dev)
 	fd_bo_cache_cleanup(&dev->bo_cache, 0);
 	drmHashDestroy(dev->handle_table);
 	drmHashDestroy(dev->name_table);
+	dev->funcs->destroy(dev);
 	if (dev->closefd)
 		close(dev->fd);
-	dev->funcs->destroy(dev);
+	free(dev);
 }
 
 drm_private void fd_device_del_locked(struct fd_device *dev)
commit d0dae26ca4e743933f50c1bf4a742e0db8e1994b
Author: Rob Clark <[email protected]>
Date:   Tue Mar 21 19:44:57 2017 -0400

    freedreno: valgrind support
    
    Signed-off-by: Rob Clark <[email protected]>

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 = \
 	$(WARN_CFLAGS) \
 	-I$(top_srcdir) \
 	$(PTHREADSTUBS_CFLAGS) \
+	$(VALGRIND_CFLAGS) \
 	-I$(top_srcdir)/include/drm
 
 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)
 	bo->bo_reuse = TRUE;
 	pthread_mutex_unlock(&table_lock);
 
+	VG_BO_ALLOC(bo);
+
 	return bo;
 }
 
@@ -118,6 +120,8 @@ fd_bo_from_handle(struct fd_device *dev, uint32_t handle, uint32_t size)
 
 	bo = bo_from_handle(dev, size, handle);
 
+	VG_BO_ALLOC(bo);
+
 out_unlock:
 	pthread_mutex_unlock(&table_lock);
 
@@ -147,6 +151,8 @@ fd_bo_from_dmabuf(struct fd_device *dev, int fd)
 
 	bo = bo_from_handle(dev, size, handle);
 
+	VG_BO_ALLOC(bo);
+
 out_unlock:
 	pthread_mutex_unlock(&table_lock);
 
@@ -177,8 +183,10 @@ struct fd_bo * fd_bo_from_name(struct fd_device *dev, uint32_t name)
 		goto out_unlock;
 
 	bo = bo_from_handle(dev, req.size, req.handle);
-	if (bo)
+	if (bo) {
 		set_name(bo, name);
+		VG_BO_ALLOC(bo);
+	}
 
 out_unlock:
 	pthread_mutex_unlock(&table_lock);
@@ -213,6 +221,8 @@ out:
 /* Called under table_lock */
 drm_private void bo_del(struct fd_bo *bo)
 {
+	VG_BO_FREE(bo);
+
 	if (bo->map)
 		drm_munmap(bo->map, bo->size);
 
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 @@
 #include "freedreno_drmif.h"
 #include "freedreno_priv.h"
 
-
 drm_private void bo_del(struct fd_bo *bo);
 drm_private extern pthread_mutex_t table_lock;
 
@@ -102,6 +101,7 @@ fd_bo_cache_cleanup(struct fd_bo_cache *cache, time_t time)
 			if (time && ((time - bo->free_time) <= 1))
 				break;
 
+			VG_BO_OBTAIN(bo);
 			list_del(&bo->list);
 			bo_del(bo);
 		}
@@ -177,6 +177,7 @@ retry:
 		*size = bucket->size;
 		bo = find_in_bucket(bucket, flags);
 		if (bo) {
+			VG_BO_OBTAIN(bo);
 			if (bo->funcs->madvise(bo, TRUE) <= 0) {
 				/* we've lost the backing pages, delete and try again: */
 				pthread_mutex_lock(&table_lock);
@@ -207,6 +208,7 @@ fd_bo_cache_free(struct fd_bo_cache *cache, struct fd_bo *bo)
 		clock_gettime(CLOCK_MONOTONIC, &time);
 
 		bo->free_time = time.tv_sec;
+		VG_BO_RELEASE(bo);
 		list_addtail(&bo->list, &bucket->list);
 		fd_bo_cache_cleanup(cache, time.tv_sec);
 
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 {
 	struct fd_bo_cache bo_cache;
 
 	int closefd;        /* call close(fd) upon destruction */
+
+	/* just for valgrind: */
+	int bo_size;
 };
 
 drm_private void fd_bo_cache_init(struct fd_bo_cache *cache, int coarse);
@@ -196,4 +199,57 @@ offset_bytes(void *end, void *start)
 	return ((char *)end) - ((char *)start);
 }
 
+#ifdef HAVE_VALGRIND
+#  include <memcheck.h>
+
+/*
+ * For tracking the backing memory (if valgrind enabled, we force a mmap
+ * for the purposes of tracking)
+ */
+static inline void VG_BO_ALLOC(struct fd_bo *bo)
+{
+	if (bo && RUNNING_ON_VALGRIND) {
+		VALGRIND_MALLOCLIKE_BLOCK(fd_bo_map(bo), bo->size, 0, 1);
+	}
+}
+
+static inline void VG_BO_FREE(struct fd_bo *bo)
+{
+	VALGRIND_FREELIKE_BLOCK(bo->map, 0);
+}
+
+/*
+ * For tracking bo structs that are in the buffer-cache, so that valgrind
+ * doesn't attribute ownership to the first one to allocate the recycled
+ * bo.
+ *
+ * Note that the list_head in fd_bo is used to track the buffers in cache
+ * so disable error reporting on the range while they are in cache so
+ * valgrind doesn't squawk about list traversal.
+ *
+ */
+static inline void VG_BO_RELEASE(struct fd_bo *bo)
+{
+	if (RUNNING_ON_VALGRIND) {
+		VALGRIND_DISABLE_ADDR_ERROR_REPORTING_IN_RANGE(bo, bo->dev->bo_size);
+		VALGRIND_MAKE_MEM_NOACCESS(bo, bo->dev->bo_size);
+		VALGRIND_FREELIKE_BLOCK(bo->map, 0);
+	}
+}
+static inline void VG_BO_OBTAIN(struct fd_bo *bo)
+{
+	if (RUNNING_ON_VALGRIND) {
+		VALGRIND_MAKE_MEM_DEFINED(bo, bo->dev->bo_size);
+		VALGRIND_ENABLE_ADDR_ERROR_REPORTING_IN_RANGE(bo, bo->dev->bo_size);
+		VALGRIND_MALLOCLIKE_BLOCK(bo->map, bo->size, 0, 1);
+	}
+}
+#else
+static inline void VG_BO_ALLOC(struct fd_bo *bo)   {}
+static inline void VG_BO_FREE(struct fd_bo *bo)    {}
+static inline void VG_BO_RELEASE(struct fd_bo *bo) {}
+static inline void VG_BO_OBTAIN(struct fd_bo *bo)  {}
+#endif
+
+
 #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)
 	dev = &kgsl_dev->base;
 	dev->funcs = &funcs;
 
+	dev->bo_size = sizeof(struct kgsl_bo);
+
 	return dev;
 }
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)
 
 	fd_bo_cache_init(&msm_dev->ring_cache, TRUE);
 
+	dev->bo_size = sizeof(struct msm_bo);
+
 	return dev;
 }

------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
--
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.