[Openpvrsgx-devgroup] [PATCH] drm: pvrsgx: dmabuf import - Do not assume scatterlist memory is contiguous

Ivaylo Dimitrov ivo.g.dimitrov.75 at gmail.com
Sat Nov 13 11:08:59 CET 2021


TILER backed BOs are not a single block of contiguous memory

Signed-off-by: Ivaylo Dimitrov <ivo.g.dimitrov.75 at gmail.com>
---
 .../eurasia_km/services4/srvkm/env/linux/dmabuf.c  | 39 ++++++++++++++++++++--
 1 file changed, 37 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/pvrsgx/1.17.4948957/eurasia_km/services4/srvkm/env/linux/dmabuf.c b/drivers/gpu/drm/pvrsgx/1.17.4948957/eurasia_km/services4/srvkm/env/linux/dmabuf.c
index 707cb13..9fefa9f 100644
--- a/drivers/gpu/drm/pvrsgx/1.17.4948957/eurasia_km/services4/srvkm/env/linux/dmabuf.c
+++ b/drivers/gpu/drm/pvrsgx/1.17.4948957/eurasia_km/services4/srvkm/env/linux/dmabuf.c
@@ -189,7 +189,43 @@ PVRSRV_ERROR DmaBufImportAndAcquirePhysAddr(const IMG_INT32 i32FD,
 
 	*puiMemInfoOffset = (uiDmaBufOffset - start_offset);
 
-	npages = (end_offset - start_offset) >> PAGE_SHIFT;
+	/* Calculate the number of pages needed for mapping the scatterlist */
+	buf_offset = 0;
+	remainder = buf_size;
+	start_offset = PAGE_MASK & uiDmaBufOffset;
+	end_offset = PAGE_ALIGN(uiDmaBufOffset + buf_size);
+
+	for_each_sg(import->sg_table->sgl, sg, import->sg_table->nents, i)
+	{
+		if (buf_offset >= end_offset)
+		{
+			break;
+		}
+
+		if ((start_offset >= buf_offset) && (start_offset < buf_offset + sg_dma_len(sg)))
+		{
+			size_t sg_start;
+			size_t sg_pos;
+			size_t sg_remainder;
+
+			sg_start = start_offset - buf_offset;
+
+			sg_remainder = MIN(sg_dma_len(sg) - sg_start, remainder);
+
+			for (sg_pos = sg_start; sg_pos < sg_start + sg_remainder; sg_pos += PAGE_SIZE)
+			{
+				npages++;
+			}
+
+			remainder -= sg_remainder;
+			buf_offset += sg_dma_len(sg);
+			start_offset = buf_offset;
+		}
+		else
+		{
+			buf_offset += sg_dma_len(sg);
+		}
+	}
 
 	/* The following allocation will be freed by the caller */
 	eError = OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
@@ -205,7 +241,6 @@ PVRSRV_ERROR DmaBufImportAndAcquirePhysAddr(const IMG_INT32 i32FD,
 	buf_offset = 0;
 	remainder = buf_size;
 	start_offset = PAGE_MASK & uiDmaBufOffset;
-	end_offset = PAGE_ALIGN(uiDmaBufOffset + buf_size);
 
 	for_each_sg(import->sg_table->sgl, sg, import->sg_table->nents, i)
 	{
-- 
1.9.1



More information about the openpvrsgx-devgroup mailing list