[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