[Mesa-dev] [libdrm PATCH] intel: Create a new drm_intel_bo offset64 field.

Kenneth Graunke kenneth at whitecape.org
Mon Jan 13 15:56:39 PST 2014


The existing 'offset' field is unfortunately typed as 'unsigned long',
which is unfortunately only 4 bytes with a 32-bit userspace.

Traditionally, the hardware has only supported 32-bit virtual addresses,
so even though the kernel uses a __u64, the value would always fit.

However, Broadwell supports 48-bit addressing.  So with a 64-bit kernel,
the card virtual address may be too large to fit in the 'offset' field.

Ideally, we would change the type of 'offset' to be a uint64_t---but
this would break the libdrm ABI.  Instead, we create a new 'offset64'
field to hold the full 64-bit value from the kernel, and store the
32-bit truncation in the existing 'offset' field, for compatibility.

Cc: Eric Anholt <eric at anholt.net>
Cc: Daniel Vetter <daniel.vetter at ffwll.ch>
Cc: Ben Widawsky <ben at bwidawsk.net>
Signed-off-by: Kenneth Graunke <kenneth at whitecape.org>
---
 intel/intel_bufmgr.h     | 12 +++++++++---
 intel/intel_bufmgr_gem.c | 16 ++++++++++------
 2 files changed, 19 insertions(+), 9 deletions(-)

I didn't update the bufmgr_fake stuff.  Do I need to...?

diff --git a/intel/intel_bufmgr.h b/intel/intel_bufmgr.h
index 2eb9742..9383c72 100644
--- a/intel/intel_bufmgr.h
+++ b/intel/intel_bufmgr.h
@@ -61,9 +61,8 @@ struct _drm_intel_bo {
 	unsigned long align;
 
 	/**
-	 * Last seen card virtual address (offset from the beginning of the
-	 * aperture) for the object.  This should be used to fill relocation
-	 * entries when calling drm_intel_bo_emit_reloc()
+	 * Deprecated field containing (possibly the low 32-bits of) the last
+	 * seen virtual card address.  Use offset64 instead.
 	 */
 	unsigned long offset;
 
@@ -84,6 +83,13 @@ struct _drm_intel_bo {
 	 * MM-specific handle for accessing object
 	 */
 	int handle;
+
+	/**
+	 * Last seen card virtual address (offset from the beginning of the
+	 * aperture) for the object.  This should be used to fill relocation
+	 * entries when calling drm_intel_bo_emit_reloc()
+	 */
+	uint64_t offset64;
 };
 
 enum aub_dump_bmp_format {
diff --git a/intel/intel_bufmgr_gem.c b/intel/intel_bufmgr_gem.c
index ad722dd..f4db1a6 100644
--- a/intel/intel_bufmgr_gem.c
+++ b/intel/intel_bufmgr_gem.c
@@ -382,7 +382,7 @@ drm_intel_gem_dump_validation_list(drm_intel_bufmgr_gem *bufmgr_gem)
 			    (unsigned long long)bo_gem->relocs[j].offset,
 			    target_gem->gem_handle,
 			    target_gem->name,
-			    target_bo->offset,
+			    target_bo->offset64,
 			    bo_gem->relocs[j].delta);
 		}
 	}
@@ -894,6 +894,7 @@ drm_intel_bo_gem_create_from_name(drm_intel_bufmgr *bufmgr,
 
 	bo_gem->bo.size = open_arg.size;
 	bo_gem->bo.offset = 0;
+	bo_gem->bo.offset64 = 0;
 	bo_gem->bo.virtual = NULL;
 	bo_gem->bo.bufmgr = bufmgr;
 	bo_gem->name = name;
@@ -1689,7 +1690,7 @@ do_bo_emit_reloc(drm_intel_bo *bo, uint32_t offset,
 	    target_bo_gem->gem_handle;
 	bo_gem->relocs[bo_gem->reloc_count].read_domains = read_domains;
 	bo_gem->relocs[bo_gem->reloc_count].write_domain = write_domain;
-	bo_gem->relocs[bo_gem->reloc_count].presumed_offset = target_bo->offset;
+	bo_gem->relocs[bo_gem->reloc_count].presumed_offset = target_bo->offset64;
 
 	bo_gem->reloc_target_info[bo_gem->reloc_count].bo = target_bo;
 	if (target_bo != bo)
@@ -1840,11 +1841,12 @@ drm_intel_update_buffer_offsets(drm_intel_bufmgr_gem *bufmgr_gem)
 		drm_intel_bo_gem *bo_gem = (drm_intel_bo_gem *) bo;
 
 		/* Update the buffer offset */
-		if (bufmgr_gem->exec_objects[i].offset != bo->offset) {
+		if (bufmgr_gem->exec_objects[i].offset != bo->offset64) {
 			DBG("BO %d (%s) migrated: 0x%08lx -> 0x%08llx\n",
-			    bo_gem->gem_handle, bo_gem->name, bo->offset,
+			    bo_gem->gem_handle, bo_gem->name, bo->offset64,
 			    (unsigned long long)bufmgr_gem->exec_objects[i].
 			    offset);
+			bo->offset64 = bufmgr_gem->exec_objects[i].offset;
 			bo->offset = bufmgr_gem->exec_objects[i].offset;
 		}
 	}
@@ -1860,10 +1862,11 @@ drm_intel_update_buffer_offsets2 (drm_intel_bufmgr_gem *bufmgr_gem)
 		drm_intel_bo_gem *bo_gem = (drm_intel_bo_gem *)bo;
 
 		/* Update the buffer offset */
-		if (bufmgr_gem->exec2_objects[i].offset != bo->offset) {
+		if (bufmgr_gem->exec2_objects[i].offset != bo->offset64) {
 			DBG("BO %d (%s) migrated: 0x%08lx -> 0x%08llx\n",
-			    bo_gem->gem_handle, bo_gem->name, bo->offset,
+			    bo_gem->gem_handle, bo_gem->name, bo->offset64,
 			    (unsigned long long)bufmgr_gem->exec2_objects[i].offset);
+			bo->offset64 = bufmgr_gem->exec2_objects[i].offset;
 			bo->offset = bufmgr_gem->exec2_objects[i].offset;
 		}
 	}
@@ -2367,6 +2370,7 @@ drm_intel_gem_bo_pin(drm_intel_bo *bo, uint32_t alignment)
 	if (ret != 0)
 		return -errno;
 
+	bo->offset64 = pin.offset;
 	bo->offset = pin.offset;
 	return 0;
 }
-- 
1.8.5.2



More information about the mesa-dev mailing list