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

Ivaylo Dimitrov ivo.g.dimitrov.75 at gmail.com
Fri Nov 19 09:45:10 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  | 55 +++++++++++++++++++---
 1 file changed, 48 insertions(+), 7 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..59d0487 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
@@ -157,7 +157,8 @@ PVRSRV_ERROR DmaBufImportAndAcquirePhysAddr(const IMG_INT32 i32FD,
 		goto error;
 	}
 
-	buf_size = uiSize ? uiSize : import->dma_buf->size;
+	/* dma_buf memory must be page aligned an its size should account for that */
+	buf_size = PAGE_ALIGN(uiSize ? uiSize : import->dma_buf->size);
 
 	if ((uiDmaBufOffset + buf_size) > import->dma_buf->size ||
 		(size_t)(uiDmaBufOffset + buf_size) < buf_size)
@@ -189,7 +190,46 @@ 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)
+	{
+		size_t dma_len = PAGE_ALIGN(sg_dma_len(sg));
+
+		if (buf_offset >= end_offset)
+		{
+			break;
+		}
+
+		if ((start_offset >= buf_offset) && (start_offset < buf_offset + dma_len))
+		{
+			size_t sg_start;
+			size_t sg_pos;
+			size_t sg_remainder;
+
+
+			sg_start = start_offset - buf_offset;
+
+			sg_remainder = MIN(dma_len - sg_start, remainder);
+
+			for (sg_pos = sg_start; sg_pos < sg_start + sg_remainder; sg_pos += PAGE_SIZE)
+			{
+				npages++;
+			}
+
+			remainder -= sg_remainder;
+			buf_offset += dma_len;
+			start_offset = buf_offset;
+		}
+		else
+		{
+			buf_offset += dma_len;
+		}
+	}
 
 	/* The following allocation will be freed by the caller */
 	eError = OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
@@ -205,16 +245,17 @@ 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)
 	{
+		size_t dma_len = PAGE_ALIGN(sg_dma_len(sg));
+
 		if (buf_offset >= end_offset)
 		{
 			break;
 		}
 
-		if ((start_offset >= buf_offset) && (start_offset < buf_offset + sg_dma_len(sg)))
+		if ((start_offset >= buf_offset) && (start_offset < buf_offset + dma_len))
 		{
 			size_t sg_start;
 			size_t sg_pos;
@@ -222,7 +263,7 @@ PVRSRV_ERROR DmaBufImportAndAcquirePhysAddr(const IMG_INT32 i32FD,
 
 			sg_start = start_offset - buf_offset;
 
-			sg_remainder = MIN(sg_dma_len(sg) - sg_start, remainder);
+			sg_remainder = MIN(dma_len - sg_start, remainder);
 
 			for (sg_pos = sg_start; sg_pos < sg_start + sg_remainder; sg_pos += PAGE_SIZE)
 			{
@@ -235,12 +276,12 @@ PVRSRV_ERROR DmaBufImportAndAcquirePhysAddr(const IMG_INT32 i32FD,
 			}
 
 			remainder -= sg_remainder;
-			buf_offset += sg_dma_len(sg);
+			buf_offset += dma_len;
 			start_offset = buf_offset;
 		}
 		else
 		{
-			buf_offset += sg_dma_len(sg);
+			buf_offset += dma_len;
 		}
 	}
 	BUG_ON(remainder);
-- 
1.9.1



More information about the openpvrsgx-devgroup mailing list