[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

libdrm: Changes to 'debian-unstable'



 amdgpu/amdgpu.h                  |    5 +
 amdgpu/amdgpu_device.c           |   33 +++++++-
 amdgpu/amdgpu_internal.h         |   13 +--
 amdgpu/amdgpu_vamgr.c            |   63 +++++++--------
 configure.ac                     |    2 
 debian/changelog                 |    7 +
 debian/libdrm-freedreno1.symbols |    1 
 debian/rules                     |    2 
 freedreno/freedreno-symbol-check |    1 
 freedreno/freedreno_drmif.h      |    3 
 freedreno/freedreno_pipe.c       |    8 +-
 freedreno/freedreno_priv.h       |    2 
 freedreno/kgsl/kgsl_pipe.c       |    3 
 freedreno/msm/msm_bo.c           |    6 -
 freedreno/msm/msm_pipe.c         |    5 -
 freedreno/msm/msm_priv.h         |   21 ++++-
 freedreno/msm/msm_ringbuffer.c   |  155 +++++++++++++++++++++++++--------------
 tests/amdgpu/amdgpu_test.c       |    5 +
 tests/amdgpu/basic_tests.c       |    5 +
 tests/amdgpu/bo_tests.c          |    5 +
 tests/amdgpu/cs_tests.c          |    5 +
 tests/amdgpu/vce_tests.c         |    6 +
 tests/modetest/modetest.c        |   94 ++++++++++++++++++++---
 xf86drmMode.c                    |   12 ---
 24 files changed, 326 insertions(+), 136 deletions(-)

New commits:
commit 50949b57acc5860b036410683b69a98e12e3fffc
Author: Robert Hooker <sarvatt@ubuntu.com>
Date:   Tue Aug 18 16:40:35 2015 -0400

    Bump symbols and shlibs for freedreno

diff --git a/debian/changelog b/debian/changelog
index c1df6aa..e9214e1 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,6 +1,7 @@
 libdrm (2.4.64-1) UNRELEASED; urgency=medium
 
   * New upstream release.
+  * Bump symbols file and shlibs for libdrm-freedreno1.
 
  -- Robert Hooker <sarvatt@ubuntu.com>  Tue, 18 Aug 2015 16:05:01 -0400
 
diff --git a/debian/libdrm-freedreno1.symbols b/debian/libdrm-freedreno1.symbols
index b7602f9..efb91a9 100644
--- a/debian/libdrm-freedreno1.symbols
+++ b/debian/libdrm-freedreno1.symbols
@@ -21,6 +21,7 @@ libdrm_freedreno.so.1 libdrm-freedreno1 #MINVER#
  fd_pipe_get_param@Base 0
  fd_pipe_new@Base 0
  fd_pipe_wait@Base 0
+ fd_pipe_wait_timeout@Base 2.4.64
  fd_ringbuffer_del@Base 0
  fd_ringbuffer_emit_reloc_ring@Base 0
  fd_ringbuffer_flush@Base 0
diff --git a/debian/rules b/debian/rules
index ec465df..dee3894 100755
--- a/debian/rules
+++ b/debian/rules
@@ -106,7 +106,7 @@ endif
 	dh_makeshlibs -plibdrm-radeon1 -V'libdrm-radeon1 (>= 2.4.39)' -- -c4
 ifeq ($(ARM), yes)
 	dh_makeshlibs -plibdrm-omap1 -V'libdrm-omap1 (>= 2.4.38)' -- -c4
-	dh_makeshlibs -plibdrm-freedreno1 -V'libdrm-freedreno1 (>= 2.4.57)' -- -c4
+	dh_makeshlibs -plibdrm-freedreno1 -V'libdrm-freedreno1 (>= 2.4.64)' -- -c4
 	dh_makeshlibs -plibdrm-exynos1 -V'libdrm-exynos1 (>= 2.4.60)' -- -c4
 	dh_makeshlibs -plibdrm-tegra0 -V'libdrm-tegra0' -- -c4
 endif

commit 564ab8aa8535474c295406154c1626529b518da4
Author: Robert Hooker <sarvatt@ubuntu.com>
Date:   Tue Aug 18 16:38:41 2015 -0400

    Bump changelog.

diff --git a/debian/changelog b/debian/changelog
index 6f71a39..c1df6aa 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,9 @@
+libdrm (2.4.64-1) UNRELEASED; urgency=medium
+
+  * New upstream release.
+
+ -- Robert Hooker <sarvatt@ubuntu.com>  Tue, 18 Aug 2015 16:05:01 -0400
+
 libdrm (2.4.63-1) unstable; urgency=medium
 
   [ Robert Hooker ]

commit ab2fadabde3829b1ec56bd4756165dd9bd281488
Author: Rob Clark <robclark@freedesktop.org>
Date:   Tue Aug 18 11:56:50 2015 -0400

    Bump version for release
    
    Signed-off-by: Rob Clark <robclark@freedesktop.org>

diff --git a/configure.ac b/configure.ac
index e2a2f16..f07507b 100644
--- a/configure.ac
+++ b/configure.ac
@@ -20,7 +20,7 @@
 
 AC_PREREQ([2.63])
 AC_INIT([libdrm],
-        [2.4.63],
+        [2.4.64],
         [https://bugs.freedesktop.org/enter_bug.cgi?product=DRI],
         [libdrm])
 

commit 04a118d800280c88aed5cb4a5f29fdfb5a38e36b
Author: Rob Clark <robclark@freedesktop.org>
Date:   Tue Aug 18 10:53:36 2015 -0400

    freedreno: update freedreno-symbol-check
    
    Signed-off-by: Rob Clark <robclark@freedesktop.org>

diff --git a/freedreno/freedreno-symbol-check b/freedreno/freedreno-symbol-check
index 7115448..e593df4 100755
--- a/freedreno/freedreno-symbol-check
+++ b/freedreno/freedreno-symbol-check
@@ -32,6 +32,7 @@ fd_pipe_del
 fd_pipe_get_param
 fd_pipe_new
 fd_pipe_wait
+fd_pipe_wait_timeout
 fd_ringbuffer_del
 fd_ringbuffer_emit_reloc_ring
 fd_ringbuffer_flush

commit 5e5a3c48b83fb3929e57cb4e7261624a327137f3
Author: Thierry Reding <treding@nvidia.com>
Date:   Wed Apr 9 09:00:49 2014 +0200

    libdrm: Make indentation consistent
    
    Use tabs and spaces consistently to align function arguments on
    subsequent lines with those of the first line.
    
    Acked-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
    Signed-off-by: Thierry Reding <treding@nvidia.com>

diff --git a/xf86drmMode.c b/xf86drmMode.c
index 23348d7..9b70ce8 100644
--- a/xf86drmMode.c
+++ b/xf86drmMode.c
@@ -249,7 +249,7 @@ err_allocs:
 }
 
 int drmModeAddFB(int fd, uint32_t width, uint32_t height, uint8_t depth,
-                 uint8_t bpp, uint32_t pitch, uint32_t bo_handle,
+		 uint8_t bpp, uint32_t pitch, uint32_t bo_handle,
 		 uint32_t *buf_id)
 {
 	struct drm_mode_fb_cmd f;
@@ -374,7 +374,7 @@ drmModeCrtcPtr drmModeGetCrtc(int fd, uint32_t crtcId)
 }
 
 int drmModeSetCrtc(int fd, uint32_t crtcId, uint32_t bufferId,
-                   uint32_t x, uint32_t y, uint32_t *connectors, int count,
+		   uint32_t x, uint32_t y, uint32_t *connectors, int count,
 		   drmModeModeInfoPtr mode)
 {
 	struct drm_mode_crtc crtc;

commit d2d361cddd2bdf8f1bf627b9ebe8ca802156f8af
Author: Thierry Reding <treding@nvidia.com>
Date:   Wed Apr 9 08:59:04 2014 +0200

    libdrm: Remove gratuitous blank lines
    
    Usage of blank lines can be a matter of taste, of course, but for these
    we can surely all agree that they're not needed and inconsistent.
    
    Acked-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
    Signed-off-by: Thierry Reding <treding@nvidia.com>

diff --git a/xf86drmMode.c b/xf86drmMode.c
index fc19504..23348d7 100644
--- a/xf86drmMode.c
+++ b/xf86drmMode.c
@@ -114,7 +114,6 @@ void drmModeFreeResources(drmModeResPtr ptr)
 	drmFree(ptr->connectors);
 	drmFree(ptr->encoders);
 	drmFree(ptr);
-
 }
 
 void drmModeFreeFB(drmModeFBPtr ptr)
@@ -132,7 +131,6 @@ void drmModeFreeCrtc(drmModeCrtcPtr ptr)
 		return;
 
 	drmFree(ptr);
-
 }
 
 void drmModeFreeConnector(drmModeConnectorPtr ptr)
@@ -145,7 +143,6 @@ void drmModeFreeConnector(drmModeConnectorPtr ptr)
 	drmFree(ptr->props);
 	drmFree(ptr->modes);
 	drmFree(ptr);
-
 }
 
 void drmModeFreeEncoder(drmModeEncoderPtr ptr)
@@ -340,7 +337,6 @@ int drmModeDirtyFB(int fd, uint32_t bufferId,
 	return DRM_IOCTL(fd, DRM_IOCTL_MODE_DIRTYFB, &dirty);
 }
 
-
 /*
  * Crtc functions
  */
@@ -377,7 +373,6 @@ drmModeCrtcPtr drmModeGetCrtc(int fd, uint32_t crtcId)
 	return r;
 }
 
-
 int drmModeSetCrtc(int fd, uint32_t crtcId, uint32_t bufferId,
                    uint32_t x, uint32_t y, uint32_t *connectors, int count,
 		   drmModeModeInfoPtr mode)
@@ -610,7 +605,6 @@ int drmModeDetachMode(int fd, uint32_t connector_id, drmModeModeInfoPtr mode_inf
 	return DRM_IOCTL(fd, DRM_IOCTL_MODE_DETACHMODE, &res);
 }
 
-
 drmModePropertyPtr drmModeGetProperty(int fd, uint32_t property_id)
 {
 	struct drm_mode_get_property prop;
@@ -944,7 +938,6 @@ int drmModeSetPlane(int fd, uint32_t plane_id, uint32_t crtc_id,
 		    uint32_t crtc_w, uint32_t crtc_h,
 		    uint32_t src_x, uint32_t src_y,
 		    uint32_t src_w, uint32_t src_h)
-
 {
 	struct drm_mode_set_plane s;
 
@@ -965,7 +958,6 @@ int drmModeSetPlane(int fd, uint32_t plane_id, uint32_t crtc_id,
 	return DRM_IOCTL(fd, DRM_IOCTL_MODE_SETPLANE, &s);
 }
 
-
 drmModePlanePtr drmModeGetPlane(int fd, uint32_t plane_id)
 {
 	struct drm_mode_get_plane ovr, counts;

commit 56d8dd6a9c03680700e0b0043cb56e0af7e3e3de
Author: Jammy Zhou <Jammy.Zhou@amd.com>
Date:   Mon Aug 17 11:09:09 2015 +0800

    amdgpu: make vamgr per device v2
    
    Each device can have its own vamgr, so make it per device now.
    This can fix the failure with multiple GPUs used in one single
    process.
    
    v2: rebase
    
    Signed-off-by: Jammy Zhou <Jammy.Zhou@amd.com>
    Reviewed-by: Christian König <christian.koenig@amd.com>

diff --git a/amdgpu/amdgpu_device.c b/amdgpu/amdgpu_device.c
index e16cd24..75b12e2 100644
--- a/amdgpu/amdgpu_device.c
+++ b/amdgpu/amdgpu_device.c
@@ -130,7 +130,8 @@ static int amdgpu_get_auth(int fd, int *auth)
 
 static void amdgpu_device_free_internal(amdgpu_device_handle dev)
 {
-	amdgpu_vamgr_reference(&dev->vamgr, NULL);
+	amdgpu_vamgr_deinit(dev->vamgr);
+	free(dev->vamgr);
 	util_hash_table_destroy(dev->bo_flink_names);
 	util_hash_table_destroy(dev->bo_handles);
 	pthread_mutex_destroy(&dev->bo_table_mutex);
@@ -251,7 +252,13 @@ int amdgpu_device_initialize(int fd,
 	if (r)
 		goto cleanup;
 
-	dev->vamgr = amdgpu_vamgr_get_global(dev);
+	dev->vamgr = calloc(1, sizeof(struct amdgpu_bo_va_mgr));
+	if (dev->vamgr == NULL)
+		goto cleanup;
+
+	amdgpu_vamgr_init(dev->vamgr, dev->dev_info.virtual_address_offset,
+			  dev->dev_info.virtual_address_max,
+			  dev->dev_info.virtual_address_alignment);
 
 	max = MIN2(dev->dev_info.virtual_address_max, 0xffffffff);
 	start = amdgpu_vamgr_find_va(dev->vamgr,
@@ -278,6 +285,8 @@ free_va:
 	r = -ENOMEM;
 	amdgpu_vamgr_free_va(dev->vamgr, start,
 			     max - dev->dev_info.virtual_address_offset);
+	amdgpu_vamgr_deinit(dev->vamgr);
+	free(dev->vamgr);
 
 cleanup:
 	if (dev->fd >= 0)
diff --git a/amdgpu/amdgpu_internal.h b/amdgpu/amdgpu_internal.h
index 3ce0969..5d86603 100644
--- a/amdgpu/amdgpu_internal.h
+++ b/amdgpu/amdgpu_internal.h
@@ -52,7 +52,6 @@ struct amdgpu_bo_va_hole {
 };
 
 struct amdgpu_bo_va_mgr {
-	atomic_t refcount;
 	/* the start virtual address */
 	uint64_t va_offset;
 	uint64_t va_max;
@@ -125,13 +124,6 @@ struct amdgpu_context {
 
 drm_private void amdgpu_bo_free_internal(amdgpu_bo_handle bo);
 
-drm_private struct amdgpu_bo_va_mgr*
-amdgpu_vamgr_get_global(struct amdgpu_device *dev);
-
-drm_private void
-amdgpu_vamgr_reference(struct amdgpu_bo_va_mgr **dst,
-		       struct amdgpu_bo_va_mgr *src);
-
 drm_private void amdgpu_vamgr_init(struct amdgpu_bo_va_mgr *mgr, uint64_t start,
 		       uint64_t max, uint64_t alignment);
 
diff --git a/amdgpu/amdgpu_vamgr.c b/amdgpu/amdgpu_vamgr.c
index 507a73a..04d2881 100644
--- a/amdgpu/amdgpu_vamgr.c
+++ b/amdgpu/amdgpu_vamgr.c
@@ -33,8 +33,6 @@
 #include "amdgpu_internal.h"
 #include "util_math.h"
 
-static struct amdgpu_bo_va_mgr vamgr = {{0}};
-
 int amdgpu_va_range_query(amdgpu_device_handle dev,
 			  enum amdgpu_gpu_va_range type, uint64_t *start, uint64_t *end)
 {
@@ -67,28 +65,6 @@ drm_private void amdgpu_vamgr_deinit(struct amdgpu_bo_va_mgr *mgr)
 	pthread_mutex_destroy(&mgr->bo_va_mutex);
 }
 
-drm_private struct amdgpu_bo_va_mgr *
-amdgpu_vamgr_get_global(struct amdgpu_device *dev)
-{
-	int ref;
-	ref = atomic_inc_return(&vamgr.refcount);
-
-	if (ref == 1)
-		amdgpu_vamgr_init(&vamgr, dev->dev_info.virtual_address_offset,
-				  dev->dev_info.virtual_address_max,
-				  dev->dev_info.virtual_address_alignment);
-	return &vamgr;
-}
-
-drm_private void
-amdgpu_vamgr_reference(struct amdgpu_bo_va_mgr **dst,
-		       struct amdgpu_bo_va_mgr *src)
-{
-	if (update_references(&(*dst)->refcount, NULL))
-		amdgpu_vamgr_deinit(*dst);
-	*dst = src;
-}
-
 drm_private uint64_t
 amdgpu_vamgr_find_va(struct amdgpu_bo_va_mgr *mgr, uint64_t size,
 		     uint64_t alignment, uint64_t base_required)
@@ -105,7 +81,7 @@ amdgpu_vamgr_find_va(struct amdgpu_bo_va_mgr *mgr, uint64_t size,
 	pthread_mutex_lock(&mgr->bo_va_mutex);
 	/* TODO: using more appropriate way to track the holes */
 	/* first look for a hole */
-	LIST_FOR_EACH_ENTRY_SAFE(hole, n, &vamgr.va_holes, list) {
+	LIST_FOR_EACH_ENTRY_SAFE(hole, n, &mgr->va_holes, list) {
 		if (base_required) {
 			if(hole->offset > base_required ||
 				(hole->offset + hole->size) < (base_required + size))

commit ffa305d0fc926418e4dff432381ead8907dc18d9
Author: Jammy Zhou <Jammy.Zhou@amd.com>
Date:   Mon Aug 17 11:09:08 2015 +0800

    amdgpu: add flag to support 32bit VA address v4
    
    The AMDGPU_VA_RANGE_32_BIT flag is added to request VA range in the
    32bit address space for amdgpu_va_range_alloc.
    
    The 32bit address space is reserved at initialization time, and managed
    with a separate VAMGR as part of the global VAMGR. And if no enough VA
    space available in range above 4GB, this reserved range can be used as
    fallback.
    
    v2: add comment for AMDGPU_VA_RANGE_32_BIT, and add vamgr to va_range
    v3: rebase to Emil's drm_private series
    v4: fix one warning
    
    Signed-off-by: Jammy Zhou <Jammy.Zhou@amd.com>
    Reviewed-by: Christian König <christian.koenig@amd.com>

diff --git a/amdgpu/amdgpu.h b/amdgpu/amdgpu.h
index a3eea84..e44d802 100644
--- a/amdgpu/amdgpu.h
+++ b/amdgpu/amdgpu.h
@@ -1075,6 +1075,11 @@ int amdgpu_read_mm_registers(amdgpu_device_handle dev, unsigned dword_offset,
 			     uint32_t *values);
 
 /**
+ * Flag to request VA address range in the 32bit address space
+*/
+#define AMDGPU_VA_RANGE_32_BIT		0x1
+
+/**
  * Allocate virtual address range
  *
  * \param dev - [in] Device handle. See #amdgpu_device_initialize()
diff --git a/amdgpu/amdgpu_device.c b/amdgpu/amdgpu_device.c
index c6bbae8..e16cd24 100644
--- a/amdgpu/amdgpu_device.c
+++ b/amdgpu/amdgpu_device.c
@@ -43,6 +43,7 @@
 #include "amdgpu_drm.h"
 #include "amdgpu_internal.h"
 #include "util_hash_table.h"
+#include "util_math.h"
 
 #define PTR_TO_UINT(x) ((unsigned)((intptr_t)(x)))
 #define UINT_TO_PTR(x) ((void *)((intptr_t)(x)))
@@ -173,6 +174,7 @@ int amdgpu_device_initialize(int fd,
 	int flag_auth = 0;
 	int flag_authexist=0;
 	uint32_t accel_working = 0;
+	uint64_t start, max;
 
 	*device_handle = NULL;
 
@@ -251,6 +253,19 @@ int amdgpu_device_initialize(int fd,
 
 	dev->vamgr = amdgpu_vamgr_get_global(dev);
 
+	max = MIN2(dev->dev_info.virtual_address_max, 0xffffffff);
+	start = amdgpu_vamgr_find_va(dev->vamgr,
+				     max - dev->dev_info.virtual_address_offset,
+				     dev->dev_info.virtual_address_alignment, 0);
+	if (start > 0xffffffff)
+		goto free_va; /* shouldn't get here */
+
+	dev->vamgr_32 =  calloc(1, sizeof(struct amdgpu_bo_va_mgr));
+	if (dev->vamgr_32 == NULL)
+		goto free_va;
+	amdgpu_vamgr_init(dev->vamgr_32, start, max,
+			  dev->dev_info.virtual_address_alignment);
+
 	*major_version = dev->major_version;
 	*minor_version = dev->minor_version;
 	*device_handle = dev;
@@ -259,6 +274,11 @@ int amdgpu_device_initialize(int fd,
 
 	return 0;
 
+free_va:
+	r = -ENOMEM;
+	amdgpu_vamgr_free_va(dev->vamgr, start,
+			     max - dev->dev_info.virtual_address_offset);
+
 cleanup:
 	if (dev->fd >= 0)
 		close(dev->fd);
diff --git a/amdgpu/amdgpu_internal.h b/amdgpu/amdgpu_internal.h
index 4b07aff..3ce0969 100644
--- a/amdgpu/amdgpu_internal.h
+++ b/amdgpu/amdgpu_internal.h
@@ -66,6 +66,7 @@ struct amdgpu_va {
 	uint64_t address;
 	uint64_t size;
 	enum amdgpu_gpu_va_range range;
+	struct amdgpu_bo_va_mgr *vamgr;
 };
 
 struct amdgpu_device {
@@ -83,7 +84,10 @@ struct amdgpu_device {
 	pthread_mutex_t bo_table_mutex;
 	struct drm_amdgpu_info_device dev_info;
 	struct amdgpu_gpu_info info;
+	/** The global VA manager for the whole virtual address space */
 	struct amdgpu_bo_va_mgr *vamgr;
+	/** The VA manager for the 32bit address space */
+	struct amdgpu_bo_va_mgr *vamgr_32;
 };
 
 struct amdgpu_bo {
@@ -128,6 +132,11 @@ drm_private void
 amdgpu_vamgr_reference(struct amdgpu_bo_va_mgr **dst,
 		       struct amdgpu_bo_va_mgr *src);
 
+drm_private void amdgpu_vamgr_init(struct amdgpu_bo_va_mgr *mgr, uint64_t start,
+		       uint64_t max, uint64_t alignment);
+
+drm_private void amdgpu_vamgr_deinit(struct amdgpu_bo_va_mgr *mgr);
+
 drm_private uint64_t
 amdgpu_vamgr_find_va(struct amdgpu_bo_va_mgr *mgr, uint64_t size,
 		     uint64_t alignment, uint64_t base_required);
diff --git a/amdgpu/amdgpu_vamgr.c b/amdgpu/amdgpu_vamgr.c
index eef8a71..507a73a 100644
--- a/amdgpu/amdgpu_vamgr.c
+++ b/amdgpu/amdgpu_vamgr.c
@@ -46,7 +46,7 @@ int amdgpu_va_range_query(amdgpu_device_handle dev,
 	return -EINVAL;
 }
 
-static void amdgpu_vamgr_init(struct amdgpu_bo_va_mgr *mgr, uint64_t start,
+drm_private void amdgpu_vamgr_init(struct amdgpu_bo_va_mgr *mgr, uint64_t start,
 			      uint64_t max, uint64_t alignment)
 {
 	mgr->va_offset = start;
@@ -57,7 +57,7 @@ static void amdgpu_vamgr_init(struct amdgpu_bo_va_mgr *mgr, uint64_t start,
 	pthread_mutex_init(&mgr->bo_va_mutex, NULL);
 }
 
-static void amdgpu_vamgr_deinit(struct amdgpu_bo_va_mgr *mgr)
+drm_private void amdgpu_vamgr_deinit(struct amdgpu_bo_va_mgr *mgr)
 {
 	struct amdgpu_bo_va_hole *hole;
 	LIST_FOR_EACH_ENTRY(hole, &mgr->va_holes, list) {
@@ -255,23 +255,39 @@ int amdgpu_va_range_alloc(amdgpu_device_handle dev,
 			  amdgpu_va_handle *va_range_handle,
 			  uint64_t flags)
 {
-	va_base_alignment = MAX2(va_base_alignment, dev->vamgr->va_alignment);
-	size = ALIGN(size, vamgr.va_alignment);
+	struct amdgpu_bo_va_mgr *vamgr;
 
-	*va_base_allocated = amdgpu_vamgr_find_va(dev->vamgr, size,
+	if (flags & AMDGPU_VA_RANGE_32_BIT)
+		vamgr = dev->vamgr_32;
+	else
+		vamgr = dev->vamgr;
+
+	va_base_alignment = MAX2(va_base_alignment, vamgr->va_alignment);
+	size = ALIGN(size, vamgr->va_alignment);
+
+	*va_base_allocated = amdgpu_vamgr_find_va(vamgr, size,
+					va_base_alignment, va_base_required);
+
+	if (!(flags & AMDGPU_VA_RANGE_32_BIT) &&
+	    (*va_base_allocated == AMDGPU_INVALID_VA_ADDRESS)) {
+		/* fallback to 32bit address */
+		vamgr = dev->vamgr_32;
+		*va_base_allocated = amdgpu_vamgr_find_va(vamgr, size,
 					va_base_alignment, va_base_required);
+	}
 
 	if (*va_base_allocated != AMDGPU_INVALID_VA_ADDRESS) {
 		struct amdgpu_va* va;
 		va = calloc(1, sizeof(struct amdgpu_va));
 		if(!va){
-			amdgpu_vamgr_free_va(dev->vamgr, *va_base_allocated, size);
+			amdgpu_vamgr_free_va(vamgr, *va_base_allocated, size);
 			return -ENOMEM;
 		}
 		va->dev = dev;
 		va->address = *va_base_allocated;
 		va->size = size;
 		va->range = va_range_type;
+		va->vamgr = vamgr;
 		*va_range_handle = va;
 	} else {
 		return -EINVAL;
@@ -284,7 +300,9 @@ int amdgpu_va_range_free(amdgpu_va_handle va_range_handle)
 {
 	if(!va_range_handle || !va_range_handle->address)
 		return 0;
-	amdgpu_vamgr_free_va(va_range_handle->dev->vamgr, va_range_handle->address,
+
+	amdgpu_vamgr_free_va(va_range_handle->vamgr,
+			va_range_handle->address,
 			va_range_handle->size);
 	free(va_range_handle);
 	return 0;

commit 102ab6f0049c2c85857fd19f098bc5b51e2a8a60
Author: Jammy Zhou <Jammy.Zhou@amd.com>
Date:   Mon Aug 17 11:09:07 2015 +0800

    amdgpu: improve amdgpu_vamgr_init
    
    Make it a generic function independent of the device info.
    
    Signed-off-by: Jammy Zhou <Jammy.Zhou@amd.com>
    Reviewed-by: Christian König <christian.koenig@amd.com>

diff --git a/amdgpu/amdgpu_vamgr.c b/amdgpu/amdgpu_vamgr.c
index b5d330f..eef8a71 100644
--- a/amdgpu/amdgpu_vamgr.c
+++ b/amdgpu/amdgpu_vamgr.c
@@ -46,11 +46,12 @@ int amdgpu_va_range_query(amdgpu_device_handle dev,
 	return -EINVAL;
 }
 
-static void amdgpu_vamgr_init(struct amdgpu_bo_va_mgr *mgr, struct amdgpu_device *dev)
+static void amdgpu_vamgr_init(struct amdgpu_bo_va_mgr *mgr, uint64_t start,
+			      uint64_t max, uint64_t alignment)
 {
-	mgr->va_offset = dev->dev_info.virtual_address_offset;
-	mgr->va_max = dev->dev_info.virtual_address_max;
-	mgr->va_alignment = dev->dev_info.virtual_address_alignment;
+	mgr->va_offset = start;
+	mgr->va_max = max;
+	mgr->va_alignment = alignment;
 
 	list_inithead(&mgr->va_holes);
 	pthread_mutex_init(&mgr->bo_va_mutex, NULL);
@@ -73,7 +74,9 @@ amdgpu_vamgr_get_global(struct amdgpu_device *dev)
 	ref = atomic_inc_return(&vamgr.refcount);
 
 	if (ref == 1)
-		amdgpu_vamgr_init(&vamgr, dev);
+		amdgpu_vamgr_init(&vamgr, dev->dev_info.virtual_address_offset,
+				  dev->dev_info.virtual_address_max,
+				  dev->dev_info.virtual_address_alignment);
 	return &vamgr;
 }
 

commit 15ba8768f7002d220002d424790ff2e89310c07f
Author: Rob Clark <robclark@freedesktop.org>
Date:   Mon Aug 17 10:33:59 2015 -0400

    freedreno: add fd_pipe_wait_timeout()
    
    We need to pass through a timeout parameter to implement
    pipe->fence_finish() properly.
    
    Signed-off-by: Rob Clark <robclark@freedesktop.org>

diff --git a/freedreno/freedreno_drmif.h b/freedreno/freedreno_drmif.h
index 88fc03d..81a14b4 100644
--- a/freedreno/freedreno_drmif.h
+++ b/freedreno/freedreno_drmif.h
@@ -86,6 +86,9 @@ void fd_pipe_del(struct fd_pipe *pipe);
 int fd_pipe_get_param(struct fd_pipe *pipe, enum fd_param_id param,
 		uint64_t *value);
 int fd_pipe_wait(struct fd_pipe *pipe, uint32_t timestamp);
+/* timeout in nanosec */
+int fd_pipe_wait_timeout(struct fd_pipe *pipe, uint32_t timestamp,
+		uint64_t timeout);
 
 
 /* buffer-object functions:
diff --git a/freedreno/freedreno_pipe.c b/freedreno/freedreno_pipe.c
index b6fed0a..4a756d7 100644
--- a/freedreno/freedreno_pipe.c
+++ b/freedreno/freedreno_pipe.c
@@ -72,5 +72,11 @@ int fd_pipe_get_param(struct fd_pipe *pipe,
 
 int fd_pipe_wait(struct fd_pipe *pipe, uint32_t timestamp)
 {
-	return pipe->funcs->wait(pipe, timestamp);
+	return fd_pipe_wait_timeout(pipe, timestamp, ~0);
+}
+
+int fd_pipe_wait_timeout(struct fd_pipe *pipe, uint32_t timestamp,
+		uint64_t timeout)
+{
+	return pipe->funcs->wait(pipe, timestamp, timeout);
 }
diff --git a/freedreno/freedreno_priv.h b/freedreno/freedreno_priv.h
index cb24780..1dddcc3 100644
--- a/freedreno/freedreno_priv.h
+++ b/freedreno/freedreno_priv.h
@@ -100,7 +100,7 @@ drm_private void fd_device_del_locked(struct fd_device *dev);
 struct fd_pipe_funcs {
 	struct fd_ringbuffer * (*ringbuffer_new)(struct fd_pipe *pipe, uint32_t size);
 	int (*get_param)(struct fd_pipe *pipe, enum fd_param_id param, uint64_t *value);
-	int (*wait)(struct fd_pipe *pipe, uint32_t timestamp);
+	int (*wait)(struct fd_pipe *pipe, uint32_t timestamp, uint64_t timeout);
 	void (*destroy)(struct fd_pipe *pipe);
 };
 
diff --git a/freedreno/kgsl/kgsl_pipe.c b/freedreno/kgsl/kgsl_pipe.c
index 08c87a6..e2fd65c 100644
--- a/freedreno/kgsl/kgsl_pipe.c
+++ b/freedreno/kgsl/kgsl_pipe.c
@@ -56,7 +56,8 @@ static int kgsl_pipe_get_param(struct fd_pipe *pipe,
 	}
 }
 
-static int kgsl_pipe_wait(struct fd_pipe *pipe, uint32_t timestamp)
+static int kgsl_pipe_wait(struct fd_pipe *pipe, uint32_t timestamp,
+		uint64_t timeout)
 {
 	struct kgsl_pipe *kgsl_pipe = to_kgsl_pipe(pipe);
 	struct kgsl_device_waittimestamp req = {
diff --git a/freedreno/msm/msm_bo.c b/freedreno/msm/msm_bo.c
index 6dc3776..fd94413 100644
--- a/freedreno/msm/msm_bo.c
+++ b/freedreno/msm/msm_bo.c
@@ -75,7 +75,7 @@ static int msm_bo_cpu_prep(struct fd_bo *bo, struct fd_pipe *pipe, uint32_t op)
 			.op = op,
 	};
 
-	get_abs_timeout(&req.timeout, 5000);
+	get_abs_timeout(&req.timeout, 5000000000);
 
 	return drmCommandWrite(bo->dev->fd, DRM_MSM_GEM_CPU_PREP, &req, sizeof(req));
 }
diff --git a/freedreno/msm/msm_pipe.c b/freedreno/msm/msm_pipe.c
index ddc975e..e1edffe 100644
--- a/freedreno/msm/msm_pipe.c
+++ b/freedreno/msm/msm_pipe.c
@@ -54,7 +54,8 @@ static int msm_pipe_get_param(struct fd_pipe *pipe,
 	}
 }
 
-static int msm_pipe_wait(struct fd_pipe *pipe, uint32_t timestamp)
+static int msm_pipe_wait(struct fd_pipe *pipe, uint32_t timestamp,
+		uint64_t timeout)
 {
 	struct fd_device *dev = pipe->dev;
 	struct drm_msm_wait_fence req = {
@@ -62,7 +63,7 @@ static int msm_pipe_wait(struct fd_pipe *pipe, uint32_t timestamp)
 	};
 	int ret;
 
-	get_abs_timeout(&req.timeout, 5000);
+	get_abs_timeout(&req.timeout, timeout);
 
 	ret = drmCommandWrite(dev->fd, DRM_MSM_WAIT_FENCE, &req, sizeof(req));
 	if (ret) {
diff --git a/freedreno/msm/msm_priv.h b/freedreno/msm/msm_priv.h
index 637cb52..e499b3b 100644
--- a/freedreno/msm/msm_priv.h
+++ b/freedreno/msm/msm_priv.h
@@ -96,13 +96,13 @@ drm_private int msm_bo_new_handle(struct fd_device *dev,
 drm_private struct fd_bo * msm_bo_from_handle(struct fd_device *dev,
 		uint32_t size, uint32_t handle);
 
-static inline void get_abs_timeout(struct drm_msm_timespec *tv, uint32_t ms)
+static inline void get_abs_timeout(struct drm_msm_timespec *tv, uint64_t ns)
 {
 	struct timespec t;
-	uint32_t s = ms / 1000;
+	uint32_t s = ns / 1000000000;
 	clock_gettime(CLOCK_MONOTONIC, &t);
 	tv->tv_sec = t.tv_sec + s;
-	tv->tv_nsec = t.tv_nsec + ((ms - (s * 1000)) * 1000000);
+	tv->tv_nsec = t.tv_nsec + ns - (s * 1000000000);
 }
 
 #endif /* MSM_PRIV_H_ */

commit 4413f191a051847c53a6150df199d35a106b6cf4
Author: Rob Clark <robclark@freedesktop.org>
Date:   Tue Jul 21 12:55:29 2015 -0400

    freedreno/msm: dump out submit info on error
    
    User should only see these with LIBGL_DEBUG=verbose.  But in case you
    are hitting issues like "handle X at index Y already on submit list"
    errors from the kernel, this gives some useful visibility for debug.
    
    Signed-off-by: Rob Clark <robclark@freedesktop.org>

diff --git a/freedreno/msm/msm_ringbuffer.c b/freedreno/msm/msm_ringbuffer.c
index 842574e..5ddea57 100644
--- a/freedreno/msm/msm_ringbuffer.c
+++ b/freedreno/msm/msm_ringbuffer.c
@@ -31,6 +31,7 @@
 #endif
 
 #include <assert.h>
+#include <inttypes.h>
 
 #include "freedreno_ringbuffer.h"
 #include "msm_priv.h"
@@ -228,7 +229,7 @@ static int msm_ringbuffer_flush(struct fd_ringbuffer *ring, uint32_t *last_start
 	struct drm_msm_gem_submit req = {
 			.pipe = to_msm_pipe(ring->pipe)->pipe,
 	};
-	uint32_t i, submit_offset, size;
+	uint32_t i, j, submit_offset, size;
 	int ret;
 
 	submit_offset = offset_bytes(last_start, ring->start);
@@ -258,6 +259,23 @@ static int msm_ringbuffer_flush(struct fd_ringbuffer *ring, uint32_t *last_start
 			&req, sizeof(req));
 	if (ret) {
 		ERROR_MSG("submit failed: %d (%s)", ret, strerror(errno));
+		ERROR_MSG("  pipe:  %u", req.pipe);
+		for (i = 0; i < msm_ring->submit.nr_bos; i++) {
+			struct drm_msm_gem_submit_bo *bo = &msm_ring->submit.bos[i];
+			ERROR_MSG("  bos[%d]: handle=%u, flags=%x", i, bo->handle, bo->flags);
+		}
+		for (i = 0; i < msm_ring->submit.nr_cmds; i++) {
+			struct drm_msm_gem_submit_cmd *cmd = &msm_ring->submit.cmds[i];
+			struct drm_msm_gem_submit_reloc *relocs = U642VOID(cmd->relocs);
+			ERROR_MSG("  cmd[%d]: type=%u, submit_idx=%u, submit_offset=%u, size=%u\n",
+					i, cmd->type, cmd->submit_idx, cmd->submit_offset, cmd->size);
+			for (j = 0; j < cmd->nr_relocs; j++) {
+				struct drm_msm_gem_submit_reloc *r = &relocs[j];
+				ERROR_MSG("    reloc[%d]: submit_offset=%u, or=%08x, shift=%d, reloc_idx=%u"
+						", reloc_offset=%"PRIu64, j, r->submit_offset, r->or, r->shift,
+						r->reloc_idx, r->reloc_offset);
+			}
+		}
 	} else {
 		/* update timestamp on all rings associated with submit: */
 		for (i = 0; i < msm_ring->submit.nr_cmds; i++) {

commit 9e34ee4f75ef559ff3a3c6d4b8f285453eea1f29
Author: Rob Clark <robclark@freedesktop.org>
Date:   Tue Jul 21 11:57:00 2015 -0400

    freedreno/msm: fix issue where same bo is on multiple rings
    
    It should be a less common case, but it is possible for a single bo to
    be on multiple rings, for example when sharing a buffer across multiple
    pipe_context's created from same pipe_screen.
    
    So rather than completely fall over in this case, fallback to slow-path
    of looping over all bo's in the ring's bo-table (but retain the fast-
    path of constant-lookup for the first ring the buffer is on).
    
    Signed-off-by: Rob Clark <robclark@freedesktop.org>

diff --git a/freedreno/msm/msm_bo.c b/freedreno/msm/msm_bo.c
index 3f5b6d0..6dc3776 100644
--- a/freedreno/msm/msm_bo.c
+++ b/freedreno/msm/msm_bo.c
@@ -129,7 +129,6 @@ drm_private struct fd_bo * msm_bo_from_handle(struct fd_device *dev,
 {
 	struct msm_bo *msm_bo;
 	struct fd_bo *bo;
-	unsigned i;
 
 	msm_bo = calloc(1, sizeof(*msm_bo));
 	if (!msm_bo)
@@ -139,8 +138,5 @@ drm_private struct fd_bo * msm_bo_from_handle(struct fd_device *dev,
 	bo->funcs = &funcs;
 	bo->fd = -1;
 
-	for (i = 0; i < ARRAY_SIZE(msm_bo->list); i++)
-		list_inithead(&msm_bo->list[i]);
-
 	return bo;
 }
diff --git a/freedreno/msm/msm_priv.h b/freedreno/msm/msm_priv.h
index 94d2357..637cb52 100644
--- a/freedreno/msm/msm_priv.h
+++ b/freedreno/msm/msm_priv.h
@@ -71,8 +71,19 @@ struct msm_bo {
 	struct fd_bo base;
 	uint64_t offset;
 	uint64_t presumed;
-	uint32_t indexp1[FD_PIPE_MAX]; /* index plus 1 */
-	struct list_head list[FD_PIPE_MAX];
+	/* in the common case, a bo won't be referenced by more than a single
+	 * (parent) ring[*].  So to avoid looping over all the bo's in the
+	 * reloc table to find the idx of a bo that might already be in the
+	 * table, we cache the idx in the bo.  But in order to detect the
+	 * slow-path where bo is ref'd in multiple rb's, we also must track
+	 * the current_ring for which the idx is valid.  See bo2idx().
+	 *
+	 * [*] in case multiple ringbuffers, ie. one toplevel and other rb(s)
+	 *     used for IB target(s), the toplevel rb is the parent which is
+	 *     tracking bo's for the submit
+	 */
+	struct fd_ringbuffer *current_ring;
+	uint32_t idx;
 };
 
 static inline struct msm_bo * to_msm_bo(struct fd_bo *x)
diff --git a/freedreno/msm/msm_ringbuffer.c b/freedreno/msm/msm_ringbuffer.c
index 2798c3f..842574e 100644
--- a/freedreno/msm/msm_ringbuffer.c
+++ b/freedreno/msm/msm_ringbuffer.c
@@ -39,8 +39,6 @@ struct msm_ringbuffer {
 	struct fd_ringbuffer base;
 	struct fd_bo *ring_bo;
 
-	struct list_head submit_list;
-
 	/* submit ioctl related tables: */
 	struct {
 		/* bo's table: */
@@ -56,11 +54,17 @@ struct msm_ringbuffer {
 		uint32_t nr_relocs, max_relocs;
 	} submit;
 
+	/* should have matching entries in submit.bos: */
+	struct fd_bo **bos;
+	uint32_t nr_bos, max_bos;
+
 	/* should have matching entries in submit.cmds: */
 	struct fd_ringbuffer **rings;
 	uint32_t nr_rings, max_rings;
 };
 
+static pthread_mutex_t idx_lock = PTHREAD_MUTEX_INITIALIZER;
+
 static void *grow(void *ptr, uint32_t nr, uint32_t *max, uint32_t sz)
 {
 	if ((nr + 1) > *max) {
@@ -83,27 +87,47 @@ static inline struct msm_ringbuffer * to_msm_ringbuffer(struct fd_ringbuffer *x)
 	return (struct msm_ringbuffer *)x;
 }
 
+static uint32_t append_bo(struct fd_ringbuffer *ring, struct fd_bo *bo)
+{
+	struct msm_ringbuffer *msm_ring = to_msm_ringbuffer(ring);
+	uint32_t idx;
+
+	idx = APPEND(&msm_ring->submit, bos);
+	idx = APPEND(msm_ring, bos);
+
+	msm_ring->submit.bos[idx].flags = 0;
+	msm_ring->submit.bos[idx].handle = bo->handle;
+	msm_ring->submit.bos[idx].presumed = to_msm_bo(bo)->presumed;
+
+	msm_ring->bos[idx] = fd_bo_ref(bo);
+
+	return idx;
+}
+
 /* add (if needed) bo, return idx: */
 static uint32_t bo2idx(struct fd_ringbuffer *ring, struct fd_bo *bo, uint32_t flags)
 {
 	struct msm_ringbuffer *msm_ring = to_msm_ringbuffer(ring);
 	struct msm_bo *msm_bo = to_msm_bo(bo);
-	int id = ring->pipe->id;
 	uint32_t idx;
-	if (!msm_bo->indexp1[id]) {
-		struct list_head *list = &msm_bo->list[id];
-		idx = APPEND(&msm_ring->submit, bos);
-		msm_ring->submit.bos[idx].flags = 0;
-		msm_ring->submit.bos[idx].handle = bo->handle;
-		msm_ring->submit.bos[idx].presumed = msm_bo->presumed;
-		msm_bo->indexp1[id] = idx + 1;
-
-		assert(LIST_IS_EMPTY(list));
-		fd_bo_ref(bo);
-		list_addtail(list, &msm_ring->submit_list);
+	pthread_mutex_lock(&idx_lock);
+	if (!msm_bo->current_ring) {
+		idx = append_bo(ring, bo);
+		msm_bo->current_ring = ring;
+		msm_bo->idx = idx;
+	} else if (msm_bo->current_ring == ring) {
+		idx = msm_bo->idx;
 	} else {
-		idx = msm_bo->indexp1[id] - 1;
+		/* slow-path: */
+		for (idx = 0; idx < msm_ring->nr_bos; idx++)
+			if (msm_ring->bos[idx] == bo)
+				break;
+		if (idx == msm_ring->nr_bos) {
+			/* not found */
+			idx = append_bo(ring, bo);
+		}
 	}
+	pthread_mutex_unlock(&idx_lock);
 	if (flags & FD_RELOC_READ)
 		msm_ring->submit.bos[idx].flags |= MSM_SUBMIT_BO_READ;
 	if (flags & FD_RELOC_WRITE)
@@ -193,6 +217,8 @@ static void flush_reset(struct fd_ringbuffer *ring)
 	msm_ring->submit.nr_relocs = 0;
 	msm_ring->submit.nr_cmds = 0;
 	msm_ring->submit.nr_bos = 0;
+	msm_ring->nr_rings = 0;
+	msm_ring->nr_bos = 0;
 }
 
 static int msm_ringbuffer_flush(struct fd_ringbuffer *ring, uint32_t *last_start)
@@ -202,9 +228,8 @@ static int msm_ringbuffer_flush(struct fd_ringbuffer *ring, uint32_t *last_start
 	struct drm_msm_gem_submit req = {
 			.pipe = to_msm_pipe(ring->pipe)->pipe,
 	};
-	struct msm_bo *msm_bo = NULL, *tmp;
 	uint32_t i, submit_offset, size;
-	int ret, id = ring->pipe->id;
+	int ret;
 
 	submit_offset = offset_bytes(last_start, ring->start);
 	size = offset_bytes(ring->cur, last_start);
@@ -242,10 +267,9 @@ static int msm_ringbuffer_flush(struct fd_ringbuffer *ring, uint32_t *last_start
 		}
 	}
 
-	LIST_FOR_EACH_ENTRY_SAFE(msm_bo, tmp, &msm_ring->submit_list, list[id]) {
-		struct list_head *list = &msm_bo->list[id];
-		list_delinit(list);
-		msm_bo->indexp1[id] = 0;
+	for (i = 0; i < msm_ring->nr_bos; i++) {
+		struct msm_bo *msm_bo = to_msm_bo(msm_ring->bos[i]);
+		msm_bo->current_ring = NULL;
 		fd_bo_del(&msm_bo->base);


Reply to: