All of lore.kernel.org
 help / color / mirror / Atom feed
From: Marek Szyprowski <m.szyprowski@samsung.com>
To: dri-devel@lists.freedesktop.org,
	iommu@lists.linux-foundation.org, linaro-mm-sig@lists.linaro.org,
	linux-kernel@vger.kernel.org
Cc: Marek Szyprowski <m.szyprowski@samsung.com>,
	Christoph Hellwig <hch@lst.de>,
	Robin Murphy <robin.murphy@arm.com>,
	Bartlomiej Zolnierkiewicz <b.zolnierkie@samsung.com>,
	Sumit Semwal <sumit.semwal@linaro.org>,
	Benjamin Gaignard <benjamin.gaignard@linaro.org>,
	intel-gfx@lists.freedesktop.org,
	linux-arm-kernel@lists.infradead.org,
	amd-gfx@lists.freedesktop.org, David Airlie <airlied@linux.ie>,
	Daniel Vetter <daniel@ffwll.ch>
Subject: [RFC 06/17] drm: i915: fix sg_table nents vs. orig_nents misuse
Date: Tue, 28 Apr 2020 15:19:54 +0200	[thread overview]
Message-ID: <20200428132005.21424-7-m.szyprowski@samsung.com> (raw)
In-Reply-To: <20200428132005.21424-1-m.szyprowski@samsung.com>

The Documentation/DMA-API-HOWTO.txt states that dma_map_sg returns the
numer of the created entries in the DMA address space. However the
subsequent calls to dma_sync_sg_for_{device,cpu} and dma_unmap_sg must be
called with the original number of entries passed to dma_map_sg. The
sg_table->nents in turn holds the result of the dma_map_sg call as stated
in include/linux/scatterlist.h. Adapt the code to obey those rules.

Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
---
 drivers/gpu/drm/i915/gem/i915_gem_dmabuf.c       | 13 +++++++------
 drivers/gpu/drm/i915/gem/i915_gem_internal.c     |  4 ++--
 drivers/gpu/drm/i915/gem/i915_gem_region.c       |  4 ++--
 drivers/gpu/drm/i915/gem/i915_gem_shmem.c        |  5 +++--
 drivers/gpu/drm/i915/gem/selftests/huge_pages.c  | 10 +++++-----
 drivers/gpu/drm/i915/gem/selftests/mock_dmabuf.c |  5 +++--
 drivers/gpu/drm/i915/gt/intel_ggtt.c             | 12 ++++++------
 drivers/gpu/drm/i915/i915_gem_gtt.c              | 12 +++++++-----
 drivers/gpu/drm/i915/i915_scatterlist.c          |  4 ++--
 drivers/gpu/drm/i915/selftests/scatterlist.c     |  8 ++++----
 10 files changed, 41 insertions(+), 36 deletions(-)

diff --git a/drivers/gpu/drm/i915/gem/i915_gem_dmabuf.c b/drivers/gpu/drm/i915/gem/i915_gem_dmabuf.c
index 7db5a79..d829852 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_dmabuf.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_dmabuf.c
@@ -36,21 +36,22 @@ static struct sg_table *i915_gem_map_dma_buf(struct dma_buf_attachment *attachme
 		goto err_unpin_pages;
 	}
 
-	ret = sg_alloc_table(st, obj->mm.pages->nents, GFP_KERNEL);
+	ret = sg_alloc_table(st, obj->mm.pages->orig_nents, GFP_KERNEL);
 	if (ret)
 		goto err_free;
 
 	src = obj->mm.pages->sgl;
 	dst = st->sgl;
-	for (i = 0; i < obj->mm.pages->nents; i++) {
+	for (i = 0; i < obj->mm.pages->orig_nents; i++) {
 		sg_set_page(dst, sg_page(src), src->length, 0);
 		dst = sg_next(dst);
 		src = sg_next(src);
 	}
 
-	if (!dma_map_sg_attrs(attachment->dev,
-			      st->sgl, st->nents, dir,
-			      DMA_ATTR_SKIP_CPU_SYNC)) {
+	st->nents = dma_map_sg_attrs(attachment->dev,
+				     st->sgl, st->orig_nents, dir,
+				     DMA_ATTR_SKIP_CPU_SYNC);
+	if (!st->nents) {
 		ret = -ENOMEM;
 		goto err_free_sg;
 	}
@@ -74,7 +75,7 @@ static void i915_gem_unmap_dma_buf(struct dma_buf_attachment *attachment,
 	struct drm_i915_gem_object *obj = dma_buf_to_obj(attachment->dmabuf);
 
 	dma_unmap_sg_attrs(attachment->dev,
-			   sg->sgl, sg->nents, dir,
+			   sg->sgl, sg->orig_nents, dir,
 			   DMA_ATTR_SKIP_CPU_SYNC);
 	sg_free_table(sg);
 	kfree(sg);
diff --git a/drivers/gpu/drm/i915/gem/i915_gem_internal.c b/drivers/gpu/drm/i915/gem/i915_gem_internal.c
index cbbff81..a8ebfdd 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_internal.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_internal.c
@@ -73,7 +73,7 @@ static int i915_gem_object_get_pages_internal(struct drm_i915_gem_object *obj)
 	}
 
 	sg = st->sgl;
-	st->nents = 0;
+	st->nents = st->orig_nents = 0;
 	sg_page_sizes = 0;
 
 	do {
@@ -94,7 +94,7 @@ static int i915_gem_object_get_pages_internal(struct drm_i915_gem_object *obj)
 
 		sg_set_page(sg, page, PAGE_SIZE << order, 0);
 		sg_page_sizes |= PAGE_SIZE << order;
-		st->nents++;
+		st->nents = st->orig_nents = st->nents + 1;
 
 		npages -= 1 << order;
 		if (!npages) {
diff --git a/drivers/gpu/drm/i915/gem/i915_gem_region.c b/drivers/gpu/drm/i915/gem/i915_gem_region.c
index 1515384..58ca560 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_region.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_region.c
@@ -53,7 +53,7 @@
 	GEM_BUG_ON(list_empty(blocks));
 
 	sg = st->sgl;
-	st->nents = 0;
+	st->nents = st->orig_nents = 0;
 	sg_page_sizes = 0;
 	prev_end = (resource_size_t)-1;
 
@@ -78,7 +78,7 @@
 
 			sg->length = block_size;
 
-			st->nents++;
+			st->nents = st->orig_nents = st->nents + 1;
 		} else {
 			sg->length += block_size;
 			sg_dma_len(sg) += block_size;
diff --git a/drivers/gpu/drm/i915/gem/i915_gem_shmem.c b/drivers/gpu/drm/i915/gem/i915_gem_shmem.c
index 5d5d7ee..851a732 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_shmem.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_shmem.c
@@ -80,7 +80,7 @@ static int shmem_get_pages(struct drm_i915_gem_object *obj)
 	noreclaim |= __GFP_NORETRY | __GFP_NOWARN;
 
 	sg = st->sgl;
-	st->nents = 0;
+	st->nents = st->orig_nents = 0;
 	sg_page_sizes = 0;
 	for (i = 0; i < page_count; i++) {
 		const unsigned int shrink[] = {
@@ -140,7 +140,8 @@ static int shmem_get_pages(struct drm_i915_gem_object *obj)
 				sg_page_sizes |= sg->length;
 				sg = sg_next(sg);
 			}
-			st->nents++;
+			st->nents = st->orig_nents = st->nents + 1;
+
 			sg_set_page(sg, page, PAGE_SIZE, 0);
 		} else {
 			sg->length += PAGE_SIZE;
diff --git a/drivers/gpu/drm/i915/gem/selftests/huge_pages.c b/drivers/gpu/drm/i915/gem/selftests/huge_pages.c
index c9988b6..bd141f9 100644
--- a/drivers/gpu/drm/i915/gem/selftests/huge_pages.c
+++ b/drivers/gpu/drm/i915/gem/selftests/huge_pages.c
@@ -76,7 +76,7 @@ static int get_huge_pages(struct drm_i915_gem_object *obj)
 
 	rem = obj->base.size;
 	sg = st->sgl;
-	st->nents = 0;
+	st->nents = st->orig_nents = 0;
 	sg_page_sizes = 0;
 
 	/*
@@ -99,7 +99,7 @@ static int get_huge_pages(struct drm_i915_gem_object *obj)
 
 			sg_set_page(sg, page, page_size, 0);
 			sg_page_sizes |= page_size;
-			st->nents++;
+			st->nents = st->orig_nents = st->nents + 1;
 
 			rem -= page_size;
 			if (!rem) {
@@ -201,7 +201,7 @@ static int fake_get_huge_pages(struct drm_i915_gem_object *obj)
 	/* Use optimal page sized chunks to fill in the sg table */
 	rem = obj->base.size;
 	sg = st->sgl;
-	st->nents = 0;
+	st->nents = st->orig_nents = 0;
 	sg_page_sizes = 0;
 	do {
 		unsigned int page_size = get_largest_page_size(i915, rem);
@@ -217,7 +217,7 @@ static int fake_get_huge_pages(struct drm_i915_gem_object *obj)
 
 		sg_page_sizes |= len;
 
-		st->nents++;
+		st->nents = st->orig_nents = st->nents + 1;
 
 		rem -= len;
 		if (!rem) {
@@ -252,7 +252,7 @@ static int fake_get_huge_pages_single(struct drm_i915_gem_object *obj)
 	}
 
 	sg = st->sgl;
-	st->nents = 1;
+	st->nents = st->orig_nents = 1;
 
 	page_size = get_largest_page_size(i915, obj->base.size);
 	GEM_BUG_ON(!page_size);
diff --git a/drivers/gpu/drm/i915/gem/selftests/mock_dmabuf.c b/drivers/gpu/drm/i915/gem/selftests/mock_dmabuf.c
index debaf7b..5723525 100644
--- a/drivers/gpu/drm/i915/gem/selftests/mock_dmabuf.c
+++ b/drivers/gpu/drm/i915/gem/selftests/mock_dmabuf.c
@@ -28,7 +28,8 @@ static struct sg_table *mock_map_dma_buf(struct dma_buf_attachment *attachment,
 		sg = sg_next(sg);
 	}
 
-	if (!dma_map_sg(attachment->dev, st->sgl, st->nents, dir)) {
+	st->nents = dma_map_sg(attachment->dev, st->sgl, st->orig_nents, dir);
+	if (!st->nents) {
 		err = -ENOMEM;
 		goto err_st;
 	}
@@ -46,7 +47,7 @@ static void mock_unmap_dma_buf(struct dma_buf_attachment *attachment,
 			       struct sg_table *st,
 			       enum dma_data_direction dir)
 {
-	dma_unmap_sg(attachment->dev, st->sgl, st->nents, dir);
+	dma_unmap_sg(attachment->dev, st->sgl, st->orig_nents, dir);
 	sg_free_table(st);
 	kfree(st);
 }
diff --git a/drivers/gpu/drm/i915/gt/intel_ggtt.c b/drivers/gpu/drm/i915/gt/intel_ggtt.c
index 66165b1..9a298bf 100644
--- a/drivers/gpu/drm/i915/gt/intel_ggtt.c
+++ b/drivers/gpu/drm/i915/gt/intel_ggtt.c
@@ -1221,7 +1221,7 @@ void i915_ggtt_resume(struct i915_ggtt *ggtt)
 	for (column = 0; column < width; column++) {
 		src_idx = stride * (height - 1) + column + offset;
 		for (row = 0; row < height; row++) {
-			st->nents++;
+			st->nents = st->orig_nents = st->nents + 1;
 			/*
 			 * We don't need the pages, but need to initialize
 			 * the entries so the sg list can be happily traversed.
@@ -1259,7 +1259,7 @@ void i915_ggtt_resume(struct i915_ggtt *ggtt)
 	if (ret)
 		goto err_sg_alloc;
 
-	st->nents = 0;
+	st->nents = st->orig_nents = 0;
 	sg = st->sgl;
 
 	for (i = 0 ; i < ARRAY_SIZE(rot_info->plane); i++) {
@@ -1306,7 +1306,7 @@ void i915_ggtt_resume(struct i915_ggtt *ggtt)
 
 			length = min(left, length);
 
-			st->nents++;
+			st->nents = st->orig_nents = st->nents + 1;
 
 			sg_set_page(sg, NULL, length, 0);
 			sg_dma_address(sg) = addr;
@@ -1343,7 +1343,7 @@ void i915_ggtt_resume(struct i915_ggtt *ggtt)
 	if (ret)
 		goto err_sg_alloc;
 
-	st->nents = 0;
+	st->nents = st->orig_nents = 0;
 	sg = st->sgl;
 
 	for (i = 0 ; i < ARRAY_SIZE(rem_info->plane); i++) {
@@ -1389,7 +1389,7 @@ void i915_ggtt_resume(struct i915_ggtt *ggtt)
 	GEM_BUG_ON(!iter);
 
 	sg = st->sgl;
-	st->nents = 0;
+	st->nents = st->orig_nents = 0;
 	do {
 		unsigned int len;
 
@@ -1400,7 +1400,7 @@ void i915_ggtt_resume(struct i915_ggtt *ggtt)
 			sg_dma_address(iter) + (offset << PAGE_SHIFT);
 		sg_dma_len(sg) = len;
 
-		st->nents++;
+		st->nents = st->orig_nents = st->nents + 1;
 		count -= len >> PAGE_SHIFT;
 		if (count == 0) {
 			sg_mark_end(sg);
diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c b/drivers/gpu/drm/i915/i915_gem_gtt.c
index cb43381..c4122cd3 100644
--- a/drivers/gpu/drm/i915/i915_gem_gtt.c
+++ b/drivers/gpu/drm/i915/i915_gem_gtt.c
@@ -28,10 +28,11 @@ int i915_gem_gtt_prepare_pages(struct drm_i915_gem_object *obj,
 			       struct sg_table *pages)
 {
 	do {
-		if (dma_map_sg_attrs(&obj->base.dev->pdev->dev,
-				     pages->sgl, pages->nents,
-				     PCI_DMA_BIDIRECTIONAL,
-				     DMA_ATTR_NO_WARN))
+		pages->nents = dma_map_sg_attrs(&obj->base.dev->pdev->dev,
+						pages->sgl, pages->orig_nents,
+						PCI_DMA_BIDIRECTIONAL,
+						DMA_ATTR_NO_WARN);
+		if (page->nents)
 			return 0;
 
 		/*
@@ -68,7 +69,8 @@ void i915_gem_gtt_finish_pages(struct drm_i915_gem_object *obj,
 		}
 	}
 
-	dma_unmap_sg(kdev, pages->sgl, pages->nents, PCI_DMA_BIDIRECTIONAL);
+	dma_unmap_sg(kdev, pages->sgl, pages->orig_nents,
+		     PCI_DMA_BIDIRECTIONAL);
 }
 
 /**
diff --git a/drivers/gpu/drm/i915/i915_scatterlist.c b/drivers/gpu/drm/i915/i915_scatterlist.c
index cc6b384..05bee13 100644
--- a/drivers/gpu/drm/i915/i915_scatterlist.c
+++ b/drivers/gpu/drm/i915/i915_scatterlist.c
@@ -15,11 +15,11 @@ bool i915_sg_trim(struct sg_table *orig_st)
 	if (orig_st->nents == orig_st->orig_nents)
 		return false;
 
-	if (sg_alloc_table(&new_st, orig_st->nents, GFP_KERNEL | __GFP_NOWARN))
+	if (sg_alloc_table(&new_st, orig_st->orig_nents, GFP_KERNEL | __GFP_NOWARN))
 		return false;
 
 	new_sg = new_st.sgl;
-	for_each_sg(orig_st->sgl, sg, orig_st->nents, i) {
+	for_each_sg(orig_st->sgl, sg, orig_st->orig_nents, i) {
 		sg_set_page(new_sg, sg_page(sg), sg->length, 0);
 		sg_dma_address(new_sg) = sg_dma_address(sg);
 		sg_dma_len(new_sg) = sg_dma_len(sg);
diff --git a/drivers/gpu/drm/i915/selftests/scatterlist.c b/drivers/gpu/drm/i915/selftests/scatterlist.c
index d599186..4456fe5 100644
--- a/drivers/gpu/drm/i915/selftests/scatterlist.c
+++ b/drivers/gpu/drm/i915/selftests/scatterlist.c
@@ -48,9 +48,9 @@ static noinline int expect_pfn_sg(struct pfn_table *pt,
 	unsigned long pfn, n;
 
 	pfn = pt->start;
-	for_each_sg(pt->st.sgl, sg, pt->st.nents, n) {
+	for_each_sg(pt->st.sgl, sg, pt->st.orig_nents, n) {
 		struct page *page = sg_page(sg);
-		unsigned int npages = npages_fn(n, pt->st.nents, rnd);
+		unsigned int npages = npages_fn(n, pt->st.orig_nents, rnd);
 
 		if (page_to_pfn(page) != pfn) {
 			pr_err("%s: %s left pages out of order, expected pfn %lu, found pfn %lu (using for_each_sg)\n",
@@ -86,7 +86,7 @@ static noinline int expect_pfn_sg_page_iter(struct pfn_table *pt,
 	unsigned long pfn;
 
 	pfn = pt->start;
-	for_each_sg_page(pt->st.sgl, &sgiter, pt->st.nents, 0) {
+	for_each_sg_page(pt->st.sgl, &sgiter, pt->st.orig_nents, 0) {
 		struct page *page = sg_page_iter_page(&sgiter);
 
 		if (page != pfn_to_page(pfn)) {
@@ -256,7 +256,7 @@ static int alloc_table(struct pfn_table *pt,
 		pfn += npages;
 	}
 	sg_mark_end(sg);
-	pt->st.nents = n;
+	pt->st.nents = pt->st.orig_nents = n;
 	pt->end = pfn;
 
 	return 0;
-- 
1.9.1


WARNING: multiple messages have this Message-ID (diff)
From: Marek Szyprowski <m.szyprowski@samsung.com>
To: dri-devel@lists.freedesktop.org,
	iommu@lists.linux-foundation.org, linaro-mm-sig@lists.linaro.org,
	linux-kernel@vger.kernel.org
Cc: Daniel Vetter <daniel@ffwll.ch>,
	Bartlomiej Zolnierkiewicz <b.zolnierkie@samsung.com>,
	David Airlie <airlied@linux.ie>,
	intel-gfx@lists.freedesktop.org, amd-gfx@lists.freedesktop.org,
	Christoph Hellwig <hch@lst.de>,
	Benjamin Gaignard <benjamin.gaignard@linaro.org>,
	Robin Murphy <robin.murphy@arm.com>,
	Sumit Semwal <sumit.semwal@linaro.org>,
	linux-arm-kernel@lists.infradead.org
Subject: [RFC 06/17] drm: i915: fix sg_table nents vs. orig_nents misuse
Date: Tue, 28 Apr 2020 15:19:54 +0200	[thread overview]
Message-ID: <20200428132005.21424-7-m.szyprowski@samsung.com> (raw)
In-Reply-To: <20200428132005.21424-1-m.szyprowski@samsung.com>

The Documentation/DMA-API-HOWTO.txt states that dma_map_sg returns the
numer of the created entries in the DMA address space. However the
subsequent calls to dma_sync_sg_for_{device,cpu} and dma_unmap_sg must be
called with the original number of entries passed to dma_map_sg. The
sg_table->nents in turn holds the result of the dma_map_sg call as stated
in include/linux/scatterlist.h. Adapt the code to obey those rules.

Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
---
 drivers/gpu/drm/i915/gem/i915_gem_dmabuf.c       | 13 +++++++------
 drivers/gpu/drm/i915/gem/i915_gem_internal.c     |  4 ++--
 drivers/gpu/drm/i915/gem/i915_gem_region.c       |  4 ++--
 drivers/gpu/drm/i915/gem/i915_gem_shmem.c        |  5 +++--
 drivers/gpu/drm/i915/gem/selftests/huge_pages.c  | 10 +++++-----
 drivers/gpu/drm/i915/gem/selftests/mock_dmabuf.c |  5 +++--
 drivers/gpu/drm/i915/gt/intel_ggtt.c             | 12 ++++++------
 drivers/gpu/drm/i915/i915_gem_gtt.c              | 12 +++++++-----
 drivers/gpu/drm/i915/i915_scatterlist.c          |  4 ++--
 drivers/gpu/drm/i915/selftests/scatterlist.c     |  8 ++++----
 10 files changed, 41 insertions(+), 36 deletions(-)

diff --git a/drivers/gpu/drm/i915/gem/i915_gem_dmabuf.c b/drivers/gpu/drm/i915/gem/i915_gem_dmabuf.c
index 7db5a79..d829852 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_dmabuf.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_dmabuf.c
@@ -36,21 +36,22 @@ static struct sg_table *i915_gem_map_dma_buf(struct dma_buf_attachment *attachme
 		goto err_unpin_pages;
 	}
 
-	ret = sg_alloc_table(st, obj->mm.pages->nents, GFP_KERNEL);
+	ret = sg_alloc_table(st, obj->mm.pages->orig_nents, GFP_KERNEL);
 	if (ret)
 		goto err_free;
 
 	src = obj->mm.pages->sgl;
 	dst = st->sgl;
-	for (i = 0; i < obj->mm.pages->nents; i++) {
+	for (i = 0; i < obj->mm.pages->orig_nents; i++) {
 		sg_set_page(dst, sg_page(src), src->length, 0);
 		dst = sg_next(dst);
 		src = sg_next(src);
 	}
 
-	if (!dma_map_sg_attrs(attachment->dev,
-			      st->sgl, st->nents, dir,
-			      DMA_ATTR_SKIP_CPU_SYNC)) {
+	st->nents = dma_map_sg_attrs(attachment->dev,
+				     st->sgl, st->orig_nents, dir,
+				     DMA_ATTR_SKIP_CPU_SYNC);
+	if (!st->nents) {
 		ret = -ENOMEM;
 		goto err_free_sg;
 	}
@@ -74,7 +75,7 @@ static void i915_gem_unmap_dma_buf(struct dma_buf_attachment *attachment,
 	struct drm_i915_gem_object *obj = dma_buf_to_obj(attachment->dmabuf);
 
 	dma_unmap_sg_attrs(attachment->dev,
-			   sg->sgl, sg->nents, dir,
+			   sg->sgl, sg->orig_nents, dir,
 			   DMA_ATTR_SKIP_CPU_SYNC);
 	sg_free_table(sg);
 	kfree(sg);
diff --git a/drivers/gpu/drm/i915/gem/i915_gem_internal.c b/drivers/gpu/drm/i915/gem/i915_gem_internal.c
index cbbff81..a8ebfdd 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_internal.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_internal.c
@@ -73,7 +73,7 @@ static int i915_gem_object_get_pages_internal(struct drm_i915_gem_object *obj)
 	}
 
 	sg = st->sgl;
-	st->nents = 0;
+	st->nents = st->orig_nents = 0;
 	sg_page_sizes = 0;
 
 	do {
@@ -94,7 +94,7 @@ static int i915_gem_object_get_pages_internal(struct drm_i915_gem_object *obj)
 
 		sg_set_page(sg, page, PAGE_SIZE << order, 0);
 		sg_page_sizes |= PAGE_SIZE << order;
-		st->nents++;
+		st->nents = st->orig_nents = st->nents + 1;
 
 		npages -= 1 << order;
 		if (!npages) {
diff --git a/drivers/gpu/drm/i915/gem/i915_gem_region.c b/drivers/gpu/drm/i915/gem/i915_gem_region.c
index 1515384..58ca560 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_region.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_region.c
@@ -53,7 +53,7 @@
 	GEM_BUG_ON(list_empty(blocks));
 
 	sg = st->sgl;
-	st->nents = 0;
+	st->nents = st->orig_nents = 0;
 	sg_page_sizes = 0;
 	prev_end = (resource_size_t)-1;
 
@@ -78,7 +78,7 @@
 
 			sg->length = block_size;
 
-			st->nents++;
+			st->nents = st->orig_nents = st->nents + 1;
 		} else {
 			sg->length += block_size;
 			sg_dma_len(sg) += block_size;
diff --git a/drivers/gpu/drm/i915/gem/i915_gem_shmem.c b/drivers/gpu/drm/i915/gem/i915_gem_shmem.c
index 5d5d7ee..851a732 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_shmem.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_shmem.c
@@ -80,7 +80,7 @@ static int shmem_get_pages(struct drm_i915_gem_object *obj)
 	noreclaim |= __GFP_NORETRY | __GFP_NOWARN;
 
 	sg = st->sgl;
-	st->nents = 0;
+	st->nents = st->orig_nents = 0;
 	sg_page_sizes = 0;
 	for (i = 0; i < page_count; i++) {
 		const unsigned int shrink[] = {
@@ -140,7 +140,8 @@ static int shmem_get_pages(struct drm_i915_gem_object *obj)
 				sg_page_sizes |= sg->length;
 				sg = sg_next(sg);
 			}
-			st->nents++;
+			st->nents = st->orig_nents = st->nents + 1;
+
 			sg_set_page(sg, page, PAGE_SIZE, 0);
 		} else {
 			sg->length += PAGE_SIZE;
diff --git a/drivers/gpu/drm/i915/gem/selftests/huge_pages.c b/drivers/gpu/drm/i915/gem/selftests/huge_pages.c
index c9988b6..bd141f9 100644
--- a/drivers/gpu/drm/i915/gem/selftests/huge_pages.c
+++ b/drivers/gpu/drm/i915/gem/selftests/huge_pages.c
@@ -76,7 +76,7 @@ static int get_huge_pages(struct drm_i915_gem_object *obj)
 
 	rem = obj->base.size;
 	sg = st->sgl;
-	st->nents = 0;
+	st->nents = st->orig_nents = 0;
 	sg_page_sizes = 0;
 
 	/*
@@ -99,7 +99,7 @@ static int get_huge_pages(struct drm_i915_gem_object *obj)
 
 			sg_set_page(sg, page, page_size, 0);
 			sg_page_sizes |= page_size;
-			st->nents++;
+			st->nents = st->orig_nents = st->nents + 1;
 
 			rem -= page_size;
 			if (!rem) {
@@ -201,7 +201,7 @@ static int fake_get_huge_pages(struct drm_i915_gem_object *obj)
 	/* Use optimal page sized chunks to fill in the sg table */
 	rem = obj->base.size;
 	sg = st->sgl;
-	st->nents = 0;
+	st->nents = st->orig_nents = 0;
 	sg_page_sizes = 0;
 	do {
 		unsigned int page_size = get_largest_page_size(i915, rem);
@@ -217,7 +217,7 @@ static int fake_get_huge_pages(struct drm_i915_gem_object *obj)
 
 		sg_page_sizes |= len;
 
-		st->nents++;
+		st->nents = st->orig_nents = st->nents + 1;
 
 		rem -= len;
 		if (!rem) {
@@ -252,7 +252,7 @@ static int fake_get_huge_pages_single(struct drm_i915_gem_object *obj)
 	}
 
 	sg = st->sgl;
-	st->nents = 1;
+	st->nents = st->orig_nents = 1;
 
 	page_size = get_largest_page_size(i915, obj->base.size);
 	GEM_BUG_ON(!page_size);
diff --git a/drivers/gpu/drm/i915/gem/selftests/mock_dmabuf.c b/drivers/gpu/drm/i915/gem/selftests/mock_dmabuf.c
index debaf7b..5723525 100644
--- a/drivers/gpu/drm/i915/gem/selftests/mock_dmabuf.c
+++ b/drivers/gpu/drm/i915/gem/selftests/mock_dmabuf.c
@@ -28,7 +28,8 @@ static struct sg_table *mock_map_dma_buf(struct dma_buf_attachment *attachment,
 		sg = sg_next(sg);
 	}
 
-	if (!dma_map_sg(attachment->dev, st->sgl, st->nents, dir)) {
+	st->nents = dma_map_sg(attachment->dev, st->sgl, st->orig_nents, dir);
+	if (!st->nents) {
 		err = -ENOMEM;
 		goto err_st;
 	}
@@ -46,7 +47,7 @@ static void mock_unmap_dma_buf(struct dma_buf_attachment *attachment,
 			       struct sg_table *st,
 			       enum dma_data_direction dir)
 {
-	dma_unmap_sg(attachment->dev, st->sgl, st->nents, dir);
+	dma_unmap_sg(attachment->dev, st->sgl, st->orig_nents, dir);
 	sg_free_table(st);
 	kfree(st);
 }
diff --git a/drivers/gpu/drm/i915/gt/intel_ggtt.c b/drivers/gpu/drm/i915/gt/intel_ggtt.c
index 66165b1..9a298bf 100644
--- a/drivers/gpu/drm/i915/gt/intel_ggtt.c
+++ b/drivers/gpu/drm/i915/gt/intel_ggtt.c
@@ -1221,7 +1221,7 @@ void i915_ggtt_resume(struct i915_ggtt *ggtt)
 	for (column = 0; column < width; column++) {
 		src_idx = stride * (height - 1) + column + offset;
 		for (row = 0; row < height; row++) {
-			st->nents++;
+			st->nents = st->orig_nents = st->nents + 1;
 			/*
 			 * We don't need the pages, but need to initialize
 			 * the entries so the sg list can be happily traversed.
@@ -1259,7 +1259,7 @@ void i915_ggtt_resume(struct i915_ggtt *ggtt)
 	if (ret)
 		goto err_sg_alloc;
 
-	st->nents = 0;
+	st->nents = st->orig_nents = 0;
 	sg = st->sgl;
 
 	for (i = 0 ; i < ARRAY_SIZE(rot_info->plane); i++) {
@@ -1306,7 +1306,7 @@ void i915_ggtt_resume(struct i915_ggtt *ggtt)
 
 			length = min(left, length);
 
-			st->nents++;
+			st->nents = st->orig_nents = st->nents + 1;
 
 			sg_set_page(sg, NULL, length, 0);
 			sg_dma_address(sg) = addr;
@@ -1343,7 +1343,7 @@ void i915_ggtt_resume(struct i915_ggtt *ggtt)
 	if (ret)
 		goto err_sg_alloc;
 
-	st->nents = 0;
+	st->nents = st->orig_nents = 0;
 	sg = st->sgl;
 
 	for (i = 0 ; i < ARRAY_SIZE(rem_info->plane); i++) {
@@ -1389,7 +1389,7 @@ void i915_ggtt_resume(struct i915_ggtt *ggtt)
 	GEM_BUG_ON(!iter);
 
 	sg = st->sgl;
-	st->nents = 0;
+	st->nents = st->orig_nents = 0;
 	do {
 		unsigned int len;
 
@@ -1400,7 +1400,7 @@ void i915_ggtt_resume(struct i915_ggtt *ggtt)
 			sg_dma_address(iter) + (offset << PAGE_SHIFT);
 		sg_dma_len(sg) = len;
 
-		st->nents++;
+		st->nents = st->orig_nents = st->nents + 1;
 		count -= len >> PAGE_SHIFT;
 		if (count == 0) {
 			sg_mark_end(sg);
diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c b/drivers/gpu/drm/i915/i915_gem_gtt.c
index cb43381..c4122cd3 100644
--- a/drivers/gpu/drm/i915/i915_gem_gtt.c
+++ b/drivers/gpu/drm/i915/i915_gem_gtt.c
@@ -28,10 +28,11 @@ int i915_gem_gtt_prepare_pages(struct drm_i915_gem_object *obj,
 			       struct sg_table *pages)
 {
 	do {
-		if (dma_map_sg_attrs(&obj->base.dev->pdev->dev,
-				     pages->sgl, pages->nents,
-				     PCI_DMA_BIDIRECTIONAL,
-				     DMA_ATTR_NO_WARN))
+		pages->nents = dma_map_sg_attrs(&obj->base.dev->pdev->dev,
+						pages->sgl, pages->orig_nents,
+						PCI_DMA_BIDIRECTIONAL,
+						DMA_ATTR_NO_WARN);
+		if (page->nents)
 			return 0;
 
 		/*
@@ -68,7 +69,8 @@ void i915_gem_gtt_finish_pages(struct drm_i915_gem_object *obj,
 		}
 	}
 
-	dma_unmap_sg(kdev, pages->sgl, pages->nents, PCI_DMA_BIDIRECTIONAL);
+	dma_unmap_sg(kdev, pages->sgl, pages->orig_nents,
+		     PCI_DMA_BIDIRECTIONAL);
 }
 
 /**
diff --git a/drivers/gpu/drm/i915/i915_scatterlist.c b/drivers/gpu/drm/i915/i915_scatterlist.c
index cc6b384..05bee13 100644
--- a/drivers/gpu/drm/i915/i915_scatterlist.c
+++ b/drivers/gpu/drm/i915/i915_scatterlist.c
@@ -15,11 +15,11 @@ bool i915_sg_trim(struct sg_table *orig_st)
 	if (orig_st->nents == orig_st->orig_nents)
 		return false;
 
-	if (sg_alloc_table(&new_st, orig_st->nents, GFP_KERNEL | __GFP_NOWARN))
+	if (sg_alloc_table(&new_st, orig_st->orig_nents, GFP_KERNEL | __GFP_NOWARN))
 		return false;
 
 	new_sg = new_st.sgl;
-	for_each_sg(orig_st->sgl, sg, orig_st->nents, i) {
+	for_each_sg(orig_st->sgl, sg, orig_st->orig_nents, i) {
 		sg_set_page(new_sg, sg_page(sg), sg->length, 0);
 		sg_dma_address(new_sg) = sg_dma_address(sg);
 		sg_dma_len(new_sg) = sg_dma_len(sg);
diff --git a/drivers/gpu/drm/i915/selftests/scatterlist.c b/drivers/gpu/drm/i915/selftests/scatterlist.c
index d599186..4456fe5 100644
--- a/drivers/gpu/drm/i915/selftests/scatterlist.c
+++ b/drivers/gpu/drm/i915/selftests/scatterlist.c
@@ -48,9 +48,9 @@ static noinline int expect_pfn_sg(struct pfn_table *pt,
 	unsigned long pfn, n;
 
 	pfn = pt->start;
-	for_each_sg(pt->st.sgl, sg, pt->st.nents, n) {
+	for_each_sg(pt->st.sgl, sg, pt->st.orig_nents, n) {
 		struct page *page = sg_page(sg);
-		unsigned int npages = npages_fn(n, pt->st.nents, rnd);
+		unsigned int npages = npages_fn(n, pt->st.orig_nents, rnd);
 
 		if (page_to_pfn(page) != pfn) {
 			pr_err("%s: %s left pages out of order, expected pfn %lu, found pfn %lu (using for_each_sg)\n",
@@ -86,7 +86,7 @@ static noinline int expect_pfn_sg_page_iter(struct pfn_table *pt,
 	unsigned long pfn;
 
 	pfn = pt->start;
-	for_each_sg_page(pt->st.sgl, &sgiter, pt->st.nents, 0) {
+	for_each_sg_page(pt->st.sgl, &sgiter, pt->st.orig_nents, 0) {
 		struct page *page = sg_page_iter_page(&sgiter);
 
 		if (page != pfn_to_page(pfn)) {
@@ -256,7 +256,7 @@ static int alloc_table(struct pfn_table *pt,
 		pfn += npages;
 	}
 	sg_mark_end(sg);
-	pt->st.nents = n;
+	pt->st.nents = pt->st.orig_nents = n;
 	pt->end = pfn;
 
 	return 0;
-- 
1.9.1

_______________________________________________
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu

WARNING: multiple messages have this Message-ID (diff)
From: Marek Szyprowski <m.szyprowski@samsung.com>
To: dri-devel@lists.freedesktop.org,
	iommu@lists.linux-foundation.org, linaro-mm-sig@lists.linaro.org,
	linux-kernel@vger.kernel.org
Cc: Daniel Vetter <daniel@ffwll.ch>,
	Bartlomiej Zolnierkiewicz <b.zolnierkie@samsung.com>,
	David Airlie <airlied@linux.ie>,
	intel-gfx@lists.freedesktop.org, amd-gfx@lists.freedesktop.org,
	Christoph Hellwig <hch@lst.de>,
	Benjamin Gaignard <benjamin.gaignard@linaro.org>,
	Robin Murphy <robin.murphy@arm.com>,
	Sumit Semwal <sumit.semwal@linaro.org>,
	linux-arm-kernel@lists.infradead.org,
	Marek Szyprowski <m.szyprowski@samsung.com>
Subject: [RFC 06/17] drm: i915: fix sg_table nents vs. orig_nents misuse
Date: Tue, 28 Apr 2020 15:19:54 +0200	[thread overview]
Message-ID: <20200428132005.21424-7-m.szyprowski@samsung.com> (raw)
In-Reply-To: <20200428132005.21424-1-m.szyprowski@samsung.com>

The Documentation/DMA-API-HOWTO.txt states that dma_map_sg returns the
numer of the created entries in the DMA address space. However the
subsequent calls to dma_sync_sg_for_{device,cpu} and dma_unmap_sg must be
called with the original number of entries passed to dma_map_sg. The
sg_table->nents in turn holds the result of the dma_map_sg call as stated
in include/linux/scatterlist.h. Adapt the code to obey those rules.

Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
---
 drivers/gpu/drm/i915/gem/i915_gem_dmabuf.c       | 13 +++++++------
 drivers/gpu/drm/i915/gem/i915_gem_internal.c     |  4 ++--
 drivers/gpu/drm/i915/gem/i915_gem_region.c       |  4 ++--
 drivers/gpu/drm/i915/gem/i915_gem_shmem.c        |  5 +++--
 drivers/gpu/drm/i915/gem/selftests/huge_pages.c  | 10 +++++-----
 drivers/gpu/drm/i915/gem/selftests/mock_dmabuf.c |  5 +++--
 drivers/gpu/drm/i915/gt/intel_ggtt.c             | 12 ++++++------
 drivers/gpu/drm/i915/i915_gem_gtt.c              | 12 +++++++-----
 drivers/gpu/drm/i915/i915_scatterlist.c          |  4 ++--
 drivers/gpu/drm/i915/selftests/scatterlist.c     |  8 ++++----
 10 files changed, 41 insertions(+), 36 deletions(-)

diff --git a/drivers/gpu/drm/i915/gem/i915_gem_dmabuf.c b/drivers/gpu/drm/i915/gem/i915_gem_dmabuf.c
index 7db5a79..d829852 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_dmabuf.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_dmabuf.c
@@ -36,21 +36,22 @@ static struct sg_table *i915_gem_map_dma_buf(struct dma_buf_attachment *attachme
 		goto err_unpin_pages;
 	}
 
-	ret = sg_alloc_table(st, obj->mm.pages->nents, GFP_KERNEL);
+	ret = sg_alloc_table(st, obj->mm.pages->orig_nents, GFP_KERNEL);
 	if (ret)
 		goto err_free;
 
 	src = obj->mm.pages->sgl;
 	dst = st->sgl;
-	for (i = 0; i < obj->mm.pages->nents; i++) {
+	for (i = 0; i < obj->mm.pages->orig_nents; i++) {
 		sg_set_page(dst, sg_page(src), src->length, 0);
 		dst = sg_next(dst);
 		src = sg_next(src);
 	}
 
-	if (!dma_map_sg_attrs(attachment->dev,
-			      st->sgl, st->nents, dir,
-			      DMA_ATTR_SKIP_CPU_SYNC)) {
+	st->nents = dma_map_sg_attrs(attachment->dev,
+				     st->sgl, st->orig_nents, dir,
+				     DMA_ATTR_SKIP_CPU_SYNC);
+	if (!st->nents) {
 		ret = -ENOMEM;
 		goto err_free_sg;
 	}
@@ -74,7 +75,7 @@ static void i915_gem_unmap_dma_buf(struct dma_buf_attachment *attachment,
 	struct drm_i915_gem_object *obj = dma_buf_to_obj(attachment->dmabuf);
 
 	dma_unmap_sg_attrs(attachment->dev,
-			   sg->sgl, sg->nents, dir,
+			   sg->sgl, sg->orig_nents, dir,
 			   DMA_ATTR_SKIP_CPU_SYNC);
 	sg_free_table(sg);
 	kfree(sg);
diff --git a/drivers/gpu/drm/i915/gem/i915_gem_internal.c b/drivers/gpu/drm/i915/gem/i915_gem_internal.c
index cbbff81..a8ebfdd 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_internal.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_internal.c
@@ -73,7 +73,7 @@ static int i915_gem_object_get_pages_internal(struct drm_i915_gem_object *obj)
 	}
 
 	sg = st->sgl;
-	st->nents = 0;
+	st->nents = st->orig_nents = 0;
 	sg_page_sizes = 0;
 
 	do {
@@ -94,7 +94,7 @@ static int i915_gem_object_get_pages_internal(struct drm_i915_gem_object *obj)
 
 		sg_set_page(sg, page, PAGE_SIZE << order, 0);
 		sg_page_sizes |= PAGE_SIZE << order;
-		st->nents++;
+		st->nents = st->orig_nents = st->nents + 1;
 
 		npages -= 1 << order;
 		if (!npages) {
diff --git a/drivers/gpu/drm/i915/gem/i915_gem_region.c b/drivers/gpu/drm/i915/gem/i915_gem_region.c
index 1515384..58ca560 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_region.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_region.c
@@ -53,7 +53,7 @@
 	GEM_BUG_ON(list_empty(blocks));
 
 	sg = st->sgl;
-	st->nents = 0;
+	st->nents = st->orig_nents = 0;
 	sg_page_sizes = 0;
 	prev_end = (resource_size_t)-1;
 
@@ -78,7 +78,7 @@
 
 			sg->length = block_size;
 
-			st->nents++;
+			st->nents = st->orig_nents = st->nents + 1;
 		} else {
 			sg->length += block_size;
 			sg_dma_len(sg) += block_size;
diff --git a/drivers/gpu/drm/i915/gem/i915_gem_shmem.c b/drivers/gpu/drm/i915/gem/i915_gem_shmem.c
index 5d5d7ee..851a732 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_shmem.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_shmem.c
@@ -80,7 +80,7 @@ static int shmem_get_pages(struct drm_i915_gem_object *obj)
 	noreclaim |= __GFP_NORETRY | __GFP_NOWARN;
 
 	sg = st->sgl;
-	st->nents = 0;
+	st->nents = st->orig_nents = 0;
 	sg_page_sizes = 0;
 	for (i = 0; i < page_count; i++) {
 		const unsigned int shrink[] = {
@@ -140,7 +140,8 @@ static int shmem_get_pages(struct drm_i915_gem_object *obj)
 				sg_page_sizes |= sg->length;
 				sg = sg_next(sg);
 			}
-			st->nents++;
+			st->nents = st->orig_nents = st->nents + 1;
+
 			sg_set_page(sg, page, PAGE_SIZE, 0);
 		} else {
 			sg->length += PAGE_SIZE;
diff --git a/drivers/gpu/drm/i915/gem/selftests/huge_pages.c b/drivers/gpu/drm/i915/gem/selftests/huge_pages.c
index c9988b6..bd141f9 100644
--- a/drivers/gpu/drm/i915/gem/selftests/huge_pages.c
+++ b/drivers/gpu/drm/i915/gem/selftests/huge_pages.c
@@ -76,7 +76,7 @@ static int get_huge_pages(struct drm_i915_gem_object *obj)
 
 	rem = obj->base.size;
 	sg = st->sgl;
-	st->nents = 0;
+	st->nents = st->orig_nents = 0;
 	sg_page_sizes = 0;
 
 	/*
@@ -99,7 +99,7 @@ static int get_huge_pages(struct drm_i915_gem_object *obj)
 
 			sg_set_page(sg, page, page_size, 0);
 			sg_page_sizes |= page_size;
-			st->nents++;
+			st->nents = st->orig_nents = st->nents + 1;
 
 			rem -= page_size;
 			if (!rem) {
@@ -201,7 +201,7 @@ static int fake_get_huge_pages(struct drm_i915_gem_object *obj)
 	/* Use optimal page sized chunks to fill in the sg table */
 	rem = obj->base.size;
 	sg = st->sgl;
-	st->nents = 0;
+	st->nents = st->orig_nents = 0;
 	sg_page_sizes = 0;
 	do {
 		unsigned int page_size = get_largest_page_size(i915, rem);
@@ -217,7 +217,7 @@ static int fake_get_huge_pages(struct drm_i915_gem_object *obj)
 
 		sg_page_sizes |= len;
 
-		st->nents++;
+		st->nents = st->orig_nents = st->nents + 1;
 
 		rem -= len;
 		if (!rem) {
@@ -252,7 +252,7 @@ static int fake_get_huge_pages_single(struct drm_i915_gem_object *obj)
 	}
 
 	sg = st->sgl;
-	st->nents = 1;
+	st->nents = st->orig_nents = 1;
 
 	page_size = get_largest_page_size(i915, obj->base.size);
 	GEM_BUG_ON(!page_size);
diff --git a/drivers/gpu/drm/i915/gem/selftests/mock_dmabuf.c b/drivers/gpu/drm/i915/gem/selftests/mock_dmabuf.c
index debaf7b..5723525 100644
--- a/drivers/gpu/drm/i915/gem/selftests/mock_dmabuf.c
+++ b/drivers/gpu/drm/i915/gem/selftests/mock_dmabuf.c
@@ -28,7 +28,8 @@ static struct sg_table *mock_map_dma_buf(struct dma_buf_attachment *attachment,
 		sg = sg_next(sg);
 	}
 
-	if (!dma_map_sg(attachment->dev, st->sgl, st->nents, dir)) {
+	st->nents = dma_map_sg(attachment->dev, st->sgl, st->orig_nents, dir);
+	if (!st->nents) {
 		err = -ENOMEM;
 		goto err_st;
 	}
@@ -46,7 +47,7 @@ static void mock_unmap_dma_buf(struct dma_buf_attachment *attachment,
 			       struct sg_table *st,
 			       enum dma_data_direction dir)
 {
-	dma_unmap_sg(attachment->dev, st->sgl, st->nents, dir);
+	dma_unmap_sg(attachment->dev, st->sgl, st->orig_nents, dir);
 	sg_free_table(st);
 	kfree(st);
 }
diff --git a/drivers/gpu/drm/i915/gt/intel_ggtt.c b/drivers/gpu/drm/i915/gt/intel_ggtt.c
index 66165b1..9a298bf 100644
--- a/drivers/gpu/drm/i915/gt/intel_ggtt.c
+++ b/drivers/gpu/drm/i915/gt/intel_ggtt.c
@@ -1221,7 +1221,7 @@ void i915_ggtt_resume(struct i915_ggtt *ggtt)
 	for (column = 0; column < width; column++) {
 		src_idx = stride * (height - 1) + column + offset;
 		for (row = 0; row < height; row++) {
-			st->nents++;
+			st->nents = st->orig_nents = st->nents + 1;
 			/*
 			 * We don't need the pages, but need to initialize
 			 * the entries so the sg list can be happily traversed.
@@ -1259,7 +1259,7 @@ void i915_ggtt_resume(struct i915_ggtt *ggtt)
 	if (ret)
 		goto err_sg_alloc;
 
-	st->nents = 0;
+	st->nents = st->orig_nents = 0;
 	sg = st->sgl;
 
 	for (i = 0 ; i < ARRAY_SIZE(rot_info->plane); i++) {
@@ -1306,7 +1306,7 @@ void i915_ggtt_resume(struct i915_ggtt *ggtt)
 
 			length = min(left, length);
 
-			st->nents++;
+			st->nents = st->orig_nents = st->nents + 1;
 
 			sg_set_page(sg, NULL, length, 0);
 			sg_dma_address(sg) = addr;
@@ -1343,7 +1343,7 @@ void i915_ggtt_resume(struct i915_ggtt *ggtt)
 	if (ret)
 		goto err_sg_alloc;
 
-	st->nents = 0;
+	st->nents = st->orig_nents = 0;
 	sg = st->sgl;
 
 	for (i = 0 ; i < ARRAY_SIZE(rem_info->plane); i++) {
@@ -1389,7 +1389,7 @@ void i915_ggtt_resume(struct i915_ggtt *ggtt)
 	GEM_BUG_ON(!iter);
 
 	sg = st->sgl;
-	st->nents = 0;
+	st->nents = st->orig_nents = 0;
 	do {
 		unsigned int len;
 
@@ -1400,7 +1400,7 @@ void i915_ggtt_resume(struct i915_ggtt *ggtt)
 			sg_dma_address(iter) + (offset << PAGE_SHIFT);
 		sg_dma_len(sg) = len;
 
-		st->nents++;
+		st->nents = st->orig_nents = st->nents + 1;
 		count -= len >> PAGE_SHIFT;
 		if (count == 0) {
 			sg_mark_end(sg);
diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c b/drivers/gpu/drm/i915/i915_gem_gtt.c
index cb43381..c4122cd3 100644
--- a/drivers/gpu/drm/i915/i915_gem_gtt.c
+++ b/drivers/gpu/drm/i915/i915_gem_gtt.c
@@ -28,10 +28,11 @@ int i915_gem_gtt_prepare_pages(struct drm_i915_gem_object *obj,
 			       struct sg_table *pages)
 {
 	do {
-		if (dma_map_sg_attrs(&obj->base.dev->pdev->dev,
-				     pages->sgl, pages->nents,
-				     PCI_DMA_BIDIRECTIONAL,
-				     DMA_ATTR_NO_WARN))
+		pages->nents = dma_map_sg_attrs(&obj->base.dev->pdev->dev,
+						pages->sgl, pages->orig_nents,
+						PCI_DMA_BIDIRECTIONAL,
+						DMA_ATTR_NO_WARN);
+		if (page->nents)
 			return 0;
 
 		/*
@@ -68,7 +69,8 @@ void i915_gem_gtt_finish_pages(struct drm_i915_gem_object *obj,
 		}
 	}
 
-	dma_unmap_sg(kdev, pages->sgl, pages->nents, PCI_DMA_BIDIRECTIONAL);
+	dma_unmap_sg(kdev, pages->sgl, pages->orig_nents,
+		     PCI_DMA_BIDIRECTIONAL);
 }
 
 /**
diff --git a/drivers/gpu/drm/i915/i915_scatterlist.c b/drivers/gpu/drm/i915/i915_scatterlist.c
index cc6b384..05bee13 100644
--- a/drivers/gpu/drm/i915/i915_scatterlist.c
+++ b/drivers/gpu/drm/i915/i915_scatterlist.c
@@ -15,11 +15,11 @@ bool i915_sg_trim(struct sg_table *orig_st)
 	if (orig_st->nents == orig_st->orig_nents)
 		return false;
 
-	if (sg_alloc_table(&new_st, orig_st->nents, GFP_KERNEL | __GFP_NOWARN))
+	if (sg_alloc_table(&new_st, orig_st->orig_nents, GFP_KERNEL | __GFP_NOWARN))
 		return false;
 
 	new_sg = new_st.sgl;
-	for_each_sg(orig_st->sgl, sg, orig_st->nents, i) {
+	for_each_sg(orig_st->sgl, sg, orig_st->orig_nents, i) {
 		sg_set_page(new_sg, sg_page(sg), sg->length, 0);
 		sg_dma_address(new_sg) = sg_dma_address(sg);
 		sg_dma_len(new_sg) = sg_dma_len(sg);
diff --git a/drivers/gpu/drm/i915/selftests/scatterlist.c b/drivers/gpu/drm/i915/selftests/scatterlist.c
index d599186..4456fe5 100644
--- a/drivers/gpu/drm/i915/selftests/scatterlist.c
+++ b/drivers/gpu/drm/i915/selftests/scatterlist.c
@@ -48,9 +48,9 @@ static noinline int expect_pfn_sg(struct pfn_table *pt,
 	unsigned long pfn, n;
 
 	pfn = pt->start;
-	for_each_sg(pt->st.sgl, sg, pt->st.nents, n) {
+	for_each_sg(pt->st.sgl, sg, pt->st.orig_nents, n) {
 		struct page *page = sg_page(sg);
-		unsigned int npages = npages_fn(n, pt->st.nents, rnd);
+		unsigned int npages = npages_fn(n, pt->st.orig_nents, rnd);
 
 		if (page_to_pfn(page) != pfn) {
 			pr_err("%s: %s left pages out of order, expected pfn %lu, found pfn %lu (using for_each_sg)\n",
@@ -86,7 +86,7 @@ static noinline int expect_pfn_sg_page_iter(struct pfn_table *pt,
 	unsigned long pfn;
 
 	pfn = pt->start;
-	for_each_sg_page(pt->st.sgl, &sgiter, pt->st.nents, 0) {
+	for_each_sg_page(pt->st.sgl, &sgiter, pt->st.orig_nents, 0) {
 		struct page *page = sg_page_iter_page(&sgiter);
 
 		if (page != pfn_to_page(pfn)) {
@@ -256,7 +256,7 @@ static int alloc_table(struct pfn_table *pt,
 		pfn += npages;
 	}
 	sg_mark_end(sg);
-	pt->st.nents = n;
+	pt->st.nents = pt->st.orig_nents = n;
 	pt->end = pfn;
 
 	return 0;
-- 
1.9.1


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

WARNING: multiple messages have this Message-ID (diff)
From: Marek Szyprowski <m.szyprowski@samsung.com>
To: dri-devel@lists.freedesktop.org,
	iommu@lists.linux-foundation.org, linaro-mm-sig@lists.linaro.org,
	linux-kernel@vger.kernel.org
Cc: Bartlomiej Zolnierkiewicz <b.zolnierkie@samsung.com>,
	David Airlie <airlied@linux.ie>,
	intel-gfx@lists.freedesktop.org, amd-gfx@lists.freedesktop.org,
	Christoph Hellwig <hch@lst.de>,
	Robin Murphy <robin.murphy@arm.com>,
	linux-arm-kernel@lists.infradead.org,
	Marek Szyprowski <m.szyprowski@samsung.com>
Subject: [RFC 06/17] drm: i915: fix sg_table nents vs. orig_nents misuse
Date: Tue, 28 Apr 2020 15:19:54 +0200	[thread overview]
Message-ID: <20200428132005.21424-7-m.szyprowski@samsung.com> (raw)
In-Reply-To: <20200428132005.21424-1-m.szyprowski@samsung.com>

The Documentation/DMA-API-HOWTO.txt states that dma_map_sg returns the
numer of the created entries in the DMA address space. However the
subsequent calls to dma_sync_sg_for_{device,cpu} and dma_unmap_sg must be
called with the original number of entries passed to dma_map_sg. The
sg_table->nents in turn holds the result of the dma_map_sg call as stated
in include/linux/scatterlist.h. Adapt the code to obey those rules.

Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
---
 drivers/gpu/drm/i915/gem/i915_gem_dmabuf.c       | 13 +++++++------
 drivers/gpu/drm/i915/gem/i915_gem_internal.c     |  4 ++--
 drivers/gpu/drm/i915/gem/i915_gem_region.c       |  4 ++--
 drivers/gpu/drm/i915/gem/i915_gem_shmem.c        |  5 +++--
 drivers/gpu/drm/i915/gem/selftests/huge_pages.c  | 10 +++++-----
 drivers/gpu/drm/i915/gem/selftests/mock_dmabuf.c |  5 +++--
 drivers/gpu/drm/i915/gt/intel_ggtt.c             | 12 ++++++------
 drivers/gpu/drm/i915/i915_gem_gtt.c              | 12 +++++++-----
 drivers/gpu/drm/i915/i915_scatterlist.c          |  4 ++--
 drivers/gpu/drm/i915/selftests/scatterlist.c     |  8 ++++----
 10 files changed, 41 insertions(+), 36 deletions(-)

diff --git a/drivers/gpu/drm/i915/gem/i915_gem_dmabuf.c b/drivers/gpu/drm/i915/gem/i915_gem_dmabuf.c
index 7db5a79..d829852 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_dmabuf.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_dmabuf.c
@@ -36,21 +36,22 @@ static struct sg_table *i915_gem_map_dma_buf(struct dma_buf_attachment *attachme
 		goto err_unpin_pages;
 	}
 
-	ret = sg_alloc_table(st, obj->mm.pages->nents, GFP_KERNEL);
+	ret = sg_alloc_table(st, obj->mm.pages->orig_nents, GFP_KERNEL);
 	if (ret)
 		goto err_free;
 
 	src = obj->mm.pages->sgl;
 	dst = st->sgl;
-	for (i = 0; i < obj->mm.pages->nents; i++) {
+	for (i = 0; i < obj->mm.pages->orig_nents; i++) {
 		sg_set_page(dst, sg_page(src), src->length, 0);
 		dst = sg_next(dst);
 		src = sg_next(src);
 	}
 
-	if (!dma_map_sg_attrs(attachment->dev,
-			      st->sgl, st->nents, dir,
-			      DMA_ATTR_SKIP_CPU_SYNC)) {
+	st->nents = dma_map_sg_attrs(attachment->dev,
+				     st->sgl, st->orig_nents, dir,
+				     DMA_ATTR_SKIP_CPU_SYNC);
+	if (!st->nents) {
 		ret = -ENOMEM;
 		goto err_free_sg;
 	}
@@ -74,7 +75,7 @@ static void i915_gem_unmap_dma_buf(struct dma_buf_attachment *attachment,
 	struct drm_i915_gem_object *obj = dma_buf_to_obj(attachment->dmabuf);
 
 	dma_unmap_sg_attrs(attachment->dev,
-			   sg->sgl, sg->nents, dir,
+			   sg->sgl, sg->orig_nents, dir,
 			   DMA_ATTR_SKIP_CPU_SYNC);
 	sg_free_table(sg);
 	kfree(sg);
diff --git a/drivers/gpu/drm/i915/gem/i915_gem_internal.c b/drivers/gpu/drm/i915/gem/i915_gem_internal.c
index cbbff81..a8ebfdd 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_internal.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_internal.c
@@ -73,7 +73,7 @@ static int i915_gem_object_get_pages_internal(struct drm_i915_gem_object *obj)
 	}
 
 	sg = st->sgl;
-	st->nents = 0;
+	st->nents = st->orig_nents = 0;
 	sg_page_sizes = 0;
 
 	do {
@@ -94,7 +94,7 @@ static int i915_gem_object_get_pages_internal(struct drm_i915_gem_object *obj)
 
 		sg_set_page(sg, page, PAGE_SIZE << order, 0);
 		sg_page_sizes |= PAGE_SIZE << order;
-		st->nents++;
+		st->nents = st->orig_nents = st->nents + 1;
 
 		npages -= 1 << order;
 		if (!npages) {
diff --git a/drivers/gpu/drm/i915/gem/i915_gem_region.c b/drivers/gpu/drm/i915/gem/i915_gem_region.c
index 1515384..58ca560 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_region.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_region.c
@@ -53,7 +53,7 @@
 	GEM_BUG_ON(list_empty(blocks));
 
 	sg = st->sgl;
-	st->nents = 0;
+	st->nents = st->orig_nents = 0;
 	sg_page_sizes = 0;
 	prev_end = (resource_size_t)-1;
 
@@ -78,7 +78,7 @@
 
 			sg->length = block_size;
 
-			st->nents++;
+			st->nents = st->orig_nents = st->nents + 1;
 		} else {
 			sg->length += block_size;
 			sg_dma_len(sg) += block_size;
diff --git a/drivers/gpu/drm/i915/gem/i915_gem_shmem.c b/drivers/gpu/drm/i915/gem/i915_gem_shmem.c
index 5d5d7ee..851a732 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_shmem.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_shmem.c
@@ -80,7 +80,7 @@ static int shmem_get_pages(struct drm_i915_gem_object *obj)
 	noreclaim |= __GFP_NORETRY | __GFP_NOWARN;
 
 	sg = st->sgl;
-	st->nents = 0;
+	st->nents = st->orig_nents = 0;
 	sg_page_sizes = 0;
 	for (i = 0; i < page_count; i++) {
 		const unsigned int shrink[] = {
@@ -140,7 +140,8 @@ static int shmem_get_pages(struct drm_i915_gem_object *obj)
 				sg_page_sizes |= sg->length;
 				sg = sg_next(sg);
 			}
-			st->nents++;
+			st->nents = st->orig_nents = st->nents + 1;
+
 			sg_set_page(sg, page, PAGE_SIZE, 0);
 		} else {
 			sg->length += PAGE_SIZE;
diff --git a/drivers/gpu/drm/i915/gem/selftests/huge_pages.c b/drivers/gpu/drm/i915/gem/selftests/huge_pages.c
index c9988b6..bd141f9 100644
--- a/drivers/gpu/drm/i915/gem/selftests/huge_pages.c
+++ b/drivers/gpu/drm/i915/gem/selftests/huge_pages.c
@@ -76,7 +76,7 @@ static int get_huge_pages(struct drm_i915_gem_object *obj)
 
 	rem = obj->base.size;
 	sg = st->sgl;
-	st->nents = 0;
+	st->nents = st->orig_nents = 0;
 	sg_page_sizes = 0;
 
 	/*
@@ -99,7 +99,7 @@ static int get_huge_pages(struct drm_i915_gem_object *obj)
 
 			sg_set_page(sg, page, page_size, 0);
 			sg_page_sizes |= page_size;
-			st->nents++;
+			st->nents = st->orig_nents = st->nents + 1;
 
 			rem -= page_size;
 			if (!rem) {
@@ -201,7 +201,7 @@ static int fake_get_huge_pages(struct drm_i915_gem_object *obj)
 	/* Use optimal page sized chunks to fill in the sg table */
 	rem = obj->base.size;
 	sg = st->sgl;
-	st->nents = 0;
+	st->nents = st->orig_nents = 0;
 	sg_page_sizes = 0;
 	do {
 		unsigned int page_size = get_largest_page_size(i915, rem);
@@ -217,7 +217,7 @@ static int fake_get_huge_pages(struct drm_i915_gem_object *obj)
 
 		sg_page_sizes |= len;
 
-		st->nents++;
+		st->nents = st->orig_nents = st->nents + 1;
 
 		rem -= len;
 		if (!rem) {
@@ -252,7 +252,7 @@ static int fake_get_huge_pages_single(struct drm_i915_gem_object *obj)
 	}
 
 	sg = st->sgl;
-	st->nents = 1;
+	st->nents = st->orig_nents = 1;
 
 	page_size = get_largest_page_size(i915, obj->base.size);
 	GEM_BUG_ON(!page_size);
diff --git a/drivers/gpu/drm/i915/gem/selftests/mock_dmabuf.c b/drivers/gpu/drm/i915/gem/selftests/mock_dmabuf.c
index debaf7b..5723525 100644
--- a/drivers/gpu/drm/i915/gem/selftests/mock_dmabuf.c
+++ b/drivers/gpu/drm/i915/gem/selftests/mock_dmabuf.c
@@ -28,7 +28,8 @@ static struct sg_table *mock_map_dma_buf(struct dma_buf_attachment *attachment,
 		sg = sg_next(sg);
 	}
 
-	if (!dma_map_sg(attachment->dev, st->sgl, st->nents, dir)) {
+	st->nents = dma_map_sg(attachment->dev, st->sgl, st->orig_nents, dir);
+	if (!st->nents) {
 		err = -ENOMEM;
 		goto err_st;
 	}
@@ -46,7 +47,7 @@ static void mock_unmap_dma_buf(struct dma_buf_attachment *attachment,
 			       struct sg_table *st,
 			       enum dma_data_direction dir)
 {
-	dma_unmap_sg(attachment->dev, st->sgl, st->nents, dir);
+	dma_unmap_sg(attachment->dev, st->sgl, st->orig_nents, dir);
 	sg_free_table(st);
 	kfree(st);
 }
diff --git a/drivers/gpu/drm/i915/gt/intel_ggtt.c b/drivers/gpu/drm/i915/gt/intel_ggtt.c
index 66165b1..9a298bf 100644
--- a/drivers/gpu/drm/i915/gt/intel_ggtt.c
+++ b/drivers/gpu/drm/i915/gt/intel_ggtt.c
@@ -1221,7 +1221,7 @@ void i915_ggtt_resume(struct i915_ggtt *ggtt)
 	for (column = 0; column < width; column++) {
 		src_idx = stride * (height - 1) + column + offset;
 		for (row = 0; row < height; row++) {
-			st->nents++;
+			st->nents = st->orig_nents = st->nents + 1;
 			/*
 			 * We don't need the pages, but need to initialize
 			 * the entries so the sg list can be happily traversed.
@@ -1259,7 +1259,7 @@ void i915_ggtt_resume(struct i915_ggtt *ggtt)
 	if (ret)
 		goto err_sg_alloc;
 
-	st->nents = 0;
+	st->nents = st->orig_nents = 0;
 	sg = st->sgl;
 
 	for (i = 0 ; i < ARRAY_SIZE(rot_info->plane); i++) {
@@ -1306,7 +1306,7 @@ void i915_ggtt_resume(struct i915_ggtt *ggtt)
 
 			length = min(left, length);
 
-			st->nents++;
+			st->nents = st->orig_nents = st->nents + 1;
 
 			sg_set_page(sg, NULL, length, 0);
 			sg_dma_address(sg) = addr;
@@ -1343,7 +1343,7 @@ void i915_ggtt_resume(struct i915_ggtt *ggtt)
 	if (ret)
 		goto err_sg_alloc;
 
-	st->nents = 0;
+	st->nents = st->orig_nents = 0;
 	sg = st->sgl;
 
 	for (i = 0 ; i < ARRAY_SIZE(rem_info->plane); i++) {
@@ -1389,7 +1389,7 @@ void i915_ggtt_resume(struct i915_ggtt *ggtt)
 	GEM_BUG_ON(!iter);
 
 	sg = st->sgl;
-	st->nents = 0;
+	st->nents = st->orig_nents = 0;
 	do {
 		unsigned int len;
 
@@ -1400,7 +1400,7 @@ void i915_ggtt_resume(struct i915_ggtt *ggtt)
 			sg_dma_address(iter) + (offset << PAGE_SHIFT);
 		sg_dma_len(sg) = len;
 
-		st->nents++;
+		st->nents = st->orig_nents = st->nents + 1;
 		count -= len >> PAGE_SHIFT;
 		if (count == 0) {
 			sg_mark_end(sg);
diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c b/drivers/gpu/drm/i915/i915_gem_gtt.c
index cb43381..c4122cd3 100644
--- a/drivers/gpu/drm/i915/i915_gem_gtt.c
+++ b/drivers/gpu/drm/i915/i915_gem_gtt.c
@@ -28,10 +28,11 @@ int i915_gem_gtt_prepare_pages(struct drm_i915_gem_object *obj,
 			       struct sg_table *pages)
 {
 	do {
-		if (dma_map_sg_attrs(&obj->base.dev->pdev->dev,
-				     pages->sgl, pages->nents,
-				     PCI_DMA_BIDIRECTIONAL,
-				     DMA_ATTR_NO_WARN))
+		pages->nents = dma_map_sg_attrs(&obj->base.dev->pdev->dev,
+						pages->sgl, pages->orig_nents,
+						PCI_DMA_BIDIRECTIONAL,
+						DMA_ATTR_NO_WARN);
+		if (page->nents)
 			return 0;
 
 		/*
@@ -68,7 +69,8 @@ void i915_gem_gtt_finish_pages(struct drm_i915_gem_object *obj,
 		}
 	}
 
-	dma_unmap_sg(kdev, pages->sgl, pages->nents, PCI_DMA_BIDIRECTIONAL);
+	dma_unmap_sg(kdev, pages->sgl, pages->orig_nents,
+		     PCI_DMA_BIDIRECTIONAL);
 }
 
 /**
diff --git a/drivers/gpu/drm/i915/i915_scatterlist.c b/drivers/gpu/drm/i915/i915_scatterlist.c
index cc6b384..05bee13 100644
--- a/drivers/gpu/drm/i915/i915_scatterlist.c
+++ b/drivers/gpu/drm/i915/i915_scatterlist.c
@@ -15,11 +15,11 @@ bool i915_sg_trim(struct sg_table *orig_st)
 	if (orig_st->nents == orig_st->orig_nents)
 		return false;
 
-	if (sg_alloc_table(&new_st, orig_st->nents, GFP_KERNEL | __GFP_NOWARN))
+	if (sg_alloc_table(&new_st, orig_st->orig_nents, GFP_KERNEL | __GFP_NOWARN))
 		return false;
 
 	new_sg = new_st.sgl;
-	for_each_sg(orig_st->sgl, sg, orig_st->nents, i) {
+	for_each_sg(orig_st->sgl, sg, orig_st->orig_nents, i) {
 		sg_set_page(new_sg, sg_page(sg), sg->length, 0);
 		sg_dma_address(new_sg) = sg_dma_address(sg);
 		sg_dma_len(new_sg) = sg_dma_len(sg);
diff --git a/drivers/gpu/drm/i915/selftests/scatterlist.c b/drivers/gpu/drm/i915/selftests/scatterlist.c
index d599186..4456fe5 100644
--- a/drivers/gpu/drm/i915/selftests/scatterlist.c
+++ b/drivers/gpu/drm/i915/selftests/scatterlist.c
@@ -48,9 +48,9 @@ static noinline int expect_pfn_sg(struct pfn_table *pt,
 	unsigned long pfn, n;
 
 	pfn = pt->start;
-	for_each_sg(pt->st.sgl, sg, pt->st.nents, n) {
+	for_each_sg(pt->st.sgl, sg, pt->st.orig_nents, n) {
 		struct page *page = sg_page(sg);
-		unsigned int npages = npages_fn(n, pt->st.nents, rnd);
+		unsigned int npages = npages_fn(n, pt->st.orig_nents, rnd);
 
 		if (page_to_pfn(page) != pfn) {
 			pr_err("%s: %s left pages out of order, expected pfn %lu, found pfn %lu (using for_each_sg)\n",
@@ -86,7 +86,7 @@ static noinline int expect_pfn_sg_page_iter(struct pfn_table *pt,
 	unsigned long pfn;
 
 	pfn = pt->start;
-	for_each_sg_page(pt->st.sgl, &sgiter, pt->st.nents, 0) {
+	for_each_sg_page(pt->st.sgl, &sgiter, pt->st.orig_nents, 0) {
 		struct page *page = sg_page_iter_page(&sgiter);
 
 		if (page != pfn_to_page(pfn)) {
@@ -256,7 +256,7 @@ static int alloc_table(struct pfn_table *pt,
 		pfn += npages;
 	}
 	sg_mark_end(sg);
-	pt->st.nents = n;
+	pt->st.nents = pt->st.orig_nents = n;
 	pt->end = pfn;
 
 	return 0;
-- 
1.9.1

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

WARNING: multiple messages have this Message-ID (diff)
From: Marek Szyprowski <m.szyprowski@samsung.com>
To: dri-devel@lists.freedesktop.org,
	iommu@lists.linux-foundation.org, linaro-mm-sig@lists.linaro.org,
	linux-kernel@vger.kernel.org
Cc: Bartlomiej Zolnierkiewicz <b.zolnierkie@samsung.com>,
	David Airlie <airlied@linux.ie>,
	intel-gfx@lists.freedesktop.org, amd-gfx@lists.freedesktop.org,
	Christoph Hellwig <hch@lst.de>,
	Benjamin Gaignard <benjamin.gaignard@linaro.org>,
	Robin Murphy <robin.murphy@arm.com>,
	Sumit Semwal <sumit.semwal@linaro.org>,
	linux-arm-kernel@lists.infradead.org,
	Marek Szyprowski <m.szyprowski@samsung.com>
Subject: [Intel-gfx] [RFC 06/17] drm: i915: fix sg_table nents vs. orig_nents misuse
Date: Tue, 28 Apr 2020 15:19:54 +0200	[thread overview]
Message-ID: <20200428132005.21424-7-m.szyprowski@samsung.com> (raw)
In-Reply-To: <20200428132005.21424-1-m.szyprowski@samsung.com>

The Documentation/DMA-API-HOWTO.txt states that dma_map_sg returns the
numer of the created entries in the DMA address space. However the
subsequent calls to dma_sync_sg_for_{device,cpu} and dma_unmap_sg must be
called with the original number of entries passed to dma_map_sg. The
sg_table->nents in turn holds the result of the dma_map_sg call as stated
in include/linux/scatterlist.h. Adapt the code to obey those rules.

Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
---
 drivers/gpu/drm/i915/gem/i915_gem_dmabuf.c       | 13 +++++++------
 drivers/gpu/drm/i915/gem/i915_gem_internal.c     |  4 ++--
 drivers/gpu/drm/i915/gem/i915_gem_region.c       |  4 ++--
 drivers/gpu/drm/i915/gem/i915_gem_shmem.c        |  5 +++--
 drivers/gpu/drm/i915/gem/selftests/huge_pages.c  | 10 +++++-----
 drivers/gpu/drm/i915/gem/selftests/mock_dmabuf.c |  5 +++--
 drivers/gpu/drm/i915/gt/intel_ggtt.c             | 12 ++++++------
 drivers/gpu/drm/i915/i915_gem_gtt.c              | 12 +++++++-----
 drivers/gpu/drm/i915/i915_scatterlist.c          |  4 ++--
 drivers/gpu/drm/i915/selftests/scatterlist.c     |  8 ++++----
 10 files changed, 41 insertions(+), 36 deletions(-)

diff --git a/drivers/gpu/drm/i915/gem/i915_gem_dmabuf.c b/drivers/gpu/drm/i915/gem/i915_gem_dmabuf.c
index 7db5a79..d829852 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_dmabuf.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_dmabuf.c
@@ -36,21 +36,22 @@ static struct sg_table *i915_gem_map_dma_buf(struct dma_buf_attachment *attachme
 		goto err_unpin_pages;
 	}
 
-	ret = sg_alloc_table(st, obj->mm.pages->nents, GFP_KERNEL);
+	ret = sg_alloc_table(st, obj->mm.pages->orig_nents, GFP_KERNEL);
 	if (ret)
 		goto err_free;
 
 	src = obj->mm.pages->sgl;
 	dst = st->sgl;
-	for (i = 0; i < obj->mm.pages->nents; i++) {
+	for (i = 0; i < obj->mm.pages->orig_nents; i++) {
 		sg_set_page(dst, sg_page(src), src->length, 0);
 		dst = sg_next(dst);
 		src = sg_next(src);
 	}
 
-	if (!dma_map_sg_attrs(attachment->dev,
-			      st->sgl, st->nents, dir,
-			      DMA_ATTR_SKIP_CPU_SYNC)) {
+	st->nents = dma_map_sg_attrs(attachment->dev,
+				     st->sgl, st->orig_nents, dir,
+				     DMA_ATTR_SKIP_CPU_SYNC);
+	if (!st->nents) {
 		ret = -ENOMEM;
 		goto err_free_sg;
 	}
@@ -74,7 +75,7 @@ static void i915_gem_unmap_dma_buf(struct dma_buf_attachment *attachment,
 	struct drm_i915_gem_object *obj = dma_buf_to_obj(attachment->dmabuf);
 
 	dma_unmap_sg_attrs(attachment->dev,
-			   sg->sgl, sg->nents, dir,
+			   sg->sgl, sg->orig_nents, dir,
 			   DMA_ATTR_SKIP_CPU_SYNC);
 	sg_free_table(sg);
 	kfree(sg);
diff --git a/drivers/gpu/drm/i915/gem/i915_gem_internal.c b/drivers/gpu/drm/i915/gem/i915_gem_internal.c
index cbbff81..a8ebfdd 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_internal.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_internal.c
@@ -73,7 +73,7 @@ static int i915_gem_object_get_pages_internal(struct drm_i915_gem_object *obj)
 	}
 
 	sg = st->sgl;
-	st->nents = 0;
+	st->nents = st->orig_nents = 0;
 	sg_page_sizes = 0;
 
 	do {
@@ -94,7 +94,7 @@ static int i915_gem_object_get_pages_internal(struct drm_i915_gem_object *obj)
 
 		sg_set_page(sg, page, PAGE_SIZE << order, 0);
 		sg_page_sizes |= PAGE_SIZE << order;
-		st->nents++;
+		st->nents = st->orig_nents = st->nents + 1;
 
 		npages -= 1 << order;
 		if (!npages) {
diff --git a/drivers/gpu/drm/i915/gem/i915_gem_region.c b/drivers/gpu/drm/i915/gem/i915_gem_region.c
index 1515384..58ca560 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_region.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_region.c
@@ -53,7 +53,7 @@
 	GEM_BUG_ON(list_empty(blocks));
 
 	sg = st->sgl;
-	st->nents = 0;
+	st->nents = st->orig_nents = 0;
 	sg_page_sizes = 0;
 	prev_end = (resource_size_t)-1;
 
@@ -78,7 +78,7 @@
 
 			sg->length = block_size;
 
-			st->nents++;
+			st->nents = st->orig_nents = st->nents + 1;
 		} else {
 			sg->length += block_size;
 			sg_dma_len(sg) += block_size;
diff --git a/drivers/gpu/drm/i915/gem/i915_gem_shmem.c b/drivers/gpu/drm/i915/gem/i915_gem_shmem.c
index 5d5d7ee..851a732 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_shmem.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_shmem.c
@@ -80,7 +80,7 @@ static int shmem_get_pages(struct drm_i915_gem_object *obj)
 	noreclaim |= __GFP_NORETRY | __GFP_NOWARN;
 
 	sg = st->sgl;
-	st->nents = 0;
+	st->nents = st->orig_nents = 0;
 	sg_page_sizes = 0;
 	for (i = 0; i < page_count; i++) {
 		const unsigned int shrink[] = {
@@ -140,7 +140,8 @@ static int shmem_get_pages(struct drm_i915_gem_object *obj)
 				sg_page_sizes |= sg->length;
 				sg = sg_next(sg);
 			}
-			st->nents++;
+			st->nents = st->orig_nents = st->nents + 1;
+
 			sg_set_page(sg, page, PAGE_SIZE, 0);
 		} else {
 			sg->length += PAGE_SIZE;
diff --git a/drivers/gpu/drm/i915/gem/selftests/huge_pages.c b/drivers/gpu/drm/i915/gem/selftests/huge_pages.c
index c9988b6..bd141f9 100644
--- a/drivers/gpu/drm/i915/gem/selftests/huge_pages.c
+++ b/drivers/gpu/drm/i915/gem/selftests/huge_pages.c
@@ -76,7 +76,7 @@ static int get_huge_pages(struct drm_i915_gem_object *obj)
 
 	rem = obj->base.size;
 	sg = st->sgl;
-	st->nents = 0;
+	st->nents = st->orig_nents = 0;
 	sg_page_sizes = 0;
 
 	/*
@@ -99,7 +99,7 @@ static int get_huge_pages(struct drm_i915_gem_object *obj)
 
 			sg_set_page(sg, page, page_size, 0);
 			sg_page_sizes |= page_size;
-			st->nents++;
+			st->nents = st->orig_nents = st->nents + 1;
 
 			rem -= page_size;
 			if (!rem) {
@@ -201,7 +201,7 @@ static int fake_get_huge_pages(struct drm_i915_gem_object *obj)
 	/* Use optimal page sized chunks to fill in the sg table */
 	rem = obj->base.size;
 	sg = st->sgl;
-	st->nents = 0;
+	st->nents = st->orig_nents = 0;
 	sg_page_sizes = 0;
 	do {
 		unsigned int page_size = get_largest_page_size(i915, rem);
@@ -217,7 +217,7 @@ static int fake_get_huge_pages(struct drm_i915_gem_object *obj)
 
 		sg_page_sizes |= len;
 
-		st->nents++;
+		st->nents = st->orig_nents = st->nents + 1;
 
 		rem -= len;
 		if (!rem) {
@@ -252,7 +252,7 @@ static int fake_get_huge_pages_single(struct drm_i915_gem_object *obj)
 	}
 
 	sg = st->sgl;
-	st->nents = 1;
+	st->nents = st->orig_nents = 1;
 
 	page_size = get_largest_page_size(i915, obj->base.size);
 	GEM_BUG_ON(!page_size);
diff --git a/drivers/gpu/drm/i915/gem/selftests/mock_dmabuf.c b/drivers/gpu/drm/i915/gem/selftests/mock_dmabuf.c
index debaf7b..5723525 100644
--- a/drivers/gpu/drm/i915/gem/selftests/mock_dmabuf.c
+++ b/drivers/gpu/drm/i915/gem/selftests/mock_dmabuf.c
@@ -28,7 +28,8 @@ static struct sg_table *mock_map_dma_buf(struct dma_buf_attachment *attachment,
 		sg = sg_next(sg);
 	}
 
-	if (!dma_map_sg(attachment->dev, st->sgl, st->nents, dir)) {
+	st->nents = dma_map_sg(attachment->dev, st->sgl, st->orig_nents, dir);
+	if (!st->nents) {
 		err = -ENOMEM;
 		goto err_st;
 	}
@@ -46,7 +47,7 @@ static void mock_unmap_dma_buf(struct dma_buf_attachment *attachment,
 			       struct sg_table *st,
 			       enum dma_data_direction dir)
 {
-	dma_unmap_sg(attachment->dev, st->sgl, st->nents, dir);
+	dma_unmap_sg(attachment->dev, st->sgl, st->orig_nents, dir);
 	sg_free_table(st);
 	kfree(st);
 }
diff --git a/drivers/gpu/drm/i915/gt/intel_ggtt.c b/drivers/gpu/drm/i915/gt/intel_ggtt.c
index 66165b1..9a298bf 100644
--- a/drivers/gpu/drm/i915/gt/intel_ggtt.c
+++ b/drivers/gpu/drm/i915/gt/intel_ggtt.c
@@ -1221,7 +1221,7 @@ void i915_ggtt_resume(struct i915_ggtt *ggtt)
 	for (column = 0; column < width; column++) {
 		src_idx = stride * (height - 1) + column + offset;
 		for (row = 0; row < height; row++) {
-			st->nents++;
+			st->nents = st->orig_nents = st->nents + 1;
 			/*
 			 * We don't need the pages, but need to initialize
 			 * the entries so the sg list can be happily traversed.
@@ -1259,7 +1259,7 @@ void i915_ggtt_resume(struct i915_ggtt *ggtt)
 	if (ret)
 		goto err_sg_alloc;
 
-	st->nents = 0;
+	st->nents = st->orig_nents = 0;
 	sg = st->sgl;
 
 	for (i = 0 ; i < ARRAY_SIZE(rot_info->plane); i++) {
@@ -1306,7 +1306,7 @@ void i915_ggtt_resume(struct i915_ggtt *ggtt)
 
 			length = min(left, length);
 
-			st->nents++;
+			st->nents = st->orig_nents = st->nents + 1;
 
 			sg_set_page(sg, NULL, length, 0);
 			sg_dma_address(sg) = addr;
@@ -1343,7 +1343,7 @@ void i915_ggtt_resume(struct i915_ggtt *ggtt)
 	if (ret)
 		goto err_sg_alloc;
 
-	st->nents = 0;
+	st->nents = st->orig_nents = 0;
 	sg = st->sgl;
 
 	for (i = 0 ; i < ARRAY_SIZE(rem_info->plane); i++) {
@@ -1389,7 +1389,7 @@ void i915_ggtt_resume(struct i915_ggtt *ggtt)
 	GEM_BUG_ON(!iter);
 
 	sg = st->sgl;
-	st->nents = 0;
+	st->nents = st->orig_nents = 0;
 	do {
 		unsigned int len;
 
@@ -1400,7 +1400,7 @@ void i915_ggtt_resume(struct i915_ggtt *ggtt)
 			sg_dma_address(iter) + (offset << PAGE_SHIFT);
 		sg_dma_len(sg) = len;
 
-		st->nents++;
+		st->nents = st->orig_nents = st->nents + 1;
 		count -= len >> PAGE_SHIFT;
 		if (count == 0) {
 			sg_mark_end(sg);
diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c b/drivers/gpu/drm/i915/i915_gem_gtt.c
index cb43381..c4122cd3 100644
--- a/drivers/gpu/drm/i915/i915_gem_gtt.c
+++ b/drivers/gpu/drm/i915/i915_gem_gtt.c
@@ -28,10 +28,11 @@ int i915_gem_gtt_prepare_pages(struct drm_i915_gem_object *obj,
 			       struct sg_table *pages)
 {
 	do {
-		if (dma_map_sg_attrs(&obj->base.dev->pdev->dev,
-				     pages->sgl, pages->nents,
-				     PCI_DMA_BIDIRECTIONAL,
-				     DMA_ATTR_NO_WARN))
+		pages->nents = dma_map_sg_attrs(&obj->base.dev->pdev->dev,
+						pages->sgl, pages->orig_nents,
+						PCI_DMA_BIDIRECTIONAL,
+						DMA_ATTR_NO_WARN);
+		if (page->nents)
 			return 0;
 
 		/*
@@ -68,7 +69,8 @@ void i915_gem_gtt_finish_pages(struct drm_i915_gem_object *obj,
 		}
 	}
 
-	dma_unmap_sg(kdev, pages->sgl, pages->nents, PCI_DMA_BIDIRECTIONAL);
+	dma_unmap_sg(kdev, pages->sgl, pages->orig_nents,
+		     PCI_DMA_BIDIRECTIONAL);
 }
 
 /**
diff --git a/drivers/gpu/drm/i915/i915_scatterlist.c b/drivers/gpu/drm/i915/i915_scatterlist.c
index cc6b384..05bee13 100644
--- a/drivers/gpu/drm/i915/i915_scatterlist.c
+++ b/drivers/gpu/drm/i915/i915_scatterlist.c
@@ -15,11 +15,11 @@ bool i915_sg_trim(struct sg_table *orig_st)
 	if (orig_st->nents == orig_st->orig_nents)
 		return false;
 
-	if (sg_alloc_table(&new_st, orig_st->nents, GFP_KERNEL | __GFP_NOWARN))
+	if (sg_alloc_table(&new_st, orig_st->orig_nents, GFP_KERNEL | __GFP_NOWARN))
 		return false;
 
 	new_sg = new_st.sgl;
-	for_each_sg(orig_st->sgl, sg, orig_st->nents, i) {
+	for_each_sg(orig_st->sgl, sg, orig_st->orig_nents, i) {
 		sg_set_page(new_sg, sg_page(sg), sg->length, 0);
 		sg_dma_address(new_sg) = sg_dma_address(sg);
 		sg_dma_len(new_sg) = sg_dma_len(sg);
diff --git a/drivers/gpu/drm/i915/selftests/scatterlist.c b/drivers/gpu/drm/i915/selftests/scatterlist.c
index d599186..4456fe5 100644
--- a/drivers/gpu/drm/i915/selftests/scatterlist.c
+++ b/drivers/gpu/drm/i915/selftests/scatterlist.c
@@ -48,9 +48,9 @@ static noinline int expect_pfn_sg(struct pfn_table *pt,
 	unsigned long pfn, n;
 
 	pfn = pt->start;
-	for_each_sg(pt->st.sgl, sg, pt->st.nents, n) {
+	for_each_sg(pt->st.sgl, sg, pt->st.orig_nents, n) {
 		struct page *page = sg_page(sg);
-		unsigned int npages = npages_fn(n, pt->st.nents, rnd);
+		unsigned int npages = npages_fn(n, pt->st.orig_nents, rnd);
 
 		if (page_to_pfn(page) != pfn) {
 			pr_err("%s: %s left pages out of order, expected pfn %lu, found pfn %lu (using for_each_sg)\n",
@@ -86,7 +86,7 @@ static noinline int expect_pfn_sg_page_iter(struct pfn_table *pt,
 	unsigned long pfn;
 
 	pfn = pt->start;
-	for_each_sg_page(pt->st.sgl, &sgiter, pt->st.nents, 0) {
+	for_each_sg_page(pt->st.sgl, &sgiter, pt->st.orig_nents, 0) {
 		struct page *page = sg_page_iter_page(&sgiter);
 
 		if (page != pfn_to_page(pfn)) {
@@ -256,7 +256,7 @@ static int alloc_table(struct pfn_table *pt,
 		pfn += npages;
 	}
 	sg_mark_end(sg);
-	pt->st.nents = n;
+	pt->st.nents = pt->st.orig_nents = n;
 	pt->end = pfn;
 
 	return 0;
-- 
1.9.1

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

WARNING: multiple messages have this Message-ID (diff)
From: Marek Szyprowski <m.szyprowski@samsung.com>
To: dri-devel@lists.freedesktop.org,
	iommu@lists.linux-foundation.org, linaro-mm-sig@lists.linaro.org,
	linux-kernel@vger.kernel.org
Cc: Daniel Vetter <daniel@ffwll.ch>,
	Bartlomiej Zolnierkiewicz <b.zolnierkie@samsung.com>,
	David Airlie <airlied@linux.ie>,
	intel-gfx@lists.freedesktop.org, amd-gfx@lists.freedesktop.org,
	Christoph Hellwig <hch@lst.de>,
	Benjamin Gaignard <benjamin.gaignard@linaro.org>,
	Robin Murphy <robin.murphy@arm.com>,
	Sumit Semwal <sumit.semwal@linaro.org>,
	linux-arm-kernel@lists.infradead.org,
	Marek Szyprowski <m.szyprowski@samsung.com>
Subject: [RFC 06/17] drm: i915: fix sg_table nents vs. orig_nents misuse
Date: Tue, 28 Apr 2020 15:19:54 +0200	[thread overview]
Message-ID: <20200428132005.21424-7-m.szyprowski@samsung.com> (raw)
In-Reply-To: <20200428132005.21424-1-m.szyprowski@samsung.com>

The Documentation/DMA-API-HOWTO.txt states that dma_map_sg returns the
numer of the created entries in the DMA address space. However the
subsequent calls to dma_sync_sg_for_{device,cpu} and dma_unmap_sg must be
called with the original number of entries passed to dma_map_sg. The
sg_table->nents in turn holds the result of the dma_map_sg call as stated
in include/linux/scatterlist.h. Adapt the code to obey those rules.

Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
---
 drivers/gpu/drm/i915/gem/i915_gem_dmabuf.c       | 13 +++++++------
 drivers/gpu/drm/i915/gem/i915_gem_internal.c     |  4 ++--
 drivers/gpu/drm/i915/gem/i915_gem_region.c       |  4 ++--
 drivers/gpu/drm/i915/gem/i915_gem_shmem.c        |  5 +++--
 drivers/gpu/drm/i915/gem/selftests/huge_pages.c  | 10 +++++-----
 drivers/gpu/drm/i915/gem/selftests/mock_dmabuf.c |  5 +++--
 drivers/gpu/drm/i915/gt/intel_ggtt.c             | 12 ++++++------
 drivers/gpu/drm/i915/i915_gem_gtt.c              | 12 +++++++-----
 drivers/gpu/drm/i915/i915_scatterlist.c          |  4 ++--
 drivers/gpu/drm/i915/selftests/scatterlist.c     |  8 ++++----
 10 files changed, 41 insertions(+), 36 deletions(-)

diff --git a/drivers/gpu/drm/i915/gem/i915_gem_dmabuf.c b/drivers/gpu/drm/i915/gem/i915_gem_dmabuf.c
index 7db5a79..d829852 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_dmabuf.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_dmabuf.c
@@ -36,21 +36,22 @@ static struct sg_table *i915_gem_map_dma_buf(struct dma_buf_attachment *attachme
 		goto err_unpin_pages;
 	}
 
-	ret = sg_alloc_table(st, obj->mm.pages->nents, GFP_KERNEL);
+	ret = sg_alloc_table(st, obj->mm.pages->orig_nents, GFP_KERNEL);
 	if (ret)
 		goto err_free;
 
 	src = obj->mm.pages->sgl;
 	dst = st->sgl;
-	for (i = 0; i < obj->mm.pages->nents; i++) {
+	for (i = 0; i < obj->mm.pages->orig_nents; i++) {
 		sg_set_page(dst, sg_page(src), src->length, 0);
 		dst = sg_next(dst);
 		src = sg_next(src);
 	}
 
-	if (!dma_map_sg_attrs(attachment->dev,
-			      st->sgl, st->nents, dir,
-			      DMA_ATTR_SKIP_CPU_SYNC)) {
+	st->nents = dma_map_sg_attrs(attachment->dev,
+				     st->sgl, st->orig_nents, dir,
+				     DMA_ATTR_SKIP_CPU_SYNC);
+	if (!st->nents) {
 		ret = -ENOMEM;
 		goto err_free_sg;
 	}
@@ -74,7 +75,7 @@ static void i915_gem_unmap_dma_buf(struct dma_buf_attachment *attachment,
 	struct drm_i915_gem_object *obj = dma_buf_to_obj(attachment->dmabuf);
 
 	dma_unmap_sg_attrs(attachment->dev,
-			   sg->sgl, sg->nents, dir,
+			   sg->sgl, sg->orig_nents, dir,
 			   DMA_ATTR_SKIP_CPU_SYNC);
 	sg_free_table(sg);
 	kfree(sg);
diff --git a/drivers/gpu/drm/i915/gem/i915_gem_internal.c b/drivers/gpu/drm/i915/gem/i915_gem_internal.c
index cbbff81..a8ebfdd 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_internal.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_internal.c
@@ -73,7 +73,7 @@ static int i915_gem_object_get_pages_internal(struct drm_i915_gem_object *obj)
 	}
 
 	sg = st->sgl;
-	st->nents = 0;
+	st->nents = st->orig_nents = 0;
 	sg_page_sizes = 0;
 
 	do {
@@ -94,7 +94,7 @@ static int i915_gem_object_get_pages_internal(struct drm_i915_gem_object *obj)
 
 		sg_set_page(sg, page, PAGE_SIZE << order, 0);
 		sg_page_sizes |= PAGE_SIZE << order;
-		st->nents++;
+		st->nents = st->orig_nents = st->nents + 1;
 
 		npages -= 1 << order;
 		if (!npages) {
diff --git a/drivers/gpu/drm/i915/gem/i915_gem_region.c b/drivers/gpu/drm/i915/gem/i915_gem_region.c
index 1515384..58ca560 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_region.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_region.c
@@ -53,7 +53,7 @@
 	GEM_BUG_ON(list_empty(blocks));
 
 	sg = st->sgl;
-	st->nents = 0;
+	st->nents = st->orig_nents = 0;
 	sg_page_sizes = 0;
 	prev_end = (resource_size_t)-1;
 
@@ -78,7 +78,7 @@
 
 			sg->length = block_size;
 
-			st->nents++;
+			st->nents = st->orig_nents = st->nents + 1;
 		} else {
 			sg->length += block_size;
 			sg_dma_len(sg) += block_size;
diff --git a/drivers/gpu/drm/i915/gem/i915_gem_shmem.c b/drivers/gpu/drm/i915/gem/i915_gem_shmem.c
index 5d5d7ee..851a732 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_shmem.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_shmem.c
@@ -80,7 +80,7 @@ static int shmem_get_pages(struct drm_i915_gem_object *obj)
 	noreclaim |= __GFP_NORETRY | __GFP_NOWARN;
 
 	sg = st->sgl;
-	st->nents = 0;
+	st->nents = st->orig_nents = 0;
 	sg_page_sizes = 0;
 	for (i = 0; i < page_count; i++) {
 		const unsigned int shrink[] = {
@@ -140,7 +140,8 @@ static int shmem_get_pages(struct drm_i915_gem_object *obj)
 				sg_page_sizes |= sg->length;
 				sg = sg_next(sg);
 			}
-			st->nents++;
+			st->nents = st->orig_nents = st->nents + 1;
+
 			sg_set_page(sg, page, PAGE_SIZE, 0);
 		} else {
 			sg->length += PAGE_SIZE;
diff --git a/drivers/gpu/drm/i915/gem/selftests/huge_pages.c b/drivers/gpu/drm/i915/gem/selftests/huge_pages.c
index c9988b6..bd141f9 100644
--- a/drivers/gpu/drm/i915/gem/selftests/huge_pages.c
+++ b/drivers/gpu/drm/i915/gem/selftests/huge_pages.c
@@ -76,7 +76,7 @@ static int get_huge_pages(struct drm_i915_gem_object *obj)
 
 	rem = obj->base.size;
 	sg = st->sgl;
-	st->nents = 0;
+	st->nents = st->orig_nents = 0;
 	sg_page_sizes = 0;
 
 	/*
@@ -99,7 +99,7 @@ static int get_huge_pages(struct drm_i915_gem_object *obj)
 
 			sg_set_page(sg, page, page_size, 0);
 			sg_page_sizes |= page_size;
-			st->nents++;
+			st->nents = st->orig_nents = st->nents + 1;
 
 			rem -= page_size;
 			if (!rem) {
@@ -201,7 +201,7 @@ static int fake_get_huge_pages(struct drm_i915_gem_object *obj)
 	/* Use optimal page sized chunks to fill in the sg table */
 	rem = obj->base.size;
 	sg = st->sgl;
-	st->nents = 0;
+	st->nents = st->orig_nents = 0;
 	sg_page_sizes = 0;
 	do {
 		unsigned int page_size = get_largest_page_size(i915, rem);
@@ -217,7 +217,7 @@ static int fake_get_huge_pages(struct drm_i915_gem_object *obj)
 
 		sg_page_sizes |= len;
 
-		st->nents++;
+		st->nents = st->orig_nents = st->nents + 1;
 
 		rem -= len;
 		if (!rem) {
@@ -252,7 +252,7 @@ static int fake_get_huge_pages_single(struct drm_i915_gem_object *obj)
 	}
 
 	sg = st->sgl;
-	st->nents = 1;
+	st->nents = st->orig_nents = 1;
 
 	page_size = get_largest_page_size(i915, obj->base.size);
 	GEM_BUG_ON(!page_size);
diff --git a/drivers/gpu/drm/i915/gem/selftests/mock_dmabuf.c b/drivers/gpu/drm/i915/gem/selftests/mock_dmabuf.c
index debaf7b..5723525 100644
--- a/drivers/gpu/drm/i915/gem/selftests/mock_dmabuf.c
+++ b/drivers/gpu/drm/i915/gem/selftests/mock_dmabuf.c
@@ -28,7 +28,8 @@ static struct sg_table *mock_map_dma_buf(struct dma_buf_attachment *attachment,
 		sg = sg_next(sg);
 	}
 
-	if (!dma_map_sg(attachment->dev, st->sgl, st->nents, dir)) {
+	st->nents = dma_map_sg(attachment->dev, st->sgl, st->orig_nents, dir);
+	if (!st->nents) {
 		err = -ENOMEM;
 		goto err_st;
 	}
@@ -46,7 +47,7 @@ static void mock_unmap_dma_buf(struct dma_buf_attachment *attachment,
 			       struct sg_table *st,
 			       enum dma_data_direction dir)
 {
-	dma_unmap_sg(attachment->dev, st->sgl, st->nents, dir);
+	dma_unmap_sg(attachment->dev, st->sgl, st->orig_nents, dir);
 	sg_free_table(st);
 	kfree(st);
 }
diff --git a/drivers/gpu/drm/i915/gt/intel_ggtt.c b/drivers/gpu/drm/i915/gt/intel_ggtt.c
index 66165b1..9a298bf 100644
--- a/drivers/gpu/drm/i915/gt/intel_ggtt.c
+++ b/drivers/gpu/drm/i915/gt/intel_ggtt.c
@@ -1221,7 +1221,7 @@ void i915_ggtt_resume(struct i915_ggtt *ggtt)
 	for (column = 0; column < width; column++) {
 		src_idx = stride * (height - 1) + column + offset;
 		for (row = 0; row < height; row++) {
-			st->nents++;
+			st->nents = st->orig_nents = st->nents + 1;
 			/*
 			 * We don't need the pages, but need to initialize
 			 * the entries so the sg list can be happily traversed.
@@ -1259,7 +1259,7 @@ void i915_ggtt_resume(struct i915_ggtt *ggtt)
 	if (ret)
 		goto err_sg_alloc;
 
-	st->nents = 0;
+	st->nents = st->orig_nents = 0;
 	sg = st->sgl;
 
 	for (i = 0 ; i < ARRAY_SIZE(rot_info->plane); i++) {
@@ -1306,7 +1306,7 @@ void i915_ggtt_resume(struct i915_ggtt *ggtt)
 
 			length = min(left, length);
 
-			st->nents++;
+			st->nents = st->orig_nents = st->nents + 1;
 
 			sg_set_page(sg, NULL, length, 0);
 			sg_dma_address(sg) = addr;
@@ -1343,7 +1343,7 @@ void i915_ggtt_resume(struct i915_ggtt *ggtt)
 	if (ret)
 		goto err_sg_alloc;
 
-	st->nents = 0;
+	st->nents = st->orig_nents = 0;
 	sg = st->sgl;
 
 	for (i = 0 ; i < ARRAY_SIZE(rem_info->plane); i++) {
@@ -1389,7 +1389,7 @@ void i915_ggtt_resume(struct i915_ggtt *ggtt)
 	GEM_BUG_ON(!iter);
 
 	sg = st->sgl;
-	st->nents = 0;
+	st->nents = st->orig_nents = 0;
 	do {
 		unsigned int len;
 
@@ -1400,7 +1400,7 @@ void i915_ggtt_resume(struct i915_ggtt *ggtt)
 			sg_dma_address(iter) + (offset << PAGE_SHIFT);
 		sg_dma_len(sg) = len;
 
-		st->nents++;
+		st->nents = st->orig_nents = st->nents + 1;
 		count -= len >> PAGE_SHIFT;
 		if (count == 0) {
 			sg_mark_end(sg);
diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c b/drivers/gpu/drm/i915/i915_gem_gtt.c
index cb43381..c4122cd3 100644
--- a/drivers/gpu/drm/i915/i915_gem_gtt.c
+++ b/drivers/gpu/drm/i915/i915_gem_gtt.c
@@ -28,10 +28,11 @@ int i915_gem_gtt_prepare_pages(struct drm_i915_gem_object *obj,
 			       struct sg_table *pages)
 {
 	do {
-		if (dma_map_sg_attrs(&obj->base.dev->pdev->dev,
-				     pages->sgl, pages->nents,
-				     PCI_DMA_BIDIRECTIONAL,
-				     DMA_ATTR_NO_WARN))
+		pages->nents = dma_map_sg_attrs(&obj->base.dev->pdev->dev,
+						pages->sgl, pages->orig_nents,
+						PCI_DMA_BIDIRECTIONAL,
+						DMA_ATTR_NO_WARN);
+		if (page->nents)
 			return 0;
 
 		/*
@@ -68,7 +69,8 @@ void i915_gem_gtt_finish_pages(struct drm_i915_gem_object *obj,
 		}
 	}
 
-	dma_unmap_sg(kdev, pages->sgl, pages->nents, PCI_DMA_BIDIRECTIONAL);
+	dma_unmap_sg(kdev, pages->sgl, pages->orig_nents,
+		     PCI_DMA_BIDIRECTIONAL);
 }
 
 /**
diff --git a/drivers/gpu/drm/i915/i915_scatterlist.c b/drivers/gpu/drm/i915/i915_scatterlist.c
index cc6b384..05bee13 100644
--- a/drivers/gpu/drm/i915/i915_scatterlist.c
+++ b/drivers/gpu/drm/i915/i915_scatterlist.c
@@ -15,11 +15,11 @@ bool i915_sg_trim(struct sg_table *orig_st)
 	if (orig_st->nents == orig_st->orig_nents)
 		return false;
 
-	if (sg_alloc_table(&new_st, orig_st->nents, GFP_KERNEL | __GFP_NOWARN))
+	if (sg_alloc_table(&new_st, orig_st->orig_nents, GFP_KERNEL | __GFP_NOWARN))
 		return false;
 
 	new_sg = new_st.sgl;
-	for_each_sg(orig_st->sgl, sg, orig_st->nents, i) {
+	for_each_sg(orig_st->sgl, sg, orig_st->orig_nents, i) {
 		sg_set_page(new_sg, sg_page(sg), sg->length, 0);
 		sg_dma_address(new_sg) = sg_dma_address(sg);
 		sg_dma_len(new_sg) = sg_dma_len(sg);
diff --git a/drivers/gpu/drm/i915/selftests/scatterlist.c b/drivers/gpu/drm/i915/selftests/scatterlist.c
index d599186..4456fe5 100644
--- a/drivers/gpu/drm/i915/selftests/scatterlist.c
+++ b/drivers/gpu/drm/i915/selftests/scatterlist.c
@@ -48,9 +48,9 @@ static noinline int expect_pfn_sg(struct pfn_table *pt,
 	unsigned long pfn, n;
 
 	pfn = pt->start;
-	for_each_sg(pt->st.sgl, sg, pt->st.nents, n) {
+	for_each_sg(pt->st.sgl, sg, pt->st.orig_nents, n) {
 		struct page *page = sg_page(sg);
-		unsigned int npages = npages_fn(n, pt->st.nents, rnd);
+		unsigned int npages = npages_fn(n, pt->st.orig_nents, rnd);
 
 		if (page_to_pfn(page) != pfn) {
 			pr_err("%s: %s left pages out of order, expected pfn %lu, found pfn %lu (using for_each_sg)\n",
@@ -86,7 +86,7 @@ static noinline int expect_pfn_sg_page_iter(struct pfn_table *pt,
 	unsigned long pfn;
 
 	pfn = pt->start;
-	for_each_sg_page(pt->st.sgl, &sgiter, pt->st.nents, 0) {
+	for_each_sg_page(pt->st.sgl, &sgiter, pt->st.orig_nents, 0) {
 		struct page *page = sg_page_iter_page(&sgiter);
 
 		if (page != pfn_to_page(pfn)) {
@@ -256,7 +256,7 @@ static int alloc_table(struct pfn_table *pt,
 		pfn += npages;
 	}
 	sg_mark_end(sg);
-	pt->st.nents = n;
+	pt->st.nents = pt->st.orig_nents = n;
 	pt->end = pfn;
 
 	return 0;
-- 
1.9.1

_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

  parent reply	other threads:[~2020-04-28 13:20 UTC|newest]

Thread overview: 152+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
     [not found] <CGME20200428132022eucas1p2aa4716cbaca61c432ee8028be15fef7a@eucas1p2.samsung.com>
2020-04-28 13:19 ` [RFC 00/17] DRM: fix struct sg_table nents vs. orig_nents misuse Marek Szyprowski
2020-04-28 13:19   ` Marek Szyprowski
2020-04-28 13:19   ` [Intel-gfx] " Marek Szyprowski
2020-04-28 13:19   ` Marek Szyprowski
2020-04-28 13:19   ` Marek Szyprowski
2020-04-28 13:19   ` Marek Szyprowski
     [not found]   ` <CGME20200428132022eucas1p22f64f56bb61cf6ee73892a9fc9ce7e09@eucas1p2.samsung.com>
2020-04-28 13:19     ` [RFC 01/17] drm: core: fix " Marek Szyprowski
2020-04-28 13:19       ` Marek Szyprowski
2020-04-28 13:19       ` [Intel-gfx] " Marek Szyprowski
2020-04-28 13:19       ` Marek Szyprowski
2020-04-28 13:19       ` Marek Szyprowski
2020-04-28 13:19       ` Marek Szyprowski
     [not found]   ` <CGME20200428132023eucas1p2a1993145eef91506698aa8c9750a7e43@eucas1p2.samsung.com>
2020-04-28 13:19     ` [RFC 02/17] drm: amdgpu: " Marek Szyprowski
2020-04-28 13:19       ` Marek Szyprowski
2020-04-28 13:19       ` [Intel-gfx] " Marek Szyprowski
2020-04-28 13:19       ` Marek Szyprowski
2020-04-28 13:19       ` Marek Szyprowski
2020-04-28 13:19       ` Marek Szyprowski
2020-04-28 15:14       ` Christian König
2020-04-28 15:14         ` Christian König
2020-04-28 15:14         ` [Intel-gfx] " Christian König
2020-04-28 15:14         ` Christian König
2020-04-28 15:14         ` Christian König
2020-04-28 15:14         ` Christian König
     [not found]   ` <CGME20200428132023eucas1p1a894986ab95ac3208c19878c6a04c0e1@eucas1p1.samsung.com>
2020-04-28 13:19     ` [RFC 03/17] drm: armada: " Marek Szyprowski
2020-04-28 13:19       ` Marek Szyprowski
2020-04-28 13:19       ` [Intel-gfx] " Marek Szyprowski
2020-04-28 13:19       ` Marek Szyprowski
2020-04-28 13:19       ` Marek Szyprowski
2020-04-28 13:19       ` Marek Szyprowski
     [not found]   ` <CGME20200428132024eucas1p1c51178774db6fb4cab748522c86646cd@eucas1p1.samsung.com>
2020-04-28 13:19     ` [RFC 04/17] drm: etnaviv: " Marek Szyprowski
2020-04-28 13:19       ` Marek Szyprowski
2020-04-28 13:19       ` [Intel-gfx] " Marek Szyprowski
2020-04-28 13:19       ` Marek Szyprowski
2020-04-28 13:19       ` Marek Szyprowski
2020-04-28 13:19       ` Marek Szyprowski
     [not found]   ` <CGME20200428132025eucas1p15cf78bdedef6eebc477c7e8429a6f971@eucas1p1.samsung.com>
2020-04-28 13:19     ` [RFC 05/17] drm: exynos: " Marek Szyprowski
2020-04-28 13:19       ` Marek Szyprowski
2020-04-28 13:19       ` [Intel-gfx] " Marek Szyprowski
2020-04-28 13:19       ` Marek Szyprowski
2020-04-28 13:19       ` Marek Szyprowski
2020-04-28 13:19       ` Marek Szyprowski
2020-04-28 21:59       ` kbuild test robot
     [not found]   ` <CGME20200428132025eucas1p21580e634500a3e85564551cddf168b4a@eucas1p2.samsung.com>
2020-04-28 13:19     ` Marek Szyprowski [this message]
2020-04-28 13:19       ` [RFC 06/17] drm: i915: " Marek Szyprowski
2020-04-28 13:19       ` [Intel-gfx] " Marek Szyprowski
2020-04-28 13:19       ` Marek Szyprowski
2020-04-28 13:19       ` Marek Szyprowski
2020-04-28 13:19       ` Marek Szyprowski
2020-04-28 14:27       ` [Intel-gfx] " Tvrtko Ursulin
2020-04-28 14:27         ` Tvrtko Ursulin
2020-04-28 14:27         ` Tvrtko Ursulin
2020-04-28 14:27         ` Tvrtko Ursulin
2020-04-28 14:27         ` Tvrtko Ursulin
2020-04-28 14:27         ` Tvrtko Ursulin
2020-04-30 14:17         ` Marek Szyprowski
2020-04-30 14:17           ` Marek Szyprowski
2020-04-30 14:17           ` Marek Szyprowski
2020-04-30 14:17           ` Marek Szyprowski
2020-04-30 14:17           ` Marek Szyprowski
2020-04-30 14:17           ` Marek Szyprowski
2020-04-28 23:04       ` kbuild test robot
2020-04-29  3:21       ` kbuild test robot
     [not found]   ` <CGME20200428132026eucas1p27c64540e53f328d0bb7bf9dae2ccb98d@eucas1p2.samsung.com>
2020-04-28 13:19     ` [RFC 07/17] drm: lima: " Marek Szyprowski
2020-04-28 13:19       ` Marek Szyprowski
2020-04-28 13:19       ` [Intel-gfx] " Marek Szyprowski
2020-04-28 13:19       ` Marek Szyprowski
2020-04-28 13:19       ` Marek Szyprowski
2020-04-28 13:19       ` Marek Szyprowski
     [not found]   ` <CGME20200428132027eucas1p2fed88e94fecf1ef12b312ba80a78bc00@eucas1p2.samsung.com>
2020-04-28 13:19     ` [RFC 08/17] drm: msm: " Marek Szyprowski
2020-04-28 13:19       ` Marek Szyprowski
2020-04-28 13:19       ` [Intel-gfx] " Marek Szyprowski
2020-04-28 13:19       ` Marek Szyprowski
2020-04-28 13:19       ` Marek Szyprowski
2020-04-28 13:19       ` Marek Szyprowski
     [not found]   ` <CGME20200428132027eucas1p1a045e89a0058ccff3ea94d1da2236af7@eucas1p1.samsung.com>
2020-04-28 13:19     ` [RFC 09/17] drm: panfrost: " Marek Szyprowski
2020-04-28 13:19       ` Marek Szyprowski
2020-04-28 13:19       ` [Intel-gfx] " Marek Szyprowski
2020-04-28 13:19       ` Marek Szyprowski
2020-04-28 13:19       ` Marek Szyprowski
2020-04-28 13:19       ` Marek Szyprowski
     [not found]   ` <CGME20200428132028eucas1p155a84ab14c6a6820b4c8240f01e98905@eucas1p1.samsung.com>
2020-04-28 13:19     ` [RFC 10/17] drm: radeon: " Marek Szyprowski
2020-04-28 13:19       ` Marek Szyprowski
2020-04-28 13:19       ` [Intel-gfx] " Marek Szyprowski
2020-04-28 13:19       ` Marek Szyprowski
2020-04-28 13:19       ` Marek Szyprowski
2020-04-28 13:19       ` Marek Szyprowski
2020-04-28 15:15       ` Christian König
2020-04-28 15:15         ` Christian König
2020-04-28 15:15         ` [Intel-gfx] " Christian König
2020-04-28 15:15         ` Christian König
2020-04-28 15:15         ` Christian König
2020-04-28 15:15         ` Christian König
     [not found]   ` <CGME20200428132028eucas1p2310cd19b879962d5241604dd13909255@eucas1p2.samsung.com>
2020-04-28 13:19     ` [RFC 11/17] drm: rockchip: " Marek Szyprowski
2020-04-28 13:19       ` Marek Szyprowski
2020-04-28 13:19       ` [Intel-gfx] " Marek Szyprowski
2020-04-28 13:19       ` Marek Szyprowski
2020-04-28 13:19       ` Marek Szyprowski
2020-04-28 13:19       ` Marek Szyprowski
     [not found]   ` <CGME20200428132029eucas1p2433959853ef384ef783cbe9a1e45fde3@eucas1p2.samsung.com>
2020-04-28 13:20     ` [RFC 12/17] drm: tegra: " Marek Szyprowski
2020-04-28 13:20       ` Marek Szyprowski
2020-04-28 13:20       ` [Intel-gfx] " Marek Szyprowski
2020-04-28 13:20       ` Marek Szyprowski
2020-04-28 13:20       ` Marek Szyprowski
2020-04-28 13:20       ` Marek Szyprowski
     [not found]   ` <CGME20200428132030eucas1p17d907110da4cf2a12651cc52ba7eaad6@eucas1p1.samsung.com>
2020-04-28 13:20     ` [RFC 13/17] drm: virtio: " Marek Szyprowski
2020-04-28 13:20       ` Marek Szyprowski
2020-04-28 13:20       ` [Intel-gfx] " Marek Szyprowski
2020-04-28 13:20       ` Marek Szyprowski
2020-04-28 13:20       ` Marek Szyprowski
2020-04-28 13:20       ` Marek Szyprowski
     [not found]   ` <CGME20200428132030eucas1p11f977e77050b5e76f580255096bb94bf@eucas1p1.samsung.com>
2020-04-28 13:20     ` [RFC 14/17] drm: vmwgfx: " Marek Szyprowski
2020-04-28 13:20       ` Marek Szyprowski
2020-04-28 13:20       ` [Intel-gfx] " Marek Szyprowski
2020-04-28 13:20       ` Marek Szyprowski
2020-04-28 13:20       ` Marek Szyprowski
2020-04-28 13:20       ` Marek Szyprowski
     [not found]   ` <CGME20200428132031eucas1p1e7a72bf0de5acea2af652cd8337a8ed5@eucas1p1.samsung.com>
2020-04-28 13:20     ` [RFC 15/17] drm: xen: " Marek Szyprowski
2020-04-28 13:20       ` Marek Szyprowski
2020-04-28 13:20       ` [Intel-gfx] " Marek Szyprowski
2020-04-28 13:20       ` Marek Szyprowski
2020-04-28 13:20       ` Marek Szyprowski
2020-04-28 13:20       ` Marek Szyprowski
     [not found]   ` <CGME20200428132031eucas1p25bf6d0d1f24a69cc3692b2001ac0ebd1@eucas1p2.samsung.com>
2020-04-28 13:20     ` [RFC 16/17] drm: host1x: " Marek Szyprowski
2020-04-28 13:20       ` Marek Szyprowski
2020-04-28 13:20       ` [Intel-gfx] " Marek Szyprowski
2020-04-28 13:20       ` Marek Szyprowski
2020-04-28 13:20       ` Marek Szyprowski
2020-04-28 13:20       ` Marek Szyprowski
     [not found]   ` <CGME20200428132032eucas1p17c2b93daf91c95c41650e75b251d525c@eucas1p1.samsung.com>
2020-04-28 13:20     ` [RFC 17/17] dmabuf: " Marek Szyprowski
2020-04-28 13:20       ` Marek Szyprowski
2020-04-28 13:20       ` [Intel-gfx] " Marek Szyprowski
2020-04-28 13:20       ` Marek Szyprowski
2020-04-28 13:20       ` Marek Szyprowski
2020-04-28 13:20       ` Marek Szyprowski
2020-04-28 14:02   ` [RFC 00/17] DRM: fix struct " Christoph Hellwig
2020-04-28 14:02     ` Christoph Hellwig
2020-04-28 14:02     ` [Intel-gfx] " Christoph Hellwig
2020-04-28 14:02     ` Christoph Hellwig
2020-04-28 14:02     ` Christoph Hellwig
2020-04-28 15:32     ` Daniel Vetter
2020-04-28 15:32       ` Daniel Vetter
2020-04-28 15:32       ` [Intel-gfx] " Daniel Vetter
2020-04-28 15:32       ` Daniel Vetter
2020-04-28 15:32       ` Daniel Vetter
2020-04-28 15:32       ` Daniel Vetter
2020-04-28 16:02       ` Robin Murphy
2020-04-28 16:02         ` Robin Murphy
2020-04-28 16:02         ` [Intel-gfx] " Robin Murphy
2020-04-28 16:02         ` Robin Murphy
2020-04-28 16:02         ` Robin Murphy
2020-04-28 16:02         ` Robin Murphy

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20200428132005.21424-7-m.szyprowski@samsung.com \
    --to=m.szyprowski@samsung.com \
    --cc=airlied@linux.ie \
    --cc=amd-gfx@lists.freedesktop.org \
    --cc=b.zolnierkie@samsung.com \
    --cc=benjamin.gaignard@linaro.org \
    --cc=daniel@ffwll.ch \
    --cc=dri-devel@lists.freedesktop.org \
    --cc=hch@lst.de \
    --cc=intel-gfx@lists.freedesktop.org \
    --cc=iommu@lists.linux-foundation.org \
    --cc=linaro-mm-sig@lists.linaro.org \
    --cc=linux-arm-kernel@lists.infradead.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=robin.murphy@arm.com \
    --cc=sumit.semwal@linaro.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.