All of lore.kernel.org
 help / color / mirror / Atom feed
* [RFC 00/17] DRM: fix struct sg_table nents vs. orig_nents misuse
       [not found] <CGME20200428132022eucas1p2aa4716cbaca61c432ee8028be15fef7a@eucas1p2.samsung.com>
                     ` (3 preceding siblings ...)
  (?)
@ 2020-04-28 13:19   ` Marek Szyprowski
  0 siblings, 0 replies; 152+ messages in thread
From: Marek Szyprowski @ 2020-04-28 13:19 UTC (permalink / raw)
  To: dri-devel, iommu, linaro-mm-sig, linux-kernel
  Cc: Marek Szyprowski, Christoph Hellwig, Robin Murphy,
	Bartlomiej Zolnierkiewicz, Sumit Semwal, Benjamin Gaignard,
	intel-gfx, linux-arm-kernel, amd-gfx, David Airlie,
	Daniel Vetter

Dear All,

During the Exynos DRM GEM rework and fixing the issues in the 
drm_prime_sg_to_page_addr_arrays() function [1] I've noticed that most
drivers in DRM framework incorrectly use nents and orig_nents entries of
the struct sg_table.

In case of the most DMA-mapping implementations exchanging those two
entries or using nents for all loops on the scatterlist is harmless,
because they both have the same value. There exists however a DMA-mapping
implementations, for which such incorrect usage breaks things. The nents
returned by dma_map_sg() might be lower than the nents passed as its
parameter and this is perfectly fine. DMA framework or IOMMU is allowed
to join consecutive chunks while mapping if such operation is supported
by the underlying HW (bus, bridge, IOMMU, etc). Example of the case
where dma_map_sg() might return 1 'DMA' chunk for the 4 'physical' pages
is described here [2]

The DMA-mapping framework documentation [3] 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 common pattern in DRM drivers were to assign the
dma_map_sg() return value to sg_table->nents and use that value for
the subsequent calls to dma_sync_sg_* or dma_unmap_sg functions. Also
the code iterated over nents times to access the pages stored in the
processed scatterlist, while it should use orig_nents as the numer of
the page entries.

I've tried to identify all such incorrect usage of sg_table->nents in the
DRM subsystem and this is a result of my research. It looks that the
incorrect pattern has been copied over the many drivers. Too bad in most
cases it even worked correctly if the system used simple, linear
DMA-mapping implementation, for which swapping nents and orig_nents
doesn't make any difference.

I wonder what to do to avoid such misuse in the future, as this case
clearly shows that the current sg_table structure is a bit hard to
understand. I have the following ideas and I would like to know your
opinion before I prepare more patches and check sg_table usage all over
the kernel:

1. introduce a dma_{map,sync,unmap}_sgtable() wrappers, which will use
   a proper sg_table entries and call respective DMA-mapping functions
   and adapt current code to it

2. rename nents and orig_nents to nr_pages, nr_dmas to clearly state
   which one refers to which part of the scatterlist; I'm open for
   other names for those entries

I will appreciate your comments.

Patches are based on top of Linux next-20200428. I've reduced the
recipients list mainly to mailing lists, the next version I will try to
send to the maintainers of the respective drivers.

Best regards,
Marek Szyprowski


References:

[1] https://lkml.org/lkml/2020/3/27/555 
[2] https://lkml.org/lkml/2020/3/29/65
[3] Documentation/DMA-API-HOWTO.txt


Patch summary:

Marek Szyprowski (17):
  drm: core: fix sg_table nents vs. orig_nents usage
  drm: amdgpu: fix sg_table nents vs. orig_nents usage
  drm: armada: fix sg_table nents vs. orig_nents usage
  drm: etnaviv: fix sg_table nents vs. orig_nents usage
  drm: exynos: fix sg_table nents vs. orig_nents usage
  drm: i915: fix sg_table nents vs. orig_nents usage
  drm: lima: fix sg_table nents vs. orig_nents usage
  drm: msm: fix sg_table nents vs. orig_nents usage
  drm: panfrost: fix sg_table nents vs. orig_nents usage
  drm: radeon: fix sg_table nents vs. orig_nents usage
  drm: rockchip: fix sg_table nents vs. orig_nents usage
  drm: tegra: fix sg_table nents vs. orig_nents usage
  drm: virtio: fix sg_table nents vs. orig_nents usage
  drm: vmwgfx: fix sg_table nents vs. orig_nents usage
  drm: xen: fix sg_table nents vs. orig_nents usage
  drm: host1x: fix sg_table nents vs. orig_nents usage
  dmabuf: fix sg_table nents vs. orig_nents usage

 drivers/dma-buf/heaps/heap-helpers.c             |  7 ++++---
 drivers/dma-buf/udmabuf.c                        |  5 +++--
 drivers/gpu/drm/amd/amdgpu/amdgpu_dma_buf.c      |  7 ++++---
 drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c          |  8 ++++----
 drivers/gpu/drm/armada/armada_gem.c              | 14 ++++++++-----
 drivers/gpu/drm/drm_cache.c                      |  2 +-
 drivers/gpu/drm/drm_gem_shmem_helper.c           |  7 ++++---
 drivers/gpu/drm/drm_prime.c                      |  9 +++++----
 drivers/gpu/drm/etnaviv/etnaviv_gem.c            | 10 ++++++----
 drivers/gpu/drm/exynos/exynos_drm_g2d.c          |  7 ++++---
 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 ++++----
 drivers/gpu/drm/lima/lima_gem.c                  |  4 ++--
 drivers/gpu/drm/msm/msm_gem.c                    |  8 ++++----
 drivers/gpu/drm/msm/msm_iommu.c                  |  3 ++-
 drivers/gpu/drm/panfrost/panfrost_gem.c          |  3 ++-
 drivers/gpu/drm/panfrost/panfrost_mmu.c          |  4 +++-
 drivers/gpu/drm/radeon/radeon_ttm.c              | 10 +++++-----
 drivers/gpu/drm/rockchip/rockchip_drm_gem.c      | 15 +++++++-------
 drivers/gpu/drm/tegra/gem.c                      | 25 ++++++++++++------------
 drivers/gpu/drm/tegra/plane.c                    | 13 ++++++------
 drivers/gpu/drm/virtio/virtgpu_object.c          | 11 ++++++-----
 drivers/gpu/drm/virtio/virtgpu_vq.c              |  8 ++++----
 drivers/gpu/drm/vmwgfx/vmwgfx_ttm_buffer.c       |  6 +++---
 drivers/gpu/drm/xen/xen_drm_front_gem.c          |  2 +-
 drivers/gpu/host1x/job.c                         | 17 ++++++++--------
 34 files changed, 154 insertions(+), 128 deletions(-)

-- 
1.9.1


^ permalink raw reply	[flat|nested] 152+ messages in thread

* [RFC 00/17] DRM: fix struct sg_table nents vs. orig_nents misuse
@ 2020-04-28 13:19   ` Marek Szyprowski
  0 siblings, 0 replies; 152+ messages in thread
From: Marek Szyprowski @ 2020-04-28 13:19 UTC (permalink / raw)
  To: dri-devel, iommu, linaro-mm-sig, linux-kernel
  Cc: Daniel Vetter, Bartlomiej Zolnierkiewicz, David Airlie,
	intel-gfx, amd-gfx, Christoph Hellwig, Benjamin Gaignard,
	Robin Murphy, Sumit Semwal, linux-arm-kernel

Dear All,

During the Exynos DRM GEM rework and fixing the issues in the 
drm_prime_sg_to_page_addr_arrays() function [1] I've noticed that most
drivers in DRM framework incorrectly use nents and orig_nents entries of
the struct sg_table.

In case of the most DMA-mapping implementations exchanging those two
entries or using nents for all loops on the scatterlist is harmless,
because they both have the same value. There exists however a DMA-mapping
implementations, for which such incorrect usage breaks things. The nents
returned by dma_map_sg() might be lower than the nents passed as its
parameter and this is perfectly fine. DMA framework or IOMMU is allowed
to join consecutive chunks while mapping if such operation is supported
by the underlying HW (bus, bridge, IOMMU, etc). Example of the case
where dma_map_sg() might return 1 'DMA' chunk for the 4 'physical' pages
is described here [2]

The DMA-mapping framework documentation [3] 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 common pattern in DRM drivers were to assign the
dma_map_sg() return value to sg_table->nents and use that value for
the subsequent calls to dma_sync_sg_* or dma_unmap_sg functions. Also
the code iterated over nents times to access the pages stored in the
processed scatterlist, while it should use orig_nents as the numer of
the page entries.

I've tried to identify all such incorrect usage of sg_table->nents in the
DRM subsystem and this is a result of my research. It looks that the
incorrect pattern has been copied over the many drivers. Too bad in most
cases it even worked correctly if the system used simple, linear
DMA-mapping implementation, for which swapping nents and orig_nents
doesn't make any difference.

I wonder what to do to avoid such misuse in the future, as this case
clearly shows that the current sg_table structure is a bit hard to
understand. I have the following ideas and I would like to know your
opinion before I prepare more patches and check sg_table usage all over
the kernel:

1. introduce a dma_{map,sync,unmap}_sgtable() wrappers, which will use
   a proper sg_table entries and call respective DMA-mapping functions
   and adapt current code to it

2. rename nents and orig_nents to nr_pages, nr_dmas to clearly state
   which one refers to which part of the scatterlist; I'm open for
   other names for those entries

I will appreciate your comments.

Patches are based on top of Linux next-20200428. I've reduced the
recipients list mainly to mailing lists, the next version I will try to
send to the maintainers of the respective drivers.

Best regards,
Marek Szyprowski


References:

[1] https://lkml.org/lkml/2020/3/27/555 
[2] https://lkml.org/lkml/2020/3/29/65
[3] Documentation/DMA-API-HOWTO.txt


Patch summary:

Marek Szyprowski (17):
  drm: core: fix sg_table nents vs. orig_nents usage
  drm: amdgpu: fix sg_table nents vs. orig_nents usage
  drm: armada: fix sg_table nents vs. orig_nents usage
  drm: etnaviv: fix sg_table nents vs. orig_nents usage
  drm: exynos: fix sg_table nents vs. orig_nents usage
  drm: i915: fix sg_table nents vs. orig_nents usage
  drm: lima: fix sg_table nents vs. orig_nents usage
  drm: msm: fix sg_table nents vs. orig_nents usage
  drm: panfrost: fix sg_table nents vs. orig_nents usage
  drm: radeon: fix sg_table nents vs. orig_nents usage
  drm: rockchip: fix sg_table nents vs. orig_nents usage
  drm: tegra: fix sg_table nents vs. orig_nents usage
  drm: virtio: fix sg_table nents vs. orig_nents usage
  drm: vmwgfx: fix sg_table nents vs. orig_nents usage
  drm: xen: fix sg_table nents vs. orig_nents usage
  drm: host1x: fix sg_table nents vs. orig_nents usage
  dmabuf: fix sg_table nents vs. orig_nents usage

 drivers/dma-buf/heaps/heap-helpers.c             |  7 ++++---
 drivers/dma-buf/udmabuf.c                        |  5 +++--
 drivers/gpu/drm/amd/amdgpu/amdgpu_dma_buf.c      |  7 ++++---
 drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c          |  8 ++++----
 drivers/gpu/drm/armada/armada_gem.c              | 14 ++++++++-----
 drivers/gpu/drm/drm_cache.c                      |  2 +-
 drivers/gpu/drm/drm_gem_shmem_helper.c           |  7 ++++---
 drivers/gpu/drm/drm_prime.c                      |  9 +++++----
 drivers/gpu/drm/etnaviv/etnaviv_gem.c            | 10 ++++++----
 drivers/gpu/drm/exynos/exynos_drm_g2d.c          |  7 ++++---
 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 ++++----
 drivers/gpu/drm/lima/lima_gem.c                  |  4 ++--
 drivers/gpu/drm/msm/msm_gem.c                    |  8 ++++----
 drivers/gpu/drm/msm/msm_iommu.c                  |  3 ++-
 drivers/gpu/drm/panfrost/panfrost_gem.c          |  3 ++-
 drivers/gpu/drm/panfrost/panfrost_mmu.c          |  4 +++-
 drivers/gpu/drm/radeon/radeon_ttm.c              | 10 +++++-----
 drivers/gpu/drm/rockchip/rockchip_drm_gem.c      | 15 +++++++-------
 drivers/gpu/drm/tegra/gem.c                      | 25 ++++++++++++------------
 drivers/gpu/drm/tegra/plane.c                    | 13 ++++++------
 drivers/gpu/drm/virtio/virtgpu_object.c          | 11 ++++++-----
 drivers/gpu/drm/virtio/virtgpu_vq.c              |  8 ++++----
 drivers/gpu/drm/vmwgfx/vmwgfx_ttm_buffer.c       |  6 +++---
 drivers/gpu/drm/xen/xen_drm_front_gem.c          |  2 +-
 drivers/gpu/host1x/job.c                         | 17 ++++++++--------
 34 files changed, 154 insertions(+), 128 deletions(-)

-- 
1.9.1

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

^ permalink raw reply	[flat|nested] 152+ messages in thread

* [RFC 00/17] DRM: fix struct sg_table nents vs. orig_nents misuse
@ 2020-04-28 13:19   ` Marek Szyprowski
  0 siblings, 0 replies; 152+ messages in thread
From: Marek Szyprowski @ 2020-04-28 13:19 UTC (permalink / raw)
  To: dri-devel, iommu, linaro-mm-sig, linux-kernel
  Cc: Daniel Vetter, Bartlomiej Zolnierkiewicz, David Airlie,
	intel-gfx, amd-gfx, Christoph Hellwig, Benjamin Gaignard,
	Robin Murphy, Sumit Semwal, linux-arm-kernel, Marek Szyprowski

Dear All,

During the Exynos DRM GEM rework and fixing the issues in the 
drm_prime_sg_to_page_addr_arrays() function [1] I've noticed that most
drivers in DRM framework incorrectly use nents and orig_nents entries of
the struct sg_table.

In case of the most DMA-mapping implementations exchanging those two
entries or using nents for all loops on the scatterlist is harmless,
because they both have the same value. There exists however a DMA-mapping
implementations, for which such incorrect usage breaks things. The nents
returned by dma_map_sg() might be lower than the nents passed as its
parameter and this is perfectly fine. DMA framework or IOMMU is allowed
to join consecutive chunks while mapping if such operation is supported
by the underlying HW (bus, bridge, IOMMU, etc). Example of the case
where dma_map_sg() might return 1 'DMA' chunk for the 4 'physical' pages
is described here [2]

The DMA-mapping framework documentation [3] 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 common pattern in DRM drivers were to assign the
dma_map_sg() return value to sg_table->nents and use that value for
the subsequent calls to dma_sync_sg_* or dma_unmap_sg functions. Also
the code iterated over nents times to access the pages stored in the
processed scatterlist, while it should use orig_nents as the numer of
the page entries.

I've tried to identify all such incorrect usage of sg_table->nents in the
DRM subsystem and this is a result of my research. It looks that the
incorrect pattern has been copied over the many drivers. Too bad in most
cases it even worked correctly if the system used simple, linear
DMA-mapping implementation, for which swapping nents and orig_nents
doesn't make any difference.

I wonder what to do to avoid such misuse in the future, as this case
clearly shows that the current sg_table structure is a bit hard to
understand. I have the following ideas and I would like to know your
opinion before I prepare more patches and check sg_table usage all over
the kernel:

1. introduce a dma_{map,sync,unmap}_sgtable() wrappers, which will use
   a proper sg_table entries and call respective DMA-mapping functions
   and adapt current code to it

2. rename nents and orig_nents to nr_pages, nr_dmas to clearly state
   which one refers to which part of the scatterlist; I'm open for
   other names for those entries

I will appreciate your comments.

Patches are based on top of Linux next-20200428. I've reduced the
recipients list mainly to mailing lists, the next version I will try to
send to the maintainers of the respective drivers.

Best regards,
Marek Szyprowski


References:

[1] https://lkml.org/lkml/2020/3/27/555 
[2] https://lkml.org/lkml/2020/3/29/65
[3] Documentation/DMA-API-HOWTO.txt


Patch summary:

Marek Szyprowski (17):
  drm: core: fix sg_table nents vs. orig_nents usage
  drm: amdgpu: fix sg_table nents vs. orig_nents usage
  drm: armada: fix sg_table nents vs. orig_nents usage
  drm: etnaviv: fix sg_table nents vs. orig_nents usage
  drm: exynos: fix sg_table nents vs. orig_nents usage
  drm: i915: fix sg_table nents vs. orig_nents usage
  drm: lima: fix sg_table nents vs. orig_nents usage
  drm: msm: fix sg_table nents vs. orig_nents usage
  drm: panfrost: fix sg_table nents vs. orig_nents usage
  drm: radeon: fix sg_table nents vs. orig_nents usage
  drm: rockchip: fix sg_table nents vs. orig_nents usage
  drm: tegra: fix sg_table nents vs. orig_nents usage
  drm: virtio: fix sg_table nents vs. orig_nents usage
  drm: vmwgfx: fix sg_table nents vs. orig_nents usage
  drm: xen: fix sg_table nents vs. orig_nents usage
  drm: host1x: fix sg_table nents vs. orig_nents usage
  dmabuf: fix sg_table nents vs. orig_nents usage

 drivers/dma-buf/heaps/heap-helpers.c             |  7 ++++---
 drivers/dma-buf/udmabuf.c                        |  5 +++--
 drivers/gpu/drm/amd/amdgpu/amdgpu_dma_buf.c      |  7 ++++---
 drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c          |  8 ++++----
 drivers/gpu/drm/armada/armada_gem.c              | 14 ++++++++-----
 drivers/gpu/drm/drm_cache.c                      |  2 +-
 drivers/gpu/drm/drm_gem_shmem_helper.c           |  7 ++++---
 drivers/gpu/drm/drm_prime.c                      |  9 +++++----
 drivers/gpu/drm/etnaviv/etnaviv_gem.c            | 10 ++++++----
 drivers/gpu/drm/exynos/exynos_drm_g2d.c          |  7 ++++---
 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 ++++----
 drivers/gpu/drm/lima/lima_gem.c                  |  4 ++--
 drivers/gpu/drm/msm/msm_gem.c                    |  8 ++++----
 drivers/gpu/drm/msm/msm_iommu.c                  |  3 ++-
 drivers/gpu/drm/panfrost/panfrost_gem.c          |  3 ++-
 drivers/gpu/drm/panfrost/panfrost_mmu.c          |  4 +++-
 drivers/gpu/drm/radeon/radeon_ttm.c              | 10 +++++-----
 drivers/gpu/drm/rockchip/rockchip_drm_gem.c      | 15 +++++++-------
 drivers/gpu/drm/tegra/gem.c                      | 25 ++++++++++++------------
 drivers/gpu/drm/tegra/plane.c                    | 13 ++++++------
 drivers/gpu/drm/virtio/virtgpu_object.c          | 11 ++++++-----
 drivers/gpu/drm/virtio/virtgpu_vq.c              |  8 ++++----
 drivers/gpu/drm/vmwgfx/vmwgfx_ttm_buffer.c       |  6 +++---
 drivers/gpu/drm/xen/xen_drm_front_gem.c          |  2 +-
 drivers/gpu/host1x/job.c                         | 17 ++++++++--------
 34 files changed, 154 insertions(+), 128 deletions(-)

-- 
1.9.1


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

^ permalink raw reply	[flat|nested] 152+ messages in thread

* [RFC 00/17] DRM: fix struct sg_table nents vs. orig_nents misuse
@ 2020-04-28 13:19   ` Marek Szyprowski
  0 siblings, 0 replies; 152+ messages in thread
From: Marek Szyprowski @ 2020-04-28 13:19 UTC (permalink / raw)
  To: dri-devel, iommu, linaro-mm-sig, linux-kernel
  Cc: Bartlomiej Zolnierkiewicz, David Airlie, intel-gfx, amd-gfx,
	Christoph Hellwig, Robin Murphy, linux-arm-kernel,
	Marek Szyprowski

Dear All,

During the Exynos DRM GEM rework and fixing the issues in the 
drm_prime_sg_to_page_addr_arrays() function [1] I've noticed that most
drivers in DRM framework incorrectly use nents and orig_nents entries of
the struct sg_table.

In case of the most DMA-mapping implementations exchanging those two
entries or using nents for all loops on the scatterlist is harmless,
because they both have the same value. There exists however a DMA-mapping
implementations, for which such incorrect usage breaks things. The nents
returned by dma_map_sg() might be lower than the nents passed as its
parameter and this is perfectly fine. DMA framework or IOMMU is allowed
to join consecutive chunks while mapping if such operation is supported
by the underlying HW (bus, bridge, IOMMU, etc). Example of the case
where dma_map_sg() might return 1 'DMA' chunk for the 4 'physical' pages
is described here [2]

The DMA-mapping framework documentation [3] 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 common pattern in DRM drivers were to assign the
dma_map_sg() return value to sg_table->nents and use that value for
the subsequent calls to dma_sync_sg_* or dma_unmap_sg functions. Also
the code iterated over nents times to access the pages stored in the
processed scatterlist, while it should use orig_nents as the numer of
the page entries.

I've tried to identify all such incorrect usage of sg_table->nents in the
DRM subsystem and this is a result of my research. It looks that the
incorrect pattern has been copied over the many drivers. Too bad in most
cases it even worked correctly if the system used simple, linear
DMA-mapping implementation, for which swapping nents and orig_nents
doesn't make any difference.

I wonder what to do to avoid such misuse in the future, as this case
clearly shows that the current sg_table structure is a bit hard to
understand. I have the following ideas and I would like to know your
opinion before I prepare more patches and check sg_table usage all over
the kernel:

1. introduce a dma_{map,sync,unmap}_sgtable() wrappers, which will use
   a proper sg_table entries and call respective DMA-mapping functions
   and adapt current code to it

2. rename nents and orig_nents to nr_pages, nr_dmas to clearly state
   which one refers to which part of the scatterlist; I'm open for
   other names for those entries

I will appreciate your comments.

Patches are based on top of Linux next-20200428. I've reduced the
recipients list mainly to mailing lists, the next version I will try to
send to the maintainers of the respective drivers.

Best regards,
Marek Szyprowski


References:

[1] https://lkml.org/lkml/2020/3/27/555 
[2] https://lkml.org/lkml/2020/3/29/65
[3] Documentation/DMA-API-HOWTO.txt


Patch summary:

Marek Szyprowski (17):
  drm: core: fix sg_table nents vs. orig_nents usage
  drm: amdgpu: fix sg_table nents vs. orig_nents usage
  drm: armada: fix sg_table nents vs. orig_nents usage
  drm: etnaviv: fix sg_table nents vs. orig_nents usage
  drm: exynos: fix sg_table nents vs. orig_nents usage
  drm: i915: fix sg_table nents vs. orig_nents usage
  drm: lima: fix sg_table nents vs. orig_nents usage
  drm: msm: fix sg_table nents vs. orig_nents usage
  drm: panfrost: fix sg_table nents vs. orig_nents usage
  drm: radeon: fix sg_table nents vs. orig_nents usage
  drm: rockchip: fix sg_table nents vs. orig_nents usage
  drm: tegra: fix sg_table nents vs. orig_nents usage
  drm: virtio: fix sg_table nents vs. orig_nents usage
  drm: vmwgfx: fix sg_table nents vs. orig_nents usage
  drm: xen: fix sg_table nents vs. orig_nents usage
  drm: host1x: fix sg_table nents vs. orig_nents usage
  dmabuf: fix sg_table nents vs. orig_nents usage

 drivers/dma-buf/heaps/heap-helpers.c             |  7 ++++---
 drivers/dma-buf/udmabuf.c                        |  5 +++--
 drivers/gpu/drm/amd/amdgpu/amdgpu_dma_buf.c      |  7 ++++---
 drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c          |  8 ++++----
 drivers/gpu/drm/armada/armada_gem.c              | 14 ++++++++-----
 drivers/gpu/drm/drm_cache.c                      |  2 +-
 drivers/gpu/drm/drm_gem_shmem_helper.c           |  7 ++++---
 drivers/gpu/drm/drm_prime.c                      |  9 +++++----
 drivers/gpu/drm/etnaviv/etnaviv_gem.c            | 10 ++++++----
 drivers/gpu/drm/exynos/exynos_drm_g2d.c          |  7 ++++---
 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 ++++----
 drivers/gpu/drm/lima/lima_gem.c                  |  4 ++--
 drivers/gpu/drm/msm/msm_gem.c                    |  8 ++++----
 drivers/gpu/drm/msm/msm_iommu.c                  |  3 ++-
 drivers/gpu/drm/panfrost/panfrost_gem.c          |  3 ++-
 drivers/gpu/drm/panfrost/panfrost_mmu.c          |  4 +++-
 drivers/gpu/drm/radeon/radeon_ttm.c              | 10 +++++-----
 drivers/gpu/drm/rockchip/rockchip_drm_gem.c      | 15 +++++++-------
 drivers/gpu/drm/tegra/gem.c                      | 25 ++++++++++++------------
 drivers/gpu/drm/tegra/plane.c                    | 13 ++++++------
 drivers/gpu/drm/virtio/virtgpu_object.c          | 11 ++++++-----
 drivers/gpu/drm/virtio/virtgpu_vq.c              |  8 ++++----
 drivers/gpu/drm/vmwgfx/vmwgfx_ttm_buffer.c       |  6 +++---
 drivers/gpu/drm/xen/xen_drm_front_gem.c          |  2 +-
 drivers/gpu/host1x/job.c                         | 17 ++++++++--------
 34 files changed, 154 insertions(+), 128 deletions(-)

-- 
1.9.1

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

^ permalink raw reply	[flat|nested] 152+ messages in thread

* [Intel-gfx] [RFC 00/17] DRM: fix struct sg_table nents vs. orig_nents misuse
@ 2020-04-28 13:19   ` Marek Szyprowski
  0 siblings, 0 replies; 152+ messages in thread
From: Marek Szyprowski @ 2020-04-28 13:19 UTC (permalink / raw)
  To: dri-devel, iommu, linaro-mm-sig, linux-kernel
  Cc: Bartlomiej Zolnierkiewicz, David Airlie, intel-gfx, amd-gfx,
	Christoph Hellwig, Benjamin Gaignard, Robin Murphy, Sumit Semwal,
	linux-arm-kernel, Marek Szyprowski

Dear All,

During the Exynos DRM GEM rework and fixing the issues in the 
drm_prime_sg_to_page_addr_arrays() function [1] I've noticed that most
drivers in DRM framework incorrectly use nents and orig_nents entries of
the struct sg_table.

In case of the most DMA-mapping implementations exchanging those two
entries or using nents for all loops on the scatterlist is harmless,
because they both have the same value. There exists however a DMA-mapping
implementations, for which such incorrect usage breaks things. The nents
returned by dma_map_sg() might be lower than the nents passed as its
parameter and this is perfectly fine. DMA framework or IOMMU is allowed
to join consecutive chunks while mapping if such operation is supported
by the underlying HW (bus, bridge, IOMMU, etc). Example of the case
where dma_map_sg() might return 1 'DMA' chunk for the 4 'physical' pages
is described here [2]

The DMA-mapping framework documentation [3] 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 common pattern in DRM drivers were to assign the
dma_map_sg() return value to sg_table->nents and use that value for
the subsequent calls to dma_sync_sg_* or dma_unmap_sg functions. Also
the code iterated over nents times to access the pages stored in the
processed scatterlist, while it should use orig_nents as the numer of
the page entries.

I've tried to identify all such incorrect usage of sg_table->nents in the
DRM subsystem and this is a result of my research. It looks that the
incorrect pattern has been copied over the many drivers. Too bad in most
cases it even worked correctly if the system used simple, linear
DMA-mapping implementation, for which swapping nents and orig_nents
doesn't make any difference.

I wonder what to do to avoid such misuse in the future, as this case
clearly shows that the current sg_table structure is a bit hard to
understand. I have the following ideas and I would like to know your
opinion before I prepare more patches and check sg_table usage all over
the kernel:

1. introduce a dma_{map,sync,unmap}_sgtable() wrappers, which will use
   a proper sg_table entries and call respective DMA-mapping functions
   and adapt current code to it

2. rename nents and orig_nents to nr_pages, nr_dmas to clearly state
   which one refers to which part of the scatterlist; I'm open for
   other names for those entries

I will appreciate your comments.

Patches are based on top of Linux next-20200428. I've reduced the
recipients list mainly to mailing lists, the next version I will try to
send to the maintainers of the respective drivers.

Best regards,
Marek Szyprowski


References:

[1] https://lkml.org/lkml/2020/3/27/555 
[2] https://lkml.org/lkml/2020/3/29/65
[3] Documentation/DMA-API-HOWTO.txt


Patch summary:

Marek Szyprowski (17):
  drm: core: fix sg_table nents vs. orig_nents usage
  drm: amdgpu: fix sg_table nents vs. orig_nents usage
  drm: armada: fix sg_table nents vs. orig_nents usage
  drm: etnaviv: fix sg_table nents vs. orig_nents usage
  drm: exynos: fix sg_table nents vs. orig_nents usage
  drm: i915: fix sg_table nents vs. orig_nents usage
  drm: lima: fix sg_table nents vs. orig_nents usage
  drm: msm: fix sg_table nents vs. orig_nents usage
  drm: panfrost: fix sg_table nents vs. orig_nents usage
  drm: radeon: fix sg_table nents vs. orig_nents usage
  drm: rockchip: fix sg_table nents vs. orig_nents usage
  drm: tegra: fix sg_table nents vs. orig_nents usage
  drm: virtio: fix sg_table nents vs. orig_nents usage
  drm: vmwgfx: fix sg_table nents vs. orig_nents usage
  drm: xen: fix sg_table nents vs. orig_nents usage
  drm: host1x: fix sg_table nents vs. orig_nents usage
  dmabuf: fix sg_table nents vs. orig_nents usage

 drivers/dma-buf/heaps/heap-helpers.c             |  7 ++++---
 drivers/dma-buf/udmabuf.c                        |  5 +++--
 drivers/gpu/drm/amd/amdgpu/amdgpu_dma_buf.c      |  7 ++++---
 drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c          |  8 ++++----
 drivers/gpu/drm/armada/armada_gem.c              | 14 ++++++++-----
 drivers/gpu/drm/drm_cache.c                      |  2 +-
 drivers/gpu/drm/drm_gem_shmem_helper.c           |  7 ++++---
 drivers/gpu/drm/drm_prime.c                      |  9 +++++----
 drivers/gpu/drm/etnaviv/etnaviv_gem.c            | 10 ++++++----
 drivers/gpu/drm/exynos/exynos_drm_g2d.c          |  7 ++++---
 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 ++++----
 drivers/gpu/drm/lima/lima_gem.c                  |  4 ++--
 drivers/gpu/drm/msm/msm_gem.c                    |  8 ++++----
 drivers/gpu/drm/msm/msm_iommu.c                  |  3 ++-
 drivers/gpu/drm/panfrost/panfrost_gem.c          |  3 ++-
 drivers/gpu/drm/panfrost/panfrost_mmu.c          |  4 +++-
 drivers/gpu/drm/radeon/radeon_ttm.c              | 10 +++++-----
 drivers/gpu/drm/rockchip/rockchip_drm_gem.c      | 15 +++++++-------
 drivers/gpu/drm/tegra/gem.c                      | 25 ++++++++++++------------
 drivers/gpu/drm/tegra/plane.c                    | 13 ++++++------
 drivers/gpu/drm/virtio/virtgpu_object.c          | 11 ++++++-----
 drivers/gpu/drm/virtio/virtgpu_vq.c              |  8 ++++----
 drivers/gpu/drm/vmwgfx/vmwgfx_ttm_buffer.c       |  6 +++---
 drivers/gpu/drm/xen/xen_drm_front_gem.c          |  2 +-
 drivers/gpu/host1x/job.c                         | 17 ++++++++--------
 34 files changed, 154 insertions(+), 128 deletions(-)

-- 
1.9.1

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

^ permalink raw reply	[flat|nested] 152+ messages in thread

* [RFC 00/17] DRM: fix struct sg_table nents vs. orig_nents misuse
@ 2020-04-28 13:19   ` Marek Szyprowski
  0 siblings, 0 replies; 152+ messages in thread
From: Marek Szyprowski @ 2020-04-28 13:19 UTC (permalink / raw)
  To: dri-devel, iommu, linaro-mm-sig, linux-kernel
  Cc: Daniel Vetter, Bartlomiej Zolnierkiewicz, David Airlie,
	intel-gfx, amd-gfx, Christoph Hellwig, Benjamin Gaignard,
	Robin Murphy, Sumit Semwal, linux-arm-kernel, Marek Szyprowski

Dear All,

During the Exynos DRM GEM rework and fixing the issues in the 
drm_prime_sg_to_page_addr_arrays() function [1] I've noticed that most
drivers in DRM framework incorrectly use nents and orig_nents entries of
the struct sg_table.

In case of the most DMA-mapping implementations exchanging those two
entries or using nents for all loops on the scatterlist is harmless,
because they both have the same value. There exists however a DMA-mapping
implementations, for which such incorrect usage breaks things. The nents
returned by dma_map_sg() might be lower than the nents passed as its
parameter and this is perfectly fine. DMA framework or IOMMU is allowed
to join consecutive chunks while mapping if such operation is supported
by the underlying HW (bus, bridge, IOMMU, etc). Example of the case
where dma_map_sg() might return 1 'DMA' chunk for the 4 'physical' pages
is described here [2]

The DMA-mapping framework documentation [3] 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 common pattern in DRM drivers were to assign the
dma_map_sg() return value to sg_table->nents and use that value for
the subsequent calls to dma_sync_sg_* or dma_unmap_sg functions. Also
the code iterated over nents times to access the pages stored in the
processed scatterlist, while it should use orig_nents as the numer of
the page entries.

I've tried to identify all such incorrect usage of sg_table->nents in the
DRM subsystem and this is a result of my research. It looks that the
incorrect pattern has been copied over the many drivers. Too bad in most
cases it even worked correctly if the system used simple, linear
DMA-mapping implementation, for which swapping nents and orig_nents
doesn't make any difference.

I wonder what to do to avoid such misuse in the future, as this case
clearly shows that the current sg_table structure is a bit hard to
understand. I have the following ideas and I would like to know your
opinion before I prepare more patches and check sg_table usage all over
the kernel:

1. introduce a dma_{map,sync,unmap}_sgtable() wrappers, which will use
   a proper sg_table entries and call respective DMA-mapping functions
   and adapt current code to it

2. rename nents and orig_nents to nr_pages, nr_dmas to clearly state
   which one refers to which part of the scatterlist; I'm open for
   other names for those entries

I will appreciate your comments.

Patches are based on top of Linux next-20200428. I've reduced the
recipients list mainly to mailing lists, the next version I will try to
send to the maintainers of the respective drivers.

Best regards,
Marek Szyprowski


References:

[1] https://lkml.org/lkml/2020/3/27/555 
[2] https://lkml.org/lkml/2020/3/29/65
[3] Documentation/DMA-API-HOWTO.txt


Patch summary:

Marek Szyprowski (17):
  drm: core: fix sg_table nents vs. orig_nents usage
  drm: amdgpu: fix sg_table nents vs. orig_nents usage
  drm: armada: fix sg_table nents vs. orig_nents usage
  drm: etnaviv: fix sg_table nents vs. orig_nents usage
  drm: exynos: fix sg_table nents vs. orig_nents usage
  drm: i915: fix sg_table nents vs. orig_nents usage
  drm: lima: fix sg_table nents vs. orig_nents usage
  drm: msm: fix sg_table nents vs. orig_nents usage
  drm: panfrost: fix sg_table nents vs. orig_nents usage
  drm: radeon: fix sg_table nents vs. orig_nents usage
  drm: rockchip: fix sg_table nents vs. orig_nents usage
  drm: tegra: fix sg_table nents vs. orig_nents usage
  drm: virtio: fix sg_table nents vs. orig_nents usage
  drm: vmwgfx: fix sg_table nents vs. orig_nents usage
  drm: xen: fix sg_table nents vs. orig_nents usage
  drm: host1x: fix sg_table nents vs. orig_nents usage
  dmabuf: fix sg_table nents vs. orig_nents usage

 drivers/dma-buf/heaps/heap-helpers.c             |  7 ++++---
 drivers/dma-buf/udmabuf.c                        |  5 +++--
 drivers/gpu/drm/amd/amdgpu/amdgpu_dma_buf.c      |  7 ++++---
 drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c          |  8 ++++----
 drivers/gpu/drm/armada/armada_gem.c              | 14 ++++++++-----
 drivers/gpu/drm/drm_cache.c                      |  2 +-
 drivers/gpu/drm/drm_gem_shmem_helper.c           |  7 ++++---
 drivers/gpu/drm/drm_prime.c                      |  9 +++++----
 drivers/gpu/drm/etnaviv/etnaviv_gem.c            | 10 ++++++----
 drivers/gpu/drm/exynos/exynos_drm_g2d.c          |  7 ++++---
 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 ++++----
 drivers/gpu/drm/lima/lima_gem.c                  |  4 ++--
 drivers/gpu/drm/msm/msm_gem.c                    |  8 ++++----
 drivers/gpu/drm/msm/msm_iommu.c                  |  3 ++-
 drivers/gpu/drm/panfrost/panfrost_gem.c          |  3 ++-
 drivers/gpu/drm/panfrost/panfrost_mmu.c          |  4 +++-
 drivers/gpu/drm/radeon/radeon_ttm.c              | 10 +++++-----
 drivers/gpu/drm/rockchip/rockchip_drm_gem.c      | 15 +++++++-------
 drivers/gpu/drm/tegra/gem.c                      | 25 ++++++++++++------------
 drivers/gpu/drm/tegra/plane.c                    | 13 ++++++------
 drivers/gpu/drm/virtio/virtgpu_object.c          | 11 ++++++-----
 drivers/gpu/drm/virtio/virtgpu_vq.c              |  8 ++++----
 drivers/gpu/drm/vmwgfx/vmwgfx_ttm_buffer.c       |  6 +++---
 drivers/gpu/drm/xen/xen_drm_front_gem.c          |  2 +-
 drivers/gpu/host1x/job.c                         | 17 ++++++++--------
 34 files changed, 154 insertions(+), 128 deletions(-)

-- 
1.9.1

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

^ permalink raw reply	[flat|nested] 152+ messages in thread

* [RFC 01/17] drm: core: fix sg_table nents vs. orig_nents misuse
       [not found]   ` <CGME20200428132022eucas1p22f64f56bb61cf6ee73892a9fc9ce7e09@eucas1p2.samsung.com>
                         ` (3 preceding siblings ...)
  (?)
@ 2020-04-28 13:19       ` Marek Szyprowski
  0 siblings, 0 replies; 152+ messages in thread
From: Marek Szyprowski @ 2020-04-28 13:19 UTC (permalink / raw)
  To: dri-devel, iommu, linaro-mm-sig, linux-kernel
  Cc: Marek Szyprowski, Christoph Hellwig, Robin Murphy,
	Bartlomiej Zolnierkiewicz, Sumit Semwal, Benjamin Gaignard,
	intel-gfx, linux-arm-kernel, amd-gfx, David Airlie,
	Daniel Vetter

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/drm_cache.c            | 2 +-
 drivers/gpu/drm/drm_gem_shmem_helper.c | 7 ++++---
 drivers/gpu/drm/drm_prime.c            | 9 +++++----
 3 files changed, 10 insertions(+), 8 deletions(-)

diff --git a/drivers/gpu/drm/drm_cache.c b/drivers/gpu/drm/drm_cache.c
index 03e01b0..63bd497 100644
--- a/drivers/gpu/drm/drm_cache.c
+++ b/drivers/gpu/drm/drm_cache.c
@@ -127,7 +127,7 @@ static void drm_cache_flush_clflush(struct page *pages[],
 		struct sg_page_iter sg_iter;
 
 		mb(); /*CLFLUSH is ordered only by using memory barriers*/
-		for_each_sg_page(st->sgl, &sg_iter, st->nents, 0)
+		for_each_sg_page(st->sgl, &sg_iter, st->orig_nents, 0)
 			drm_clflush_page(sg_page_iter_page(&sg_iter));
 		mb(); /*Make sure that all cache line entry is flushed*/
 
diff --git a/drivers/gpu/drm/drm_gem_shmem_helper.c b/drivers/gpu/drm/drm_gem_shmem_helper.c
index df31e57..f47caa7 100644
--- a/drivers/gpu/drm/drm_gem_shmem_helper.c
+++ b/drivers/gpu/drm/drm_gem_shmem_helper.c
@@ -118,7 +118,7 @@ void drm_gem_shmem_free_object(struct drm_gem_object *obj)
 	} else {
 		if (shmem->sgt) {
 			dma_unmap_sg(obj->dev->dev, shmem->sgt->sgl,
-				     shmem->sgt->nents, DMA_BIDIRECTIONAL);
+				     shmem->sgt->orig_nents, DMA_BIDIRECTIONAL);
 			sg_free_table(shmem->sgt);
 			kfree(shmem->sgt);
 		}
@@ -396,7 +396,7 @@ void drm_gem_shmem_purge_locked(struct drm_gem_object *obj)
 	WARN_ON(!drm_gem_shmem_is_purgeable(shmem));
 
 	dma_unmap_sg(obj->dev->dev, shmem->sgt->sgl,
-		     shmem->sgt->nents, DMA_BIDIRECTIONAL);
+		     shmem->sgt->orig_nents, DMA_BIDIRECTIONAL);
 	sg_free_table(shmem->sgt);
 	kfree(shmem->sgt);
 	shmem->sgt = NULL;
@@ -623,7 +623,8 @@ struct sg_table *drm_gem_shmem_get_pages_sgt(struct drm_gem_object *obj)
 		goto err_put_pages;
 	}
 	/* Map the pages for use by the h/w. */
-	dma_map_sg(obj->dev->dev, sgt->sgl, sgt->nents, DMA_BIDIRECTIONAL);
+	sgt->nents = dma_map_sg(obj->dev->dev, sgt->sgl, sgt->orig_nents,
+				DMA_BIDIRECTIONAL);
 
 	shmem->sgt = sgt;
 
diff --git a/drivers/gpu/drm/drm_prime.c b/drivers/gpu/drm/drm_prime.c
index 282774e..f3e2d2a 100644
--- a/drivers/gpu/drm/drm_prime.c
+++ b/drivers/gpu/drm/drm_prime.c
@@ -626,8 +626,9 @@ struct sg_table *drm_gem_map_dma_buf(struct dma_buf_attachment *attach,
 	else
 		sgt = obj->dev->driver->gem_prime_get_sg_table(obj);
 
-	if (!dma_map_sg_attrs(attach->dev, sgt->sgl, sgt->nents, dir,
-			      DMA_ATTR_SKIP_CPU_SYNC)) {
+	sgt->nents = dma_map_sg_attrs(attach->dev, sgt->sgl, sgt->orig_nents,
+				      dir, DMA_ATTR_SKIP_CPU_SYNC);
+	if (!sgt->nents) {
 		sg_free_table(sgt);
 		kfree(sgt);
 		sgt = ERR_PTR(-ENOMEM);
@@ -652,7 +653,7 @@ void drm_gem_unmap_dma_buf(struct dma_buf_attachment *attach,
 	if (!sgt)
 		return;
 
-	dma_unmap_sg_attrs(attach->dev, sgt->sgl, sgt->nents, dir,
+	dma_unmap_sg_attrs(attach->dev, sgt->sgl, sgt->orig_nents, dir,
 			   DMA_ATTR_SKIP_CPU_SYNC);
 	sg_free_table(sgt);
 	kfree(sgt);
@@ -975,7 +976,7 @@ int drm_prime_sg_to_page_addr_arrays(struct sg_table *sgt, struct page **pages,
 	 */
 	page_index = 0;
 	dma_index = 0;
-	for_each_sg(sgt->sgl, sg, sgt->nents, count) {
+	for_each_sg(sgt->sgl, sg, sgt->orig_nents, count) {
 		page_len = sg->length;
 		page = sg_page(sg);
 		dma_len = sg_dma_len(sg);
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 152+ messages in thread

* [RFC 01/17] drm: core: fix sg_table nents vs. orig_nents misuse
@ 2020-04-28 13:19       ` Marek Szyprowski
  0 siblings, 0 replies; 152+ messages in thread
From: Marek Szyprowski @ 2020-04-28 13:19 UTC (permalink / raw)
  To: dri-devel, iommu, linaro-mm-sig, linux-kernel
  Cc: Daniel Vetter, Bartlomiej Zolnierkiewicz, David Airlie,
	intel-gfx, amd-gfx, Christoph Hellwig, Benjamin Gaignard,
	Robin Murphy, Sumit Semwal, linux-arm-kernel

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/drm_cache.c            | 2 +-
 drivers/gpu/drm/drm_gem_shmem_helper.c | 7 ++++---
 drivers/gpu/drm/drm_prime.c            | 9 +++++----
 3 files changed, 10 insertions(+), 8 deletions(-)

diff --git a/drivers/gpu/drm/drm_cache.c b/drivers/gpu/drm/drm_cache.c
index 03e01b0..63bd497 100644
--- a/drivers/gpu/drm/drm_cache.c
+++ b/drivers/gpu/drm/drm_cache.c
@@ -127,7 +127,7 @@ static void drm_cache_flush_clflush(struct page *pages[],
 		struct sg_page_iter sg_iter;
 
 		mb(); /*CLFLUSH is ordered only by using memory barriers*/
-		for_each_sg_page(st->sgl, &sg_iter, st->nents, 0)
+		for_each_sg_page(st->sgl, &sg_iter, st->orig_nents, 0)
 			drm_clflush_page(sg_page_iter_page(&sg_iter));
 		mb(); /*Make sure that all cache line entry is flushed*/
 
diff --git a/drivers/gpu/drm/drm_gem_shmem_helper.c b/drivers/gpu/drm/drm_gem_shmem_helper.c
index df31e57..f47caa7 100644
--- a/drivers/gpu/drm/drm_gem_shmem_helper.c
+++ b/drivers/gpu/drm/drm_gem_shmem_helper.c
@@ -118,7 +118,7 @@ void drm_gem_shmem_free_object(struct drm_gem_object *obj)
 	} else {
 		if (shmem->sgt) {
 			dma_unmap_sg(obj->dev->dev, shmem->sgt->sgl,
-				     shmem->sgt->nents, DMA_BIDIRECTIONAL);
+				     shmem->sgt->orig_nents, DMA_BIDIRECTIONAL);
 			sg_free_table(shmem->sgt);
 			kfree(shmem->sgt);
 		}
@@ -396,7 +396,7 @@ void drm_gem_shmem_purge_locked(struct drm_gem_object *obj)
 	WARN_ON(!drm_gem_shmem_is_purgeable(shmem));
 
 	dma_unmap_sg(obj->dev->dev, shmem->sgt->sgl,
-		     shmem->sgt->nents, DMA_BIDIRECTIONAL);
+		     shmem->sgt->orig_nents, DMA_BIDIRECTIONAL);
 	sg_free_table(shmem->sgt);
 	kfree(shmem->sgt);
 	shmem->sgt = NULL;
@@ -623,7 +623,8 @@ struct sg_table *drm_gem_shmem_get_pages_sgt(struct drm_gem_object *obj)
 		goto err_put_pages;
 	}
 	/* Map the pages for use by the h/w. */
-	dma_map_sg(obj->dev->dev, sgt->sgl, sgt->nents, DMA_BIDIRECTIONAL);
+	sgt->nents = dma_map_sg(obj->dev->dev, sgt->sgl, sgt->orig_nents,
+				DMA_BIDIRECTIONAL);
 
 	shmem->sgt = sgt;
 
diff --git a/drivers/gpu/drm/drm_prime.c b/drivers/gpu/drm/drm_prime.c
index 282774e..f3e2d2a 100644
--- a/drivers/gpu/drm/drm_prime.c
+++ b/drivers/gpu/drm/drm_prime.c
@@ -626,8 +626,9 @@ struct sg_table *drm_gem_map_dma_buf(struct dma_buf_attachment *attach,
 	else
 		sgt = obj->dev->driver->gem_prime_get_sg_table(obj);
 
-	if (!dma_map_sg_attrs(attach->dev, sgt->sgl, sgt->nents, dir,
-			      DMA_ATTR_SKIP_CPU_SYNC)) {
+	sgt->nents = dma_map_sg_attrs(attach->dev, sgt->sgl, sgt->orig_nents,
+				      dir, DMA_ATTR_SKIP_CPU_SYNC);
+	if (!sgt->nents) {
 		sg_free_table(sgt);
 		kfree(sgt);
 		sgt = ERR_PTR(-ENOMEM);
@@ -652,7 +653,7 @@ void drm_gem_unmap_dma_buf(struct dma_buf_attachment *attach,
 	if (!sgt)
 		return;
 
-	dma_unmap_sg_attrs(attach->dev, sgt->sgl, sgt->nents, dir,
+	dma_unmap_sg_attrs(attach->dev, sgt->sgl, sgt->orig_nents, dir,
 			   DMA_ATTR_SKIP_CPU_SYNC);
 	sg_free_table(sgt);
 	kfree(sgt);
@@ -975,7 +976,7 @@ int drm_prime_sg_to_page_addr_arrays(struct sg_table *sgt, struct page **pages,
 	 */
 	page_index = 0;
 	dma_index = 0;
-	for_each_sg(sgt->sgl, sg, sgt->nents, count) {
+	for_each_sg(sgt->sgl, sg, sgt->orig_nents, count) {
 		page_len = sg->length;
 		page = sg_page(sg);
 		dma_len = sg_dma_len(sg);
-- 
1.9.1

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

^ permalink raw reply related	[flat|nested] 152+ messages in thread

* [RFC 01/17] drm: core: fix sg_table nents vs. orig_nents misuse
@ 2020-04-28 13:19       ` Marek Szyprowski
  0 siblings, 0 replies; 152+ messages in thread
From: Marek Szyprowski @ 2020-04-28 13:19 UTC (permalink / raw)
  To: dri-devel, iommu, linaro-mm-sig, linux-kernel
  Cc: Daniel Vetter, Bartlomiej Zolnierkiewicz, David Airlie,
	intel-gfx, amd-gfx, Christoph Hellwig, Benjamin Gaignard,
	Robin Murphy, Sumit Semwal, linux-arm-kernel, Marek Szyprowski

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/drm_cache.c            | 2 +-
 drivers/gpu/drm/drm_gem_shmem_helper.c | 7 ++++---
 drivers/gpu/drm/drm_prime.c            | 9 +++++----
 3 files changed, 10 insertions(+), 8 deletions(-)

diff --git a/drivers/gpu/drm/drm_cache.c b/drivers/gpu/drm/drm_cache.c
index 03e01b0..63bd497 100644
--- a/drivers/gpu/drm/drm_cache.c
+++ b/drivers/gpu/drm/drm_cache.c
@@ -127,7 +127,7 @@ static void drm_cache_flush_clflush(struct page *pages[],
 		struct sg_page_iter sg_iter;
 
 		mb(); /*CLFLUSH is ordered only by using memory barriers*/
-		for_each_sg_page(st->sgl, &sg_iter, st->nents, 0)
+		for_each_sg_page(st->sgl, &sg_iter, st->orig_nents, 0)
 			drm_clflush_page(sg_page_iter_page(&sg_iter));
 		mb(); /*Make sure that all cache line entry is flushed*/
 
diff --git a/drivers/gpu/drm/drm_gem_shmem_helper.c b/drivers/gpu/drm/drm_gem_shmem_helper.c
index df31e57..f47caa7 100644
--- a/drivers/gpu/drm/drm_gem_shmem_helper.c
+++ b/drivers/gpu/drm/drm_gem_shmem_helper.c
@@ -118,7 +118,7 @@ void drm_gem_shmem_free_object(struct drm_gem_object *obj)
 	} else {
 		if (shmem->sgt) {
 			dma_unmap_sg(obj->dev->dev, shmem->sgt->sgl,
-				     shmem->sgt->nents, DMA_BIDIRECTIONAL);
+				     shmem->sgt->orig_nents, DMA_BIDIRECTIONAL);
 			sg_free_table(shmem->sgt);
 			kfree(shmem->sgt);
 		}
@@ -396,7 +396,7 @@ void drm_gem_shmem_purge_locked(struct drm_gem_object *obj)
 	WARN_ON(!drm_gem_shmem_is_purgeable(shmem));
 
 	dma_unmap_sg(obj->dev->dev, shmem->sgt->sgl,
-		     shmem->sgt->nents, DMA_BIDIRECTIONAL);
+		     shmem->sgt->orig_nents, DMA_BIDIRECTIONAL);
 	sg_free_table(shmem->sgt);
 	kfree(shmem->sgt);
 	shmem->sgt = NULL;
@@ -623,7 +623,8 @@ struct sg_table *drm_gem_shmem_get_pages_sgt(struct drm_gem_object *obj)
 		goto err_put_pages;
 	}
 	/* Map the pages for use by the h/w. */
-	dma_map_sg(obj->dev->dev, sgt->sgl, sgt->nents, DMA_BIDIRECTIONAL);
+	sgt->nents = dma_map_sg(obj->dev->dev, sgt->sgl, sgt->orig_nents,
+				DMA_BIDIRECTIONAL);
 
 	shmem->sgt = sgt;
 
diff --git a/drivers/gpu/drm/drm_prime.c b/drivers/gpu/drm/drm_prime.c
index 282774e..f3e2d2a 100644
--- a/drivers/gpu/drm/drm_prime.c
+++ b/drivers/gpu/drm/drm_prime.c
@@ -626,8 +626,9 @@ struct sg_table *drm_gem_map_dma_buf(struct dma_buf_attachment *attach,
 	else
 		sgt = obj->dev->driver->gem_prime_get_sg_table(obj);
 
-	if (!dma_map_sg_attrs(attach->dev, sgt->sgl, sgt->nents, dir,
-			      DMA_ATTR_SKIP_CPU_SYNC)) {
+	sgt->nents = dma_map_sg_attrs(attach->dev, sgt->sgl, sgt->orig_nents,
+				      dir, DMA_ATTR_SKIP_CPU_SYNC);
+	if (!sgt->nents) {
 		sg_free_table(sgt);
 		kfree(sgt);
 		sgt = ERR_PTR(-ENOMEM);
@@ -652,7 +653,7 @@ void drm_gem_unmap_dma_buf(struct dma_buf_attachment *attach,
 	if (!sgt)
 		return;
 
-	dma_unmap_sg_attrs(attach->dev, sgt->sgl, sgt->nents, dir,
+	dma_unmap_sg_attrs(attach->dev, sgt->sgl, sgt->orig_nents, dir,
 			   DMA_ATTR_SKIP_CPU_SYNC);
 	sg_free_table(sgt);
 	kfree(sgt);
@@ -975,7 +976,7 @@ int drm_prime_sg_to_page_addr_arrays(struct sg_table *sgt, struct page **pages,
 	 */
 	page_index = 0;
 	dma_index = 0;
-	for_each_sg(sgt->sgl, sg, sgt->nents, count) {
+	for_each_sg(sgt->sgl, sg, sgt->orig_nents, count) {
 		page_len = sg->length;
 		page = sg_page(sg);
 		dma_len = sg_dma_len(sg);
-- 
1.9.1


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

^ permalink raw reply related	[flat|nested] 152+ messages in thread

* [RFC 01/17] drm: core: fix sg_table nents vs. orig_nents misuse
@ 2020-04-28 13:19       ` Marek Szyprowski
  0 siblings, 0 replies; 152+ messages in thread
From: Marek Szyprowski @ 2020-04-28 13:19 UTC (permalink / raw)
  To: dri-devel, iommu, linaro-mm-sig, linux-kernel
  Cc: Bartlomiej Zolnierkiewicz, David Airlie, intel-gfx, amd-gfx,
	Christoph Hellwig, Robin Murphy, linux-arm-kernel,
	Marek Szyprowski

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/drm_cache.c            | 2 +-
 drivers/gpu/drm/drm_gem_shmem_helper.c | 7 ++++---
 drivers/gpu/drm/drm_prime.c            | 9 +++++----
 3 files changed, 10 insertions(+), 8 deletions(-)

diff --git a/drivers/gpu/drm/drm_cache.c b/drivers/gpu/drm/drm_cache.c
index 03e01b0..63bd497 100644
--- a/drivers/gpu/drm/drm_cache.c
+++ b/drivers/gpu/drm/drm_cache.c
@@ -127,7 +127,7 @@ static void drm_cache_flush_clflush(struct page *pages[],
 		struct sg_page_iter sg_iter;
 
 		mb(); /*CLFLUSH is ordered only by using memory barriers*/
-		for_each_sg_page(st->sgl, &sg_iter, st->nents, 0)
+		for_each_sg_page(st->sgl, &sg_iter, st->orig_nents, 0)
 			drm_clflush_page(sg_page_iter_page(&sg_iter));
 		mb(); /*Make sure that all cache line entry is flushed*/
 
diff --git a/drivers/gpu/drm/drm_gem_shmem_helper.c b/drivers/gpu/drm/drm_gem_shmem_helper.c
index df31e57..f47caa7 100644
--- a/drivers/gpu/drm/drm_gem_shmem_helper.c
+++ b/drivers/gpu/drm/drm_gem_shmem_helper.c
@@ -118,7 +118,7 @@ void drm_gem_shmem_free_object(struct drm_gem_object *obj)
 	} else {
 		if (shmem->sgt) {
 			dma_unmap_sg(obj->dev->dev, shmem->sgt->sgl,
-				     shmem->sgt->nents, DMA_BIDIRECTIONAL);
+				     shmem->sgt->orig_nents, DMA_BIDIRECTIONAL);
 			sg_free_table(shmem->sgt);
 			kfree(shmem->sgt);
 		}
@@ -396,7 +396,7 @@ void drm_gem_shmem_purge_locked(struct drm_gem_object *obj)
 	WARN_ON(!drm_gem_shmem_is_purgeable(shmem));
 
 	dma_unmap_sg(obj->dev->dev, shmem->sgt->sgl,
-		     shmem->sgt->nents, DMA_BIDIRECTIONAL);
+		     shmem->sgt->orig_nents, DMA_BIDIRECTIONAL);
 	sg_free_table(shmem->sgt);
 	kfree(shmem->sgt);
 	shmem->sgt = NULL;
@@ -623,7 +623,8 @@ struct sg_table *drm_gem_shmem_get_pages_sgt(struct drm_gem_object *obj)
 		goto err_put_pages;
 	}
 	/* Map the pages for use by the h/w. */
-	dma_map_sg(obj->dev->dev, sgt->sgl, sgt->nents, DMA_BIDIRECTIONAL);
+	sgt->nents = dma_map_sg(obj->dev->dev, sgt->sgl, sgt->orig_nents,
+				DMA_BIDIRECTIONAL);
 
 	shmem->sgt = sgt;
 
diff --git a/drivers/gpu/drm/drm_prime.c b/drivers/gpu/drm/drm_prime.c
index 282774e..f3e2d2a 100644
--- a/drivers/gpu/drm/drm_prime.c
+++ b/drivers/gpu/drm/drm_prime.c
@@ -626,8 +626,9 @@ struct sg_table *drm_gem_map_dma_buf(struct dma_buf_attachment *attach,
 	else
 		sgt = obj->dev->driver->gem_prime_get_sg_table(obj);
 
-	if (!dma_map_sg_attrs(attach->dev, sgt->sgl, sgt->nents, dir,
-			      DMA_ATTR_SKIP_CPU_SYNC)) {
+	sgt->nents = dma_map_sg_attrs(attach->dev, sgt->sgl, sgt->orig_nents,
+				      dir, DMA_ATTR_SKIP_CPU_SYNC);
+	if (!sgt->nents) {
 		sg_free_table(sgt);
 		kfree(sgt);
 		sgt = ERR_PTR(-ENOMEM);
@@ -652,7 +653,7 @@ void drm_gem_unmap_dma_buf(struct dma_buf_attachment *attach,
 	if (!sgt)
 		return;
 
-	dma_unmap_sg_attrs(attach->dev, sgt->sgl, sgt->nents, dir,
+	dma_unmap_sg_attrs(attach->dev, sgt->sgl, sgt->orig_nents, dir,
 			   DMA_ATTR_SKIP_CPU_SYNC);
 	sg_free_table(sgt);
 	kfree(sgt);
@@ -975,7 +976,7 @@ int drm_prime_sg_to_page_addr_arrays(struct sg_table *sgt, struct page **pages,
 	 */
 	page_index = 0;
 	dma_index = 0;
-	for_each_sg(sgt->sgl, sg, sgt->nents, count) {
+	for_each_sg(sgt->sgl, sg, sgt->orig_nents, count) {
 		page_len = sg->length;
 		page = sg_page(sg);
 		dma_len = sg_dma_len(sg);
-- 
1.9.1

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

^ permalink raw reply related	[flat|nested] 152+ messages in thread

* [Intel-gfx] [RFC 01/17] drm: core: fix sg_table nents vs. orig_nents misuse
@ 2020-04-28 13:19       ` Marek Szyprowski
  0 siblings, 0 replies; 152+ messages in thread
From: Marek Szyprowski @ 2020-04-28 13:19 UTC (permalink / raw)
  To: dri-devel, iommu, linaro-mm-sig, linux-kernel
  Cc: Bartlomiej Zolnierkiewicz, David Airlie, intel-gfx, amd-gfx,
	Christoph Hellwig, Benjamin Gaignard, Robin Murphy, Sumit Semwal,
	linux-arm-kernel, Marek Szyprowski

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/drm_cache.c            | 2 +-
 drivers/gpu/drm/drm_gem_shmem_helper.c | 7 ++++---
 drivers/gpu/drm/drm_prime.c            | 9 +++++----
 3 files changed, 10 insertions(+), 8 deletions(-)

diff --git a/drivers/gpu/drm/drm_cache.c b/drivers/gpu/drm/drm_cache.c
index 03e01b0..63bd497 100644
--- a/drivers/gpu/drm/drm_cache.c
+++ b/drivers/gpu/drm/drm_cache.c
@@ -127,7 +127,7 @@ static void drm_cache_flush_clflush(struct page *pages[],
 		struct sg_page_iter sg_iter;
 
 		mb(); /*CLFLUSH is ordered only by using memory barriers*/
-		for_each_sg_page(st->sgl, &sg_iter, st->nents, 0)
+		for_each_sg_page(st->sgl, &sg_iter, st->orig_nents, 0)
 			drm_clflush_page(sg_page_iter_page(&sg_iter));
 		mb(); /*Make sure that all cache line entry is flushed*/
 
diff --git a/drivers/gpu/drm/drm_gem_shmem_helper.c b/drivers/gpu/drm/drm_gem_shmem_helper.c
index df31e57..f47caa7 100644
--- a/drivers/gpu/drm/drm_gem_shmem_helper.c
+++ b/drivers/gpu/drm/drm_gem_shmem_helper.c
@@ -118,7 +118,7 @@ void drm_gem_shmem_free_object(struct drm_gem_object *obj)
 	} else {
 		if (shmem->sgt) {
 			dma_unmap_sg(obj->dev->dev, shmem->sgt->sgl,
-				     shmem->sgt->nents, DMA_BIDIRECTIONAL);
+				     shmem->sgt->orig_nents, DMA_BIDIRECTIONAL);
 			sg_free_table(shmem->sgt);
 			kfree(shmem->sgt);
 		}
@@ -396,7 +396,7 @@ void drm_gem_shmem_purge_locked(struct drm_gem_object *obj)
 	WARN_ON(!drm_gem_shmem_is_purgeable(shmem));
 
 	dma_unmap_sg(obj->dev->dev, shmem->sgt->sgl,
-		     shmem->sgt->nents, DMA_BIDIRECTIONAL);
+		     shmem->sgt->orig_nents, DMA_BIDIRECTIONAL);
 	sg_free_table(shmem->sgt);
 	kfree(shmem->sgt);
 	shmem->sgt = NULL;
@@ -623,7 +623,8 @@ struct sg_table *drm_gem_shmem_get_pages_sgt(struct drm_gem_object *obj)
 		goto err_put_pages;
 	}
 	/* Map the pages for use by the h/w. */
-	dma_map_sg(obj->dev->dev, sgt->sgl, sgt->nents, DMA_BIDIRECTIONAL);
+	sgt->nents = dma_map_sg(obj->dev->dev, sgt->sgl, sgt->orig_nents,
+				DMA_BIDIRECTIONAL);
 
 	shmem->sgt = sgt;
 
diff --git a/drivers/gpu/drm/drm_prime.c b/drivers/gpu/drm/drm_prime.c
index 282774e..f3e2d2a 100644
--- a/drivers/gpu/drm/drm_prime.c
+++ b/drivers/gpu/drm/drm_prime.c
@@ -626,8 +626,9 @@ struct sg_table *drm_gem_map_dma_buf(struct dma_buf_attachment *attach,
 	else
 		sgt = obj->dev->driver->gem_prime_get_sg_table(obj);
 
-	if (!dma_map_sg_attrs(attach->dev, sgt->sgl, sgt->nents, dir,
-			      DMA_ATTR_SKIP_CPU_SYNC)) {
+	sgt->nents = dma_map_sg_attrs(attach->dev, sgt->sgl, sgt->orig_nents,
+				      dir, DMA_ATTR_SKIP_CPU_SYNC);
+	if (!sgt->nents) {
 		sg_free_table(sgt);
 		kfree(sgt);
 		sgt = ERR_PTR(-ENOMEM);
@@ -652,7 +653,7 @@ void drm_gem_unmap_dma_buf(struct dma_buf_attachment *attach,
 	if (!sgt)
 		return;
 
-	dma_unmap_sg_attrs(attach->dev, sgt->sgl, sgt->nents, dir,
+	dma_unmap_sg_attrs(attach->dev, sgt->sgl, sgt->orig_nents, dir,
 			   DMA_ATTR_SKIP_CPU_SYNC);
 	sg_free_table(sgt);
 	kfree(sgt);
@@ -975,7 +976,7 @@ int drm_prime_sg_to_page_addr_arrays(struct sg_table *sgt, struct page **pages,
 	 */
 	page_index = 0;
 	dma_index = 0;
-	for_each_sg(sgt->sgl, sg, sgt->nents, count) {
+	for_each_sg(sgt->sgl, sg, sgt->orig_nents, count) {
 		page_len = sg->length;
 		page = sg_page(sg);
 		dma_len = sg_dma_len(sg);
-- 
1.9.1

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

^ permalink raw reply related	[flat|nested] 152+ messages in thread

* [RFC 01/17] drm: core: fix sg_table nents vs. orig_nents misuse
@ 2020-04-28 13:19       ` Marek Szyprowski
  0 siblings, 0 replies; 152+ messages in thread
From: Marek Szyprowski @ 2020-04-28 13:19 UTC (permalink / raw)
  To: dri-devel, iommu, linaro-mm-sig, linux-kernel
  Cc: Daniel Vetter, Bartlomiej Zolnierkiewicz, David Airlie,
	intel-gfx, amd-gfx, Christoph Hellwig, Benjamin Gaignard,
	Robin Murphy, Sumit Semwal, linux-arm-kernel, Marek Szyprowski

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/drm_cache.c            | 2 +-
 drivers/gpu/drm/drm_gem_shmem_helper.c | 7 ++++---
 drivers/gpu/drm/drm_prime.c            | 9 +++++----
 3 files changed, 10 insertions(+), 8 deletions(-)

diff --git a/drivers/gpu/drm/drm_cache.c b/drivers/gpu/drm/drm_cache.c
index 03e01b0..63bd497 100644
--- a/drivers/gpu/drm/drm_cache.c
+++ b/drivers/gpu/drm/drm_cache.c
@@ -127,7 +127,7 @@ static void drm_cache_flush_clflush(struct page *pages[],
 		struct sg_page_iter sg_iter;
 
 		mb(); /*CLFLUSH is ordered only by using memory barriers*/
-		for_each_sg_page(st->sgl, &sg_iter, st->nents, 0)
+		for_each_sg_page(st->sgl, &sg_iter, st->orig_nents, 0)
 			drm_clflush_page(sg_page_iter_page(&sg_iter));
 		mb(); /*Make sure that all cache line entry is flushed*/
 
diff --git a/drivers/gpu/drm/drm_gem_shmem_helper.c b/drivers/gpu/drm/drm_gem_shmem_helper.c
index df31e57..f47caa7 100644
--- a/drivers/gpu/drm/drm_gem_shmem_helper.c
+++ b/drivers/gpu/drm/drm_gem_shmem_helper.c
@@ -118,7 +118,7 @@ void drm_gem_shmem_free_object(struct drm_gem_object *obj)
 	} else {
 		if (shmem->sgt) {
 			dma_unmap_sg(obj->dev->dev, shmem->sgt->sgl,
-				     shmem->sgt->nents, DMA_BIDIRECTIONAL);
+				     shmem->sgt->orig_nents, DMA_BIDIRECTIONAL);
 			sg_free_table(shmem->sgt);
 			kfree(shmem->sgt);
 		}
@@ -396,7 +396,7 @@ void drm_gem_shmem_purge_locked(struct drm_gem_object *obj)
 	WARN_ON(!drm_gem_shmem_is_purgeable(shmem));
 
 	dma_unmap_sg(obj->dev->dev, shmem->sgt->sgl,
-		     shmem->sgt->nents, DMA_BIDIRECTIONAL);
+		     shmem->sgt->orig_nents, DMA_BIDIRECTIONAL);
 	sg_free_table(shmem->sgt);
 	kfree(shmem->sgt);
 	shmem->sgt = NULL;
@@ -623,7 +623,8 @@ struct sg_table *drm_gem_shmem_get_pages_sgt(struct drm_gem_object *obj)
 		goto err_put_pages;
 	}
 	/* Map the pages for use by the h/w. */
-	dma_map_sg(obj->dev->dev, sgt->sgl, sgt->nents, DMA_BIDIRECTIONAL);
+	sgt->nents = dma_map_sg(obj->dev->dev, sgt->sgl, sgt->orig_nents,
+				DMA_BIDIRECTIONAL);
 
 	shmem->sgt = sgt;
 
diff --git a/drivers/gpu/drm/drm_prime.c b/drivers/gpu/drm/drm_prime.c
index 282774e..f3e2d2a 100644
--- a/drivers/gpu/drm/drm_prime.c
+++ b/drivers/gpu/drm/drm_prime.c
@@ -626,8 +626,9 @@ struct sg_table *drm_gem_map_dma_buf(struct dma_buf_attachment *attach,
 	else
 		sgt = obj->dev->driver->gem_prime_get_sg_table(obj);
 
-	if (!dma_map_sg_attrs(attach->dev, sgt->sgl, sgt->nents, dir,
-			      DMA_ATTR_SKIP_CPU_SYNC)) {
+	sgt->nents = dma_map_sg_attrs(attach->dev, sgt->sgl, sgt->orig_nents,
+				      dir, DMA_ATTR_SKIP_CPU_SYNC);
+	if (!sgt->nents) {
 		sg_free_table(sgt);
 		kfree(sgt);
 		sgt = ERR_PTR(-ENOMEM);
@@ -652,7 +653,7 @@ void drm_gem_unmap_dma_buf(struct dma_buf_attachment *attach,
 	if (!sgt)
 		return;
 
-	dma_unmap_sg_attrs(attach->dev, sgt->sgl, sgt->nents, dir,
+	dma_unmap_sg_attrs(attach->dev, sgt->sgl, sgt->orig_nents, dir,
 			   DMA_ATTR_SKIP_CPU_SYNC);
 	sg_free_table(sgt);
 	kfree(sgt);
@@ -975,7 +976,7 @@ int drm_prime_sg_to_page_addr_arrays(struct sg_table *sgt, struct page **pages,
 	 */
 	page_index = 0;
 	dma_index = 0;
-	for_each_sg(sgt->sgl, sg, sgt->nents, count) {
+	for_each_sg(sgt->sgl, sg, sgt->orig_nents, count) {
 		page_len = sg->length;
 		page = sg_page(sg);
 		dma_len = sg_dma_len(sg);
-- 
1.9.1

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

^ permalink raw reply related	[flat|nested] 152+ messages in thread

* [RFC 02/17] drm: amdgpu: fix sg_table nents vs. orig_nents misuse
       [not found]   ` <CGME20200428132023eucas1p2a1993145eef91506698aa8c9750a7e43@eucas1p2.samsung.com>
                         ` (3 preceding siblings ...)
  (?)
@ 2020-04-28 13:19       ` Marek Szyprowski
  0 siblings, 0 replies; 152+ messages in thread
From: Marek Szyprowski @ 2020-04-28 13:19 UTC (permalink / raw)
  To: dri-devel, iommu, linaro-mm-sig, linux-kernel
  Cc: Marek Szyprowski, Christoph Hellwig, Robin Murphy,
	Bartlomiej Zolnierkiewicz, Sumit Semwal, Benjamin Gaignard,
	intel-gfx, linux-arm-kernel, amd-gfx, David Airlie,
	Daniel Vetter

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/amd/amdgpu/amdgpu_dma_buf.c | 7 ++++---
 drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c     | 8 ++++----
 2 files changed, 8 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_dma_buf.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_dma_buf.c
index 43d8ed7..4df813e 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_dma_buf.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_dma_buf.c
@@ -307,8 +307,9 @@ static struct sg_table *amdgpu_dma_buf_map(struct dma_buf_attachment *attach,
 		if (IS_ERR(sgt))
 			return sgt;
 
-		if (!dma_map_sg_attrs(attach->dev, sgt->sgl, sgt->nents, dir,
-				      DMA_ATTR_SKIP_CPU_SYNC))
+		sgt->nents = dma_map_sg_attrs(attach->dev, sgt->sgl, sgt->orig_nents,
+					      dir, DMA_ATTR_SKIP_CPU_SYNC);
+		if (!sgt->nents)
 			goto error_free;
 		break;
 
@@ -349,7 +350,7 @@ static void amdgpu_dma_buf_unmap(struct dma_buf_attachment *attach,
 	struct amdgpu_device *adev = amdgpu_ttm_adev(bo->tbo.bdev);
 
 	if (sgt->sgl->page_link) {
-		dma_unmap_sg(attach->dev, sgt->sgl, sgt->nents, dir);
+		dma_unmap_sg(attach->dev, sgt->sgl, sgt->orig_nents, dir);
 		sg_free_table(sgt);
 		kfree(sgt);
 	} else {
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
index d5543c2..5f31585 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
@@ -1043,7 +1043,6 @@ static int amdgpu_ttm_tt_pin_userptr(struct ttm_tt *ttm)
 {
 	struct amdgpu_device *adev = amdgpu_ttm_adev(ttm->bdev);
 	struct amdgpu_ttm_tt *gtt = (void *)ttm;
-	unsigned nents;
 	int r;
 
 	int write = !(gtt->userflags & AMDGPU_GEM_USERPTR_READONLY);
@@ -1059,8 +1058,9 @@ static int amdgpu_ttm_tt_pin_userptr(struct ttm_tt *ttm)
 
 	/* Map SG to device */
 	r = -ENOMEM;
-	nents = dma_map_sg(adev->dev, ttm->sg->sgl, ttm->sg->nents, direction);
-	if (nents == 0)
+	ttm->sg->nents = dma_map_sg(adev->dev, ttm->sg->sgl,
+				    ttm->sg->orig_nents, direction);
+	if (ttm->sg->nents == 0)
 		goto release_sg;
 
 	/* convert SG to linear array of pages and dma addresses */
@@ -1091,7 +1091,7 @@ static void amdgpu_ttm_tt_unpin_userptr(struct ttm_tt *ttm)
 		return;
 
 	/* unmap the pages mapped to the device */
-	dma_unmap_sg(adev->dev, ttm->sg->sgl, ttm->sg->nents, direction);
+	dma_unmap_sg(adev->dev, ttm->sg->sgl, ttm->sg->orig_nents, direction);
 
 	sg_free_table(ttm->sg);
 
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 152+ messages in thread

* [RFC 02/17] drm: amdgpu: fix sg_table nents vs. orig_nents misuse
@ 2020-04-28 13:19       ` Marek Szyprowski
  0 siblings, 0 replies; 152+ messages in thread
From: Marek Szyprowski @ 2020-04-28 13:19 UTC (permalink / raw)
  To: dri-devel, iommu, linaro-mm-sig, linux-kernel
  Cc: Daniel Vetter, Bartlomiej Zolnierkiewicz, David Airlie,
	intel-gfx, amd-gfx, Christoph Hellwig, Benjamin Gaignard,
	Robin Murphy, Sumit Semwal, linux-arm-kernel

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/amd/amdgpu/amdgpu_dma_buf.c | 7 ++++---
 drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c     | 8 ++++----
 2 files changed, 8 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_dma_buf.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_dma_buf.c
index 43d8ed7..4df813e 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_dma_buf.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_dma_buf.c
@@ -307,8 +307,9 @@ static struct sg_table *amdgpu_dma_buf_map(struct dma_buf_attachment *attach,
 		if (IS_ERR(sgt))
 			return sgt;
 
-		if (!dma_map_sg_attrs(attach->dev, sgt->sgl, sgt->nents, dir,
-				      DMA_ATTR_SKIP_CPU_SYNC))
+		sgt->nents = dma_map_sg_attrs(attach->dev, sgt->sgl, sgt->orig_nents,
+					      dir, DMA_ATTR_SKIP_CPU_SYNC);
+		if (!sgt->nents)
 			goto error_free;
 		break;
 
@@ -349,7 +350,7 @@ static void amdgpu_dma_buf_unmap(struct dma_buf_attachment *attach,
 	struct amdgpu_device *adev = amdgpu_ttm_adev(bo->tbo.bdev);
 
 	if (sgt->sgl->page_link) {
-		dma_unmap_sg(attach->dev, sgt->sgl, sgt->nents, dir);
+		dma_unmap_sg(attach->dev, sgt->sgl, sgt->orig_nents, dir);
 		sg_free_table(sgt);
 		kfree(sgt);
 	} else {
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
index d5543c2..5f31585 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
@@ -1043,7 +1043,6 @@ static int amdgpu_ttm_tt_pin_userptr(struct ttm_tt *ttm)
 {
 	struct amdgpu_device *adev = amdgpu_ttm_adev(ttm->bdev);
 	struct amdgpu_ttm_tt *gtt = (void *)ttm;
-	unsigned nents;
 	int r;
 
 	int write = !(gtt->userflags & AMDGPU_GEM_USERPTR_READONLY);
@@ -1059,8 +1058,9 @@ static int amdgpu_ttm_tt_pin_userptr(struct ttm_tt *ttm)
 
 	/* Map SG to device */
 	r = -ENOMEM;
-	nents = dma_map_sg(adev->dev, ttm->sg->sgl, ttm->sg->nents, direction);
-	if (nents == 0)
+	ttm->sg->nents = dma_map_sg(adev->dev, ttm->sg->sgl,
+				    ttm->sg->orig_nents, direction);
+	if (ttm->sg->nents == 0)
 		goto release_sg;
 
 	/* convert SG to linear array of pages and dma addresses */
@@ -1091,7 +1091,7 @@ static void amdgpu_ttm_tt_unpin_userptr(struct ttm_tt *ttm)
 		return;
 
 	/* unmap the pages mapped to the device */
-	dma_unmap_sg(adev->dev, ttm->sg->sgl, ttm->sg->nents, direction);
+	dma_unmap_sg(adev->dev, ttm->sg->sgl, ttm->sg->orig_nents, direction);
 
 	sg_free_table(ttm->sg);
 
-- 
1.9.1

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

^ permalink raw reply related	[flat|nested] 152+ messages in thread

* [RFC 02/17] drm: amdgpu: fix sg_table nents vs. orig_nents misuse
@ 2020-04-28 13:19       ` Marek Szyprowski
  0 siblings, 0 replies; 152+ messages in thread
From: Marek Szyprowski @ 2020-04-28 13:19 UTC (permalink / raw)
  To: dri-devel, iommu, linaro-mm-sig, linux-kernel
  Cc: Daniel Vetter, Bartlomiej Zolnierkiewicz, David Airlie,
	intel-gfx, amd-gfx, Christoph Hellwig, Benjamin Gaignard,
	Robin Murphy, Sumit Semwal, linux-arm-kernel, Marek Szyprowski

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/amd/amdgpu/amdgpu_dma_buf.c | 7 ++++---
 drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c     | 8 ++++----
 2 files changed, 8 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_dma_buf.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_dma_buf.c
index 43d8ed7..4df813e 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_dma_buf.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_dma_buf.c
@@ -307,8 +307,9 @@ static struct sg_table *amdgpu_dma_buf_map(struct dma_buf_attachment *attach,
 		if (IS_ERR(sgt))
 			return sgt;
 
-		if (!dma_map_sg_attrs(attach->dev, sgt->sgl, sgt->nents, dir,
-				      DMA_ATTR_SKIP_CPU_SYNC))
+		sgt->nents = dma_map_sg_attrs(attach->dev, sgt->sgl, sgt->orig_nents,
+					      dir, DMA_ATTR_SKIP_CPU_SYNC);
+		if (!sgt->nents)
 			goto error_free;
 		break;
 
@@ -349,7 +350,7 @@ static void amdgpu_dma_buf_unmap(struct dma_buf_attachment *attach,
 	struct amdgpu_device *adev = amdgpu_ttm_adev(bo->tbo.bdev);
 
 	if (sgt->sgl->page_link) {
-		dma_unmap_sg(attach->dev, sgt->sgl, sgt->nents, dir);
+		dma_unmap_sg(attach->dev, sgt->sgl, sgt->orig_nents, dir);
 		sg_free_table(sgt);
 		kfree(sgt);
 	} else {
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
index d5543c2..5f31585 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
@@ -1043,7 +1043,6 @@ static int amdgpu_ttm_tt_pin_userptr(struct ttm_tt *ttm)
 {
 	struct amdgpu_device *adev = amdgpu_ttm_adev(ttm->bdev);
 	struct amdgpu_ttm_tt *gtt = (void *)ttm;
-	unsigned nents;
 	int r;
 
 	int write = !(gtt->userflags & AMDGPU_GEM_USERPTR_READONLY);
@@ -1059,8 +1058,9 @@ static int amdgpu_ttm_tt_pin_userptr(struct ttm_tt *ttm)
 
 	/* Map SG to device */
 	r = -ENOMEM;
-	nents = dma_map_sg(adev->dev, ttm->sg->sgl, ttm->sg->nents, direction);
-	if (nents == 0)
+	ttm->sg->nents = dma_map_sg(adev->dev, ttm->sg->sgl,
+				    ttm->sg->orig_nents, direction);
+	if (ttm->sg->nents == 0)
 		goto release_sg;
 
 	/* convert SG to linear array of pages and dma addresses */
@@ -1091,7 +1091,7 @@ static void amdgpu_ttm_tt_unpin_userptr(struct ttm_tt *ttm)
 		return;
 
 	/* unmap the pages mapped to the device */
-	dma_unmap_sg(adev->dev, ttm->sg->sgl, ttm->sg->nents, direction);
+	dma_unmap_sg(adev->dev, ttm->sg->sgl, ttm->sg->orig_nents, direction);
 
 	sg_free_table(ttm->sg);
 
-- 
1.9.1


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

^ permalink raw reply related	[flat|nested] 152+ messages in thread

* [RFC 02/17] drm: amdgpu: fix sg_table nents vs. orig_nents misuse
@ 2020-04-28 13:19       ` Marek Szyprowski
  0 siblings, 0 replies; 152+ messages in thread
From: Marek Szyprowski @ 2020-04-28 13:19 UTC (permalink / raw)
  To: dri-devel, iommu, linaro-mm-sig, linux-kernel
  Cc: Bartlomiej Zolnierkiewicz, David Airlie, intel-gfx, amd-gfx,
	Christoph Hellwig, Robin Murphy, linux-arm-kernel,
	Marek Szyprowski

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/amd/amdgpu/amdgpu_dma_buf.c | 7 ++++---
 drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c     | 8 ++++----
 2 files changed, 8 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_dma_buf.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_dma_buf.c
index 43d8ed7..4df813e 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_dma_buf.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_dma_buf.c
@@ -307,8 +307,9 @@ static struct sg_table *amdgpu_dma_buf_map(struct dma_buf_attachment *attach,
 		if (IS_ERR(sgt))
 			return sgt;
 
-		if (!dma_map_sg_attrs(attach->dev, sgt->sgl, sgt->nents, dir,
-				      DMA_ATTR_SKIP_CPU_SYNC))
+		sgt->nents = dma_map_sg_attrs(attach->dev, sgt->sgl, sgt->orig_nents,
+					      dir, DMA_ATTR_SKIP_CPU_SYNC);
+		if (!sgt->nents)
 			goto error_free;
 		break;
 
@@ -349,7 +350,7 @@ static void amdgpu_dma_buf_unmap(struct dma_buf_attachment *attach,
 	struct amdgpu_device *adev = amdgpu_ttm_adev(bo->tbo.bdev);
 
 	if (sgt->sgl->page_link) {
-		dma_unmap_sg(attach->dev, sgt->sgl, sgt->nents, dir);
+		dma_unmap_sg(attach->dev, sgt->sgl, sgt->orig_nents, dir);
 		sg_free_table(sgt);
 		kfree(sgt);
 	} else {
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
index d5543c2..5f31585 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
@@ -1043,7 +1043,6 @@ static int amdgpu_ttm_tt_pin_userptr(struct ttm_tt *ttm)
 {
 	struct amdgpu_device *adev = amdgpu_ttm_adev(ttm->bdev);
 	struct amdgpu_ttm_tt *gtt = (void *)ttm;
-	unsigned nents;
 	int r;
 
 	int write = !(gtt->userflags & AMDGPU_GEM_USERPTR_READONLY);
@@ -1059,8 +1058,9 @@ static int amdgpu_ttm_tt_pin_userptr(struct ttm_tt *ttm)
 
 	/* Map SG to device */
 	r = -ENOMEM;
-	nents = dma_map_sg(adev->dev, ttm->sg->sgl, ttm->sg->nents, direction);
-	if (nents == 0)
+	ttm->sg->nents = dma_map_sg(adev->dev, ttm->sg->sgl,
+				    ttm->sg->orig_nents, direction);
+	if (ttm->sg->nents == 0)
 		goto release_sg;
 
 	/* convert SG to linear array of pages and dma addresses */
@@ -1091,7 +1091,7 @@ static void amdgpu_ttm_tt_unpin_userptr(struct ttm_tt *ttm)
 		return;
 
 	/* unmap the pages mapped to the device */
-	dma_unmap_sg(adev->dev, ttm->sg->sgl, ttm->sg->nents, direction);
+	dma_unmap_sg(adev->dev, ttm->sg->sgl, ttm->sg->orig_nents, direction);
 
 	sg_free_table(ttm->sg);
 
-- 
1.9.1

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

^ permalink raw reply related	[flat|nested] 152+ messages in thread

* [Intel-gfx] [RFC 02/17] drm: amdgpu: fix sg_table nents vs. orig_nents misuse
@ 2020-04-28 13:19       ` Marek Szyprowski
  0 siblings, 0 replies; 152+ messages in thread
From: Marek Szyprowski @ 2020-04-28 13:19 UTC (permalink / raw)
  To: dri-devel, iommu, linaro-mm-sig, linux-kernel
  Cc: Bartlomiej Zolnierkiewicz, David Airlie, intel-gfx, amd-gfx,
	Christoph Hellwig, Benjamin Gaignard, Robin Murphy, Sumit Semwal,
	linux-arm-kernel, Marek Szyprowski

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/amd/amdgpu/amdgpu_dma_buf.c | 7 ++++---
 drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c     | 8 ++++----
 2 files changed, 8 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_dma_buf.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_dma_buf.c
index 43d8ed7..4df813e 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_dma_buf.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_dma_buf.c
@@ -307,8 +307,9 @@ static struct sg_table *amdgpu_dma_buf_map(struct dma_buf_attachment *attach,
 		if (IS_ERR(sgt))
 			return sgt;
 
-		if (!dma_map_sg_attrs(attach->dev, sgt->sgl, sgt->nents, dir,
-				      DMA_ATTR_SKIP_CPU_SYNC))
+		sgt->nents = dma_map_sg_attrs(attach->dev, sgt->sgl, sgt->orig_nents,
+					      dir, DMA_ATTR_SKIP_CPU_SYNC);
+		if (!sgt->nents)
 			goto error_free;
 		break;
 
@@ -349,7 +350,7 @@ static void amdgpu_dma_buf_unmap(struct dma_buf_attachment *attach,
 	struct amdgpu_device *adev = amdgpu_ttm_adev(bo->tbo.bdev);
 
 	if (sgt->sgl->page_link) {
-		dma_unmap_sg(attach->dev, sgt->sgl, sgt->nents, dir);
+		dma_unmap_sg(attach->dev, sgt->sgl, sgt->orig_nents, dir);
 		sg_free_table(sgt);
 		kfree(sgt);
 	} else {
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
index d5543c2..5f31585 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
@@ -1043,7 +1043,6 @@ static int amdgpu_ttm_tt_pin_userptr(struct ttm_tt *ttm)
 {
 	struct amdgpu_device *adev = amdgpu_ttm_adev(ttm->bdev);
 	struct amdgpu_ttm_tt *gtt = (void *)ttm;
-	unsigned nents;
 	int r;
 
 	int write = !(gtt->userflags & AMDGPU_GEM_USERPTR_READONLY);
@@ -1059,8 +1058,9 @@ static int amdgpu_ttm_tt_pin_userptr(struct ttm_tt *ttm)
 
 	/* Map SG to device */
 	r = -ENOMEM;
-	nents = dma_map_sg(adev->dev, ttm->sg->sgl, ttm->sg->nents, direction);
-	if (nents == 0)
+	ttm->sg->nents = dma_map_sg(adev->dev, ttm->sg->sgl,
+				    ttm->sg->orig_nents, direction);
+	if (ttm->sg->nents == 0)
 		goto release_sg;
 
 	/* convert SG to linear array of pages and dma addresses */
@@ -1091,7 +1091,7 @@ static void amdgpu_ttm_tt_unpin_userptr(struct ttm_tt *ttm)
 		return;
 
 	/* unmap the pages mapped to the device */
-	dma_unmap_sg(adev->dev, ttm->sg->sgl, ttm->sg->nents, direction);
+	dma_unmap_sg(adev->dev, ttm->sg->sgl, ttm->sg->orig_nents, direction);
 
 	sg_free_table(ttm->sg);
 
-- 
1.9.1

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

^ permalink raw reply related	[flat|nested] 152+ messages in thread

* [RFC 02/17] drm: amdgpu: fix sg_table nents vs. orig_nents misuse
@ 2020-04-28 13:19       ` Marek Szyprowski
  0 siblings, 0 replies; 152+ messages in thread
From: Marek Szyprowski @ 2020-04-28 13:19 UTC (permalink / raw)
  To: dri-devel, iommu, linaro-mm-sig, linux-kernel
  Cc: Daniel Vetter, Bartlomiej Zolnierkiewicz, David Airlie,
	intel-gfx, amd-gfx, Christoph Hellwig, Benjamin Gaignard,
	Robin Murphy, Sumit Semwal, linux-arm-kernel, Marek Szyprowski

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/amd/amdgpu/amdgpu_dma_buf.c | 7 ++++---
 drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c     | 8 ++++----
 2 files changed, 8 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_dma_buf.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_dma_buf.c
index 43d8ed7..4df813e 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_dma_buf.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_dma_buf.c
@@ -307,8 +307,9 @@ static struct sg_table *amdgpu_dma_buf_map(struct dma_buf_attachment *attach,
 		if (IS_ERR(sgt))
 			return sgt;
 
-		if (!dma_map_sg_attrs(attach->dev, sgt->sgl, sgt->nents, dir,
-				      DMA_ATTR_SKIP_CPU_SYNC))
+		sgt->nents = dma_map_sg_attrs(attach->dev, sgt->sgl, sgt->orig_nents,
+					      dir, DMA_ATTR_SKIP_CPU_SYNC);
+		if (!sgt->nents)
 			goto error_free;
 		break;
 
@@ -349,7 +350,7 @@ static void amdgpu_dma_buf_unmap(struct dma_buf_attachment *attach,
 	struct amdgpu_device *adev = amdgpu_ttm_adev(bo->tbo.bdev);
 
 	if (sgt->sgl->page_link) {
-		dma_unmap_sg(attach->dev, sgt->sgl, sgt->nents, dir);
+		dma_unmap_sg(attach->dev, sgt->sgl, sgt->orig_nents, dir);
 		sg_free_table(sgt);
 		kfree(sgt);
 	} else {
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
index d5543c2..5f31585 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
@@ -1043,7 +1043,6 @@ static int amdgpu_ttm_tt_pin_userptr(struct ttm_tt *ttm)
 {
 	struct amdgpu_device *adev = amdgpu_ttm_adev(ttm->bdev);
 	struct amdgpu_ttm_tt *gtt = (void *)ttm;
-	unsigned nents;
 	int r;
 
 	int write = !(gtt->userflags & AMDGPU_GEM_USERPTR_READONLY);
@@ -1059,8 +1058,9 @@ static int amdgpu_ttm_tt_pin_userptr(struct ttm_tt *ttm)
 
 	/* Map SG to device */
 	r = -ENOMEM;
-	nents = dma_map_sg(adev->dev, ttm->sg->sgl, ttm->sg->nents, direction);
-	if (nents == 0)
+	ttm->sg->nents = dma_map_sg(adev->dev, ttm->sg->sgl,
+				    ttm->sg->orig_nents, direction);
+	if (ttm->sg->nents == 0)
 		goto release_sg;
 
 	/* convert SG to linear array of pages and dma addresses */
@@ -1091,7 +1091,7 @@ static void amdgpu_ttm_tt_unpin_userptr(struct ttm_tt *ttm)
 		return;
 
 	/* unmap the pages mapped to the device */
-	dma_unmap_sg(adev->dev, ttm->sg->sgl, ttm->sg->nents, direction);
+	dma_unmap_sg(adev->dev, ttm->sg->sgl, ttm->sg->orig_nents, direction);
 
 	sg_free_table(ttm->sg);
 
-- 
1.9.1

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

^ permalink raw reply related	[flat|nested] 152+ messages in thread

* [RFC 03/17] drm: armada: fix sg_table nents vs. orig_nents misuse
       [not found]   ` <CGME20200428132023eucas1p1a894986ab95ac3208c19878c6a04c0e1@eucas1p1.samsung.com>
                         ` (3 preceding siblings ...)
  (?)
@ 2020-04-28 13:19       ` Marek Szyprowski
  0 siblings, 0 replies; 152+ messages in thread
From: Marek Szyprowski @ 2020-04-28 13:19 UTC (permalink / raw)
  To: dri-devel, iommu, linaro-mm-sig, linux-kernel
  Cc: Marek Szyprowski, Christoph Hellwig, Robin Murphy,
	Bartlomiej Zolnierkiewicz, Sumit Semwal, Benjamin Gaignard,
	intel-gfx, linux-arm-kernel, amd-gfx, David Airlie,
	Daniel Vetter

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/armada/armada_gem.c | 14 +++++++++-----
 1 file changed, 9 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/armada/armada_gem.c b/drivers/gpu/drm/armada/armada_gem.c
index 976685f..749647f 100644
--- a/drivers/gpu/drm/armada/armada_gem.c
+++ b/drivers/gpu/drm/armada/armada_gem.c
@@ -407,8 +407,10 @@ int armada_gem_pwrite_ioctl(struct drm_device *dev, void *data,
 			sg_set_page(sg, page, PAGE_SIZE, 0);
 		}
 
-		if (dma_map_sg(attach->dev, sgt->sgl, sgt->nents, dir) == 0) {
-			num = sgt->nents;
+		sgt->nents = dma_map_sg(attach->dev, sgt->sgl, sgt->orig_nents,
+					dir);
+		if (sgt->nents == 0) {
+			num = sgt->orig_nents;
 			goto release;
 		}
 	} else if (dobj->page) {
@@ -418,7 +420,9 @@ int armada_gem_pwrite_ioctl(struct drm_device *dev, void *data,
 
 		sg_set_page(sgt->sgl, dobj->page, dobj->obj.size, 0);
 
-		if (dma_map_sg(attach->dev, sgt->sgl, sgt->nents, dir) == 0)
+		sgt->nents = dma_map_sg(attach->dev, sgt->sgl, sgt->orig_nents,
+					dir);
+		if (sgt->nents == 0)
 			goto free_table;
 	} else if (dobj->linear) {
 		/* Single contiguous physical region - no struct page */
@@ -449,11 +453,11 @@ static void armada_gem_prime_unmap_dma_buf(struct dma_buf_attachment *attach,
 	int i;
 
 	if (!dobj->linear)
-		dma_unmap_sg(attach->dev, sgt->sgl, sgt->nents, dir);
+		dma_unmap_sg(attach->dev, sgt->sgl, sgt->orig_nents, dir);
 
 	if (dobj->obj.filp) {
 		struct scatterlist *sg;
-		for_each_sg(sgt->sgl, sg, sgt->nents, i)
+		for_each_sg(sgt->sgl, sg, sgt->orig_nents, i)
 			put_page(sg_page(sg));
 	}
 
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 152+ messages in thread

* [RFC 03/17] drm: armada: fix sg_table nents vs. orig_nents misuse
@ 2020-04-28 13:19       ` Marek Szyprowski
  0 siblings, 0 replies; 152+ messages in thread
From: Marek Szyprowski @ 2020-04-28 13:19 UTC (permalink / raw)
  To: dri-devel, iommu, linaro-mm-sig, linux-kernel
  Cc: Daniel Vetter, Bartlomiej Zolnierkiewicz, David Airlie,
	intel-gfx, amd-gfx, Christoph Hellwig, Benjamin Gaignard,
	Robin Murphy, Sumit Semwal, linux-arm-kernel

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/armada/armada_gem.c | 14 +++++++++-----
 1 file changed, 9 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/armada/armada_gem.c b/drivers/gpu/drm/armada/armada_gem.c
index 976685f..749647f 100644
--- a/drivers/gpu/drm/armada/armada_gem.c
+++ b/drivers/gpu/drm/armada/armada_gem.c
@@ -407,8 +407,10 @@ int armada_gem_pwrite_ioctl(struct drm_device *dev, void *data,
 			sg_set_page(sg, page, PAGE_SIZE, 0);
 		}
 
-		if (dma_map_sg(attach->dev, sgt->sgl, sgt->nents, dir) == 0) {
-			num = sgt->nents;
+		sgt->nents = dma_map_sg(attach->dev, sgt->sgl, sgt->orig_nents,
+					dir);
+		if (sgt->nents == 0) {
+			num = sgt->orig_nents;
 			goto release;
 		}
 	} else if (dobj->page) {
@@ -418,7 +420,9 @@ int armada_gem_pwrite_ioctl(struct drm_device *dev, void *data,
 
 		sg_set_page(sgt->sgl, dobj->page, dobj->obj.size, 0);
 
-		if (dma_map_sg(attach->dev, sgt->sgl, sgt->nents, dir) == 0)
+		sgt->nents = dma_map_sg(attach->dev, sgt->sgl, sgt->orig_nents,
+					dir);
+		if (sgt->nents == 0)
 			goto free_table;
 	} else if (dobj->linear) {
 		/* Single contiguous physical region - no struct page */
@@ -449,11 +453,11 @@ static void armada_gem_prime_unmap_dma_buf(struct dma_buf_attachment *attach,
 	int i;
 
 	if (!dobj->linear)
-		dma_unmap_sg(attach->dev, sgt->sgl, sgt->nents, dir);
+		dma_unmap_sg(attach->dev, sgt->sgl, sgt->orig_nents, dir);
 
 	if (dobj->obj.filp) {
 		struct scatterlist *sg;
-		for_each_sg(sgt->sgl, sg, sgt->nents, i)
+		for_each_sg(sgt->sgl, sg, sgt->orig_nents, i)
 			put_page(sg_page(sg));
 	}
 
-- 
1.9.1

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

^ permalink raw reply related	[flat|nested] 152+ messages in thread

* [RFC 03/17] drm: armada: fix sg_table nents vs. orig_nents misuse
@ 2020-04-28 13:19       ` Marek Szyprowski
  0 siblings, 0 replies; 152+ messages in thread
From: Marek Szyprowski @ 2020-04-28 13:19 UTC (permalink / raw)
  To: dri-devel, iommu, linaro-mm-sig, linux-kernel
  Cc: Daniel Vetter, Bartlomiej Zolnierkiewicz, David Airlie,
	intel-gfx, amd-gfx, Christoph Hellwig, Benjamin Gaignard,
	Robin Murphy, Sumit Semwal, linux-arm-kernel, Marek Szyprowski

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/armada/armada_gem.c | 14 +++++++++-----
 1 file changed, 9 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/armada/armada_gem.c b/drivers/gpu/drm/armada/armada_gem.c
index 976685f..749647f 100644
--- a/drivers/gpu/drm/armada/armada_gem.c
+++ b/drivers/gpu/drm/armada/armada_gem.c
@@ -407,8 +407,10 @@ int armada_gem_pwrite_ioctl(struct drm_device *dev, void *data,
 			sg_set_page(sg, page, PAGE_SIZE, 0);
 		}
 
-		if (dma_map_sg(attach->dev, sgt->sgl, sgt->nents, dir) == 0) {
-			num = sgt->nents;
+		sgt->nents = dma_map_sg(attach->dev, sgt->sgl, sgt->orig_nents,
+					dir);
+		if (sgt->nents == 0) {
+			num = sgt->orig_nents;
 			goto release;
 		}
 	} else if (dobj->page) {
@@ -418,7 +420,9 @@ int armada_gem_pwrite_ioctl(struct drm_device *dev, void *data,
 
 		sg_set_page(sgt->sgl, dobj->page, dobj->obj.size, 0);
 
-		if (dma_map_sg(attach->dev, sgt->sgl, sgt->nents, dir) == 0)
+		sgt->nents = dma_map_sg(attach->dev, sgt->sgl, sgt->orig_nents,
+					dir);
+		if (sgt->nents == 0)
 			goto free_table;
 	} else if (dobj->linear) {
 		/* Single contiguous physical region - no struct page */
@@ -449,11 +453,11 @@ static void armada_gem_prime_unmap_dma_buf(struct dma_buf_attachment *attach,
 	int i;
 
 	if (!dobj->linear)
-		dma_unmap_sg(attach->dev, sgt->sgl, sgt->nents, dir);
+		dma_unmap_sg(attach->dev, sgt->sgl, sgt->orig_nents, dir);
 
 	if (dobj->obj.filp) {
 		struct scatterlist *sg;
-		for_each_sg(sgt->sgl, sg, sgt->nents, i)
+		for_each_sg(sgt->sgl, sg, sgt->orig_nents, i)
 			put_page(sg_page(sg));
 	}
 
-- 
1.9.1


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

^ permalink raw reply related	[flat|nested] 152+ messages in thread

* [RFC 03/17] drm: armada: fix sg_table nents vs. orig_nents misuse
@ 2020-04-28 13:19       ` Marek Szyprowski
  0 siblings, 0 replies; 152+ messages in thread
From: Marek Szyprowski @ 2020-04-28 13:19 UTC (permalink / raw)
  To: dri-devel, iommu, linaro-mm-sig, linux-kernel
  Cc: Bartlomiej Zolnierkiewicz, David Airlie, intel-gfx, amd-gfx,
	Christoph Hellwig, Robin Murphy, linux-arm-kernel,
	Marek Szyprowski

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/armada/armada_gem.c | 14 +++++++++-----
 1 file changed, 9 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/armada/armada_gem.c b/drivers/gpu/drm/armada/armada_gem.c
index 976685f..749647f 100644
--- a/drivers/gpu/drm/armada/armada_gem.c
+++ b/drivers/gpu/drm/armada/armada_gem.c
@@ -407,8 +407,10 @@ int armada_gem_pwrite_ioctl(struct drm_device *dev, void *data,
 			sg_set_page(sg, page, PAGE_SIZE, 0);
 		}
 
-		if (dma_map_sg(attach->dev, sgt->sgl, sgt->nents, dir) == 0) {
-			num = sgt->nents;
+		sgt->nents = dma_map_sg(attach->dev, sgt->sgl, sgt->orig_nents,
+					dir);
+		if (sgt->nents == 0) {
+			num = sgt->orig_nents;
 			goto release;
 		}
 	} else if (dobj->page) {
@@ -418,7 +420,9 @@ int armada_gem_pwrite_ioctl(struct drm_device *dev, void *data,
 
 		sg_set_page(sgt->sgl, dobj->page, dobj->obj.size, 0);
 
-		if (dma_map_sg(attach->dev, sgt->sgl, sgt->nents, dir) == 0)
+		sgt->nents = dma_map_sg(attach->dev, sgt->sgl, sgt->orig_nents,
+					dir);
+		if (sgt->nents == 0)
 			goto free_table;
 	} else if (dobj->linear) {
 		/* Single contiguous physical region - no struct page */
@@ -449,11 +453,11 @@ static void armada_gem_prime_unmap_dma_buf(struct dma_buf_attachment *attach,
 	int i;
 
 	if (!dobj->linear)
-		dma_unmap_sg(attach->dev, sgt->sgl, sgt->nents, dir);
+		dma_unmap_sg(attach->dev, sgt->sgl, sgt->orig_nents, dir);
 
 	if (dobj->obj.filp) {
 		struct scatterlist *sg;
-		for_each_sg(sgt->sgl, sg, sgt->nents, i)
+		for_each_sg(sgt->sgl, sg, sgt->orig_nents, i)
 			put_page(sg_page(sg));
 	}
 
-- 
1.9.1

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

^ permalink raw reply related	[flat|nested] 152+ messages in thread

* [Intel-gfx] [RFC 03/17] drm: armada: fix sg_table nents vs. orig_nents misuse
@ 2020-04-28 13:19       ` Marek Szyprowski
  0 siblings, 0 replies; 152+ messages in thread
From: Marek Szyprowski @ 2020-04-28 13:19 UTC (permalink / raw)
  To: dri-devel, iommu, linaro-mm-sig, linux-kernel
  Cc: Bartlomiej Zolnierkiewicz, David Airlie, intel-gfx, amd-gfx,
	Christoph Hellwig, Benjamin Gaignard, Robin Murphy, Sumit Semwal,
	linux-arm-kernel, Marek Szyprowski

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/armada/armada_gem.c | 14 +++++++++-----
 1 file changed, 9 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/armada/armada_gem.c b/drivers/gpu/drm/armada/armada_gem.c
index 976685f..749647f 100644
--- a/drivers/gpu/drm/armada/armada_gem.c
+++ b/drivers/gpu/drm/armada/armada_gem.c
@@ -407,8 +407,10 @@ int armada_gem_pwrite_ioctl(struct drm_device *dev, void *data,
 			sg_set_page(sg, page, PAGE_SIZE, 0);
 		}
 
-		if (dma_map_sg(attach->dev, sgt->sgl, sgt->nents, dir) == 0) {
-			num = sgt->nents;
+		sgt->nents = dma_map_sg(attach->dev, sgt->sgl, sgt->orig_nents,
+					dir);
+		if (sgt->nents == 0) {
+			num = sgt->orig_nents;
 			goto release;
 		}
 	} else if (dobj->page) {
@@ -418,7 +420,9 @@ int armada_gem_pwrite_ioctl(struct drm_device *dev, void *data,
 
 		sg_set_page(sgt->sgl, dobj->page, dobj->obj.size, 0);
 
-		if (dma_map_sg(attach->dev, sgt->sgl, sgt->nents, dir) == 0)
+		sgt->nents = dma_map_sg(attach->dev, sgt->sgl, sgt->orig_nents,
+					dir);
+		if (sgt->nents == 0)
 			goto free_table;
 	} else if (dobj->linear) {
 		/* Single contiguous physical region - no struct page */
@@ -449,11 +453,11 @@ static void armada_gem_prime_unmap_dma_buf(struct dma_buf_attachment *attach,
 	int i;
 
 	if (!dobj->linear)
-		dma_unmap_sg(attach->dev, sgt->sgl, sgt->nents, dir);
+		dma_unmap_sg(attach->dev, sgt->sgl, sgt->orig_nents, dir);
 
 	if (dobj->obj.filp) {
 		struct scatterlist *sg;
-		for_each_sg(sgt->sgl, sg, sgt->nents, i)
+		for_each_sg(sgt->sgl, sg, sgt->orig_nents, i)
 			put_page(sg_page(sg));
 	}
 
-- 
1.9.1

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

^ permalink raw reply related	[flat|nested] 152+ messages in thread

* [RFC 03/17] drm: armada: fix sg_table nents vs. orig_nents misuse
@ 2020-04-28 13:19       ` Marek Szyprowski
  0 siblings, 0 replies; 152+ messages in thread
From: Marek Szyprowski @ 2020-04-28 13:19 UTC (permalink / raw)
  To: dri-devel, iommu, linaro-mm-sig, linux-kernel
  Cc: Daniel Vetter, Bartlomiej Zolnierkiewicz, David Airlie,
	intel-gfx, amd-gfx, Christoph Hellwig, Benjamin Gaignard,
	Robin Murphy, Sumit Semwal, linux-arm-kernel, Marek Szyprowski

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/armada/armada_gem.c | 14 +++++++++-----
 1 file changed, 9 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/armada/armada_gem.c b/drivers/gpu/drm/armada/armada_gem.c
index 976685f..749647f 100644
--- a/drivers/gpu/drm/armada/armada_gem.c
+++ b/drivers/gpu/drm/armada/armada_gem.c
@@ -407,8 +407,10 @@ int armada_gem_pwrite_ioctl(struct drm_device *dev, void *data,
 			sg_set_page(sg, page, PAGE_SIZE, 0);
 		}
 
-		if (dma_map_sg(attach->dev, sgt->sgl, sgt->nents, dir) == 0) {
-			num = sgt->nents;
+		sgt->nents = dma_map_sg(attach->dev, sgt->sgl, sgt->orig_nents,
+					dir);
+		if (sgt->nents == 0) {
+			num = sgt->orig_nents;
 			goto release;
 		}
 	} else if (dobj->page) {
@@ -418,7 +420,9 @@ int armada_gem_pwrite_ioctl(struct drm_device *dev, void *data,
 
 		sg_set_page(sgt->sgl, dobj->page, dobj->obj.size, 0);
 
-		if (dma_map_sg(attach->dev, sgt->sgl, sgt->nents, dir) == 0)
+		sgt->nents = dma_map_sg(attach->dev, sgt->sgl, sgt->orig_nents,
+					dir);
+		if (sgt->nents == 0)
 			goto free_table;
 	} else if (dobj->linear) {
 		/* Single contiguous physical region - no struct page */
@@ -449,11 +453,11 @@ static void armada_gem_prime_unmap_dma_buf(struct dma_buf_attachment *attach,
 	int i;
 
 	if (!dobj->linear)
-		dma_unmap_sg(attach->dev, sgt->sgl, sgt->nents, dir);
+		dma_unmap_sg(attach->dev, sgt->sgl, sgt->orig_nents, dir);
 
 	if (dobj->obj.filp) {
 		struct scatterlist *sg;
-		for_each_sg(sgt->sgl, sg, sgt->nents, i)
+		for_each_sg(sgt->sgl, sg, sgt->orig_nents, i)
 			put_page(sg_page(sg));
 	}
 
-- 
1.9.1

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

^ permalink raw reply related	[flat|nested] 152+ messages in thread

* [RFC 04/17] drm: etnaviv: fix sg_table nents vs. orig_nents misuse
       [not found]   ` <CGME20200428132024eucas1p1c51178774db6fb4cab748522c86646cd@eucas1p1.samsung.com>
                         ` (3 preceding siblings ...)
  (?)
@ 2020-04-28 13:19       ` Marek Szyprowski
  0 siblings, 0 replies; 152+ messages in thread
From: Marek Szyprowski @ 2020-04-28 13:19 UTC (permalink / raw)
  To: dri-devel, iommu, linaro-mm-sig, linux-kernel
  Cc: Marek Szyprowski, Christoph Hellwig, Robin Murphy,
	Bartlomiej Zolnierkiewicz, Sumit Semwal, Benjamin Gaignard,
	intel-gfx, linux-arm-kernel, amd-gfx, David Airlie,
	Daniel Vetter

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/etnaviv/etnaviv_gem.c | 10 ++++++----
 1 file changed, 6 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/etnaviv/etnaviv_gem.c b/drivers/gpu/drm/etnaviv/etnaviv_gem.c
index dc9ef30..a224a97 100644
--- a/drivers/gpu/drm/etnaviv/etnaviv_gem.c
+++ b/drivers/gpu/drm/etnaviv/etnaviv_gem.c
@@ -27,7 +27,8 @@ static void etnaviv_gem_scatter_map(struct etnaviv_gem_object *etnaviv_obj)
 	 * because display controller, GPU, etc. are not coherent.
 	 */
 	if (etnaviv_obj->flags & ETNA_BO_CACHE_MASK)
-		dma_map_sg(dev->dev, sgt->sgl, sgt->nents, DMA_BIDIRECTIONAL);
+		sgt->nents = dma_map_sg(dev->dev, sgt->sgl, sgt->orig_nents,
+					DMA_BIDIRECTIONAL);
 }
 
 static void etnaviv_gem_scatterlist_unmap(struct etnaviv_gem_object *etnaviv_obj)
@@ -51,7 +52,8 @@ static void etnaviv_gem_scatterlist_unmap(struct etnaviv_gem_object *etnaviv_obj
 	 * discard those writes.
 	 */
 	if (etnaviv_obj->flags & ETNA_BO_CACHE_MASK)
-		dma_unmap_sg(dev->dev, sgt->sgl, sgt->nents, DMA_BIDIRECTIONAL);
+		dma_unmap_sg(dev->dev, sgt->sgl, sgt->orig_nents,
+			     DMA_BIDIRECTIONAL);
 }
 
 /* called with etnaviv_obj->lock held */
@@ -405,7 +407,7 @@ int etnaviv_gem_cpu_prep(struct drm_gem_object *obj, u32 op,
 
 	if (etnaviv_obj->flags & ETNA_BO_CACHED) {
 		dma_sync_sg_for_cpu(dev->dev, etnaviv_obj->sgt->sgl,
-				    etnaviv_obj->sgt->nents,
+				    etnaviv_obj->sgt->orig_nents,
 				    etnaviv_op_to_dma_dir(op));
 		etnaviv_obj->last_cpu_prep_op = op;
 	}
@@ -422,7 +424,7 @@ int etnaviv_gem_cpu_fini(struct drm_gem_object *obj)
 		/* fini without a prep is almost certainly a userspace error */
 		WARN_ON(etnaviv_obj->last_cpu_prep_op == 0);
 		dma_sync_sg_for_device(dev->dev, etnaviv_obj->sgt->sgl,
-			etnaviv_obj->sgt->nents,
+			etnaviv_obj->sgt->orig_nents,
 			etnaviv_op_to_dma_dir(etnaviv_obj->last_cpu_prep_op));
 		etnaviv_obj->last_cpu_prep_op = 0;
 	}
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 152+ messages in thread

* [RFC 04/17] drm: etnaviv: fix sg_table nents vs. orig_nents misuse
@ 2020-04-28 13:19       ` Marek Szyprowski
  0 siblings, 0 replies; 152+ messages in thread
From: Marek Szyprowski @ 2020-04-28 13:19 UTC (permalink / raw)
  To: dri-devel, iommu, linaro-mm-sig, linux-kernel
  Cc: Daniel Vetter, Bartlomiej Zolnierkiewicz, David Airlie,
	intel-gfx, amd-gfx, Christoph Hellwig, Benjamin Gaignard,
	Robin Murphy, Sumit Semwal, linux-arm-kernel

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/etnaviv/etnaviv_gem.c | 10 ++++++----
 1 file changed, 6 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/etnaviv/etnaviv_gem.c b/drivers/gpu/drm/etnaviv/etnaviv_gem.c
index dc9ef30..a224a97 100644
--- a/drivers/gpu/drm/etnaviv/etnaviv_gem.c
+++ b/drivers/gpu/drm/etnaviv/etnaviv_gem.c
@@ -27,7 +27,8 @@ static void etnaviv_gem_scatter_map(struct etnaviv_gem_object *etnaviv_obj)
 	 * because display controller, GPU, etc. are not coherent.
 	 */
 	if (etnaviv_obj->flags & ETNA_BO_CACHE_MASK)
-		dma_map_sg(dev->dev, sgt->sgl, sgt->nents, DMA_BIDIRECTIONAL);
+		sgt->nents = dma_map_sg(dev->dev, sgt->sgl, sgt->orig_nents,
+					DMA_BIDIRECTIONAL);
 }
 
 static void etnaviv_gem_scatterlist_unmap(struct etnaviv_gem_object *etnaviv_obj)
@@ -51,7 +52,8 @@ static void etnaviv_gem_scatterlist_unmap(struct etnaviv_gem_object *etnaviv_obj
 	 * discard those writes.
 	 */
 	if (etnaviv_obj->flags & ETNA_BO_CACHE_MASK)
-		dma_unmap_sg(dev->dev, sgt->sgl, sgt->nents, DMA_BIDIRECTIONAL);
+		dma_unmap_sg(dev->dev, sgt->sgl, sgt->orig_nents,
+			     DMA_BIDIRECTIONAL);
 }
 
 /* called with etnaviv_obj->lock held */
@@ -405,7 +407,7 @@ int etnaviv_gem_cpu_prep(struct drm_gem_object *obj, u32 op,
 
 	if (etnaviv_obj->flags & ETNA_BO_CACHED) {
 		dma_sync_sg_for_cpu(dev->dev, etnaviv_obj->sgt->sgl,
-				    etnaviv_obj->sgt->nents,
+				    etnaviv_obj->sgt->orig_nents,
 				    etnaviv_op_to_dma_dir(op));
 		etnaviv_obj->last_cpu_prep_op = op;
 	}
@@ -422,7 +424,7 @@ int etnaviv_gem_cpu_fini(struct drm_gem_object *obj)
 		/* fini without a prep is almost certainly a userspace error */
 		WARN_ON(etnaviv_obj->last_cpu_prep_op == 0);
 		dma_sync_sg_for_device(dev->dev, etnaviv_obj->sgt->sgl,
-			etnaviv_obj->sgt->nents,
+			etnaviv_obj->sgt->orig_nents,
 			etnaviv_op_to_dma_dir(etnaviv_obj->last_cpu_prep_op));
 		etnaviv_obj->last_cpu_prep_op = 0;
 	}
-- 
1.9.1

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

^ permalink raw reply related	[flat|nested] 152+ messages in thread

* [RFC 04/17] drm: etnaviv: fix sg_table nents vs. orig_nents misuse
@ 2020-04-28 13:19       ` Marek Szyprowski
  0 siblings, 0 replies; 152+ messages in thread
From: Marek Szyprowski @ 2020-04-28 13:19 UTC (permalink / raw)
  To: dri-devel, iommu, linaro-mm-sig, linux-kernel
  Cc: Daniel Vetter, Bartlomiej Zolnierkiewicz, David Airlie,
	intel-gfx, amd-gfx, Christoph Hellwig, Benjamin Gaignard,
	Robin Murphy, Sumit Semwal, linux-arm-kernel, Marek Szyprowski

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/etnaviv/etnaviv_gem.c | 10 ++++++----
 1 file changed, 6 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/etnaviv/etnaviv_gem.c b/drivers/gpu/drm/etnaviv/etnaviv_gem.c
index dc9ef30..a224a97 100644
--- a/drivers/gpu/drm/etnaviv/etnaviv_gem.c
+++ b/drivers/gpu/drm/etnaviv/etnaviv_gem.c
@@ -27,7 +27,8 @@ static void etnaviv_gem_scatter_map(struct etnaviv_gem_object *etnaviv_obj)
 	 * because display controller, GPU, etc. are not coherent.
 	 */
 	if (etnaviv_obj->flags & ETNA_BO_CACHE_MASK)
-		dma_map_sg(dev->dev, sgt->sgl, sgt->nents, DMA_BIDIRECTIONAL);
+		sgt->nents = dma_map_sg(dev->dev, sgt->sgl, sgt->orig_nents,
+					DMA_BIDIRECTIONAL);
 }
 
 static void etnaviv_gem_scatterlist_unmap(struct etnaviv_gem_object *etnaviv_obj)
@@ -51,7 +52,8 @@ static void etnaviv_gem_scatterlist_unmap(struct etnaviv_gem_object *etnaviv_obj
 	 * discard those writes.
 	 */
 	if (etnaviv_obj->flags & ETNA_BO_CACHE_MASK)
-		dma_unmap_sg(dev->dev, sgt->sgl, sgt->nents, DMA_BIDIRECTIONAL);
+		dma_unmap_sg(dev->dev, sgt->sgl, sgt->orig_nents,
+			     DMA_BIDIRECTIONAL);
 }
 
 /* called with etnaviv_obj->lock held */
@@ -405,7 +407,7 @@ int etnaviv_gem_cpu_prep(struct drm_gem_object *obj, u32 op,
 
 	if (etnaviv_obj->flags & ETNA_BO_CACHED) {
 		dma_sync_sg_for_cpu(dev->dev, etnaviv_obj->sgt->sgl,
-				    etnaviv_obj->sgt->nents,
+				    etnaviv_obj->sgt->orig_nents,
 				    etnaviv_op_to_dma_dir(op));
 		etnaviv_obj->last_cpu_prep_op = op;
 	}
@@ -422,7 +424,7 @@ int etnaviv_gem_cpu_fini(struct drm_gem_object *obj)
 		/* fini without a prep is almost certainly a userspace error */
 		WARN_ON(etnaviv_obj->last_cpu_prep_op == 0);
 		dma_sync_sg_for_device(dev->dev, etnaviv_obj->sgt->sgl,
-			etnaviv_obj->sgt->nents,
+			etnaviv_obj->sgt->orig_nents,
 			etnaviv_op_to_dma_dir(etnaviv_obj->last_cpu_prep_op));
 		etnaviv_obj->last_cpu_prep_op = 0;
 	}
-- 
1.9.1


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

^ permalink raw reply related	[flat|nested] 152+ messages in thread

* [RFC 04/17] drm: etnaviv: fix sg_table nents vs. orig_nents misuse
@ 2020-04-28 13:19       ` Marek Szyprowski
  0 siblings, 0 replies; 152+ messages in thread
From: Marek Szyprowski @ 2020-04-28 13:19 UTC (permalink / raw)
  To: dri-devel, iommu, linaro-mm-sig, linux-kernel
  Cc: Bartlomiej Zolnierkiewicz, David Airlie, intel-gfx, amd-gfx,
	Christoph Hellwig, Robin Murphy, linux-arm-kernel,
	Marek Szyprowski

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/etnaviv/etnaviv_gem.c | 10 ++++++----
 1 file changed, 6 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/etnaviv/etnaviv_gem.c b/drivers/gpu/drm/etnaviv/etnaviv_gem.c
index dc9ef30..a224a97 100644
--- a/drivers/gpu/drm/etnaviv/etnaviv_gem.c
+++ b/drivers/gpu/drm/etnaviv/etnaviv_gem.c
@@ -27,7 +27,8 @@ static void etnaviv_gem_scatter_map(struct etnaviv_gem_object *etnaviv_obj)
 	 * because display controller, GPU, etc. are not coherent.
 	 */
 	if (etnaviv_obj->flags & ETNA_BO_CACHE_MASK)
-		dma_map_sg(dev->dev, sgt->sgl, sgt->nents, DMA_BIDIRECTIONAL);
+		sgt->nents = dma_map_sg(dev->dev, sgt->sgl, sgt->orig_nents,
+					DMA_BIDIRECTIONAL);
 }
 
 static void etnaviv_gem_scatterlist_unmap(struct etnaviv_gem_object *etnaviv_obj)
@@ -51,7 +52,8 @@ static void etnaviv_gem_scatterlist_unmap(struct etnaviv_gem_object *etnaviv_obj
 	 * discard those writes.
 	 */
 	if (etnaviv_obj->flags & ETNA_BO_CACHE_MASK)
-		dma_unmap_sg(dev->dev, sgt->sgl, sgt->nents, DMA_BIDIRECTIONAL);
+		dma_unmap_sg(dev->dev, sgt->sgl, sgt->orig_nents,
+			     DMA_BIDIRECTIONAL);
 }
 
 /* called with etnaviv_obj->lock held */
@@ -405,7 +407,7 @@ int etnaviv_gem_cpu_prep(struct drm_gem_object *obj, u32 op,
 
 	if (etnaviv_obj->flags & ETNA_BO_CACHED) {
 		dma_sync_sg_for_cpu(dev->dev, etnaviv_obj->sgt->sgl,
-				    etnaviv_obj->sgt->nents,
+				    etnaviv_obj->sgt->orig_nents,
 				    etnaviv_op_to_dma_dir(op));
 		etnaviv_obj->last_cpu_prep_op = op;
 	}
@@ -422,7 +424,7 @@ int etnaviv_gem_cpu_fini(struct drm_gem_object *obj)
 		/* fini without a prep is almost certainly a userspace error */
 		WARN_ON(etnaviv_obj->last_cpu_prep_op == 0);
 		dma_sync_sg_for_device(dev->dev, etnaviv_obj->sgt->sgl,
-			etnaviv_obj->sgt->nents,
+			etnaviv_obj->sgt->orig_nents,
 			etnaviv_op_to_dma_dir(etnaviv_obj->last_cpu_prep_op));
 		etnaviv_obj->last_cpu_prep_op = 0;
 	}
-- 
1.9.1

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

^ permalink raw reply related	[flat|nested] 152+ messages in thread

* [Intel-gfx] [RFC 04/17] drm: etnaviv: fix sg_table nents vs. orig_nents misuse
@ 2020-04-28 13:19       ` Marek Szyprowski
  0 siblings, 0 replies; 152+ messages in thread
From: Marek Szyprowski @ 2020-04-28 13:19 UTC (permalink / raw)
  To: dri-devel, iommu, linaro-mm-sig, linux-kernel
  Cc: Bartlomiej Zolnierkiewicz, David Airlie, intel-gfx, amd-gfx,
	Christoph Hellwig, Benjamin Gaignard, Robin Murphy, Sumit Semwal,
	linux-arm-kernel, Marek Szyprowski

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/etnaviv/etnaviv_gem.c | 10 ++++++----
 1 file changed, 6 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/etnaviv/etnaviv_gem.c b/drivers/gpu/drm/etnaviv/etnaviv_gem.c
index dc9ef30..a224a97 100644
--- a/drivers/gpu/drm/etnaviv/etnaviv_gem.c
+++ b/drivers/gpu/drm/etnaviv/etnaviv_gem.c
@@ -27,7 +27,8 @@ static void etnaviv_gem_scatter_map(struct etnaviv_gem_object *etnaviv_obj)
 	 * because display controller, GPU, etc. are not coherent.
 	 */
 	if (etnaviv_obj->flags & ETNA_BO_CACHE_MASK)
-		dma_map_sg(dev->dev, sgt->sgl, sgt->nents, DMA_BIDIRECTIONAL);
+		sgt->nents = dma_map_sg(dev->dev, sgt->sgl, sgt->orig_nents,
+					DMA_BIDIRECTIONAL);
 }
 
 static void etnaviv_gem_scatterlist_unmap(struct etnaviv_gem_object *etnaviv_obj)
@@ -51,7 +52,8 @@ static void etnaviv_gem_scatterlist_unmap(struct etnaviv_gem_object *etnaviv_obj
 	 * discard those writes.
 	 */
 	if (etnaviv_obj->flags & ETNA_BO_CACHE_MASK)
-		dma_unmap_sg(dev->dev, sgt->sgl, sgt->nents, DMA_BIDIRECTIONAL);
+		dma_unmap_sg(dev->dev, sgt->sgl, sgt->orig_nents,
+			     DMA_BIDIRECTIONAL);
 }
 
 /* called with etnaviv_obj->lock held */
@@ -405,7 +407,7 @@ int etnaviv_gem_cpu_prep(struct drm_gem_object *obj, u32 op,
 
 	if (etnaviv_obj->flags & ETNA_BO_CACHED) {
 		dma_sync_sg_for_cpu(dev->dev, etnaviv_obj->sgt->sgl,
-				    etnaviv_obj->sgt->nents,
+				    etnaviv_obj->sgt->orig_nents,
 				    etnaviv_op_to_dma_dir(op));
 		etnaviv_obj->last_cpu_prep_op = op;
 	}
@@ -422,7 +424,7 @@ int etnaviv_gem_cpu_fini(struct drm_gem_object *obj)
 		/* fini without a prep is almost certainly a userspace error */
 		WARN_ON(etnaviv_obj->last_cpu_prep_op == 0);
 		dma_sync_sg_for_device(dev->dev, etnaviv_obj->sgt->sgl,
-			etnaviv_obj->sgt->nents,
+			etnaviv_obj->sgt->orig_nents,
 			etnaviv_op_to_dma_dir(etnaviv_obj->last_cpu_prep_op));
 		etnaviv_obj->last_cpu_prep_op = 0;
 	}
-- 
1.9.1

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

^ permalink raw reply related	[flat|nested] 152+ messages in thread

* [RFC 04/17] drm: etnaviv: fix sg_table nents vs. orig_nents misuse
@ 2020-04-28 13:19       ` Marek Szyprowski
  0 siblings, 0 replies; 152+ messages in thread
From: Marek Szyprowski @ 2020-04-28 13:19 UTC (permalink / raw)
  To: dri-devel, iommu, linaro-mm-sig, linux-kernel
  Cc: Daniel Vetter, Bartlomiej Zolnierkiewicz, David Airlie,
	intel-gfx, amd-gfx, Christoph Hellwig, Benjamin Gaignard,
	Robin Murphy, Sumit Semwal, linux-arm-kernel, Marek Szyprowski

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/etnaviv/etnaviv_gem.c | 10 ++++++----
 1 file changed, 6 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/etnaviv/etnaviv_gem.c b/drivers/gpu/drm/etnaviv/etnaviv_gem.c
index dc9ef30..a224a97 100644
--- a/drivers/gpu/drm/etnaviv/etnaviv_gem.c
+++ b/drivers/gpu/drm/etnaviv/etnaviv_gem.c
@@ -27,7 +27,8 @@ static void etnaviv_gem_scatter_map(struct etnaviv_gem_object *etnaviv_obj)
 	 * because display controller, GPU, etc. are not coherent.
 	 */
 	if (etnaviv_obj->flags & ETNA_BO_CACHE_MASK)
-		dma_map_sg(dev->dev, sgt->sgl, sgt->nents, DMA_BIDIRECTIONAL);
+		sgt->nents = dma_map_sg(dev->dev, sgt->sgl, sgt->orig_nents,
+					DMA_BIDIRECTIONAL);
 }
 
 static void etnaviv_gem_scatterlist_unmap(struct etnaviv_gem_object *etnaviv_obj)
@@ -51,7 +52,8 @@ static void etnaviv_gem_scatterlist_unmap(struct etnaviv_gem_object *etnaviv_obj
 	 * discard those writes.
 	 */
 	if (etnaviv_obj->flags & ETNA_BO_CACHE_MASK)
-		dma_unmap_sg(dev->dev, sgt->sgl, sgt->nents, DMA_BIDIRECTIONAL);
+		dma_unmap_sg(dev->dev, sgt->sgl, sgt->orig_nents,
+			     DMA_BIDIRECTIONAL);
 }
 
 /* called with etnaviv_obj->lock held */
@@ -405,7 +407,7 @@ int etnaviv_gem_cpu_prep(struct drm_gem_object *obj, u32 op,
 
 	if (etnaviv_obj->flags & ETNA_BO_CACHED) {
 		dma_sync_sg_for_cpu(dev->dev, etnaviv_obj->sgt->sgl,
-				    etnaviv_obj->sgt->nents,
+				    etnaviv_obj->sgt->orig_nents,
 				    etnaviv_op_to_dma_dir(op));
 		etnaviv_obj->last_cpu_prep_op = op;
 	}
@@ -422,7 +424,7 @@ int etnaviv_gem_cpu_fini(struct drm_gem_object *obj)
 		/* fini without a prep is almost certainly a userspace error */
 		WARN_ON(etnaviv_obj->last_cpu_prep_op == 0);
 		dma_sync_sg_for_device(dev->dev, etnaviv_obj->sgt->sgl,
-			etnaviv_obj->sgt->nents,
+			etnaviv_obj->sgt->orig_nents,
 			etnaviv_op_to_dma_dir(etnaviv_obj->last_cpu_prep_op));
 		etnaviv_obj->last_cpu_prep_op = 0;
 	}
-- 
1.9.1

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

^ permalink raw reply related	[flat|nested] 152+ messages in thread

* [RFC 05/17] drm: exynos: fix sg_table nents vs. orig_nents misuse
       [not found]   ` <CGME20200428132025eucas1p15cf78bdedef6eebc477c7e8429a6f971@eucas1p1.samsung.com>
                         ` (3 preceding siblings ...)
  (?)
@ 2020-04-28 13:19       ` Marek Szyprowski
  0 siblings, 0 replies; 152+ messages in thread
From: Marek Szyprowski @ 2020-04-28 13:19 UTC (permalink / raw)
  To: dri-devel, iommu, linaro-mm-sig, linux-kernel
  Cc: Marek Szyprowski, Christoph Hellwig, Robin Murphy,
	Bartlomiej Zolnierkiewicz, Sumit Semwal, Benjamin Gaignard,
	intel-gfx, linux-arm-kernel, amd-gfx, David Airlie,
	Daniel Vetter

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/exynos/exynos_drm_g2d.c | 7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/exynos/exynos_drm_g2d.c b/drivers/gpu/drm/exynos/exynos_drm_g2d.c
index fcee33a..e27715c 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_g2d.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_g2d.c
@@ -396,7 +396,7 @@ static void g2d_userptr_put_dma_addr(struct g2d_data *g2d,
 
 out:
 	dma_unmap_sg(to_dma_dev(g2d->drm_dev), g2d_userptr->sgt->sgl,
-			g2d_userptr->sgt->nents, DMA_BIDIRECTIONAL);
+		     g2d_userptr->sgt->orig_nents, DMA_BIDIRECTIONAL);
 
 	pages = frame_vector_pages(g2d_userptr->vec);
 	if (!IS_ERR(pages)) {
@@ -511,8 +511,9 @@ static dma_addr_t *g2d_userptr_get_dma_addr(struct g2d_data *g2d,
 
 	g2d_userptr->sgt = sgt;
 
-	if (!dma_map_sg(to_dma_dev(g2d->drm_dev), sgt->sgl, sgt->nents,
-				DMA_BIDIRECTIONAL)) {
+	sgt->nents = dma_map_sg(to_dma_dev(g2d->drm_dev), sgt->sgl,
+				sgt->orig_nents, DMA_BIDIRECTIONAL)
+	if (!sgt->nents) {
 		DRM_DEV_ERROR(g2d->dev, "failed to map sgt with dma region.\n");
 		ret = -ENOMEM;
 		goto err_sg_free_table;
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 152+ messages in thread

* [RFC 05/17] drm: exynos: fix sg_table nents vs. orig_nents misuse
@ 2020-04-28 13:19       ` Marek Szyprowski
  0 siblings, 0 replies; 152+ messages in thread
From: Marek Szyprowski @ 2020-04-28 13:19 UTC (permalink / raw)
  To: dri-devel, iommu, linaro-mm-sig, linux-kernel
  Cc: Daniel Vetter, Bartlomiej Zolnierkiewicz, David Airlie,
	intel-gfx, amd-gfx, Christoph Hellwig, Benjamin Gaignard,
	Robin Murphy, Sumit Semwal, linux-arm-kernel

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/exynos/exynos_drm_g2d.c | 7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/exynos/exynos_drm_g2d.c b/drivers/gpu/drm/exynos/exynos_drm_g2d.c
index fcee33a..e27715c 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_g2d.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_g2d.c
@@ -396,7 +396,7 @@ static void g2d_userptr_put_dma_addr(struct g2d_data *g2d,
 
 out:
 	dma_unmap_sg(to_dma_dev(g2d->drm_dev), g2d_userptr->sgt->sgl,
-			g2d_userptr->sgt->nents, DMA_BIDIRECTIONAL);
+		     g2d_userptr->sgt->orig_nents, DMA_BIDIRECTIONAL);
 
 	pages = frame_vector_pages(g2d_userptr->vec);
 	if (!IS_ERR(pages)) {
@@ -511,8 +511,9 @@ static dma_addr_t *g2d_userptr_get_dma_addr(struct g2d_data *g2d,
 
 	g2d_userptr->sgt = sgt;
 
-	if (!dma_map_sg(to_dma_dev(g2d->drm_dev), sgt->sgl, sgt->nents,
-				DMA_BIDIRECTIONAL)) {
+	sgt->nents = dma_map_sg(to_dma_dev(g2d->drm_dev), sgt->sgl,
+				sgt->orig_nents, DMA_BIDIRECTIONAL)
+	if (!sgt->nents) {
 		DRM_DEV_ERROR(g2d->dev, "failed to map sgt with dma region.\n");
 		ret = -ENOMEM;
 		goto err_sg_free_table;
-- 
1.9.1

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

^ permalink raw reply related	[flat|nested] 152+ messages in thread

* [RFC 05/17] drm: exynos: fix sg_table nents vs. orig_nents misuse
@ 2020-04-28 13:19       ` Marek Szyprowski
  0 siblings, 0 replies; 152+ messages in thread
From: Marek Szyprowski @ 2020-04-28 13:19 UTC (permalink / raw)
  To: dri-devel, iommu, linaro-mm-sig, linux-kernel
  Cc: Daniel Vetter, Bartlomiej Zolnierkiewicz, David Airlie,
	intel-gfx, amd-gfx, Christoph Hellwig, Benjamin Gaignard,
	Robin Murphy, Sumit Semwal, linux-arm-kernel, Marek Szyprowski

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/exynos/exynos_drm_g2d.c | 7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/exynos/exynos_drm_g2d.c b/drivers/gpu/drm/exynos/exynos_drm_g2d.c
index fcee33a..e27715c 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_g2d.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_g2d.c
@@ -396,7 +396,7 @@ static void g2d_userptr_put_dma_addr(struct g2d_data *g2d,
 
 out:
 	dma_unmap_sg(to_dma_dev(g2d->drm_dev), g2d_userptr->sgt->sgl,
-			g2d_userptr->sgt->nents, DMA_BIDIRECTIONAL);
+		     g2d_userptr->sgt->orig_nents, DMA_BIDIRECTIONAL);
 
 	pages = frame_vector_pages(g2d_userptr->vec);
 	if (!IS_ERR(pages)) {
@@ -511,8 +511,9 @@ static dma_addr_t *g2d_userptr_get_dma_addr(struct g2d_data *g2d,
 
 	g2d_userptr->sgt = sgt;
 
-	if (!dma_map_sg(to_dma_dev(g2d->drm_dev), sgt->sgl, sgt->nents,
-				DMA_BIDIRECTIONAL)) {
+	sgt->nents = dma_map_sg(to_dma_dev(g2d->drm_dev), sgt->sgl,
+				sgt->orig_nents, DMA_BIDIRECTIONAL)
+	if (!sgt->nents) {
 		DRM_DEV_ERROR(g2d->dev, "failed to map sgt with dma region.\n");
 		ret = -ENOMEM;
 		goto err_sg_free_table;
-- 
1.9.1


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

^ permalink raw reply related	[flat|nested] 152+ messages in thread

* [RFC 05/17] drm: exynos: fix sg_table nents vs. orig_nents misuse
@ 2020-04-28 13:19       ` Marek Szyprowski
  0 siblings, 0 replies; 152+ messages in thread
From: Marek Szyprowski @ 2020-04-28 13:19 UTC (permalink / raw)
  To: dri-devel, iommu, linaro-mm-sig, linux-kernel
  Cc: Bartlomiej Zolnierkiewicz, David Airlie, intel-gfx, amd-gfx,
	Christoph Hellwig, Robin Murphy, linux-arm-kernel,
	Marek Szyprowski

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/exynos/exynos_drm_g2d.c | 7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/exynos/exynos_drm_g2d.c b/drivers/gpu/drm/exynos/exynos_drm_g2d.c
index fcee33a..e27715c 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_g2d.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_g2d.c
@@ -396,7 +396,7 @@ static void g2d_userptr_put_dma_addr(struct g2d_data *g2d,
 
 out:
 	dma_unmap_sg(to_dma_dev(g2d->drm_dev), g2d_userptr->sgt->sgl,
-			g2d_userptr->sgt->nents, DMA_BIDIRECTIONAL);
+		     g2d_userptr->sgt->orig_nents, DMA_BIDIRECTIONAL);
 
 	pages = frame_vector_pages(g2d_userptr->vec);
 	if (!IS_ERR(pages)) {
@@ -511,8 +511,9 @@ static dma_addr_t *g2d_userptr_get_dma_addr(struct g2d_data *g2d,
 
 	g2d_userptr->sgt = sgt;
 
-	if (!dma_map_sg(to_dma_dev(g2d->drm_dev), sgt->sgl, sgt->nents,
-				DMA_BIDIRECTIONAL)) {
+	sgt->nents = dma_map_sg(to_dma_dev(g2d->drm_dev), sgt->sgl,
+				sgt->orig_nents, DMA_BIDIRECTIONAL)
+	if (!sgt->nents) {
 		DRM_DEV_ERROR(g2d->dev, "failed to map sgt with dma region.\n");
 		ret = -ENOMEM;
 		goto err_sg_free_table;
-- 
1.9.1

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

^ permalink raw reply related	[flat|nested] 152+ messages in thread

* [Intel-gfx] [RFC 05/17] drm: exynos: fix sg_table nents vs. orig_nents misuse
@ 2020-04-28 13:19       ` Marek Szyprowski
  0 siblings, 0 replies; 152+ messages in thread
From: Marek Szyprowski @ 2020-04-28 13:19 UTC (permalink / raw)
  To: dri-devel, iommu, linaro-mm-sig, linux-kernel
  Cc: Bartlomiej Zolnierkiewicz, David Airlie, intel-gfx, amd-gfx,
	Christoph Hellwig, Benjamin Gaignard, Robin Murphy, Sumit Semwal,
	linux-arm-kernel, Marek Szyprowski

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/exynos/exynos_drm_g2d.c | 7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/exynos/exynos_drm_g2d.c b/drivers/gpu/drm/exynos/exynos_drm_g2d.c
index fcee33a..e27715c 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_g2d.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_g2d.c
@@ -396,7 +396,7 @@ static void g2d_userptr_put_dma_addr(struct g2d_data *g2d,
 
 out:
 	dma_unmap_sg(to_dma_dev(g2d->drm_dev), g2d_userptr->sgt->sgl,
-			g2d_userptr->sgt->nents, DMA_BIDIRECTIONAL);
+		     g2d_userptr->sgt->orig_nents, DMA_BIDIRECTIONAL);
 
 	pages = frame_vector_pages(g2d_userptr->vec);
 	if (!IS_ERR(pages)) {
@@ -511,8 +511,9 @@ static dma_addr_t *g2d_userptr_get_dma_addr(struct g2d_data *g2d,
 
 	g2d_userptr->sgt = sgt;
 
-	if (!dma_map_sg(to_dma_dev(g2d->drm_dev), sgt->sgl, sgt->nents,
-				DMA_BIDIRECTIONAL)) {
+	sgt->nents = dma_map_sg(to_dma_dev(g2d->drm_dev), sgt->sgl,
+				sgt->orig_nents, DMA_BIDIRECTIONAL)
+	if (!sgt->nents) {
 		DRM_DEV_ERROR(g2d->dev, "failed to map sgt with dma region.\n");
 		ret = -ENOMEM;
 		goto err_sg_free_table;
-- 
1.9.1

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

^ permalink raw reply related	[flat|nested] 152+ messages in thread

* [RFC 05/17] drm: exynos: fix sg_table nents vs. orig_nents misuse
@ 2020-04-28 13:19       ` Marek Szyprowski
  0 siblings, 0 replies; 152+ messages in thread
From: Marek Szyprowski @ 2020-04-28 13:19 UTC (permalink / raw)
  To: dri-devel, iommu, linaro-mm-sig, linux-kernel
  Cc: Daniel Vetter, Bartlomiej Zolnierkiewicz, David Airlie,
	intel-gfx, amd-gfx, Christoph Hellwig, Benjamin Gaignard,
	Robin Murphy, Sumit Semwal, linux-arm-kernel, Marek Szyprowski

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/exynos/exynos_drm_g2d.c | 7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/exynos/exynos_drm_g2d.c b/drivers/gpu/drm/exynos/exynos_drm_g2d.c
index fcee33a..e27715c 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_g2d.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_g2d.c
@@ -396,7 +396,7 @@ static void g2d_userptr_put_dma_addr(struct g2d_data *g2d,
 
 out:
 	dma_unmap_sg(to_dma_dev(g2d->drm_dev), g2d_userptr->sgt->sgl,
-			g2d_userptr->sgt->nents, DMA_BIDIRECTIONAL);
+		     g2d_userptr->sgt->orig_nents, DMA_BIDIRECTIONAL);
 
 	pages = frame_vector_pages(g2d_userptr->vec);
 	if (!IS_ERR(pages)) {
@@ -511,8 +511,9 @@ static dma_addr_t *g2d_userptr_get_dma_addr(struct g2d_data *g2d,
 
 	g2d_userptr->sgt = sgt;
 
-	if (!dma_map_sg(to_dma_dev(g2d->drm_dev), sgt->sgl, sgt->nents,
-				DMA_BIDIRECTIONAL)) {
+	sgt->nents = dma_map_sg(to_dma_dev(g2d->drm_dev), sgt->sgl,
+				sgt->orig_nents, DMA_BIDIRECTIONAL)
+	if (!sgt->nents) {
 		DRM_DEV_ERROR(g2d->dev, "failed to map sgt with dma region.\n");
 		ret = -ENOMEM;
 		goto err_sg_free_table;
-- 
1.9.1

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

^ permalink raw reply related	[flat|nested] 152+ messages in thread

* [RFC 06/17] drm: i915: fix sg_table nents vs. orig_nents misuse
       [not found]   ` <CGME20200428132025eucas1p21580e634500a3e85564551cddf168b4a@eucas1p2.samsung.com>
                         ` (3 preceding siblings ...)
  (?)
@ 2020-04-28 13:19       ` Marek Szyprowski
  0 siblings, 0 replies; 152+ messages in thread
From: Marek Szyprowski @ 2020-04-28 13:19 UTC (permalink / raw)
  To: dri-devel, iommu, linaro-mm-sig, linux-kernel
  Cc: Marek Szyprowski, Christoph Hellwig, Robin Murphy,
	Bartlomiej Zolnierkiewicz, Sumit Semwal, Benjamin Gaignard,
	intel-gfx, linux-arm-kernel, amd-gfx, David Airlie,
	Daniel Vetter

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


^ permalink raw reply related	[flat|nested] 152+ messages in thread

* [RFC 06/17] drm: i915: fix sg_table nents vs. orig_nents misuse
@ 2020-04-28 13:19       ` Marek Szyprowski
  0 siblings, 0 replies; 152+ messages in thread
From: Marek Szyprowski @ 2020-04-28 13:19 UTC (permalink / raw)
  To: dri-devel, iommu, linaro-mm-sig, linux-kernel
  Cc: Daniel Vetter, Bartlomiej Zolnierkiewicz, David Airlie,
	intel-gfx, amd-gfx, Christoph Hellwig, Benjamin Gaignard,
	Robin Murphy, Sumit Semwal, linux-arm-kernel

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

^ permalink raw reply related	[flat|nested] 152+ messages in thread

* [RFC 06/17] drm: i915: fix sg_table nents vs. orig_nents misuse
@ 2020-04-28 13:19       ` Marek Szyprowski
  0 siblings, 0 replies; 152+ messages in thread
From: Marek Szyprowski @ 2020-04-28 13:19 UTC (permalink / raw)
  To: dri-devel, iommu, linaro-mm-sig, linux-kernel
  Cc: Daniel Vetter, Bartlomiej Zolnierkiewicz, David Airlie,
	intel-gfx, amd-gfx, Christoph Hellwig, Benjamin Gaignard,
	Robin Murphy, Sumit Semwal, linux-arm-kernel, Marek Szyprowski

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

^ permalink raw reply related	[flat|nested] 152+ messages in thread

* [RFC 06/17] drm: i915: fix sg_table nents vs. orig_nents misuse
@ 2020-04-28 13:19       ` Marek Szyprowski
  0 siblings, 0 replies; 152+ messages in thread
From: Marek Szyprowski @ 2020-04-28 13:19 UTC (permalink / raw)
  To: dri-devel, iommu, linaro-mm-sig, linux-kernel
  Cc: Bartlomiej Zolnierkiewicz, David Airlie, intel-gfx, amd-gfx,
	Christoph Hellwig, Robin Murphy, linux-arm-kernel,
	Marek Szyprowski

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

^ permalink raw reply related	[flat|nested] 152+ messages in thread

* [Intel-gfx] [RFC 06/17] drm: i915: fix sg_table nents vs. orig_nents misuse
@ 2020-04-28 13:19       ` Marek Szyprowski
  0 siblings, 0 replies; 152+ messages in thread
From: Marek Szyprowski @ 2020-04-28 13:19 UTC (permalink / raw)
  To: dri-devel, iommu, linaro-mm-sig, linux-kernel
  Cc: Bartlomiej Zolnierkiewicz, David Airlie, intel-gfx, amd-gfx,
	Christoph Hellwig, Benjamin Gaignard, Robin Murphy, Sumit Semwal,
	linux-arm-kernel, Marek Szyprowski

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

^ permalink raw reply related	[flat|nested] 152+ messages in thread

* [RFC 06/17] drm: i915: fix sg_table nents vs. orig_nents misuse
@ 2020-04-28 13:19       ` Marek Szyprowski
  0 siblings, 0 replies; 152+ messages in thread
From: Marek Szyprowski @ 2020-04-28 13:19 UTC (permalink / raw)
  To: dri-devel, iommu, linaro-mm-sig, linux-kernel
  Cc: Daniel Vetter, Bartlomiej Zolnierkiewicz, David Airlie,
	intel-gfx, amd-gfx, Christoph Hellwig, Benjamin Gaignard,
	Robin Murphy, Sumit Semwal, linux-arm-kernel, Marek Szyprowski

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

^ permalink raw reply related	[flat|nested] 152+ messages in thread

* [RFC 07/17] drm: lima: fix sg_table nents vs. orig_nents misuse
       [not found]   ` <CGME20200428132026eucas1p27c64540e53f328d0bb7bf9dae2ccb98d@eucas1p2.samsung.com>
                         ` (3 preceding siblings ...)
  (?)
@ 2020-04-28 13:19       ` Marek Szyprowski
  0 siblings, 0 replies; 152+ messages in thread
From: Marek Szyprowski @ 2020-04-28 13:19 UTC (permalink / raw)
  To: dri-devel, iommu, linaro-mm-sig, linux-kernel
  Cc: Marek Szyprowski, Christoph Hellwig, Robin Murphy,
	Bartlomiej Zolnierkiewicz, Sumit Semwal, Benjamin Gaignard,
	intel-gfx, linux-arm-kernel, amd-gfx, David Airlie,
	Daniel Vetter

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/lima/lima_gem.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/lima/lima_gem.c b/drivers/gpu/drm/lima/lima_gem.c
index 5404e0d..3edd2ff 100644
--- a/drivers/gpu/drm/lima/lima_gem.c
+++ b/drivers/gpu/drm/lima/lima_gem.c
@@ -70,7 +70,7 @@ int lima_heap_alloc(struct lima_bo *bo, struct lima_vm *vm)
 
 	if (bo->base.sgt) {
 		dma_unmap_sg(dev, bo->base.sgt->sgl,
-			     bo->base.sgt->nents, DMA_BIDIRECTIONAL);
+			     bo->base.sgt->orig_nents, DMA_BIDIRECTIONAL);
 		sg_free_table(bo->base.sgt);
 	} else {
 		bo->base.sgt = kmalloc(sizeof(*bo->base.sgt), GFP_KERNEL);
@@ -80,7 +80,7 @@ int lima_heap_alloc(struct lima_bo *bo, struct lima_vm *vm)
 		}
 	}
 
-	dma_map_sg(dev, sgt.sgl, sgt.nents, DMA_BIDIRECTIONAL);
+	sgt.nents = dma_map_sg(dev, sgt.sgl, sgt.orig_nents, DMA_BIDIRECTIONAL);
 
 	*bo->base.sgt = sgt;
 
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 152+ messages in thread

* [RFC 07/17] drm: lima: fix sg_table nents vs. orig_nents misuse
@ 2020-04-28 13:19       ` Marek Szyprowski
  0 siblings, 0 replies; 152+ messages in thread
From: Marek Szyprowski @ 2020-04-28 13:19 UTC (permalink / raw)
  To: dri-devel, iommu, linaro-mm-sig, linux-kernel
  Cc: Daniel Vetter, Bartlomiej Zolnierkiewicz, David Airlie,
	intel-gfx, amd-gfx, Christoph Hellwig, Benjamin Gaignard,
	Robin Murphy, Sumit Semwal, linux-arm-kernel

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/lima/lima_gem.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/lima/lima_gem.c b/drivers/gpu/drm/lima/lima_gem.c
index 5404e0d..3edd2ff 100644
--- a/drivers/gpu/drm/lima/lima_gem.c
+++ b/drivers/gpu/drm/lima/lima_gem.c
@@ -70,7 +70,7 @@ int lima_heap_alloc(struct lima_bo *bo, struct lima_vm *vm)
 
 	if (bo->base.sgt) {
 		dma_unmap_sg(dev, bo->base.sgt->sgl,
-			     bo->base.sgt->nents, DMA_BIDIRECTIONAL);
+			     bo->base.sgt->orig_nents, DMA_BIDIRECTIONAL);
 		sg_free_table(bo->base.sgt);
 	} else {
 		bo->base.sgt = kmalloc(sizeof(*bo->base.sgt), GFP_KERNEL);
@@ -80,7 +80,7 @@ int lima_heap_alloc(struct lima_bo *bo, struct lima_vm *vm)
 		}
 	}
 
-	dma_map_sg(dev, sgt.sgl, sgt.nents, DMA_BIDIRECTIONAL);
+	sgt.nents = dma_map_sg(dev, sgt.sgl, sgt.orig_nents, DMA_BIDIRECTIONAL);
 
 	*bo->base.sgt = sgt;
 
-- 
1.9.1

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

^ permalink raw reply related	[flat|nested] 152+ messages in thread

* [RFC 07/17] drm: lima: fix sg_table nents vs. orig_nents misuse
@ 2020-04-28 13:19       ` Marek Szyprowski
  0 siblings, 0 replies; 152+ messages in thread
From: Marek Szyprowski @ 2020-04-28 13:19 UTC (permalink / raw)
  To: dri-devel, iommu, linaro-mm-sig, linux-kernel
  Cc: Daniel Vetter, Bartlomiej Zolnierkiewicz, David Airlie,
	intel-gfx, amd-gfx, Christoph Hellwig, Benjamin Gaignard,
	Robin Murphy, Sumit Semwal, linux-arm-kernel, Marek Szyprowski

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/lima/lima_gem.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/lima/lima_gem.c b/drivers/gpu/drm/lima/lima_gem.c
index 5404e0d..3edd2ff 100644
--- a/drivers/gpu/drm/lima/lima_gem.c
+++ b/drivers/gpu/drm/lima/lima_gem.c
@@ -70,7 +70,7 @@ int lima_heap_alloc(struct lima_bo *bo, struct lima_vm *vm)
 
 	if (bo->base.sgt) {
 		dma_unmap_sg(dev, bo->base.sgt->sgl,
-			     bo->base.sgt->nents, DMA_BIDIRECTIONAL);
+			     bo->base.sgt->orig_nents, DMA_BIDIRECTIONAL);
 		sg_free_table(bo->base.sgt);
 	} else {
 		bo->base.sgt = kmalloc(sizeof(*bo->base.sgt), GFP_KERNEL);
@@ -80,7 +80,7 @@ int lima_heap_alloc(struct lima_bo *bo, struct lima_vm *vm)
 		}
 	}
 
-	dma_map_sg(dev, sgt.sgl, sgt.nents, DMA_BIDIRECTIONAL);
+	sgt.nents = dma_map_sg(dev, sgt.sgl, sgt.orig_nents, DMA_BIDIRECTIONAL);
 
 	*bo->base.sgt = sgt;
 
-- 
1.9.1


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

^ permalink raw reply related	[flat|nested] 152+ messages in thread

* [RFC 07/17] drm: lima: fix sg_table nents vs. orig_nents misuse
@ 2020-04-28 13:19       ` Marek Szyprowski
  0 siblings, 0 replies; 152+ messages in thread
From: Marek Szyprowski @ 2020-04-28 13:19 UTC (permalink / raw)
  To: dri-devel, iommu, linaro-mm-sig, linux-kernel
  Cc: Bartlomiej Zolnierkiewicz, David Airlie, intel-gfx, amd-gfx,
	Christoph Hellwig, Robin Murphy, linux-arm-kernel,
	Marek Szyprowski

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/lima/lima_gem.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/lima/lima_gem.c b/drivers/gpu/drm/lima/lima_gem.c
index 5404e0d..3edd2ff 100644
--- a/drivers/gpu/drm/lima/lima_gem.c
+++ b/drivers/gpu/drm/lima/lima_gem.c
@@ -70,7 +70,7 @@ int lima_heap_alloc(struct lima_bo *bo, struct lima_vm *vm)
 
 	if (bo->base.sgt) {
 		dma_unmap_sg(dev, bo->base.sgt->sgl,
-			     bo->base.sgt->nents, DMA_BIDIRECTIONAL);
+			     bo->base.sgt->orig_nents, DMA_BIDIRECTIONAL);
 		sg_free_table(bo->base.sgt);
 	} else {
 		bo->base.sgt = kmalloc(sizeof(*bo->base.sgt), GFP_KERNEL);
@@ -80,7 +80,7 @@ int lima_heap_alloc(struct lima_bo *bo, struct lima_vm *vm)
 		}
 	}
 
-	dma_map_sg(dev, sgt.sgl, sgt.nents, DMA_BIDIRECTIONAL);
+	sgt.nents = dma_map_sg(dev, sgt.sgl, sgt.orig_nents, DMA_BIDIRECTIONAL);
 
 	*bo->base.sgt = sgt;
 
-- 
1.9.1

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

^ permalink raw reply related	[flat|nested] 152+ messages in thread

* [Intel-gfx] [RFC 07/17] drm: lima: fix sg_table nents vs. orig_nents misuse
@ 2020-04-28 13:19       ` Marek Szyprowski
  0 siblings, 0 replies; 152+ messages in thread
From: Marek Szyprowski @ 2020-04-28 13:19 UTC (permalink / raw)
  To: dri-devel, iommu, linaro-mm-sig, linux-kernel
  Cc: Bartlomiej Zolnierkiewicz, David Airlie, intel-gfx, amd-gfx,
	Christoph Hellwig, Benjamin Gaignard, Robin Murphy, Sumit Semwal,
	linux-arm-kernel, Marek Szyprowski

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/lima/lima_gem.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/lima/lima_gem.c b/drivers/gpu/drm/lima/lima_gem.c
index 5404e0d..3edd2ff 100644
--- a/drivers/gpu/drm/lima/lima_gem.c
+++ b/drivers/gpu/drm/lima/lima_gem.c
@@ -70,7 +70,7 @@ int lima_heap_alloc(struct lima_bo *bo, struct lima_vm *vm)
 
 	if (bo->base.sgt) {
 		dma_unmap_sg(dev, bo->base.sgt->sgl,
-			     bo->base.sgt->nents, DMA_BIDIRECTIONAL);
+			     bo->base.sgt->orig_nents, DMA_BIDIRECTIONAL);
 		sg_free_table(bo->base.sgt);
 	} else {
 		bo->base.sgt = kmalloc(sizeof(*bo->base.sgt), GFP_KERNEL);
@@ -80,7 +80,7 @@ int lima_heap_alloc(struct lima_bo *bo, struct lima_vm *vm)
 		}
 	}
 
-	dma_map_sg(dev, sgt.sgl, sgt.nents, DMA_BIDIRECTIONAL);
+	sgt.nents = dma_map_sg(dev, sgt.sgl, sgt.orig_nents, DMA_BIDIRECTIONAL);
 
 	*bo->base.sgt = sgt;
 
-- 
1.9.1

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

^ permalink raw reply related	[flat|nested] 152+ messages in thread

* [RFC 07/17] drm: lima: fix sg_table nents vs. orig_nents misuse
@ 2020-04-28 13:19       ` Marek Szyprowski
  0 siblings, 0 replies; 152+ messages in thread
From: Marek Szyprowski @ 2020-04-28 13:19 UTC (permalink / raw)
  To: dri-devel, iommu, linaro-mm-sig, linux-kernel
  Cc: Daniel Vetter, Bartlomiej Zolnierkiewicz, David Airlie,
	intel-gfx, amd-gfx, Christoph Hellwig, Benjamin Gaignard,
	Robin Murphy, Sumit Semwal, linux-arm-kernel, Marek Szyprowski

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/lima/lima_gem.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/lima/lima_gem.c b/drivers/gpu/drm/lima/lima_gem.c
index 5404e0d..3edd2ff 100644
--- a/drivers/gpu/drm/lima/lima_gem.c
+++ b/drivers/gpu/drm/lima/lima_gem.c
@@ -70,7 +70,7 @@ int lima_heap_alloc(struct lima_bo *bo, struct lima_vm *vm)
 
 	if (bo->base.sgt) {
 		dma_unmap_sg(dev, bo->base.sgt->sgl,
-			     bo->base.sgt->nents, DMA_BIDIRECTIONAL);
+			     bo->base.sgt->orig_nents, DMA_BIDIRECTIONAL);
 		sg_free_table(bo->base.sgt);
 	} else {
 		bo->base.sgt = kmalloc(sizeof(*bo->base.sgt), GFP_KERNEL);
@@ -80,7 +80,7 @@ int lima_heap_alloc(struct lima_bo *bo, struct lima_vm *vm)
 		}
 	}
 
-	dma_map_sg(dev, sgt.sgl, sgt.nents, DMA_BIDIRECTIONAL);
+	sgt.nents = dma_map_sg(dev, sgt.sgl, sgt.orig_nents, DMA_BIDIRECTIONAL);
 
 	*bo->base.sgt = sgt;
 
-- 
1.9.1

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

^ permalink raw reply related	[flat|nested] 152+ messages in thread

* [RFC 08/17] drm: msm: fix sg_table nents vs. orig_nents misuse
       [not found]   ` <CGME20200428132027eucas1p2fed88e94fecf1ef12b312ba80a78bc00@eucas1p2.samsung.com>
                         ` (3 preceding siblings ...)
  (?)
@ 2020-04-28 13:19       ` Marek Szyprowski
  0 siblings, 0 replies; 152+ messages in thread
From: Marek Szyprowski @ 2020-04-28 13:19 UTC (permalink / raw)
  To: dri-devel, iommu, linaro-mm-sig, linux-kernel
  Cc: Marek Szyprowski, Christoph Hellwig, Robin Murphy,
	Bartlomiej Zolnierkiewicz, Sumit Semwal, Benjamin Gaignard,
	intel-gfx, linux-arm-kernel, amd-gfx, David Airlie,
	Daniel Vetter

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/msm/msm_gem.c   | 8 ++++----
 drivers/gpu/drm/msm/msm_iommu.c | 3 ++-
 2 files changed, 6 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/msm/msm_gem.c b/drivers/gpu/drm/msm/msm_gem.c
index 5a6a79f..54c3bbb 100644
--- a/drivers/gpu/drm/msm/msm_gem.c
+++ b/drivers/gpu/drm/msm/msm_gem.c
@@ -54,10 +54,10 @@ static void sync_for_device(struct msm_gem_object *msm_obj)
 
 	if (get_dma_ops(dev) && IS_ENABLED(CONFIG_ARM64)) {
 		dma_sync_sg_for_device(dev, msm_obj->sgt->sgl,
-			msm_obj->sgt->nents, DMA_BIDIRECTIONAL);
+			msm_obj->sgt->orig_nents, DMA_BIDIRECTIONAL);
 	} else {
 		dma_map_sg(dev, msm_obj->sgt->sgl,
-			msm_obj->sgt->nents, DMA_BIDIRECTIONAL);
+			msm_obj->sgt->orig_nents, DMA_BIDIRECTIONAL);
 	}
 }
 
@@ -67,10 +67,10 @@ static void sync_for_cpu(struct msm_gem_object *msm_obj)
 
 	if (get_dma_ops(dev) && IS_ENABLED(CONFIG_ARM64)) {
 		dma_sync_sg_for_cpu(dev, msm_obj->sgt->sgl,
-			msm_obj->sgt->nents, DMA_BIDIRECTIONAL);
+			msm_obj->sgt->orig_nents, DMA_BIDIRECTIONAL);
 	} else {
 		dma_unmap_sg(dev, msm_obj->sgt->sgl,
-			msm_obj->sgt->nents, DMA_BIDIRECTIONAL);
+			msm_obj->sgt->orig_nents, DMA_BIDIRECTIONAL);
 	}
 }
 
diff --git a/drivers/gpu/drm/msm/msm_iommu.c b/drivers/gpu/drm/msm/msm_iommu.c
index ad58cfe..b0ca084 100644
--- a/drivers/gpu/drm/msm/msm_iommu.c
+++ b/drivers/gpu/drm/msm/msm_iommu.c
@@ -43,7 +43,8 @@ static int msm_iommu_map(struct msm_mmu *mmu, uint64_t iova,
 	struct msm_iommu *iommu = to_msm_iommu(mmu);
 	size_t ret;
 
-	ret = iommu_map_sg(iommu->domain, iova, sgt->sgl, sgt->nents, prot);
+	ret = iommu_map_sg(iommu->domain, iova, sgt->sgl, sgt->orig_nents,
+			   prot);
 	WARN_ON(!ret);
 
 	return (ret == len) ? 0 : -EINVAL;
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 152+ messages in thread

* [RFC 08/17] drm: msm: fix sg_table nents vs. orig_nents misuse
@ 2020-04-28 13:19       ` Marek Szyprowski
  0 siblings, 0 replies; 152+ messages in thread
From: Marek Szyprowski @ 2020-04-28 13:19 UTC (permalink / raw)
  To: dri-devel, iommu, linaro-mm-sig, linux-kernel
  Cc: Daniel Vetter, Bartlomiej Zolnierkiewicz, David Airlie,
	intel-gfx, amd-gfx, Christoph Hellwig, Benjamin Gaignard,
	Robin Murphy, Sumit Semwal, linux-arm-kernel

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/msm/msm_gem.c   | 8 ++++----
 drivers/gpu/drm/msm/msm_iommu.c | 3 ++-
 2 files changed, 6 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/msm/msm_gem.c b/drivers/gpu/drm/msm/msm_gem.c
index 5a6a79f..54c3bbb 100644
--- a/drivers/gpu/drm/msm/msm_gem.c
+++ b/drivers/gpu/drm/msm/msm_gem.c
@@ -54,10 +54,10 @@ static void sync_for_device(struct msm_gem_object *msm_obj)
 
 	if (get_dma_ops(dev) && IS_ENABLED(CONFIG_ARM64)) {
 		dma_sync_sg_for_device(dev, msm_obj->sgt->sgl,
-			msm_obj->sgt->nents, DMA_BIDIRECTIONAL);
+			msm_obj->sgt->orig_nents, DMA_BIDIRECTIONAL);
 	} else {
 		dma_map_sg(dev, msm_obj->sgt->sgl,
-			msm_obj->sgt->nents, DMA_BIDIRECTIONAL);
+			msm_obj->sgt->orig_nents, DMA_BIDIRECTIONAL);
 	}
 }
 
@@ -67,10 +67,10 @@ static void sync_for_cpu(struct msm_gem_object *msm_obj)
 
 	if (get_dma_ops(dev) && IS_ENABLED(CONFIG_ARM64)) {
 		dma_sync_sg_for_cpu(dev, msm_obj->sgt->sgl,
-			msm_obj->sgt->nents, DMA_BIDIRECTIONAL);
+			msm_obj->sgt->orig_nents, DMA_BIDIRECTIONAL);
 	} else {
 		dma_unmap_sg(dev, msm_obj->sgt->sgl,
-			msm_obj->sgt->nents, DMA_BIDIRECTIONAL);
+			msm_obj->sgt->orig_nents, DMA_BIDIRECTIONAL);
 	}
 }
 
diff --git a/drivers/gpu/drm/msm/msm_iommu.c b/drivers/gpu/drm/msm/msm_iommu.c
index ad58cfe..b0ca084 100644
--- a/drivers/gpu/drm/msm/msm_iommu.c
+++ b/drivers/gpu/drm/msm/msm_iommu.c
@@ -43,7 +43,8 @@ static int msm_iommu_map(struct msm_mmu *mmu, uint64_t iova,
 	struct msm_iommu *iommu = to_msm_iommu(mmu);
 	size_t ret;
 
-	ret = iommu_map_sg(iommu->domain, iova, sgt->sgl, sgt->nents, prot);
+	ret = iommu_map_sg(iommu->domain, iova, sgt->sgl, sgt->orig_nents,
+			   prot);
 	WARN_ON(!ret);
 
 	return (ret == len) ? 0 : -EINVAL;
-- 
1.9.1

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

^ permalink raw reply related	[flat|nested] 152+ messages in thread

* [RFC 08/17] drm: msm: fix sg_table nents vs. orig_nents misuse
@ 2020-04-28 13:19       ` Marek Szyprowski
  0 siblings, 0 replies; 152+ messages in thread
From: Marek Szyprowski @ 2020-04-28 13:19 UTC (permalink / raw)
  To: dri-devel, iommu, linaro-mm-sig, linux-kernel
  Cc: Daniel Vetter, Bartlomiej Zolnierkiewicz, David Airlie,
	intel-gfx, amd-gfx, Christoph Hellwig, Benjamin Gaignard,
	Robin Murphy, Sumit Semwal, linux-arm-kernel, Marek Szyprowski

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/msm/msm_gem.c   | 8 ++++----
 drivers/gpu/drm/msm/msm_iommu.c | 3 ++-
 2 files changed, 6 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/msm/msm_gem.c b/drivers/gpu/drm/msm/msm_gem.c
index 5a6a79f..54c3bbb 100644
--- a/drivers/gpu/drm/msm/msm_gem.c
+++ b/drivers/gpu/drm/msm/msm_gem.c
@@ -54,10 +54,10 @@ static void sync_for_device(struct msm_gem_object *msm_obj)
 
 	if (get_dma_ops(dev) && IS_ENABLED(CONFIG_ARM64)) {
 		dma_sync_sg_for_device(dev, msm_obj->sgt->sgl,
-			msm_obj->sgt->nents, DMA_BIDIRECTIONAL);
+			msm_obj->sgt->orig_nents, DMA_BIDIRECTIONAL);
 	} else {
 		dma_map_sg(dev, msm_obj->sgt->sgl,
-			msm_obj->sgt->nents, DMA_BIDIRECTIONAL);
+			msm_obj->sgt->orig_nents, DMA_BIDIRECTIONAL);
 	}
 }
 
@@ -67,10 +67,10 @@ static void sync_for_cpu(struct msm_gem_object *msm_obj)
 
 	if (get_dma_ops(dev) && IS_ENABLED(CONFIG_ARM64)) {
 		dma_sync_sg_for_cpu(dev, msm_obj->sgt->sgl,
-			msm_obj->sgt->nents, DMA_BIDIRECTIONAL);
+			msm_obj->sgt->orig_nents, DMA_BIDIRECTIONAL);
 	} else {
 		dma_unmap_sg(dev, msm_obj->sgt->sgl,
-			msm_obj->sgt->nents, DMA_BIDIRECTIONAL);
+			msm_obj->sgt->orig_nents, DMA_BIDIRECTIONAL);
 	}
 }
 
diff --git a/drivers/gpu/drm/msm/msm_iommu.c b/drivers/gpu/drm/msm/msm_iommu.c
index ad58cfe..b0ca084 100644
--- a/drivers/gpu/drm/msm/msm_iommu.c
+++ b/drivers/gpu/drm/msm/msm_iommu.c
@@ -43,7 +43,8 @@ static int msm_iommu_map(struct msm_mmu *mmu, uint64_t iova,
 	struct msm_iommu *iommu = to_msm_iommu(mmu);
 	size_t ret;
 
-	ret = iommu_map_sg(iommu->domain, iova, sgt->sgl, sgt->nents, prot);
+	ret = iommu_map_sg(iommu->domain, iova, sgt->sgl, sgt->orig_nents,
+			   prot);
 	WARN_ON(!ret);
 
 	return (ret == len) ? 0 : -EINVAL;
-- 
1.9.1


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

^ permalink raw reply related	[flat|nested] 152+ messages in thread

* [RFC 08/17] drm: msm: fix sg_table nents vs. orig_nents misuse
@ 2020-04-28 13:19       ` Marek Szyprowski
  0 siblings, 0 replies; 152+ messages in thread
From: Marek Szyprowski @ 2020-04-28 13:19 UTC (permalink / raw)
  To: dri-devel, iommu, linaro-mm-sig, linux-kernel
  Cc: Bartlomiej Zolnierkiewicz, David Airlie, intel-gfx, amd-gfx,
	Christoph Hellwig, Robin Murphy, linux-arm-kernel,
	Marek Szyprowski

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/msm/msm_gem.c   | 8 ++++----
 drivers/gpu/drm/msm/msm_iommu.c | 3 ++-
 2 files changed, 6 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/msm/msm_gem.c b/drivers/gpu/drm/msm/msm_gem.c
index 5a6a79f..54c3bbb 100644
--- a/drivers/gpu/drm/msm/msm_gem.c
+++ b/drivers/gpu/drm/msm/msm_gem.c
@@ -54,10 +54,10 @@ static void sync_for_device(struct msm_gem_object *msm_obj)
 
 	if (get_dma_ops(dev) && IS_ENABLED(CONFIG_ARM64)) {
 		dma_sync_sg_for_device(dev, msm_obj->sgt->sgl,
-			msm_obj->sgt->nents, DMA_BIDIRECTIONAL);
+			msm_obj->sgt->orig_nents, DMA_BIDIRECTIONAL);
 	} else {
 		dma_map_sg(dev, msm_obj->sgt->sgl,
-			msm_obj->sgt->nents, DMA_BIDIRECTIONAL);
+			msm_obj->sgt->orig_nents, DMA_BIDIRECTIONAL);
 	}
 }
 
@@ -67,10 +67,10 @@ static void sync_for_cpu(struct msm_gem_object *msm_obj)
 
 	if (get_dma_ops(dev) && IS_ENABLED(CONFIG_ARM64)) {
 		dma_sync_sg_for_cpu(dev, msm_obj->sgt->sgl,
-			msm_obj->sgt->nents, DMA_BIDIRECTIONAL);
+			msm_obj->sgt->orig_nents, DMA_BIDIRECTIONAL);
 	} else {
 		dma_unmap_sg(dev, msm_obj->sgt->sgl,
-			msm_obj->sgt->nents, DMA_BIDIRECTIONAL);
+			msm_obj->sgt->orig_nents, DMA_BIDIRECTIONAL);
 	}
 }
 
diff --git a/drivers/gpu/drm/msm/msm_iommu.c b/drivers/gpu/drm/msm/msm_iommu.c
index ad58cfe..b0ca084 100644
--- a/drivers/gpu/drm/msm/msm_iommu.c
+++ b/drivers/gpu/drm/msm/msm_iommu.c
@@ -43,7 +43,8 @@ static int msm_iommu_map(struct msm_mmu *mmu, uint64_t iova,
 	struct msm_iommu *iommu = to_msm_iommu(mmu);
 	size_t ret;
 
-	ret = iommu_map_sg(iommu->domain, iova, sgt->sgl, sgt->nents, prot);
+	ret = iommu_map_sg(iommu->domain, iova, sgt->sgl, sgt->orig_nents,
+			   prot);
 	WARN_ON(!ret);
 
 	return (ret == len) ? 0 : -EINVAL;
-- 
1.9.1

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

^ permalink raw reply related	[flat|nested] 152+ messages in thread

* [Intel-gfx] [RFC 08/17] drm: msm: fix sg_table nents vs. orig_nents misuse
@ 2020-04-28 13:19       ` Marek Szyprowski
  0 siblings, 0 replies; 152+ messages in thread
From: Marek Szyprowski @ 2020-04-28 13:19 UTC (permalink / raw)
  To: dri-devel, iommu, linaro-mm-sig, linux-kernel
  Cc: Bartlomiej Zolnierkiewicz, David Airlie, intel-gfx, amd-gfx,
	Christoph Hellwig, Benjamin Gaignard, Robin Murphy, Sumit Semwal,
	linux-arm-kernel, Marek Szyprowski

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/msm/msm_gem.c   | 8 ++++----
 drivers/gpu/drm/msm/msm_iommu.c | 3 ++-
 2 files changed, 6 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/msm/msm_gem.c b/drivers/gpu/drm/msm/msm_gem.c
index 5a6a79f..54c3bbb 100644
--- a/drivers/gpu/drm/msm/msm_gem.c
+++ b/drivers/gpu/drm/msm/msm_gem.c
@@ -54,10 +54,10 @@ static void sync_for_device(struct msm_gem_object *msm_obj)
 
 	if (get_dma_ops(dev) && IS_ENABLED(CONFIG_ARM64)) {
 		dma_sync_sg_for_device(dev, msm_obj->sgt->sgl,
-			msm_obj->sgt->nents, DMA_BIDIRECTIONAL);
+			msm_obj->sgt->orig_nents, DMA_BIDIRECTIONAL);
 	} else {
 		dma_map_sg(dev, msm_obj->sgt->sgl,
-			msm_obj->sgt->nents, DMA_BIDIRECTIONAL);
+			msm_obj->sgt->orig_nents, DMA_BIDIRECTIONAL);
 	}
 }
 
@@ -67,10 +67,10 @@ static void sync_for_cpu(struct msm_gem_object *msm_obj)
 
 	if (get_dma_ops(dev) && IS_ENABLED(CONFIG_ARM64)) {
 		dma_sync_sg_for_cpu(dev, msm_obj->sgt->sgl,
-			msm_obj->sgt->nents, DMA_BIDIRECTIONAL);
+			msm_obj->sgt->orig_nents, DMA_BIDIRECTIONAL);
 	} else {
 		dma_unmap_sg(dev, msm_obj->sgt->sgl,
-			msm_obj->sgt->nents, DMA_BIDIRECTIONAL);
+			msm_obj->sgt->orig_nents, DMA_BIDIRECTIONAL);
 	}
 }
 
diff --git a/drivers/gpu/drm/msm/msm_iommu.c b/drivers/gpu/drm/msm/msm_iommu.c
index ad58cfe..b0ca084 100644
--- a/drivers/gpu/drm/msm/msm_iommu.c
+++ b/drivers/gpu/drm/msm/msm_iommu.c
@@ -43,7 +43,8 @@ static int msm_iommu_map(struct msm_mmu *mmu, uint64_t iova,
 	struct msm_iommu *iommu = to_msm_iommu(mmu);
 	size_t ret;
 
-	ret = iommu_map_sg(iommu->domain, iova, sgt->sgl, sgt->nents, prot);
+	ret = iommu_map_sg(iommu->domain, iova, sgt->sgl, sgt->orig_nents,
+			   prot);
 	WARN_ON(!ret);
 
 	return (ret == len) ? 0 : -EINVAL;
-- 
1.9.1

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

^ permalink raw reply related	[flat|nested] 152+ messages in thread

* [RFC 08/17] drm: msm: fix sg_table nents vs. orig_nents misuse
@ 2020-04-28 13:19       ` Marek Szyprowski
  0 siblings, 0 replies; 152+ messages in thread
From: Marek Szyprowski @ 2020-04-28 13:19 UTC (permalink / raw)
  To: dri-devel, iommu, linaro-mm-sig, linux-kernel
  Cc: Daniel Vetter, Bartlomiej Zolnierkiewicz, David Airlie,
	intel-gfx, amd-gfx, Christoph Hellwig, Benjamin Gaignard,
	Robin Murphy, Sumit Semwal, linux-arm-kernel, Marek Szyprowski

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/msm/msm_gem.c   | 8 ++++----
 drivers/gpu/drm/msm/msm_iommu.c | 3 ++-
 2 files changed, 6 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/msm/msm_gem.c b/drivers/gpu/drm/msm/msm_gem.c
index 5a6a79f..54c3bbb 100644
--- a/drivers/gpu/drm/msm/msm_gem.c
+++ b/drivers/gpu/drm/msm/msm_gem.c
@@ -54,10 +54,10 @@ static void sync_for_device(struct msm_gem_object *msm_obj)
 
 	if (get_dma_ops(dev) && IS_ENABLED(CONFIG_ARM64)) {
 		dma_sync_sg_for_device(dev, msm_obj->sgt->sgl,
-			msm_obj->sgt->nents, DMA_BIDIRECTIONAL);
+			msm_obj->sgt->orig_nents, DMA_BIDIRECTIONAL);
 	} else {
 		dma_map_sg(dev, msm_obj->sgt->sgl,
-			msm_obj->sgt->nents, DMA_BIDIRECTIONAL);
+			msm_obj->sgt->orig_nents, DMA_BIDIRECTIONAL);
 	}
 }
 
@@ -67,10 +67,10 @@ static void sync_for_cpu(struct msm_gem_object *msm_obj)
 
 	if (get_dma_ops(dev) && IS_ENABLED(CONFIG_ARM64)) {
 		dma_sync_sg_for_cpu(dev, msm_obj->sgt->sgl,
-			msm_obj->sgt->nents, DMA_BIDIRECTIONAL);
+			msm_obj->sgt->orig_nents, DMA_BIDIRECTIONAL);
 	} else {
 		dma_unmap_sg(dev, msm_obj->sgt->sgl,
-			msm_obj->sgt->nents, DMA_BIDIRECTIONAL);
+			msm_obj->sgt->orig_nents, DMA_BIDIRECTIONAL);
 	}
 }
 
diff --git a/drivers/gpu/drm/msm/msm_iommu.c b/drivers/gpu/drm/msm/msm_iommu.c
index ad58cfe..b0ca084 100644
--- a/drivers/gpu/drm/msm/msm_iommu.c
+++ b/drivers/gpu/drm/msm/msm_iommu.c
@@ -43,7 +43,8 @@ static int msm_iommu_map(struct msm_mmu *mmu, uint64_t iova,
 	struct msm_iommu *iommu = to_msm_iommu(mmu);
 	size_t ret;
 
-	ret = iommu_map_sg(iommu->domain, iova, sgt->sgl, sgt->nents, prot);
+	ret = iommu_map_sg(iommu->domain, iova, sgt->sgl, sgt->orig_nents,
+			   prot);
 	WARN_ON(!ret);
 
 	return (ret == len) ? 0 : -EINVAL;
-- 
1.9.1

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

^ permalink raw reply related	[flat|nested] 152+ messages in thread

* [RFC 09/17] drm: panfrost: fix sg_table nents vs. orig_nents misuse
       [not found]   ` <CGME20200428132027eucas1p1a045e89a0058ccff3ea94d1da2236af7@eucas1p1.samsung.com>
                         ` (3 preceding siblings ...)
  (?)
@ 2020-04-28 13:19       ` Marek Szyprowski
  0 siblings, 0 replies; 152+ messages in thread
From: Marek Szyprowski @ 2020-04-28 13:19 UTC (permalink / raw)
  To: dri-devel, iommu, linaro-mm-sig, linux-kernel
  Cc: Marek Szyprowski, Christoph Hellwig, Robin Murphy,
	Bartlomiej Zolnierkiewicz, Sumit Semwal, Benjamin Gaignard,
	intel-gfx, linux-arm-kernel, amd-gfx, David Airlie,
	Daniel Vetter

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/panfrost/panfrost_gem.c | 3 ++-
 drivers/gpu/drm/panfrost/panfrost_mmu.c | 4 +++-
 2 files changed, 5 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/panfrost/panfrost_gem.c b/drivers/gpu/drm/panfrost/panfrost_gem.c
index 17b654e..22fec7c 100644
--- a/drivers/gpu/drm/panfrost/panfrost_gem.c
+++ b/drivers/gpu/drm/panfrost/panfrost_gem.c
@@ -42,7 +42,8 @@ static void panfrost_gem_free_object(struct drm_gem_object *obj)
 		for (i = 0; i < n_sgt; i++) {
 			if (bo->sgts[i].sgl) {
 				dma_unmap_sg(pfdev->dev, bo->sgts[i].sgl,
-					     bo->sgts[i].nents, DMA_BIDIRECTIONAL);
+					     bo->sgts[i].orig_nents,
+					     DMA_BIDIRECTIONAL);
 				sg_free_table(&bo->sgts[i]);
 			}
 		}
diff --git a/drivers/gpu/drm/panfrost/panfrost_mmu.c b/drivers/gpu/drm/panfrost/panfrost_mmu.c
index ed28aeb..2d9b1f9 100644
--- a/drivers/gpu/drm/panfrost/panfrost_mmu.c
+++ b/drivers/gpu/drm/panfrost/panfrost_mmu.c
@@ -517,7 +517,9 @@ static int panfrost_mmu_map_fault_addr(struct panfrost_device *pfdev, int as,
 	if (ret)
 		goto err_pages;
 
-	if (!dma_map_sg(pfdev->dev, sgt->sgl, sgt->nents, DMA_BIDIRECTIONAL)) {
+	sgt->nents = dma_map_sg(pfdev->dev, sgt->sgl, sgt->orig_nents,
+				DMA_BIDIRECTIONAL);
+	if (!sgt->nents) {
 		ret = -EINVAL;
 		goto err_map;
 	}
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 152+ messages in thread

* [RFC 09/17] drm: panfrost: fix sg_table nents vs. orig_nents misuse
@ 2020-04-28 13:19       ` Marek Szyprowski
  0 siblings, 0 replies; 152+ messages in thread
From: Marek Szyprowski @ 2020-04-28 13:19 UTC (permalink / raw)
  To: dri-devel, iommu, linaro-mm-sig, linux-kernel
  Cc: Daniel Vetter, Bartlomiej Zolnierkiewicz, David Airlie,
	intel-gfx, amd-gfx, Christoph Hellwig, Benjamin Gaignard,
	Robin Murphy, Sumit Semwal, linux-arm-kernel

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/panfrost/panfrost_gem.c | 3 ++-
 drivers/gpu/drm/panfrost/panfrost_mmu.c | 4 +++-
 2 files changed, 5 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/panfrost/panfrost_gem.c b/drivers/gpu/drm/panfrost/panfrost_gem.c
index 17b654e..22fec7c 100644
--- a/drivers/gpu/drm/panfrost/panfrost_gem.c
+++ b/drivers/gpu/drm/panfrost/panfrost_gem.c
@@ -42,7 +42,8 @@ static void panfrost_gem_free_object(struct drm_gem_object *obj)
 		for (i = 0; i < n_sgt; i++) {
 			if (bo->sgts[i].sgl) {
 				dma_unmap_sg(pfdev->dev, bo->sgts[i].sgl,
-					     bo->sgts[i].nents, DMA_BIDIRECTIONAL);
+					     bo->sgts[i].orig_nents,
+					     DMA_BIDIRECTIONAL);
 				sg_free_table(&bo->sgts[i]);
 			}
 		}
diff --git a/drivers/gpu/drm/panfrost/panfrost_mmu.c b/drivers/gpu/drm/panfrost/panfrost_mmu.c
index ed28aeb..2d9b1f9 100644
--- a/drivers/gpu/drm/panfrost/panfrost_mmu.c
+++ b/drivers/gpu/drm/panfrost/panfrost_mmu.c
@@ -517,7 +517,9 @@ static int panfrost_mmu_map_fault_addr(struct panfrost_device *pfdev, int as,
 	if (ret)
 		goto err_pages;
 
-	if (!dma_map_sg(pfdev->dev, sgt->sgl, sgt->nents, DMA_BIDIRECTIONAL)) {
+	sgt->nents = dma_map_sg(pfdev->dev, sgt->sgl, sgt->orig_nents,
+				DMA_BIDIRECTIONAL);
+	if (!sgt->nents) {
 		ret = -EINVAL;
 		goto err_map;
 	}
-- 
1.9.1

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

^ permalink raw reply related	[flat|nested] 152+ messages in thread

* [RFC 09/17] drm: panfrost: fix sg_table nents vs. orig_nents misuse
@ 2020-04-28 13:19       ` Marek Szyprowski
  0 siblings, 0 replies; 152+ messages in thread
From: Marek Szyprowski @ 2020-04-28 13:19 UTC (permalink / raw)
  To: dri-devel, iommu, linaro-mm-sig, linux-kernel
  Cc: Daniel Vetter, Bartlomiej Zolnierkiewicz, David Airlie,
	intel-gfx, amd-gfx, Christoph Hellwig, Benjamin Gaignard,
	Robin Murphy, Sumit Semwal, linux-arm-kernel, Marek Szyprowski

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/panfrost/panfrost_gem.c | 3 ++-
 drivers/gpu/drm/panfrost/panfrost_mmu.c | 4 +++-
 2 files changed, 5 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/panfrost/panfrost_gem.c b/drivers/gpu/drm/panfrost/panfrost_gem.c
index 17b654e..22fec7c 100644
--- a/drivers/gpu/drm/panfrost/panfrost_gem.c
+++ b/drivers/gpu/drm/panfrost/panfrost_gem.c
@@ -42,7 +42,8 @@ static void panfrost_gem_free_object(struct drm_gem_object *obj)
 		for (i = 0; i < n_sgt; i++) {
 			if (bo->sgts[i].sgl) {
 				dma_unmap_sg(pfdev->dev, bo->sgts[i].sgl,
-					     bo->sgts[i].nents, DMA_BIDIRECTIONAL);
+					     bo->sgts[i].orig_nents,
+					     DMA_BIDIRECTIONAL);
 				sg_free_table(&bo->sgts[i]);
 			}
 		}
diff --git a/drivers/gpu/drm/panfrost/panfrost_mmu.c b/drivers/gpu/drm/panfrost/panfrost_mmu.c
index ed28aeb..2d9b1f9 100644
--- a/drivers/gpu/drm/panfrost/panfrost_mmu.c
+++ b/drivers/gpu/drm/panfrost/panfrost_mmu.c
@@ -517,7 +517,9 @@ static int panfrost_mmu_map_fault_addr(struct panfrost_device *pfdev, int as,
 	if (ret)
 		goto err_pages;
 
-	if (!dma_map_sg(pfdev->dev, sgt->sgl, sgt->nents, DMA_BIDIRECTIONAL)) {
+	sgt->nents = dma_map_sg(pfdev->dev, sgt->sgl, sgt->orig_nents,
+				DMA_BIDIRECTIONAL);
+	if (!sgt->nents) {
 		ret = -EINVAL;
 		goto err_map;
 	}
-- 
1.9.1


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

^ permalink raw reply related	[flat|nested] 152+ messages in thread

* [RFC 09/17] drm: panfrost: fix sg_table nents vs. orig_nents misuse
@ 2020-04-28 13:19       ` Marek Szyprowski
  0 siblings, 0 replies; 152+ messages in thread
From: Marek Szyprowski @ 2020-04-28 13:19 UTC (permalink / raw)
  To: dri-devel, iommu, linaro-mm-sig, linux-kernel
  Cc: Bartlomiej Zolnierkiewicz, David Airlie, intel-gfx, amd-gfx,
	Christoph Hellwig, Robin Murphy, linux-arm-kernel,
	Marek Szyprowski

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/panfrost/panfrost_gem.c | 3 ++-
 drivers/gpu/drm/panfrost/panfrost_mmu.c | 4 +++-
 2 files changed, 5 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/panfrost/panfrost_gem.c b/drivers/gpu/drm/panfrost/panfrost_gem.c
index 17b654e..22fec7c 100644
--- a/drivers/gpu/drm/panfrost/panfrost_gem.c
+++ b/drivers/gpu/drm/panfrost/panfrost_gem.c
@@ -42,7 +42,8 @@ static void panfrost_gem_free_object(struct drm_gem_object *obj)
 		for (i = 0; i < n_sgt; i++) {
 			if (bo->sgts[i].sgl) {
 				dma_unmap_sg(pfdev->dev, bo->sgts[i].sgl,
-					     bo->sgts[i].nents, DMA_BIDIRECTIONAL);
+					     bo->sgts[i].orig_nents,
+					     DMA_BIDIRECTIONAL);
 				sg_free_table(&bo->sgts[i]);
 			}
 		}
diff --git a/drivers/gpu/drm/panfrost/panfrost_mmu.c b/drivers/gpu/drm/panfrost/panfrost_mmu.c
index ed28aeb..2d9b1f9 100644
--- a/drivers/gpu/drm/panfrost/panfrost_mmu.c
+++ b/drivers/gpu/drm/panfrost/panfrost_mmu.c
@@ -517,7 +517,9 @@ static int panfrost_mmu_map_fault_addr(struct panfrost_device *pfdev, int as,
 	if (ret)
 		goto err_pages;
 
-	if (!dma_map_sg(pfdev->dev, sgt->sgl, sgt->nents, DMA_BIDIRECTIONAL)) {
+	sgt->nents = dma_map_sg(pfdev->dev, sgt->sgl, sgt->orig_nents,
+				DMA_BIDIRECTIONAL);
+	if (!sgt->nents) {
 		ret = -EINVAL;
 		goto err_map;
 	}
-- 
1.9.1

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

^ permalink raw reply related	[flat|nested] 152+ messages in thread

* [Intel-gfx] [RFC 09/17] drm: panfrost: fix sg_table nents vs. orig_nents misuse
@ 2020-04-28 13:19       ` Marek Szyprowski
  0 siblings, 0 replies; 152+ messages in thread
From: Marek Szyprowski @ 2020-04-28 13:19 UTC (permalink / raw)
  To: dri-devel, iommu, linaro-mm-sig, linux-kernel
  Cc: Bartlomiej Zolnierkiewicz, David Airlie, intel-gfx, amd-gfx,
	Christoph Hellwig, Benjamin Gaignard, Robin Murphy, Sumit Semwal,
	linux-arm-kernel, Marek Szyprowski

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/panfrost/panfrost_gem.c | 3 ++-
 drivers/gpu/drm/panfrost/panfrost_mmu.c | 4 +++-
 2 files changed, 5 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/panfrost/panfrost_gem.c b/drivers/gpu/drm/panfrost/panfrost_gem.c
index 17b654e..22fec7c 100644
--- a/drivers/gpu/drm/panfrost/panfrost_gem.c
+++ b/drivers/gpu/drm/panfrost/panfrost_gem.c
@@ -42,7 +42,8 @@ static void panfrost_gem_free_object(struct drm_gem_object *obj)
 		for (i = 0; i < n_sgt; i++) {
 			if (bo->sgts[i].sgl) {
 				dma_unmap_sg(pfdev->dev, bo->sgts[i].sgl,
-					     bo->sgts[i].nents, DMA_BIDIRECTIONAL);
+					     bo->sgts[i].orig_nents,
+					     DMA_BIDIRECTIONAL);
 				sg_free_table(&bo->sgts[i]);
 			}
 		}
diff --git a/drivers/gpu/drm/panfrost/panfrost_mmu.c b/drivers/gpu/drm/panfrost/panfrost_mmu.c
index ed28aeb..2d9b1f9 100644
--- a/drivers/gpu/drm/panfrost/panfrost_mmu.c
+++ b/drivers/gpu/drm/panfrost/panfrost_mmu.c
@@ -517,7 +517,9 @@ static int panfrost_mmu_map_fault_addr(struct panfrost_device *pfdev, int as,
 	if (ret)
 		goto err_pages;
 
-	if (!dma_map_sg(pfdev->dev, sgt->sgl, sgt->nents, DMA_BIDIRECTIONAL)) {
+	sgt->nents = dma_map_sg(pfdev->dev, sgt->sgl, sgt->orig_nents,
+				DMA_BIDIRECTIONAL);
+	if (!sgt->nents) {
 		ret = -EINVAL;
 		goto err_map;
 	}
-- 
1.9.1

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

^ permalink raw reply related	[flat|nested] 152+ messages in thread

* [RFC 09/17] drm: panfrost: fix sg_table nents vs. orig_nents misuse
@ 2020-04-28 13:19       ` Marek Szyprowski
  0 siblings, 0 replies; 152+ messages in thread
From: Marek Szyprowski @ 2020-04-28 13:19 UTC (permalink / raw)
  To: dri-devel, iommu, linaro-mm-sig, linux-kernel
  Cc: Daniel Vetter, Bartlomiej Zolnierkiewicz, David Airlie,
	intel-gfx, amd-gfx, Christoph Hellwig, Benjamin Gaignard,
	Robin Murphy, Sumit Semwal, linux-arm-kernel, Marek Szyprowski

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/panfrost/panfrost_gem.c | 3 ++-
 drivers/gpu/drm/panfrost/panfrost_mmu.c | 4 +++-
 2 files changed, 5 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/panfrost/panfrost_gem.c b/drivers/gpu/drm/panfrost/panfrost_gem.c
index 17b654e..22fec7c 100644
--- a/drivers/gpu/drm/panfrost/panfrost_gem.c
+++ b/drivers/gpu/drm/panfrost/panfrost_gem.c
@@ -42,7 +42,8 @@ static void panfrost_gem_free_object(struct drm_gem_object *obj)
 		for (i = 0; i < n_sgt; i++) {
 			if (bo->sgts[i].sgl) {
 				dma_unmap_sg(pfdev->dev, bo->sgts[i].sgl,
-					     bo->sgts[i].nents, DMA_BIDIRECTIONAL);
+					     bo->sgts[i].orig_nents,
+					     DMA_BIDIRECTIONAL);
 				sg_free_table(&bo->sgts[i]);
 			}
 		}
diff --git a/drivers/gpu/drm/panfrost/panfrost_mmu.c b/drivers/gpu/drm/panfrost/panfrost_mmu.c
index ed28aeb..2d9b1f9 100644
--- a/drivers/gpu/drm/panfrost/panfrost_mmu.c
+++ b/drivers/gpu/drm/panfrost/panfrost_mmu.c
@@ -517,7 +517,9 @@ static int panfrost_mmu_map_fault_addr(struct panfrost_device *pfdev, int as,
 	if (ret)
 		goto err_pages;
 
-	if (!dma_map_sg(pfdev->dev, sgt->sgl, sgt->nents, DMA_BIDIRECTIONAL)) {
+	sgt->nents = dma_map_sg(pfdev->dev, sgt->sgl, sgt->orig_nents,
+				DMA_BIDIRECTIONAL);
+	if (!sgt->nents) {
 		ret = -EINVAL;
 		goto err_map;
 	}
-- 
1.9.1

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

^ permalink raw reply related	[flat|nested] 152+ messages in thread

* [RFC 10/17] drm: radeon: fix sg_table nents vs. orig_nents misuse
       [not found]   ` <CGME20200428132028eucas1p155a84ab14c6a6820b4c8240f01e98905@eucas1p1.samsung.com>
                         ` (3 preceding siblings ...)
  (?)
@ 2020-04-28 13:19       ` Marek Szyprowski
  0 siblings, 0 replies; 152+ messages in thread
From: Marek Szyprowski @ 2020-04-28 13:19 UTC (permalink / raw)
  To: dri-devel, iommu, linaro-mm-sig, linux-kernel
  Cc: Marek Szyprowski, Christoph Hellwig, Robin Murphy,
	Bartlomiej Zolnierkiewicz, Sumit Semwal, Benjamin Gaignard,
	intel-gfx, linux-arm-kernel, amd-gfx, David Airlie,
	Daniel Vetter

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/radeon/radeon_ttm.c | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/radeon/radeon_ttm.c b/drivers/gpu/drm/radeon/radeon_ttm.c
index 5d50c9e..4770880 100644
--- a/drivers/gpu/drm/radeon/radeon_ttm.c
+++ b/drivers/gpu/drm/radeon/radeon_ttm.c
@@ -481,7 +481,7 @@ static int radeon_ttm_tt_pin_userptr(struct ttm_tt *ttm)
 {
 	struct radeon_device *rdev = radeon_get_rdev(ttm->bdev);
 	struct radeon_ttm_tt *gtt = (void *)ttm;
-	unsigned pinned = 0, nents;
+	unsigned pinned = 0;
 	int r;
 
 	int write = !(gtt->userflags & RADEON_GEM_USERPTR_READONLY);
@@ -522,8 +522,8 @@ static int radeon_ttm_tt_pin_userptr(struct ttm_tt *ttm)
 		goto release_sg;
 
 	r = -ENOMEM;
-	nents = dma_map_sg(rdev->dev, ttm->sg->sgl, ttm->sg->nents, direction);
-	if (nents == 0)
+	ttm->sg->nents = dma_map_sg(rdev->dev, ttm->sg->sgl,
+	if (ttm->sg->nents == 0)
 		goto release_sg;
 
 	drm_prime_sg_to_page_addr_arrays(ttm->sg, ttm->pages,
@@ -554,9 +554,9 @@ static void radeon_ttm_tt_unpin_userptr(struct ttm_tt *ttm)
 		return;
 
 	/* free the sg table and pages again */
-	dma_unmap_sg(rdev->dev, ttm->sg->sgl, ttm->sg->nents, direction);
+	dma_unmap_sg(rdev->dev, ttm->sg->sgl, ttm->sg->orig_nents, direction);
 
-	for_each_sg_page(ttm->sg->sgl, &sg_iter, ttm->sg->nents, 0) {
+	for_each_sg_page(ttm->sg->sgl, &sg_iter, ttm->sg->orig_nents, 0) {
 		struct page *page = sg_page_iter_page(&sg_iter);
 		if (!(gtt->userflags & RADEON_GEM_USERPTR_READONLY))
 			set_page_dirty(page);
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 152+ messages in thread

* [RFC 10/17] drm: radeon: fix sg_table nents vs. orig_nents misuse
@ 2020-04-28 13:19       ` Marek Szyprowski
  0 siblings, 0 replies; 152+ messages in thread
From: Marek Szyprowski @ 2020-04-28 13:19 UTC (permalink / raw)
  To: dri-devel, iommu, linaro-mm-sig, linux-kernel
  Cc: Daniel Vetter, Bartlomiej Zolnierkiewicz, David Airlie,
	intel-gfx, amd-gfx, Christoph Hellwig, Benjamin Gaignard,
	Robin Murphy, Sumit Semwal, linux-arm-kernel

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/radeon/radeon_ttm.c | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/radeon/radeon_ttm.c b/drivers/gpu/drm/radeon/radeon_ttm.c
index 5d50c9e..4770880 100644
--- a/drivers/gpu/drm/radeon/radeon_ttm.c
+++ b/drivers/gpu/drm/radeon/radeon_ttm.c
@@ -481,7 +481,7 @@ static int radeon_ttm_tt_pin_userptr(struct ttm_tt *ttm)
 {
 	struct radeon_device *rdev = radeon_get_rdev(ttm->bdev);
 	struct radeon_ttm_tt *gtt = (void *)ttm;
-	unsigned pinned = 0, nents;
+	unsigned pinned = 0;
 	int r;
 
 	int write = !(gtt->userflags & RADEON_GEM_USERPTR_READONLY);
@@ -522,8 +522,8 @@ static int radeon_ttm_tt_pin_userptr(struct ttm_tt *ttm)
 		goto release_sg;
 
 	r = -ENOMEM;
-	nents = dma_map_sg(rdev->dev, ttm->sg->sgl, ttm->sg->nents, direction);
-	if (nents == 0)
+	ttm->sg->nents = dma_map_sg(rdev->dev, ttm->sg->sgl,
+	if (ttm->sg->nents == 0)
 		goto release_sg;
 
 	drm_prime_sg_to_page_addr_arrays(ttm->sg, ttm->pages,
@@ -554,9 +554,9 @@ static void radeon_ttm_tt_unpin_userptr(struct ttm_tt *ttm)
 		return;
 
 	/* free the sg table and pages again */
-	dma_unmap_sg(rdev->dev, ttm->sg->sgl, ttm->sg->nents, direction);
+	dma_unmap_sg(rdev->dev, ttm->sg->sgl, ttm->sg->orig_nents, direction);
 
-	for_each_sg_page(ttm->sg->sgl, &sg_iter, ttm->sg->nents, 0) {
+	for_each_sg_page(ttm->sg->sgl, &sg_iter, ttm->sg->orig_nents, 0) {
 		struct page *page = sg_page_iter_page(&sg_iter);
 		if (!(gtt->userflags & RADEON_GEM_USERPTR_READONLY))
 			set_page_dirty(page);
-- 
1.9.1

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

^ permalink raw reply related	[flat|nested] 152+ messages in thread

* [RFC 10/17] drm: radeon: fix sg_table nents vs. orig_nents misuse
@ 2020-04-28 13:19       ` Marek Szyprowski
  0 siblings, 0 replies; 152+ messages in thread
From: Marek Szyprowski @ 2020-04-28 13:19 UTC (permalink / raw)
  To: dri-devel, iommu, linaro-mm-sig, linux-kernel
  Cc: Daniel Vetter, Bartlomiej Zolnierkiewicz, David Airlie,
	intel-gfx, amd-gfx, Christoph Hellwig, Benjamin Gaignard,
	Robin Murphy, Sumit Semwal, linux-arm-kernel, Marek Szyprowski

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/radeon/radeon_ttm.c | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/radeon/radeon_ttm.c b/drivers/gpu/drm/radeon/radeon_ttm.c
index 5d50c9e..4770880 100644
--- a/drivers/gpu/drm/radeon/radeon_ttm.c
+++ b/drivers/gpu/drm/radeon/radeon_ttm.c
@@ -481,7 +481,7 @@ static int radeon_ttm_tt_pin_userptr(struct ttm_tt *ttm)
 {
 	struct radeon_device *rdev = radeon_get_rdev(ttm->bdev);
 	struct radeon_ttm_tt *gtt = (void *)ttm;
-	unsigned pinned = 0, nents;
+	unsigned pinned = 0;
 	int r;
 
 	int write = !(gtt->userflags & RADEON_GEM_USERPTR_READONLY);
@@ -522,8 +522,8 @@ static int radeon_ttm_tt_pin_userptr(struct ttm_tt *ttm)
 		goto release_sg;
 
 	r = -ENOMEM;
-	nents = dma_map_sg(rdev->dev, ttm->sg->sgl, ttm->sg->nents, direction);
-	if (nents == 0)
+	ttm->sg->nents = dma_map_sg(rdev->dev, ttm->sg->sgl,
+	if (ttm->sg->nents == 0)
 		goto release_sg;
 
 	drm_prime_sg_to_page_addr_arrays(ttm->sg, ttm->pages,
@@ -554,9 +554,9 @@ static void radeon_ttm_tt_unpin_userptr(struct ttm_tt *ttm)
 		return;
 
 	/* free the sg table and pages again */
-	dma_unmap_sg(rdev->dev, ttm->sg->sgl, ttm->sg->nents, direction);
+	dma_unmap_sg(rdev->dev, ttm->sg->sgl, ttm->sg->orig_nents, direction);
 
-	for_each_sg_page(ttm->sg->sgl, &sg_iter, ttm->sg->nents, 0) {
+	for_each_sg_page(ttm->sg->sgl, &sg_iter, ttm->sg->orig_nents, 0) {
 		struct page *page = sg_page_iter_page(&sg_iter);
 		if (!(gtt->userflags & RADEON_GEM_USERPTR_READONLY))
 			set_page_dirty(page);
-- 
1.9.1


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

^ permalink raw reply related	[flat|nested] 152+ messages in thread

* [RFC 10/17] drm: radeon: fix sg_table nents vs. orig_nents misuse
@ 2020-04-28 13:19       ` Marek Szyprowski
  0 siblings, 0 replies; 152+ messages in thread
From: Marek Szyprowski @ 2020-04-28 13:19 UTC (permalink / raw)
  To: dri-devel, iommu, linaro-mm-sig, linux-kernel
  Cc: Bartlomiej Zolnierkiewicz, David Airlie, intel-gfx, amd-gfx,
	Christoph Hellwig, Robin Murphy, linux-arm-kernel,
	Marek Szyprowski

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/radeon/radeon_ttm.c | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/radeon/radeon_ttm.c b/drivers/gpu/drm/radeon/radeon_ttm.c
index 5d50c9e..4770880 100644
--- a/drivers/gpu/drm/radeon/radeon_ttm.c
+++ b/drivers/gpu/drm/radeon/radeon_ttm.c
@@ -481,7 +481,7 @@ static int radeon_ttm_tt_pin_userptr(struct ttm_tt *ttm)
 {
 	struct radeon_device *rdev = radeon_get_rdev(ttm->bdev);
 	struct radeon_ttm_tt *gtt = (void *)ttm;
-	unsigned pinned = 0, nents;
+	unsigned pinned = 0;
 	int r;
 
 	int write = !(gtt->userflags & RADEON_GEM_USERPTR_READONLY);
@@ -522,8 +522,8 @@ static int radeon_ttm_tt_pin_userptr(struct ttm_tt *ttm)
 		goto release_sg;
 
 	r = -ENOMEM;
-	nents = dma_map_sg(rdev->dev, ttm->sg->sgl, ttm->sg->nents, direction);
-	if (nents == 0)
+	ttm->sg->nents = dma_map_sg(rdev->dev, ttm->sg->sgl,
+	if (ttm->sg->nents == 0)
 		goto release_sg;
 
 	drm_prime_sg_to_page_addr_arrays(ttm->sg, ttm->pages,
@@ -554,9 +554,9 @@ static void radeon_ttm_tt_unpin_userptr(struct ttm_tt *ttm)
 		return;
 
 	/* free the sg table and pages again */
-	dma_unmap_sg(rdev->dev, ttm->sg->sgl, ttm->sg->nents, direction);
+	dma_unmap_sg(rdev->dev, ttm->sg->sgl, ttm->sg->orig_nents, direction);
 
-	for_each_sg_page(ttm->sg->sgl, &sg_iter, ttm->sg->nents, 0) {
+	for_each_sg_page(ttm->sg->sgl, &sg_iter, ttm->sg->orig_nents, 0) {
 		struct page *page = sg_page_iter_page(&sg_iter);
 		if (!(gtt->userflags & RADEON_GEM_USERPTR_READONLY))
 			set_page_dirty(page);
-- 
1.9.1

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

^ permalink raw reply related	[flat|nested] 152+ messages in thread

* [Intel-gfx] [RFC 10/17] drm: radeon: fix sg_table nents vs. orig_nents misuse
@ 2020-04-28 13:19       ` Marek Szyprowski
  0 siblings, 0 replies; 152+ messages in thread
From: Marek Szyprowski @ 2020-04-28 13:19 UTC (permalink / raw)
  To: dri-devel, iommu, linaro-mm-sig, linux-kernel
  Cc: Bartlomiej Zolnierkiewicz, David Airlie, intel-gfx, amd-gfx,
	Christoph Hellwig, Benjamin Gaignard, Robin Murphy, Sumit Semwal,
	linux-arm-kernel, Marek Szyprowski

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/radeon/radeon_ttm.c | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/radeon/radeon_ttm.c b/drivers/gpu/drm/radeon/radeon_ttm.c
index 5d50c9e..4770880 100644
--- a/drivers/gpu/drm/radeon/radeon_ttm.c
+++ b/drivers/gpu/drm/radeon/radeon_ttm.c
@@ -481,7 +481,7 @@ static int radeon_ttm_tt_pin_userptr(struct ttm_tt *ttm)
 {
 	struct radeon_device *rdev = radeon_get_rdev(ttm->bdev);
 	struct radeon_ttm_tt *gtt = (void *)ttm;
-	unsigned pinned = 0, nents;
+	unsigned pinned = 0;
 	int r;
 
 	int write = !(gtt->userflags & RADEON_GEM_USERPTR_READONLY);
@@ -522,8 +522,8 @@ static int radeon_ttm_tt_pin_userptr(struct ttm_tt *ttm)
 		goto release_sg;
 
 	r = -ENOMEM;
-	nents = dma_map_sg(rdev->dev, ttm->sg->sgl, ttm->sg->nents, direction);
-	if (nents == 0)
+	ttm->sg->nents = dma_map_sg(rdev->dev, ttm->sg->sgl,
+	if (ttm->sg->nents == 0)
 		goto release_sg;
 
 	drm_prime_sg_to_page_addr_arrays(ttm->sg, ttm->pages,
@@ -554,9 +554,9 @@ static void radeon_ttm_tt_unpin_userptr(struct ttm_tt *ttm)
 		return;
 
 	/* free the sg table and pages again */
-	dma_unmap_sg(rdev->dev, ttm->sg->sgl, ttm->sg->nents, direction);
+	dma_unmap_sg(rdev->dev, ttm->sg->sgl, ttm->sg->orig_nents, direction);
 
-	for_each_sg_page(ttm->sg->sgl, &sg_iter, ttm->sg->nents, 0) {
+	for_each_sg_page(ttm->sg->sgl, &sg_iter, ttm->sg->orig_nents, 0) {
 		struct page *page = sg_page_iter_page(&sg_iter);
 		if (!(gtt->userflags & RADEON_GEM_USERPTR_READONLY))
 			set_page_dirty(page);
-- 
1.9.1

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

^ permalink raw reply related	[flat|nested] 152+ messages in thread

* [RFC 10/17] drm: radeon: fix sg_table nents vs. orig_nents misuse
@ 2020-04-28 13:19       ` Marek Szyprowski
  0 siblings, 0 replies; 152+ messages in thread
From: Marek Szyprowski @ 2020-04-28 13:19 UTC (permalink / raw)
  To: dri-devel, iommu, linaro-mm-sig, linux-kernel
  Cc: Daniel Vetter, Bartlomiej Zolnierkiewicz, David Airlie,
	intel-gfx, amd-gfx, Christoph Hellwig, Benjamin Gaignard,
	Robin Murphy, Sumit Semwal, linux-arm-kernel, Marek Szyprowski

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/radeon/radeon_ttm.c | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/radeon/radeon_ttm.c b/drivers/gpu/drm/radeon/radeon_ttm.c
index 5d50c9e..4770880 100644
--- a/drivers/gpu/drm/radeon/radeon_ttm.c
+++ b/drivers/gpu/drm/radeon/radeon_ttm.c
@@ -481,7 +481,7 @@ static int radeon_ttm_tt_pin_userptr(struct ttm_tt *ttm)
 {
 	struct radeon_device *rdev = radeon_get_rdev(ttm->bdev);
 	struct radeon_ttm_tt *gtt = (void *)ttm;
-	unsigned pinned = 0, nents;
+	unsigned pinned = 0;
 	int r;
 
 	int write = !(gtt->userflags & RADEON_GEM_USERPTR_READONLY);
@@ -522,8 +522,8 @@ static int radeon_ttm_tt_pin_userptr(struct ttm_tt *ttm)
 		goto release_sg;
 
 	r = -ENOMEM;
-	nents = dma_map_sg(rdev->dev, ttm->sg->sgl, ttm->sg->nents, direction);
-	if (nents == 0)
+	ttm->sg->nents = dma_map_sg(rdev->dev, ttm->sg->sgl,
+	if (ttm->sg->nents == 0)
 		goto release_sg;
 
 	drm_prime_sg_to_page_addr_arrays(ttm->sg, ttm->pages,
@@ -554,9 +554,9 @@ static void radeon_ttm_tt_unpin_userptr(struct ttm_tt *ttm)
 		return;
 
 	/* free the sg table and pages again */
-	dma_unmap_sg(rdev->dev, ttm->sg->sgl, ttm->sg->nents, direction);
+	dma_unmap_sg(rdev->dev, ttm->sg->sgl, ttm->sg->orig_nents, direction);
 
-	for_each_sg_page(ttm->sg->sgl, &sg_iter, ttm->sg->nents, 0) {
+	for_each_sg_page(ttm->sg->sgl, &sg_iter, ttm->sg->orig_nents, 0) {
 		struct page *page = sg_page_iter_page(&sg_iter);
 		if (!(gtt->userflags & RADEON_GEM_USERPTR_READONLY))
 			set_page_dirty(page);
-- 
1.9.1

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

^ permalink raw reply related	[flat|nested] 152+ messages in thread

* [RFC 11/17] drm: rockchip: fix sg_table nents vs. orig_nents misuse
       [not found]   ` <CGME20200428132028eucas1p2310cd19b879962d5241604dd13909255@eucas1p2.samsung.com>
                         ` (3 preceding siblings ...)
  (?)
@ 2020-04-28 13:19       ` Marek Szyprowski
  0 siblings, 0 replies; 152+ messages in thread
From: Marek Szyprowski @ 2020-04-28 13:19 UTC (permalink / raw)
  To: dri-devel, iommu, linaro-mm-sig, linux-kernel
  Cc: Marek Szyprowski, Christoph Hellwig, Robin Murphy,
	Bartlomiej Zolnierkiewicz, Sumit Semwal, Benjamin Gaignard,
	intel-gfx, linux-arm-kernel, amd-gfx, David Airlie,
	Daniel Vetter

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/rockchip/rockchip_drm_gem.c | 15 ++++++++-------
 1 file changed, 8 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_gem.c b/drivers/gpu/drm/rockchip/rockchip_drm_gem.c
index 0d18846..a024c71 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_gem.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_gem.c
@@ -37,7 +37,7 @@ static int rockchip_gem_iommu_map(struct rockchip_gem_object *rk_obj)
 	rk_obj->dma_addr = rk_obj->mm.start;
 
 	ret = iommu_map_sg(private->domain, rk_obj->dma_addr, rk_obj->sgt->sgl,
-			   rk_obj->sgt->nents, prot);
+			   rk_obj->sgt->orig_nents, prot);
 	if (ret < rk_obj->base.size) {
 		DRM_ERROR("failed to map buffer: size=%zd request_size=%zd\n",
 			  ret, rk_obj->base.size);
@@ -98,11 +98,11 @@ static int rockchip_gem_get_pages(struct rockchip_gem_object *rk_obj)
 	 * TODO: Replace this by drm_clflush_sg() once it can be implemented
 	 * without relying on symbols that are not exported.
 	 */
-	for_each_sg(rk_obj->sgt->sgl, s, rk_obj->sgt->nents, i)
+	for_each_sg(rk_obj->sgt->sgl, s, rk_obj->sgt->orig_nents, i)
 		sg_dma_address(s) = sg_phys(s);
 
-	dma_sync_sg_for_device(drm->dev, rk_obj->sgt->sgl, rk_obj->sgt->nents,
-			       DMA_TO_DEVICE);
+	dma_sync_sg_for_device(drm->dev, rk_obj->sgt->sgl,
+			       rk_obj->sgt->orig_nents, DMA_TO_DEVICE);
 
 	return 0;
 
@@ -351,7 +351,8 @@ void rockchip_gem_free_object(struct drm_gem_object *obj)
 			rockchip_gem_iommu_unmap(rk_obj);
 		} else {
 			dma_unmap_sg(drm->dev, rk_obj->sgt->sgl,
-				     rk_obj->sgt->nents, DMA_BIDIRECTIONAL);
+				     rk_obj->sgt->orig_nents,
+				     DMA_BIDIRECTIONAL);
 		}
 		drm_prime_gem_destroy(obj, rk_obj->sgt);
 	} else {
@@ -493,14 +494,14 @@ static unsigned long rockchip_sg_get_contiguous_size(struct sg_table *sgt,
 			struct sg_table *sg,
 			struct rockchip_gem_object *rk_obj)
 {
-	int count = dma_map_sg(drm->dev, sg->sgl, sg->nents,
+	int count = dma_map_sg(drm->dev, sg->sgl, sg->orig_nents,
 			       DMA_BIDIRECTIONAL);
 	if (!count)
 		return -EINVAL;
 
 	if (rockchip_sg_get_contiguous_size(sg, count) < attach->dmabuf->size) {
 		DRM_ERROR("failed to map sg_table to contiguous linear address.\n");
-		dma_unmap_sg(drm->dev, sg->sgl, sg->nents,
+		dma_unmap_sg(drm->dev, sg->sgl, sg->orig_nents,
 			     DMA_BIDIRECTIONAL);
 		return -EINVAL;
 	}
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 152+ messages in thread

* [RFC 11/17] drm: rockchip: fix sg_table nents vs. orig_nents misuse
@ 2020-04-28 13:19       ` Marek Szyprowski
  0 siblings, 0 replies; 152+ messages in thread
From: Marek Szyprowski @ 2020-04-28 13:19 UTC (permalink / raw)
  To: dri-devel, iommu, linaro-mm-sig, linux-kernel
  Cc: Daniel Vetter, Bartlomiej Zolnierkiewicz, David Airlie,
	intel-gfx, amd-gfx, Christoph Hellwig, Benjamin Gaignard,
	Robin Murphy, Sumit Semwal, linux-arm-kernel

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/rockchip/rockchip_drm_gem.c | 15 ++++++++-------
 1 file changed, 8 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_gem.c b/drivers/gpu/drm/rockchip/rockchip_drm_gem.c
index 0d18846..a024c71 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_gem.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_gem.c
@@ -37,7 +37,7 @@ static int rockchip_gem_iommu_map(struct rockchip_gem_object *rk_obj)
 	rk_obj->dma_addr = rk_obj->mm.start;
 
 	ret = iommu_map_sg(private->domain, rk_obj->dma_addr, rk_obj->sgt->sgl,
-			   rk_obj->sgt->nents, prot);
+			   rk_obj->sgt->orig_nents, prot);
 	if (ret < rk_obj->base.size) {
 		DRM_ERROR("failed to map buffer: size=%zd request_size=%zd\n",
 			  ret, rk_obj->base.size);
@@ -98,11 +98,11 @@ static int rockchip_gem_get_pages(struct rockchip_gem_object *rk_obj)
 	 * TODO: Replace this by drm_clflush_sg() once it can be implemented
 	 * without relying on symbols that are not exported.
 	 */
-	for_each_sg(rk_obj->sgt->sgl, s, rk_obj->sgt->nents, i)
+	for_each_sg(rk_obj->sgt->sgl, s, rk_obj->sgt->orig_nents, i)
 		sg_dma_address(s) = sg_phys(s);
 
-	dma_sync_sg_for_device(drm->dev, rk_obj->sgt->sgl, rk_obj->sgt->nents,
-			       DMA_TO_DEVICE);
+	dma_sync_sg_for_device(drm->dev, rk_obj->sgt->sgl,
+			       rk_obj->sgt->orig_nents, DMA_TO_DEVICE);
 
 	return 0;
 
@@ -351,7 +351,8 @@ void rockchip_gem_free_object(struct drm_gem_object *obj)
 			rockchip_gem_iommu_unmap(rk_obj);
 		} else {
 			dma_unmap_sg(drm->dev, rk_obj->sgt->sgl,
-				     rk_obj->sgt->nents, DMA_BIDIRECTIONAL);
+				     rk_obj->sgt->orig_nents,
+				     DMA_BIDIRECTIONAL);
 		}
 		drm_prime_gem_destroy(obj, rk_obj->sgt);
 	} else {
@@ -493,14 +494,14 @@ static unsigned long rockchip_sg_get_contiguous_size(struct sg_table *sgt,
 			struct sg_table *sg,
 			struct rockchip_gem_object *rk_obj)
 {
-	int count = dma_map_sg(drm->dev, sg->sgl, sg->nents,
+	int count = dma_map_sg(drm->dev, sg->sgl, sg->orig_nents,
 			       DMA_BIDIRECTIONAL);
 	if (!count)
 		return -EINVAL;
 
 	if (rockchip_sg_get_contiguous_size(sg, count) < attach->dmabuf->size) {
 		DRM_ERROR("failed to map sg_table to contiguous linear address.\n");
-		dma_unmap_sg(drm->dev, sg->sgl, sg->nents,
+		dma_unmap_sg(drm->dev, sg->sgl, sg->orig_nents,
 			     DMA_BIDIRECTIONAL);
 		return -EINVAL;
 	}
-- 
1.9.1

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

^ permalink raw reply related	[flat|nested] 152+ messages in thread

* [RFC 11/17] drm: rockchip: fix sg_table nents vs. orig_nents misuse
@ 2020-04-28 13:19       ` Marek Szyprowski
  0 siblings, 0 replies; 152+ messages in thread
From: Marek Szyprowski @ 2020-04-28 13:19 UTC (permalink / raw)
  To: dri-devel, iommu, linaro-mm-sig, linux-kernel
  Cc: Daniel Vetter, Bartlomiej Zolnierkiewicz, David Airlie,
	intel-gfx, amd-gfx, Christoph Hellwig, Benjamin Gaignard,
	Robin Murphy, Sumit Semwal, linux-arm-kernel, Marek Szyprowski

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/rockchip/rockchip_drm_gem.c | 15 ++++++++-------
 1 file changed, 8 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_gem.c b/drivers/gpu/drm/rockchip/rockchip_drm_gem.c
index 0d18846..a024c71 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_gem.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_gem.c
@@ -37,7 +37,7 @@ static int rockchip_gem_iommu_map(struct rockchip_gem_object *rk_obj)
 	rk_obj->dma_addr = rk_obj->mm.start;
 
 	ret = iommu_map_sg(private->domain, rk_obj->dma_addr, rk_obj->sgt->sgl,
-			   rk_obj->sgt->nents, prot);
+			   rk_obj->sgt->orig_nents, prot);
 	if (ret < rk_obj->base.size) {
 		DRM_ERROR("failed to map buffer: size=%zd request_size=%zd\n",
 			  ret, rk_obj->base.size);
@@ -98,11 +98,11 @@ static int rockchip_gem_get_pages(struct rockchip_gem_object *rk_obj)
 	 * TODO: Replace this by drm_clflush_sg() once it can be implemented
 	 * without relying on symbols that are not exported.
 	 */
-	for_each_sg(rk_obj->sgt->sgl, s, rk_obj->sgt->nents, i)
+	for_each_sg(rk_obj->sgt->sgl, s, rk_obj->sgt->orig_nents, i)
 		sg_dma_address(s) = sg_phys(s);
 
-	dma_sync_sg_for_device(drm->dev, rk_obj->sgt->sgl, rk_obj->sgt->nents,
-			       DMA_TO_DEVICE);
+	dma_sync_sg_for_device(drm->dev, rk_obj->sgt->sgl,
+			       rk_obj->sgt->orig_nents, DMA_TO_DEVICE);
 
 	return 0;
 
@@ -351,7 +351,8 @@ void rockchip_gem_free_object(struct drm_gem_object *obj)
 			rockchip_gem_iommu_unmap(rk_obj);
 		} else {
 			dma_unmap_sg(drm->dev, rk_obj->sgt->sgl,
-				     rk_obj->sgt->nents, DMA_BIDIRECTIONAL);
+				     rk_obj->sgt->orig_nents,
+				     DMA_BIDIRECTIONAL);
 		}
 		drm_prime_gem_destroy(obj, rk_obj->sgt);
 	} else {
@@ -493,14 +494,14 @@ static unsigned long rockchip_sg_get_contiguous_size(struct sg_table *sgt,
 			struct sg_table *sg,
 			struct rockchip_gem_object *rk_obj)
 {
-	int count = dma_map_sg(drm->dev, sg->sgl, sg->nents,
+	int count = dma_map_sg(drm->dev, sg->sgl, sg->orig_nents,
 			       DMA_BIDIRECTIONAL);
 	if (!count)
 		return -EINVAL;
 
 	if (rockchip_sg_get_contiguous_size(sg, count) < attach->dmabuf->size) {
 		DRM_ERROR("failed to map sg_table to contiguous linear address.\n");
-		dma_unmap_sg(drm->dev, sg->sgl, sg->nents,
+		dma_unmap_sg(drm->dev, sg->sgl, sg->orig_nents,
 			     DMA_BIDIRECTIONAL);
 		return -EINVAL;
 	}
-- 
1.9.1


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

^ permalink raw reply related	[flat|nested] 152+ messages in thread

* [RFC 11/17] drm: rockchip: fix sg_table nents vs. orig_nents misuse
@ 2020-04-28 13:19       ` Marek Szyprowski
  0 siblings, 0 replies; 152+ messages in thread
From: Marek Szyprowski @ 2020-04-28 13:19 UTC (permalink / raw)
  To: dri-devel, iommu, linaro-mm-sig, linux-kernel
  Cc: Bartlomiej Zolnierkiewicz, David Airlie, intel-gfx, amd-gfx,
	Christoph Hellwig, Robin Murphy, linux-arm-kernel,
	Marek Szyprowski

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/rockchip/rockchip_drm_gem.c | 15 ++++++++-------
 1 file changed, 8 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_gem.c b/drivers/gpu/drm/rockchip/rockchip_drm_gem.c
index 0d18846..a024c71 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_gem.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_gem.c
@@ -37,7 +37,7 @@ static int rockchip_gem_iommu_map(struct rockchip_gem_object *rk_obj)
 	rk_obj->dma_addr = rk_obj->mm.start;
 
 	ret = iommu_map_sg(private->domain, rk_obj->dma_addr, rk_obj->sgt->sgl,
-			   rk_obj->sgt->nents, prot);
+			   rk_obj->sgt->orig_nents, prot);
 	if (ret < rk_obj->base.size) {
 		DRM_ERROR("failed to map buffer: size=%zd request_size=%zd\n",
 			  ret, rk_obj->base.size);
@@ -98,11 +98,11 @@ static int rockchip_gem_get_pages(struct rockchip_gem_object *rk_obj)
 	 * TODO: Replace this by drm_clflush_sg() once it can be implemented
 	 * without relying on symbols that are not exported.
 	 */
-	for_each_sg(rk_obj->sgt->sgl, s, rk_obj->sgt->nents, i)
+	for_each_sg(rk_obj->sgt->sgl, s, rk_obj->sgt->orig_nents, i)
 		sg_dma_address(s) = sg_phys(s);
 
-	dma_sync_sg_for_device(drm->dev, rk_obj->sgt->sgl, rk_obj->sgt->nents,
-			       DMA_TO_DEVICE);
+	dma_sync_sg_for_device(drm->dev, rk_obj->sgt->sgl,
+			       rk_obj->sgt->orig_nents, DMA_TO_DEVICE);
 
 	return 0;
 
@@ -351,7 +351,8 @@ void rockchip_gem_free_object(struct drm_gem_object *obj)
 			rockchip_gem_iommu_unmap(rk_obj);
 		} else {
 			dma_unmap_sg(drm->dev, rk_obj->sgt->sgl,
-				     rk_obj->sgt->nents, DMA_BIDIRECTIONAL);
+				     rk_obj->sgt->orig_nents,
+				     DMA_BIDIRECTIONAL);
 		}
 		drm_prime_gem_destroy(obj, rk_obj->sgt);
 	} else {
@@ -493,14 +494,14 @@ static unsigned long rockchip_sg_get_contiguous_size(struct sg_table *sgt,
 			struct sg_table *sg,
 			struct rockchip_gem_object *rk_obj)
 {
-	int count = dma_map_sg(drm->dev, sg->sgl, sg->nents,
+	int count = dma_map_sg(drm->dev, sg->sgl, sg->orig_nents,
 			       DMA_BIDIRECTIONAL);
 	if (!count)
 		return -EINVAL;
 
 	if (rockchip_sg_get_contiguous_size(sg, count) < attach->dmabuf->size) {
 		DRM_ERROR("failed to map sg_table to contiguous linear address.\n");
-		dma_unmap_sg(drm->dev, sg->sgl, sg->nents,
+		dma_unmap_sg(drm->dev, sg->sgl, sg->orig_nents,
 			     DMA_BIDIRECTIONAL);
 		return -EINVAL;
 	}
-- 
1.9.1

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

^ permalink raw reply related	[flat|nested] 152+ messages in thread

* [Intel-gfx] [RFC 11/17] drm: rockchip: fix sg_table nents vs. orig_nents misuse
@ 2020-04-28 13:19       ` Marek Szyprowski
  0 siblings, 0 replies; 152+ messages in thread
From: Marek Szyprowski @ 2020-04-28 13:19 UTC (permalink / raw)
  To: dri-devel, iommu, linaro-mm-sig, linux-kernel
  Cc: Bartlomiej Zolnierkiewicz, David Airlie, intel-gfx, amd-gfx,
	Christoph Hellwig, Benjamin Gaignard, Robin Murphy, Sumit Semwal,
	linux-arm-kernel, Marek Szyprowski

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/rockchip/rockchip_drm_gem.c | 15 ++++++++-------
 1 file changed, 8 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_gem.c b/drivers/gpu/drm/rockchip/rockchip_drm_gem.c
index 0d18846..a024c71 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_gem.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_gem.c
@@ -37,7 +37,7 @@ static int rockchip_gem_iommu_map(struct rockchip_gem_object *rk_obj)
 	rk_obj->dma_addr = rk_obj->mm.start;
 
 	ret = iommu_map_sg(private->domain, rk_obj->dma_addr, rk_obj->sgt->sgl,
-			   rk_obj->sgt->nents, prot);
+			   rk_obj->sgt->orig_nents, prot);
 	if (ret < rk_obj->base.size) {
 		DRM_ERROR("failed to map buffer: size=%zd request_size=%zd\n",
 			  ret, rk_obj->base.size);
@@ -98,11 +98,11 @@ static int rockchip_gem_get_pages(struct rockchip_gem_object *rk_obj)
 	 * TODO: Replace this by drm_clflush_sg() once it can be implemented
 	 * without relying on symbols that are not exported.
 	 */
-	for_each_sg(rk_obj->sgt->sgl, s, rk_obj->sgt->nents, i)
+	for_each_sg(rk_obj->sgt->sgl, s, rk_obj->sgt->orig_nents, i)
 		sg_dma_address(s) = sg_phys(s);
 
-	dma_sync_sg_for_device(drm->dev, rk_obj->sgt->sgl, rk_obj->sgt->nents,
-			       DMA_TO_DEVICE);
+	dma_sync_sg_for_device(drm->dev, rk_obj->sgt->sgl,
+			       rk_obj->sgt->orig_nents, DMA_TO_DEVICE);
 
 	return 0;
 
@@ -351,7 +351,8 @@ void rockchip_gem_free_object(struct drm_gem_object *obj)
 			rockchip_gem_iommu_unmap(rk_obj);
 		} else {
 			dma_unmap_sg(drm->dev, rk_obj->sgt->sgl,
-				     rk_obj->sgt->nents, DMA_BIDIRECTIONAL);
+				     rk_obj->sgt->orig_nents,
+				     DMA_BIDIRECTIONAL);
 		}
 		drm_prime_gem_destroy(obj, rk_obj->sgt);
 	} else {
@@ -493,14 +494,14 @@ static unsigned long rockchip_sg_get_contiguous_size(struct sg_table *sgt,
 			struct sg_table *sg,
 			struct rockchip_gem_object *rk_obj)
 {
-	int count = dma_map_sg(drm->dev, sg->sgl, sg->nents,
+	int count = dma_map_sg(drm->dev, sg->sgl, sg->orig_nents,
 			       DMA_BIDIRECTIONAL);
 	if (!count)
 		return -EINVAL;
 
 	if (rockchip_sg_get_contiguous_size(sg, count) < attach->dmabuf->size) {
 		DRM_ERROR("failed to map sg_table to contiguous linear address.\n");
-		dma_unmap_sg(drm->dev, sg->sgl, sg->nents,
+		dma_unmap_sg(drm->dev, sg->sgl, sg->orig_nents,
 			     DMA_BIDIRECTIONAL);
 		return -EINVAL;
 	}
-- 
1.9.1

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

^ permalink raw reply related	[flat|nested] 152+ messages in thread

* [RFC 11/17] drm: rockchip: fix sg_table nents vs. orig_nents misuse
@ 2020-04-28 13:19       ` Marek Szyprowski
  0 siblings, 0 replies; 152+ messages in thread
From: Marek Szyprowski @ 2020-04-28 13:19 UTC (permalink / raw)
  To: dri-devel, iommu, linaro-mm-sig, linux-kernel
  Cc: Daniel Vetter, Bartlomiej Zolnierkiewicz, David Airlie,
	intel-gfx, amd-gfx, Christoph Hellwig, Benjamin Gaignard,
	Robin Murphy, Sumit Semwal, linux-arm-kernel, Marek Szyprowski

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/rockchip/rockchip_drm_gem.c | 15 ++++++++-------
 1 file changed, 8 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_gem.c b/drivers/gpu/drm/rockchip/rockchip_drm_gem.c
index 0d18846..a024c71 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_gem.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_gem.c
@@ -37,7 +37,7 @@ static int rockchip_gem_iommu_map(struct rockchip_gem_object *rk_obj)
 	rk_obj->dma_addr = rk_obj->mm.start;
 
 	ret = iommu_map_sg(private->domain, rk_obj->dma_addr, rk_obj->sgt->sgl,
-			   rk_obj->sgt->nents, prot);
+			   rk_obj->sgt->orig_nents, prot);
 	if (ret < rk_obj->base.size) {
 		DRM_ERROR("failed to map buffer: size=%zd request_size=%zd\n",
 			  ret, rk_obj->base.size);
@@ -98,11 +98,11 @@ static int rockchip_gem_get_pages(struct rockchip_gem_object *rk_obj)
 	 * TODO: Replace this by drm_clflush_sg() once it can be implemented
 	 * without relying on symbols that are not exported.
 	 */
-	for_each_sg(rk_obj->sgt->sgl, s, rk_obj->sgt->nents, i)
+	for_each_sg(rk_obj->sgt->sgl, s, rk_obj->sgt->orig_nents, i)
 		sg_dma_address(s) = sg_phys(s);
 
-	dma_sync_sg_for_device(drm->dev, rk_obj->sgt->sgl, rk_obj->sgt->nents,
-			       DMA_TO_DEVICE);
+	dma_sync_sg_for_device(drm->dev, rk_obj->sgt->sgl,
+			       rk_obj->sgt->orig_nents, DMA_TO_DEVICE);
 
 	return 0;
 
@@ -351,7 +351,8 @@ void rockchip_gem_free_object(struct drm_gem_object *obj)
 			rockchip_gem_iommu_unmap(rk_obj);
 		} else {
 			dma_unmap_sg(drm->dev, rk_obj->sgt->sgl,
-				     rk_obj->sgt->nents, DMA_BIDIRECTIONAL);
+				     rk_obj->sgt->orig_nents,
+				     DMA_BIDIRECTIONAL);
 		}
 		drm_prime_gem_destroy(obj, rk_obj->sgt);
 	} else {
@@ -493,14 +494,14 @@ static unsigned long rockchip_sg_get_contiguous_size(struct sg_table *sgt,
 			struct sg_table *sg,
 			struct rockchip_gem_object *rk_obj)
 {
-	int count = dma_map_sg(drm->dev, sg->sgl, sg->nents,
+	int count = dma_map_sg(drm->dev, sg->sgl, sg->orig_nents,
 			       DMA_BIDIRECTIONAL);
 	if (!count)
 		return -EINVAL;
 
 	if (rockchip_sg_get_contiguous_size(sg, count) < attach->dmabuf->size) {
 		DRM_ERROR("failed to map sg_table to contiguous linear address.\n");
-		dma_unmap_sg(drm->dev, sg->sgl, sg->nents,
+		dma_unmap_sg(drm->dev, sg->sgl, sg->orig_nents,
 			     DMA_BIDIRECTIONAL);
 		return -EINVAL;
 	}
-- 
1.9.1

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

^ permalink raw reply related	[flat|nested] 152+ messages in thread

* [RFC 12/17] drm: tegra: fix sg_table nents vs. orig_nents misuse
       [not found]   ` <CGME20200428132029eucas1p2433959853ef384ef783cbe9a1e45fde3@eucas1p2.samsung.com>
                         ` (3 preceding siblings ...)
  (?)
@ 2020-04-28 13:20       ` Marek Szyprowski
  0 siblings, 0 replies; 152+ messages in thread
From: Marek Szyprowski @ 2020-04-28 13:20 UTC (permalink / raw)
  To: dri-devel, iommu, linaro-mm-sig, linux-kernel
  Cc: Marek Szyprowski, Christoph Hellwig, Robin Murphy,
	Bartlomiej Zolnierkiewicz, Sumit Semwal, Benjamin Gaignard,
	intel-gfx, linux-arm-kernel, amd-gfx, David Airlie,
	Daniel Vetter

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/tegra/gem.c   | 25 +++++++++++++------------
 drivers/gpu/drm/tegra/plane.c | 13 +++++++------
 2 files changed, 20 insertions(+), 18 deletions(-)

diff --git a/drivers/gpu/drm/tegra/gem.c b/drivers/gpu/drm/tegra/gem.c
index 6237681..5710ab4 100644
--- a/drivers/gpu/drm/tegra/gem.c
+++ b/drivers/gpu/drm/tegra/gem.c
@@ -98,8 +98,8 @@ static struct sg_table *tegra_bo_pin(struct device *dev, struct host1x_bo *bo,
 		 * the SG table needs to be copied to avoid overwriting any
 		 * other potential users of the original SG table.
 		 */
-		err = sg_alloc_table_from_sg(sgt, obj->sgt->sgl, obj->sgt->nents,
-					     GFP_KERNEL);
+		err = sg_alloc_table_from_sg(sgt, obj->sgt->sgl,
+					     obj->sgt->orig_nents, GFP_KERNEL);
 		if (err < 0)
 			goto free;
 	} else {
@@ -197,7 +197,7 @@ static int tegra_bo_iommu_map(struct tegra_drm *tegra, struct tegra_bo *bo)
 	bo->iova = bo->mm->start;
 
 	bo->size = iommu_map_sg(tegra->domain, bo->iova, bo->sgt->sgl,
-				bo->sgt->nents, prot);
+				bo->sgt->orig_nents, prot);
 	if (!bo->size) {
 		dev_err(tegra->drm->dev, "failed to map buffer\n");
 		err = -ENOMEM;
@@ -264,7 +264,7 @@ static struct tegra_bo *tegra_bo_alloc_object(struct drm_device *drm,
 static void tegra_bo_free(struct drm_device *drm, struct tegra_bo *bo)
 {
 	if (bo->pages) {
-		dma_unmap_sg(drm->dev, bo->sgt->sgl, bo->sgt->nents,
+		dma_unmap_sg(drm->dev, bo->sgt->sgl, bo->sgt->orig_nents,
 			     DMA_FROM_DEVICE);
 		drm_gem_put_pages(&bo->gem, bo->pages, true, true);
 		sg_free_table(bo->sgt);
@@ -290,9 +290,9 @@ static int tegra_bo_get_pages(struct drm_device *drm, struct tegra_bo *bo)
 		goto put_pages;
 	}
 
-	err = dma_map_sg(drm->dev, bo->sgt->sgl, bo->sgt->nents,
-			 DMA_FROM_DEVICE);
-	if (err == 0) {
+	bo->sgt->nents = dma_map_sg(drm->dev, bo->sgt->sgl, bo->sgt->orig_nents,
+				DMA_FROM_DEVICE);
+	if (bo->sgt->nents == 0) {
 		err = -EFAULT;
 		goto free_sgt;
 	}
@@ -571,7 +571,8 @@ int tegra_drm_mmap(struct file *file, struct vm_area_struct *vma)
 			goto free;
 	}
 
-	if (dma_map_sg(attach->dev, sgt->sgl, sgt->nents, dir) == 0)
+	sgt->nents = dma_map_sg(attach->dev, sgt->sgl, sgt->orig_nents, dir);
+	if (sgt->nents == 0)
 		goto free;
 
 	return sgt;
@@ -590,7 +591,7 @@ static void tegra_gem_prime_unmap_dma_buf(struct dma_buf_attachment *attach,
 	struct tegra_bo *bo = to_tegra_bo(gem);
 
 	if (bo->pages)
-		dma_unmap_sg(attach->dev, sgt->sgl, sgt->nents, dir);
+		dma_unmap_sg(attach->dev, sgt->sgl, sgt->orig_nents, dir);
 
 	sg_free_table(sgt);
 	kfree(sgt);
@@ -609,7 +610,7 @@ static int tegra_gem_prime_begin_cpu_access(struct dma_buf *buf,
 	struct drm_device *drm = gem->dev;
 
 	if (bo->pages)
-		dma_sync_sg_for_cpu(drm->dev, bo->sgt->sgl, bo->sgt->nents,
+		dma_sync_sg_for_cpu(drm->dev, bo->sgt->sgl, bo->sgt->orig_nents,
 				    DMA_FROM_DEVICE);
 
 	return 0;
@@ -623,8 +624,8 @@ static int tegra_gem_prime_end_cpu_access(struct dma_buf *buf,
 	struct drm_device *drm = gem->dev;
 
 	if (bo->pages)
-		dma_sync_sg_for_device(drm->dev, bo->sgt->sgl, bo->sgt->nents,
-				       DMA_TO_DEVICE);
+		dma_sync_sg_for_device(drm->dev, bo->sgt->sgl,
+				       bo->sgt->orig_nents, DMA_TO_DEVICE);
 
 	return 0;
 }
diff --git a/drivers/gpu/drm/tegra/plane.c b/drivers/gpu/drm/tegra/plane.c
index 9ccfb56..3982bf8 100644
--- a/drivers/gpu/drm/tegra/plane.c
+++ b/drivers/gpu/drm/tegra/plane.c
@@ -130,9 +130,10 @@ static int tegra_dc_pin(struct tegra_dc *dc, struct tegra_plane_state *state)
 		}
 
 		if (sgt) {
-			err = dma_map_sg(dc->dev, sgt->sgl, sgt->nents,
-					 DMA_TO_DEVICE);
-			if (err == 0) {
+			sgt->nents = dma_map_sg(dc->dev, sgt->sgl,
+						sgt->orig_nents,
+						DMA_TO_DEVICE);
+			if (sgt->nents == 0) {
 				err = -ENOMEM;
 				goto unpin;
 			}
@@ -143,7 +144,7 @@ static int tegra_dc_pin(struct tegra_dc *dc, struct tegra_plane_state *state)
 			 * map its SG table to a single contiguous chunk of
 			 * I/O virtual memory.
 			 */
-			if (err > 1) {
+			if (sgt->nents > 1) {
 				err = -EINVAL;
 				goto unpin;
 			}
@@ -165,7 +166,7 @@ static int tegra_dc_pin(struct tegra_dc *dc, struct tegra_plane_state *state)
 		struct sg_table *sgt = state->sgt[i];
 
 		if (sgt)
-			dma_unmap_sg(dc->dev, sgt->sgl, sgt->nents,
+			dma_unmap_sg(dc->dev, sgt->sgl, sgt->orig_nents,
 				     DMA_TO_DEVICE);
 
 		host1x_bo_unpin(dc->dev, &bo->base, sgt);
@@ -185,7 +186,7 @@ static void tegra_dc_unpin(struct tegra_dc *dc, struct tegra_plane_state *state)
 		struct sg_table *sgt = state->sgt[i];
 
 		if (sgt)
-			dma_unmap_sg(dc->dev, sgt->sgl, sgt->nents,
+			dma_unmap_sg(dc->dev, sgt->sgl, sgt->orig_nents,
 				     DMA_TO_DEVICE);
 
 		host1x_bo_unpin(dc->dev, &bo->base, sgt);
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 152+ messages in thread

* [RFC 12/17] drm: tegra: fix sg_table nents vs. orig_nents misuse
@ 2020-04-28 13:20       ` Marek Szyprowski
  0 siblings, 0 replies; 152+ messages in thread
From: Marek Szyprowski @ 2020-04-28 13:20 UTC (permalink / raw)
  To: dri-devel, iommu, linaro-mm-sig, linux-kernel
  Cc: Daniel Vetter, Bartlomiej Zolnierkiewicz, David Airlie,
	intel-gfx, amd-gfx, Christoph Hellwig, Benjamin Gaignard,
	Robin Murphy, Sumit Semwal, linux-arm-kernel

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/tegra/gem.c   | 25 +++++++++++++------------
 drivers/gpu/drm/tegra/plane.c | 13 +++++++------
 2 files changed, 20 insertions(+), 18 deletions(-)

diff --git a/drivers/gpu/drm/tegra/gem.c b/drivers/gpu/drm/tegra/gem.c
index 6237681..5710ab4 100644
--- a/drivers/gpu/drm/tegra/gem.c
+++ b/drivers/gpu/drm/tegra/gem.c
@@ -98,8 +98,8 @@ static struct sg_table *tegra_bo_pin(struct device *dev, struct host1x_bo *bo,
 		 * the SG table needs to be copied to avoid overwriting any
 		 * other potential users of the original SG table.
 		 */
-		err = sg_alloc_table_from_sg(sgt, obj->sgt->sgl, obj->sgt->nents,
-					     GFP_KERNEL);
+		err = sg_alloc_table_from_sg(sgt, obj->sgt->sgl,
+					     obj->sgt->orig_nents, GFP_KERNEL);
 		if (err < 0)
 			goto free;
 	} else {
@@ -197,7 +197,7 @@ static int tegra_bo_iommu_map(struct tegra_drm *tegra, struct tegra_bo *bo)
 	bo->iova = bo->mm->start;
 
 	bo->size = iommu_map_sg(tegra->domain, bo->iova, bo->sgt->sgl,
-				bo->sgt->nents, prot);
+				bo->sgt->orig_nents, prot);
 	if (!bo->size) {
 		dev_err(tegra->drm->dev, "failed to map buffer\n");
 		err = -ENOMEM;
@@ -264,7 +264,7 @@ static struct tegra_bo *tegra_bo_alloc_object(struct drm_device *drm,
 static void tegra_bo_free(struct drm_device *drm, struct tegra_bo *bo)
 {
 	if (bo->pages) {
-		dma_unmap_sg(drm->dev, bo->sgt->sgl, bo->sgt->nents,
+		dma_unmap_sg(drm->dev, bo->sgt->sgl, bo->sgt->orig_nents,
 			     DMA_FROM_DEVICE);
 		drm_gem_put_pages(&bo->gem, bo->pages, true, true);
 		sg_free_table(bo->sgt);
@@ -290,9 +290,9 @@ static int tegra_bo_get_pages(struct drm_device *drm, struct tegra_bo *bo)
 		goto put_pages;
 	}
 
-	err = dma_map_sg(drm->dev, bo->sgt->sgl, bo->sgt->nents,
-			 DMA_FROM_DEVICE);
-	if (err == 0) {
+	bo->sgt->nents = dma_map_sg(drm->dev, bo->sgt->sgl, bo->sgt->orig_nents,
+				DMA_FROM_DEVICE);
+	if (bo->sgt->nents == 0) {
 		err = -EFAULT;
 		goto free_sgt;
 	}
@@ -571,7 +571,8 @@ int tegra_drm_mmap(struct file *file, struct vm_area_struct *vma)
 			goto free;
 	}
 
-	if (dma_map_sg(attach->dev, sgt->sgl, sgt->nents, dir) == 0)
+	sgt->nents = dma_map_sg(attach->dev, sgt->sgl, sgt->orig_nents, dir);
+	if (sgt->nents == 0)
 		goto free;
 
 	return sgt;
@@ -590,7 +591,7 @@ static void tegra_gem_prime_unmap_dma_buf(struct dma_buf_attachment *attach,
 	struct tegra_bo *bo = to_tegra_bo(gem);
 
 	if (bo->pages)
-		dma_unmap_sg(attach->dev, sgt->sgl, sgt->nents, dir);
+		dma_unmap_sg(attach->dev, sgt->sgl, sgt->orig_nents, dir);
 
 	sg_free_table(sgt);
 	kfree(sgt);
@@ -609,7 +610,7 @@ static int tegra_gem_prime_begin_cpu_access(struct dma_buf *buf,
 	struct drm_device *drm = gem->dev;
 
 	if (bo->pages)
-		dma_sync_sg_for_cpu(drm->dev, bo->sgt->sgl, bo->sgt->nents,
+		dma_sync_sg_for_cpu(drm->dev, bo->sgt->sgl, bo->sgt->orig_nents,
 				    DMA_FROM_DEVICE);
 
 	return 0;
@@ -623,8 +624,8 @@ static int tegra_gem_prime_end_cpu_access(struct dma_buf *buf,
 	struct drm_device *drm = gem->dev;
 
 	if (bo->pages)
-		dma_sync_sg_for_device(drm->dev, bo->sgt->sgl, bo->sgt->nents,
-				       DMA_TO_DEVICE);
+		dma_sync_sg_for_device(drm->dev, bo->sgt->sgl,
+				       bo->sgt->orig_nents, DMA_TO_DEVICE);
 
 	return 0;
 }
diff --git a/drivers/gpu/drm/tegra/plane.c b/drivers/gpu/drm/tegra/plane.c
index 9ccfb56..3982bf8 100644
--- a/drivers/gpu/drm/tegra/plane.c
+++ b/drivers/gpu/drm/tegra/plane.c
@@ -130,9 +130,10 @@ static int tegra_dc_pin(struct tegra_dc *dc, struct tegra_plane_state *state)
 		}
 
 		if (sgt) {
-			err = dma_map_sg(dc->dev, sgt->sgl, sgt->nents,
-					 DMA_TO_DEVICE);
-			if (err == 0) {
+			sgt->nents = dma_map_sg(dc->dev, sgt->sgl,
+						sgt->orig_nents,
+						DMA_TO_DEVICE);
+			if (sgt->nents == 0) {
 				err = -ENOMEM;
 				goto unpin;
 			}
@@ -143,7 +144,7 @@ static int tegra_dc_pin(struct tegra_dc *dc, struct tegra_plane_state *state)
 			 * map its SG table to a single contiguous chunk of
 			 * I/O virtual memory.
 			 */
-			if (err > 1) {
+			if (sgt->nents > 1) {
 				err = -EINVAL;
 				goto unpin;
 			}
@@ -165,7 +166,7 @@ static int tegra_dc_pin(struct tegra_dc *dc, struct tegra_plane_state *state)
 		struct sg_table *sgt = state->sgt[i];
 
 		if (sgt)
-			dma_unmap_sg(dc->dev, sgt->sgl, sgt->nents,
+			dma_unmap_sg(dc->dev, sgt->sgl, sgt->orig_nents,
 				     DMA_TO_DEVICE);
 
 		host1x_bo_unpin(dc->dev, &bo->base, sgt);
@@ -185,7 +186,7 @@ static void tegra_dc_unpin(struct tegra_dc *dc, struct tegra_plane_state *state)
 		struct sg_table *sgt = state->sgt[i];
 
 		if (sgt)
-			dma_unmap_sg(dc->dev, sgt->sgl, sgt->nents,
+			dma_unmap_sg(dc->dev, sgt->sgl, sgt->orig_nents,
 				     DMA_TO_DEVICE);
 
 		host1x_bo_unpin(dc->dev, &bo->base, sgt);
-- 
1.9.1

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

^ permalink raw reply related	[flat|nested] 152+ messages in thread

* [RFC 12/17] drm: tegra: fix sg_table nents vs. orig_nents misuse
@ 2020-04-28 13:20       ` Marek Szyprowski
  0 siblings, 0 replies; 152+ messages in thread
From: Marek Szyprowski @ 2020-04-28 13:20 UTC (permalink / raw)
  To: dri-devel, iommu, linaro-mm-sig, linux-kernel
  Cc: Daniel Vetter, Bartlomiej Zolnierkiewicz, David Airlie,
	intel-gfx, amd-gfx, Christoph Hellwig, Benjamin Gaignard,
	Robin Murphy, Sumit Semwal, linux-arm-kernel, Marek Szyprowski

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/tegra/gem.c   | 25 +++++++++++++------------
 drivers/gpu/drm/tegra/plane.c | 13 +++++++------
 2 files changed, 20 insertions(+), 18 deletions(-)

diff --git a/drivers/gpu/drm/tegra/gem.c b/drivers/gpu/drm/tegra/gem.c
index 6237681..5710ab4 100644
--- a/drivers/gpu/drm/tegra/gem.c
+++ b/drivers/gpu/drm/tegra/gem.c
@@ -98,8 +98,8 @@ static struct sg_table *tegra_bo_pin(struct device *dev, struct host1x_bo *bo,
 		 * the SG table needs to be copied to avoid overwriting any
 		 * other potential users of the original SG table.
 		 */
-		err = sg_alloc_table_from_sg(sgt, obj->sgt->sgl, obj->sgt->nents,
-					     GFP_KERNEL);
+		err = sg_alloc_table_from_sg(sgt, obj->sgt->sgl,
+					     obj->sgt->orig_nents, GFP_KERNEL);
 		if (err < 0)
 			goto free;
 	} else {
@@ -197,7 +197,7 @@ static int tegra_bo_iommu_map(struct tegra_drm *tegra, struct tegra_bo *bo)
 	bo->iova = bo->mm->start;
 
 	bo->size = iommu_map_sg(tegra->domain, bo->iova, bo->sgt->sgl,
-				bo->sgt->nents, prot);
+				bo->sgt->orig_nents, prot);
 	if (!bo->size) {
 		dev_err(tegra->drm->dev, "failed to map buffer\n");
 		err = -ENOMEM;
@@ -264,7 +264,7 @@ static struct tegra_bo *tegra_bo_alloc_object(struct drm_device *drm,
 static void tegra_bo_free(struct drm_device *drm, struct tegra_bo *bo)
 {
 	if (bo->pages) {
-		dma_unmap_sg(drm->dev, bo->sgt->sgl, bo->sgt->nents,
+		dma_unmap_sg(drm->dev, bo->sgt->sgl, bo->sgt->orig_nents,
 			     DMA_FROM_DEVICE);
 		drm_gem_put_pages(&bo->gem, bo->pages, true, true);
 		sg_free_table(bo->sgt);
@@ -290,9 +290,9 @@ static int tegra_bo_get_pages(struct drm_device *drm, struct tegra_bo *bo)
 		goto put_pages;
 	}
 
-	err = dma_map_sg(drm->dev, bo->sgt->sgl, bo->sgt->nents,
-			 DMA_FROM_DEVICE);
-	if (err == 0) {
+	bo->sgt->nents = dma_map_sg(drm->dev, bo->sgt->sgl, bo->sgt->orig_nents,
+				DMA_FROM_DEVICE);
+	if (bo->sgt->nents == 0) {
 		err = -EFAULT;
 		goto free_sgt;
 	}
@@ -571,7 +571,8 @@ int tegra_drm_mmap(struct file *file, struct vm_area_struct *vma)
 			goto free;
 	}
 
-	if (dma_map_sg(attach->dev, sgt->sgl, sgt->nents, dir) == 0)
+	sgt->nents = dma_map_sg(attach->dev, sgt->sgl, sgt->orig_nents, dir);
+	if (sgt->nents == 0)
 		goto free;
 
 	return sgt;
@@ -590,7 +591,7 @@ static void tegra_gem_prime_unmap_dma_buf(struct dma_buf_attachment *attach,
 	struct tegra_bo *bo = to_tegra_bo(gem);
 
 	if (bo->pages)
-		dma_unmap_sg(attach->dev, sgt->sgl, sgt->nents, dir);
+		dma_unmap_sg(attach->dev, sgt->sgl, sgt->orig_nents, dir);
 
 	sg_free_table(sgt);
 	kfree(sgt);
@@ -609,7 +610,7 @@ static int tegra_gem_prime_begin_cpu_access(struct dma_buf *buf,
 	struct drm_device *drm = gem->dev;
 
 	if (bo->pages)
-		dma_sync_sg_for_cpu(drm->dev, bo->sgt->sgl, bo->sgt->nents,
+		dma_sync_sg_for_cpu(drm->dev, bo->sgt->sgl, bo->sgt->orig_nents,
 				    DMA_FROM_DEVICE);
 
 	return 0;
@@ -623,8 +624,8 @@ static int tegra_gem_prime_end_cpu_access(struct dma_buf *buf,
 	struct drm_device *drm = gem->dev;
 
 	if (bo->pages)
-		dma_sync_sg_for_device(drm->dev, bo->sgt->sgl, bo->sgt->nents,
-				       DMA_TO_DEVICE);
+		dma_sync_sg_for_device(drm->dev, bo->sgt->sgl,
+				       bo->sgt->orig_nents, DMA_TO_DEVICE);
 
 	return 0;
 }
diff --git a/drivers/gpu/drm/tegra/plane.c b/drivers/gpu/drm/tegra/plane.c
index 9ccfb56..3982bf8 100644
--- a/drivers/gpu/drm/tegra/plane.c
+++ b/drivers/gpu/drm/tegra/plane.c
@@ -130,9 +130,10 @@ static int tegra_dc_pin(struct tegra_dc *dc, struct tegra_plane_state *state)
 		}
 
 		if (sgt) {
-			err = dma_map_sg(dc->dev, sgt->sgl, sgt->nents,
-					 DMA_TO_DEVICE);
-			if (err == 0) {
+			sgt->nents = dma_map_sg(dc->dev, sgt->sgl,
+						sgt->orig_nents,
+						DMA_TO_DEVICE);
+			if (sgt->nents == 0) {
 				err = -ENOMEM;
 				goto unpin;
 			}
@@ -143,7 +144,7 @@ static int tegra_dc_pin(struct tegra_dc *dc, struct tegra_plane_state *state)
 			 * map its SG table to a single contiguous chunk of
 			 * I/O virtual memory.
 			 */
-			if (err > 1) {
+			if (sgt->nents > 1) {
 				err = -EINVAL;
 				goto unpin;
 			}
@@ -165,7 +166,7 @@ static int tegra_dc_pin(struct tegra_dc *dc, struct tegra_plane_state *state)
 		struct sg_table *sgt = state->sgt[i];
 
 		if (sgt)
-			dma_unmap_sg(dc->dev, sgt->sgl, sgt->nents,
+			dma_unmap_sg(dc->dev, sgt->sgl, sgt->orig_nents,
 				     DMA_TO_DEVICE);
 
 		host1x_bo_unpin(dc->dev, &bo->base, sgt);
@@ -185,7 +186,7 @@ static void tegra_dc_unpin(struct tegra_dc *dc, struct tegra_plane_state *state)
 		struct sg_table *sgt = state->sgt[i];
 
 		if (sgt)
-			dma_unmap_sg(dc->dev, sgt->sgl, sgt->nents,
+			dma_unmap_sg(dc->dev, sgt->sgl, sgt->orig_nents,
 				     DMA_TO_DEVICE);
 
 		host1x_bo_unpin(dc->dev, &bo->base, sgt);
-- 
1.9.1


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

^ permalink raw reply related	[flat|nested] 152+ messages in thread

* [RFC 12/17] drm: tegra: fix sg_table nents vs. orig_nents misuse
@ 2020-04-28 13:20       ` Marek Szyprowski
  0 siblings, 0 replies; 152+ messages in thread
From: Marek Szyprowski @ 2020-04-28 13:20 UTC (permalink / raw)
  To: dri-devel, iommu, linaro-mm-sig, linux-kernel
  Cc: Bartlomiej Zolnierkiewicz, David Airlie, intel-gfx, amd-gfx,
	Christoph Hellwig, Robin Murphy, linux-arm-kernel,
	Marek Szyprowski

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/tegra/gem.c   | 25 +++++++++++++------------
 drivers/gpu/drm/tegra/plane.c | 13 +++++++------
 2 files changed, 20 insertions(+), 18 deletions(-)

diff --git a/drivers/gpu/drm/tegra/gem.c b/drivers/gpu/drm/tegra/gem.c
index 6237681..5710ab4 100644
--- a/drivers/gpu/drm/tegra/gem.c
+++ b/drivers/gpu/drm/tegra/gem.c
@@ -98,8 +98,8 @@ static struct sg_table *tegra_bo_pin(struct device *dev, struct host1x_bo *bo,
 		 * the SG table needs to be copied to avoid overwriting any
 		 * other potential users of the original SG table.
 		 */
-		err = sg_alloc_table_from_sg(sgt, obj->sgt->sgl, obj->sgt->nents,
-					     GFP_KERNEL);
+		err = sg_alloc_table_from_sg(sgt, obj->sgt->sgl,
+					     obj->sgt->orig_nents, GFP_KERNEL);
 		if (err < 0)
 			goto free;
 	} else {
@@ -197,7 +197,7 @@ static int tegra_bo_iommu_map(struct tegra_drm *tegra, struct tegra_bo *bo)
 	bo->iova = bo->mm->start;
 
 	bo->size = iommu_map_sg(tegra->domain, bo->iova, bo->sgt->sgl,
-				bo->sgt->nents, prot);
+				bo->sgt->orig_nents, prot);
 	if (!bo->size) {
 		dev_err(tegra->drm->dev, "failed to map buffer\n");
 		err = -ENOMEM;
@@ -264,7 +264,7 @@ static struct tegra_bo *tegra_bo_alloc_object(struct drm_device *drm,
 static void tegra_bo_free(struct drm_device *drm, struct tegra_bo *bo)
 {
 	if (bo->pages) {
-		dma_unmap_sg(drm->dev, bo->sgt->sgl, bo->sgt->nents,
+		dma_unmap_sg(drm->dev, bo->sgt->sgl, bo->sgt->orig_nents,
 			     DMA_FROM_DEVICE);
 		drm_gem_put_pages(&bo->gem, bo->pages, true, true);
 		sg_free_table(bo->sgt);
@@ -290,9 +290,9 @@ static int tegra_bo_get_pages(struct drm_device *drm, struct tegra_bo *bo)
 		goto put_pages;
 	}
 
-	err = dma_map_sg(drm->dev, bo->sgt->sgl, bo->sgt->nents,
-			 DMA_FROM_DEVICE);
-	if (err == 0) {
+	bo->sgt->nents = dma_map_sg(drm->dev, bo->sgt->sgl, bo->sgt->orig_nents,
+				DMA_FROM_DEVICE);
+	if (bo->sgt->nents == 0) {
 		err = -EFAULT;
 		goto free_sgt;
 	}
@@ -571,7 +571,8 @@ int tegra_drm_mmap(struct file *file, struct vm_area_struct *vma)
 			goto free;
 	}
 
-	if (dma_map_sg(attach->dev, sgt->sgl, sgt->nents, dir) == 0)
+	sgt->nents = dma_map_sg(attach->dev, sgt->sgl, sgt->orig_nents, dir);
+	if (sgt->nents == 0)
 		goto free;
 
 	return sgt;
@@ -590,7 +591,7 @@ static void tegra_gem_prime_unmap_dma_buf(struct dma_buf_attachment *attach,
 	struct tegra_bo *bo = to_tegra_bo(gem);
 
 	if (bo->pages)
-		dma_unmap_sg(attach->dev, sgt->sgl, sgt->nents, dir);
+		dma_unmap_sg(attach->dev, sgt->sgl, sgt->orig_nents, dir);
 
 	sg_free_table(sgt);
 	kfree(sgt);
@@ -609,7 +610,7 @@ static int tegra_gem_prime_begin_cpu_access(struct dma_buf *buf,
 	struct drm_device *drm = gem->dev;
 
 	if (bo->pages)
-		dma_sync_sg_for_cpu(drm->dev, bo->sgt->sgl, bo->sgt->nents,
+		dma_sync_sg_for_cpu(drm->dev, bo->sgt->sgl, bo->sgt->orig_nents,
 				    DMA_FROM_DEVICE);
 
 	return 0;
@@ -623,8 +624,8 @@ static int tegra_gem_prime_end_cpu_access(struct dma_buf *buf,
 	struct drm_device *drm = gem->dev;
 
 	if (bo->pages)
-		dma_sync_sg_for_device(drm->dev, bo->sgt->sgl, bo->sgt->nents,
-				       DMA_TO_DEVICE);
+		dma_sync_sg_for_device(drm->dev, bo->sgt->sgl,
+				       bo->sgt->orig_nents, DMA_TO_DEVICE);
 
 	return 0;
 }
diff --git a/drivers/gpu/drm/tegra/plane.c b/drivers/gpu/drm/tegra/plane.c
index 9ccfb56..3982bf8 100644
--- a/drivers/gpu/drm/tegra/plane.c
+++ b/drivers/gpu/drm/tegra/plane.c
@@ -130,9 +130,10 @@ static int tegra_dc_pin(struct tegra_dc *dc, struct tegra_plane_state *state)
 		}
 
 		if (sgt) {
-			err = dma_map_sg(dc->dev, sgt->sgl, sgt->nents,
-					 DMA_TO_DEVICE);
-			if (err == 0) {
+			sgt->nents = dma_map_sg(dc->dev, sgt->sgl,
+						sgt->orig_nents,
+						DMA_TO_DEVICE);
+			if (sgt->nents == 0) {
 				err = -ENOMEM;
 				goto unpin;
 			}
@@ -143,7 +144,7 @@ static int tegra_dc_pin(struct tegra_dc *dc, struct tegra_plane_state *state)
 			 * map its SG table to a single contiguous chunk of
 			 * I/O virtual memory.
 			 */
-			if (err > 1) {
+			if (sgt->nents > 1) {
 				err = -EINVAL;
 				goto unpin;
 			}
@@ -165,7 +166,7 @@ static int tegra_dc_pin(struct tegra_dc *dc, struct tegra_plane_state *state)
 		struct sg_table *sgt = state->sgt[i];
 
 		if (sgt)
-			dma_unmap_sg(dc->dev, sgt->sgl, sgt->nents,
+			dma_unmap_sg(dc->dev, sgt->sgl, sgt->orig_nents,
 				     DMA_TO_DEVICE);
 
 		host1x_bo_unpin(dc->dev, &bo->base, sgt);
@@ -185,7 +186,7 @@ static void tegra_dc_unpin(struct tegra_dc *dc, struct tegra_plane_state *state)
 		struct sg_table *sgt = state->sgt[i];
 
 		if (sgt)
-			dma_unmap_sg(dc->dev, sgt->sgl, sgt->nents,
+			dma_unmap_sg(dc->dev, sgt->sgl, sgt->orig_nents,
 				     DMA_TO_DEVICE);
 
 		host1x_bo_unpin(dc->dev, &bo->base, sgt);
-- 
1.9.1

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

^ permalink raw reply related	[flat|nested] 152+ messages in thread

* [Intel-gfx] [RFC 12/17] drm: tegra: fix sg_table nents vs. orig_nents misuse
@ 2020-04-28 13:20       ` Marek Szyprowski
  0 siblings, 0 replies; 152+ messages in thread
From: Marek Szyprowski @ 2020-04-28 13:20 UTC (permalink / raw)
  To: dri-devel, iommu, linaro-mm-sig, linux-kernel
  Cc: Bartlomiej Zolnierkiewicz, David Airlie, intel-gfx, amd-gfx,
	Christoph Hellwig, Benjamin Gaignard, Robin Murphy, Sumit Semwal,
	linux-arm-kernel, Marek Szyprowski

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/tegra/gem.c   | 25 +++++++++++++------------
 drivers/gpu/drm/tegra/plane.c | 13 +++++++------
 2 files changed, 20 insertions(+), 18 deletions(-)

diff --git a/drivers/gpu/drm/tegra/gem.c b/drivers/gpu/drm/tegra/gem.c
index 6237681..5710ab4 100644
--- a/drivers/gpu/drm/tegra/gem.c
+++ b/drivers/gpu/drm/tegra/gem.c
@@ -98,8 +98,8 @@ static struct sg_table *tegra_bo_pin(struct device *dev, struct host1x_bo *bo,
 		 * the SG table needs to be copied to avoid overwriting any
 		 * other potential users of the original SG table.
 		 */
-		err = sg_alloc_table_from_sg(sgt, obj->sgt->sgl, obj->sgt->nents,
-					     GFP_KERNEL);
+		err = sg_alloc_table_from_sg(sgt, obj->sgt->sgl,
+					     obj->sgt->orig_nents, GFP_KERNEL);
 		if (err < 0)
 			goto free;
 	} else {
@@ -197,7 +197,7 @@ static int tegra_bo_iommu_map(struct tegra_drm *tegra, struct tegra_bo *bo)
 	bo->iova = bo->mm->start;
 
 	bo->size = iommu_map_sg(tegra->domain, bo->iova, bo->sgt->sgl,
-				bo->sgt->nents, prot);
+				bo->sgt->orig_nents, prot);
 	if (!bo->size) {
 		dev_err(tegra->drm->dev, "failed to map buffer\n");
 		err = -ENOMEM;
@@ -264,7 +264,7 @@ static struct tegra_bo *tegra_bo_alloc_object(struct drm_device *drm,
 static void tegra_bo_free(struct drm_device *drm, struct tegra_bo *bo)
 {
 	if (bo->pages) {
-		dma_unmap_sg(drm->dev, bo->sgt->sgl, bo->sgt->nents,
+		dma_unmap_sg(drm->dev, bo->sgt->sgl, bo->sgt->orig_nents,
 			     DMA_FROM_DEVICE);
 		drm_gem_put_pages(&bo->gem, bo->pages, true, true);
 		sg_free_table(bo->sgt);
@@ -290,9 +290,9 @@ static int tegra_bo_get_pages(struct drm_device *drm, struct tegra_bo *bo)
 		goto put_pages;
 	}
 
-	err = dma_map_sg(drm->dev, bo->sgt->sgl, bo->sgt->nents,
-			 DMA_FROM_DEVICE);
-	if (err == 0) {
+	bo->sgt->nents = dma_map_sg(drm->dev, bo->sgt->sgl, bo->sgt->orig_nents,
+				DMA_FROM_DEVICE);
+	if (bo->sgt->nents == 0) {
 		err = -EFAULT;
 		goto free_sgt;
 	}
@@ -571,7 +571,8 @@ int tegra_drm_mmap(struct file *file, struct vm_area_struct *vma)
 			goto free;
 	}
 
-	if (dma_map_sg(attach->dev, sgt->sgl, sgt->nents, dir) == 0)
+	sgt->nents = dma_map_sg(attach->dev, sgt->sgl, sgt->orig_nents, dir);
+	if (sgt->nents == 0)
 		goto free;
 
 	return sgt;
@@ -590,7 +591,7 @@ static void tegra_gem_prime_unmap_dma_buf(struct dma_buf_attachment *attach,
 	struct tegra_bo *bo = to_tegra_bo(gem);
 
 	if (bo->pages)
-		dma_unmap_sg(attach->dev, sgt->sgl, sgt->nents, dir);
+		dma_unmap_sg(attach->dev, sgt->sgl, sgt->orig_nents, dir);
 
 	sg_free_table(sgt);
 	kfree(sgt);
@@ -609,7 +610,7 @@ static int tegra_gem_prime_begin_cpu_access(struct dma_buf *buf,
 	struct drm_device *drm = gem->dev;
 
 	if (bo->pages)
-		dma_sync_sg_for_cpu(drm->dev, bo->sgt->sgl, bo->sgt->nents,
+		dma_sync_sg_for_cpu(drm->dev, bo->sgt->sgl, bo->sgt->orig_nents,
 				    DMA_FROM_DEVICE);
 
 	return 0;
@@ -623,8 +624,8 @@ static int tegra_gem_prime_end_cpu_access(struct dma_buf *buf,
 	struct drm_device *drm = gem->dev;
 
 	if (bo->pages)
-		dma_sync_sg_for_device(drm->dev, bo->sgt->sgl, bo->sgt->nents,
-				       DMA_TO_DEVICE);
+		dma_sync_sg_for_device(drm->dev, bo->sgt->sgl,
+				       bo->sgt->orig_nents, DMA_TO_DEVICE);
 
 	return 0;
 }
diff --git a/drivers/gpu/drm/tegra/plane.c b/drivers/gpu/drm/tegra/plane.c
index 9ccfb56..3982bf8 100644
--- a/drivers/gpu/drm/tegra/plane.c
+++ b/drivers/gpu/drm/tegra/plane.c
@@ -130,9 +130,10 @@ static int tegra_dc_pin(struct tegra_dc *dc, struct tegra_plane_state *state)
 		}
 
 		if (sgt) {
-			err = dma_map_sg(dc->dev, sgt->sgl, sgt->nents,
-					 DMA_TO_DEVICE);
-			if (err == 0) {
+			sgt->nents = dma_map_sg(dc->dev, sgt->sgl,
+						sgt->orig_nents,
+						DMA_TO_DEVICE);
+			if (sgt->nents == 0) {
 				err = -ENOMEM;
 				goto unpin;
 			}
@@ -143,7 +144,7 @@ static int tegra_dc_pin(struct tegra_dc *dc, struct tegra_plane_state *state)
 			 * map its SG table to a single contiguous chunk of
 			 * I/O virtual memory.
 			 */
-			if (err > 1) {
+			if (sgt->nents > 1) {
 				err = -EINVAL;
 				goto unpin;
 			}
@@ -165,7 +166,7 @@ static int tegra_dc_pin(struct tegra_dc *dc, struct tegra_plane_state *state)
 		struct sg_table *sgt = state->sgt[i];
 
 		if (sgt)
-			dma_unmap_sg(dc->dev, sgt->sgl, sgt->nents,
+			dma_unmap_sg(dc->dev, sgt->sgl, sgt->orig_nents,
 				     DMA_TO_DEVICE);
 
 		host1x_bo_unpin(dc->dev, &bo->base, sgt);
@@ -185,7 +186,7 @@ static void tegra_dc_unpin(struct tegra_dc *dc, struct tegra_plane_state *state)
 		struct sg_table *sgt = state->sgt[i];
 
 		if (sgt)
-			dma_unmap_sg(dc->dev, sgt->sgl, sgt->nents,
+			dma_unmap_sg(dc->dev, sgt->sgl, sgt->orig_nents,
 				     DMA_TO_DEVICE);
 
 		host1x_bo_unpin(dc->dev, &bo->base, sgt);
-- 
1.9.1

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

^ permalink raw reply related	[flat|nested] 152+ messages in thread

* [RFC 12/17] drm: tegra: fix sg_table nents vs. orig_nents misuse
@ 2020-04-28 13:20       ` Marek Szyprowski
  0 siblings, 0 replies; 152+ messages in thread
From: Marek Szyprowski @ 2020-04-28 13:20 UTC (permalink / raw)
  To: dri-devel, iommu, linaro-mm-sig, linux-kernel
  Cc: Daniel Vetter, Bartlomiej Zolnierkiewicz, David Airlie,
	intel-gfx, amd-gfx, Christoph Hellwig, Benjamin Gaignard,
	Robin Murphy, Sumit Semwal, linux-arm-kernel, Marek Szyprowski

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/tegra/gem.c   | 25 +++++++++++++------------
 drivers/gpu/drm/tegra/plane.c | 13 +++++++------
 2 files changed, 20 insertions(+), 18 deletions(-)

diff --git a/drivers/gpu/drm/tegra/gem.c b/drivers/gpu/drm/tegra/gem.c
index 6237681..5710ab4 100644
--- a/drivers/gpu/drm/tegra/gem.c
+++ b/drivers/gpu/drm/tegra/gem.c
@@ -98,8 +98,8 @@ static struct sg_table *tegra_bo_pin(struct device *dev, struct host1x_bo *bo,
 		 * the SG table needs to be copied to avoid overwriting any
 		 * other potential users of the original SG table.
 		 */
-		err = sg_alloc_table_from_sg(sgt, obj->sgt->sgl, obj->sgt->nents,
-					     GFP_KERNEL);
+		err = sg_alloc_table_from_sg(sgt, obj->sgt->sgl,
+					     obj->sgt->orig_nents, GFP_KERNEL);
 		if (err < 0)
 			goto free;
 	} else {
@@ -197,7 +197,7 @@ static int tegra_bo_iommu_map(struct tegra_drm *tegra, struct tegra_bo *bo)
 	bo->iova = bo->mm->start;
 
 	bo->size = iommu_map_sg(tegra->domain, bo->iova, bo->sgt->sgl,
-				bo->sgt->nents, prot);
+				bo->sgt->orig_nents, prot);
 	if (!bo->size) {
 		dev_err(tegra->drm->dev, "failed to map buffer\n");
 		err = -ENOMEM;
@@ -264,7 +264,7 @@ static struct tegra_bo *tegra_bo_alloc_object(struct drm_device *drm,
 static void tegra_bo_free(struct drm_device *drm, struct tegra_bo *bo)
 {
 	if (bo->pages) {
-		dma_unmap_sg(drm->dev, bo->sgt->sgl, bo->sgt->nents,
+		dma_unmap_sg(drm->dev, bo->sgt->sgl, bo->sgt->orig_nents,
 			     DMA_FROM_DEVICE);
 		drm_gem_put_pages(&bo->gem, bo->pages, true, true);
 		sg_free_table(bo->sgt);
@@ -290,9 +290,9 @@ static int tegra_bo_get_pages(struct drm_device *drm, struct tegra_bo *bo)
 		goto put_pages;
 	}
 
-	err = dma_map_sg(drm->dev, bo->sgt->sgl, bo->sgt->nents,
-			 DMA_FROM_DEVICE);
-	if (err == 0) {
+	bo->sgt->nents = dma_map_sg(drm->dev, bo->sgt->sgl, bo->sgt->orig_nents,
+				DMA_FROM_DEVICE);
+	if (bo->sgt->nents == 0) {
 		err = -EFAULT;
 		goto free_sgt;
 	}
@@ -571,7 +571,8 @@ int tegra_drm_mmap(struct file *file, struct vm_area_struct *vma)
 			goto free;
 	}
 
-	if (dma_map_sg(attach->dev, sgt->sgl, sgt->nents, dir) == 0)
+	sgt->nents = dma_map_sg(attach->dev, sgt->sgl, sgt->orig_nents, dir);
+	if (sgt->nents == 0)
 		goto free;
 
 	return sgt;
@@ -590,7 +591,7 @@ static void tegra_gem_prime_unmap_dma_buf(struct dma_buf_attachment *attach,
 	struct tegra_bo *bo = to_tegra_bo(gem);
 
 	if (bo->pages)
-		dma_unmap_sg(attach->dev, sgt->sgl, sgt->nents, dir);
+		dma_unmap_sg(attach->dev, sgt->sgl, sgt->orig_nents, dir);
 
 	sg_free_table(sgt);
 	kfree(sgt);
@@ -609,7 +610,7 @@ static int tegra_gem_prime_begin_cpu_access(struct dma_buf *buf,
 	struct drm_device *drm = gem->dev;
 
 	if (bo->pages)
-		dma_sync_sg_for_cpu(drm->dev, bo->sgt->sgl, bo->sgt->nents,
+		dma_sync_sg_for_cpu(drm->dev, bo->sgt->sgl, bo->sgt->orig_nents,
 				    DMA_FROM_DEVICE);
 
 	return 0;
@@ -623,8 +624,8 @@ static int tegra_gem_prime_end_cpu_access(struct dma_buf *buf,
 	struct drm_device *drm = gem->dev;
 
 	if (bo->pages)
-		dma_sync_sg_for_device(drm->dev, bo->sgt->sgl, bo->sgt->nents,
-				       DMA_TO_DEVICE);
+		dma_sync_sg_for_device(drm->dev, bo->sgt->sgl,
+				       bo->sgt->orig_nents, DMA_TO_DEVICE);
 
 	return 0;
 }
diff --git a/drivers/gpu/drm/tegra/plane.c b/drivers/gpu/drm/tegra/plane.c
index 9ccfb56..3982bf8 100644
--- a/drivers/gpu/drm/tegra/plane.c
+++ b/drivers/gpu/drm/tegra/plane.c
@@ -130,9 +130,10 @@ static int tegra_dc_pin(struct tegra_dc *dc, struct tegra_plane_state *state)
 		}
 
 		if (sgt) {
-			err = dma_map_sg(dc->dev, sgt->sgl, sgt->nents,
-					 DMA_TO_DEVICE);
-			if (err == 0) {
+			sgt->nents = dma_map_sg(dc->dev, sgt->sgl,
+						sgt->orig_nents,
+						DMA_TO_DEVICE);
+			if (sgt->nents == 0) {
 				err = -ENOMEM;
 				goto unpin;
 			}
@@ -143,7 +144,7 @@ static int tegra_dc_pin(struct tegra_dc *dc, struct tegra_plane_state *state)
 			 * map its SG table to a single contiguous chunk of
 			 * I/O virtual memory.
 			 */
-			if (err > 1) {
+			if (sgt->nents > 1) {
 				err = -EINVAL;
 				goto unpin;
 			}
@@ -165,7 +166,7 @@ static int tegra_dc_pin(struct tegra_dc *dc, struct tegra_plane_state *state)
 		struct sg_table *sgt = state->sgt[i];
 
 		if (sgt)
-			dma_unmap_sg(dc->dev, sgt->sgl, sgt->nents,
+			dma_unmap_sg(dc->dev, sgt->sgl, sgt->orig_nents,
 				     DMA_TO_DEVICE);
 
 		host1x_bo_unpin(dc->dev, &bo->base, sgt);
@@ -185,7 +186,7 @@ static void tegra_dc_unpin(struct tegra_dc *dc, struct tegra_plane_state *state)
 		struct sg_table *sgt = state->sgt[i];
 
 		if (sgt)
-			dma_unmap_sg(dc->dev, sgt->sgl, sgt->nents,
+			dma_unmap_sg(dc->dev, sgt->sgl, sgt->orig_nents,
 				     DMA_TO_DEVICE);
 
 		host1x_bo_unpin(dc->dev, &bo->base, sgt);
-- 
1.9.1

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

^ permalink raw reply related	[flat|nested] 152+ messages in thread

* [RFC 13/17] drm: virtio: fix sg_table nents vs. orig_nents misuse
       [not found]   ` <CGME20200428132030eucas1p17d907110da4cf2a12651cc52ba7eaad6@eucas1p1.samsung.com>
                         ` (3 preceding siblings ...)
  (?)
@ 2020-04-28 13:20       ` Marek Szyprowski
  0 siblings, 0 replies; 152+ messages in thread
From: Marek Szyprowski @ 2020-04-28 13:20 UTC (permalink / raw)
  To: dri-devel, iommu, linaro-mm-sig, linux-kernel
  Cc: Marek Szyprowski, Christoph Hellwig, Robin Murphy,
	Bartlomiej Zolnierkiewicz, Sumit Semwal, Benjamin Gaignard,
	intel-gfx, linux-arm-kernel, amd-gfx, David Airlie,
	Daniel Vetter

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/virtio/virtgpu_object.c | 11 ++++++-----
 drivers/gpu/drm/virtio/virtgpu_vq.c     |  8 ++++----
 2 files changed, 10 insertions(+), 9 deletions(-)

diff --git a/drivers/gpu/drm/virtio/virtgpu_object.c b/drivers/gpu/drm/virtio/virtgpu_object.c
index 6ccbd01..12f6bee 100644
--- a/drivers/gpu/drm/virtio/virtgpu_object.c
+++ b/drivers/gpu/drm/virtio/virtgpu_object.c
@@ -73,7 +73,8 @@ void virtio_gpu_cleanup_object(struct virtio_gpu_object *bo)
 		if (shmem->pages) {
 			if (shmem->mapped) {
 				dma_unmap_sg(vgdev->vdev->dev.parent,
-					     shmem->pages->sgl, shmem->mapped,
+					     shmem->pages->sgl,
+					     shmem->pages->orig_nents,
 					     DMA_TO_DEVICE);
 				shmem->mapped = 0;
 			}
@@ -157,13 +158,13 @@ static int virtio_gpu_object_shmem_init(struct virtio_gpu_device *vgdev,
 	}
 
 	if (use_dma_api) {
-		shmem->mapped = dma_map_sg(vgdev->vdev->dev.parent,
+		shmem->pages->nents = dma_map_sg(vgdev->vdev->dev.parent,
 					   shmem->pages->sgl,
-					   shmem->pages->nents,
+					   shmem->pages->orig_nents,
 					   DMA_TO_DEVICE);
-		*nents = shmem->mapped;
+		*nents = shmem->mapped = shmem->pages->nents;
 	} else {
-		*nents = shmem->pages->nents;
+		*nents = shmem->pages->orig_nents;
 	}
 
 	*ents = kmalloc_array(*nents, sizeof(struct virtio_gpu_mem_entry),
diff --git a/drivers/gpu/drm/virtio/virtgpu_vq.c b/drivers/gpu/drm/virtio/virtgpu_vq.c
index 9e663a5..661325b 100644
--- a/drivers/gpu/drm/virtio/virtgpu_vq.c
+++ b/drivers/gpu/drm/virtio/virtgpu_vq.c
@@ -604,8 +604,8 @@ void virtio_gpu_cmd_transfer_to_host_2d(struct virtio_gpu_device *vgdev,
 
 	if (use_dma_api)
 		dma_sync_sg_for_device(vgdev->vdev->dev.parent,
-				       shmem->pages->sgl, shmem->pages->nents,
-				       DMA_TO_DEVICE);
+				       shmem->pages->sgl,
+				       shmem->pages->orig_nents, DMA_TO_DEVICE);
 
 	cmd_p = virtio_gpu_alloc_cmd(vgdev, &vbuf, sizeof(*cmd_p));
 	memset(cmd_p, 0, sizeof(*cmd_p));
@@ -1020,8 +1020,8 @@ void virtio_gpu_cmd_transfer_to_host_3d(struct virtio_gpu_device *vgdev,
 
 	if (use_dma_api)
 		dma_sync_sg_for_device(vgdev->vdev->dev.parent,
-				       shmem->pages->sgl, shmem->pages->nents,
-				       DMA_TO_DEVICE);
+				       shmem->pages->sgl,
+				       shmem->pages->orig_nents, DMA_TO_DEVICE);
 
 	cmd_p = virtio_gpu_alloc_cmd(vgdev, &vbuf, sizeof(*cmd_p));
 	memset(cmd_p, 0, sizeof(*cmd_p));
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 152+ messages in thread

* [RFC 13/17] drm: virtio: fix sg_table nents vs. orig_nents misuse
@ 2020-04-28 13:20       ` Marek Szyprowski
  0 siblings, 0 replies; 152+ messages in thread
From: Marek Szyprowski @ 2020-04-28 13:20 UTC (permalink / raw)
  To: dri-devel, iommu, linaro-mm-sig, linux-kernel
  Cc: Daniel Vetter, Bartlomiej Zolnierkiewicz, David Airlie,
	intel-gfx, amd-gfx, Christoph Hellwig, Benjamin Gaignard,
	Robin Murphy, Sumit Semwal, linux-arm-kernel

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/virtio/virtgpu_object.c | 11 ++++++-----
 drivers/gpu/drm/virtio/virtgpu_vq.c     |  8 ++++----
 2 files changed, 10 insertions(+), 9 deletions(-)

diff --git a/drivers/gpu/drm/virtio/virtgpu_object.c b/drivers/gpu/drm/virtio/virtgpu_object.c
index 6ccbd01..12f6bee 100644
--- a/drivers/gpu/drm/virtio/virtgpu_object.c
+++ b/drivers/gpu/drm/virtio/virtgpu_object.c
@@ -73,7 +73,8 @@ void virtio_gpu_cleanup_object(struct virtio_gpu_object *bo)
 		if (shmem->pages) {
 			if (shmem->mapped) {
 				dma_unmap_sg(vgdev->vdev->dev.parent,
-					     shmem->pages->sgl, shmem->mapped,
+					     shmem->pages->sgl,
+					     shmem->pages->orig_nents,
 					     DMA_TO_DEVICE);
 				shmem->mapped = 0;
 			}
@@ -157,13 +158,13 @@ static int virtio_gpu_object_shmem_init(struct virtio_gpu_device *vgdev,
 	}
 
 	if (use_dma_api) {
-		shmem->mapped = dma_map_sg(vgdev->vdev->dev.parent,
+		shmem->pages->nents = dma_map_sg(vgdev->vdev->dev.parent,
 					   shmem->pages->sgl,
-					   shmem->pages->nents,
+					   shmem->pages->orig_nents,
 					   DMA_TO_DEVICE);
-		*nents = shmem->mapped;
+		*nents = shmem->mapped = shmem->pages->nents;
 	} else {
-		*nents = shmem->pages->nents;
+		*nents = shmem->pages->orig_nents;
 	}
 
 	*ents = kmalloc_array(*nents, sizeof(struct virtio_gpu_mem_entry),
diff --git a/drivers/gpu/drm/virtio/virtgpu_vq.c b/drivers/gpu/drm/virtio/virtgpu_vq.c
index 9e663a5..661325b 100644
--- a/drivers/gpu/drm/virtio/virtgpu_vq.c
+++ b/drivers/gpu/drm/virtio/virtgpu_vq.c
@@ -604,8 +604,8 @@ void virtio_gpu_cmd_transfer_to_host_2d(struct virtio_gpu_device *vgdev,
 
 	if (use_dma_api)
 		dma_sync_sg_for_device(vgdev->vdev->dev.parent,
-				       shmem->pages->sgl, shmem->pages->nents,
-				       DMA_TO_DEVICE);
+				       shmem->pages->sgl,
+				       shmem->pages->orig_nents, DMA_TO_DEVICE);
 
 	cmd_p = virtio_gpu_alloc_cmd(vgdev, &vbuf, sizeof(*cmd_p));
 	memset(cmd_p, 0, sizeof(*cmd_p));
@@ -1020,8 +1020,8 @@ void virtio_gpu_cmd_transfer_to_host_3d(struct virtio_gpu_device *vgdev,
 
 	if (use_dma_api)
 		dma_sync_sg_for_device(vgdev->vdev->dev.parent,
-				       shmem->pages->sgl, shmem->pages->nents,
-				       DMA_TO_DEVICE);
+				       shmem->pages->sgl,
+				       shmem->pages->orig_nents, DMA_TO_DEVICE);
 
 	cmd_p = virtio_gpu_alloc_cmd(vgdev, &vbuf, sizeof(*cmd_p));
 	memset(cmd_p, 0, sizeof(*cmd_p));
-- 
1.9.1

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

^ permalink raw reply related	[flat|nested] 152+ messages in thread

* [RFC 13/17] drm: virtio: fix sg_table nents vs. orig_nents misuse
@ 2020-04-28 13:20       ` Marek Szyprowski
  0 siblings, 0 replies; 152+ messages in thread
From: Marek Szyprowski @ 2020-04-28 13:20 UTC (permalink / raw)
  To: dri-devel, iommu, linaro-mm-sig, linux-kernel
  Cc: Daniel Vetter, Bartlomiej Zolnierkiewicz, David Airlie,
	intel-gfx, amd-gfx, Christoph Hellwig, Benjamin Gaignard,
	Robin Murphy, Sumit Semwal, linux-arm-kernel, Marek Szyprowski

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/virtio/virtgpu_object.c | 11 ++++++-----
 drivers/gpu/drm/virtio/virtgpu_vq.c     |  8 ++++----
 2 files changed, 10 insertions(+), 9 deletions(-)

diff --git a/drivers/gpu/drm/virtio/virtgpu_object.c b/drivers/gpu/drm/virtio/virtgpu_object.c
index 6ccbd01..12f6bee 100644
--- a/drivers/gpu/drm/virtio/virtgpu_object.c
+++ b/drivers/gpu/drm/virtio/virtgpu_object.c
@@ -73,7 +73,8 @@ void virtio_gpu_cleanup_object(struct virtio_gpu_object *bo)
 		if (shmem->pages) {
 			if (shmem->mapped) {
 				dma_unmap_sg(vgdev->vdev->dev.parent,
-					     shmem->pages->sgl, shmem->mapped,
+					     shmem->pages->sgl,
+					     shmem->pages->orig_nents,
 					     DMA_TO_DEVICE);
 				shmem->mapped = 0;
 			}
@@ -157,13 +158,13 @@ static int virtio_gpu_object_shmem_init(struct virtio_gpu_device *vgdev,
 	}
 
 	if (use_dma_api) {
-		shmem->mapped = dma_map_sg(vgdev->vdev->dev.parent,
+		shmem->pages->nents = dma_map_sg(vgdev->vdev->dev.parent,
 					   shmem->pages->sgl,
-					   shmem->pages->nents,
+					   shmem->pages->orig_nents,
 					   DMA_TO_DEVICE);
-		*nents = shmem->mapped;
+		*nents = shmem->mapped = shmem->pages->nents;
 	} else {
-		*nents = shmem->pages->nents;
+		*nents = shmem->pages->orig_nents;
 	}
 
 	*ents = kmalloc_array(*nents, sizeof(struct virtio_gpu_mem_entry),
diff --git a/drivers/gpu/drm/virtio/virtgpu_vq.c b/drivers/gpu/drm/virtio/virtgpu_vq.c
index 9e663a5..661325b 100644
--- a/drivers/gpu/drm/virtio/virtgpu_vq.c
+++ b/drivers/gpu/drm/virtio/virtgpu_vq.c
@@ -604,8 +604,8 @@ void virtio_gpu_cmd_transfer_to_host_2d(struct virtio_gpu_device *vgdev,
 
 	if (use_dma_api)
 		dma_sync_sg_for_device(vgdev->vdev->dev.parent,
-				       shmem->pages->sgl, shmem->pages->nents,
-				       DMA_TO_DEVICE);
+				       shmem->pages->sgl,
+				       shmem->pages->orig_nents, DMA_TO_DEVICE);
 
 	cmd_p = virtio_gpu_alloc_cmd(vgdev, &vbuf, sizeof(*cmd_p));
 	memset(cmd_p, 0, sizeof(*cmd_p));
@@ -1020,8 +1020,8 @@ void virtio_gpu_cmd_transfer_to_host_3d(struct virtio_gpu_device *vgdev,
 
 	if (use_dma_api)
 		dma_sync_sg_for_device(vgdev->vdev->dev.parent,
-				       shmem->pages->sgl, shmem->pages->nents,
-				       DMA_TO_DEVICE);
+				       shmem->pages->sgl,
+				       shmem->pages->orig_nents, DMA_TO_DEVICE);
 
 	cmd_p = virtio_gpu_alloc_cmd(vgdev, &vbuf, sizeof(*cmd_p));
 	memset(cmd_p, 0, sizeof(*cmd_p));
-- 
1.9.1


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

^ permalink raw reply related	[flat|nested] 152+ messages in thread

* [RFC 13/17] drm: virtio: fix sg_table nents vs. orig_nents misuse
@ 2020-04-28 13:20       ` Marek Szyprowski
  0 siblings, 0 replies; 152+ messages in thread
From: Marek Szyprowski @ 2020-04-28 13:20 UTC (permalink / raw)
  To: dri-devel, iommu, linaro-mm-sig, linux-kernel
  Cc: Bartlomiej Zolnierkiewicz, David Airlie, intel-gfx, amd-gfx,
	Christoph Hellwig, Robin Murphy, linux-arm-kernel,
	Marek Szyprowski

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/virtio/virtgpu_object.c | 11 ++++++-----
 drivers/gpu/drm/virtio/virtgpu_vq.c     |  8 ++++----
 2 files changed, 10 insertions(+), 9 deletions(-)

diff --git a/drivers/gpu/drm/virtio/virtgpu_object.c b/drivers/gpu/drm/virtio/virtgpu_object.c
index 6ccbd01..12f6bee 100644
--- a/drivers/gpu/drm/virtio/virtgpu_object.c
+++ b/drivers/gpu/drm/virtio/virtgpu_object.c
@@ -73,7 +73,8 @@ void virtio_gpu_cleanup_object(struct virtio_gpu_object *bo)
 		if (shmem->pages) {
 			if (shmem->mapped) {
 				dma_unmap_sg(vgdev->vdev->dev.parent,
-					     shmem->pages->sgl, shmem->mapped,
+					     shmem->pages->sgl,
+					     shmem->pages->orig_nents,
 					     DMA_TO_DEVICE);
 				shmem->mapped = 0;
 			}
@@ -157,13 +158,13 @@ static int virtio_gpu_object_shmem_init(struct virtio_gpu_device *vgdev,
 	}
 
 	if (use_dma_api) {
-		shmem->mapped = dma_map_sg(vgdev->vdev->dev.parent,
+		shmem->pages->nents = dma_map_sg(vgdev->vdev->dev.parent,
 					   shmem->pages->sgl,
-					   shmem->pages->nents,
+					   shmem->pages->orig_nents,
 					   DMA_TO_DEVICE);
-		*nents = shmem->mapped;
+		*nents = shmem->mapped = shmem->pages->nents;
 	} else {
-		*nents = shmem->pages->nents;
+		*nents = shmem->pages->orig_nents;
 	}
 
 	*ents = kmalloc_array(*nents, sizeof(struct virtio_gpu_mem_entry),
diff --git a/drivers/gpu/drm/virtio/virtgpu_vq.c b/drivers/gpu/drm/virtio/virtgpu_vq.c
index 9e663a5..661325b 100644
--- a/drivers/gpu/drm/virtio/virtgpu_vq.c
+++ b/drivers/gpu/drm/virtio/virtgpu_vq.c
@@ -604,8 +604,8 @@ void virtio_gpu_cmd_transfer_to_host_2d(struct virtio_gpu_device *vgdev,
 
 	if (use_dma_api)
 		dma_sync_sg_for_device(vgdev->vdev->dev.parent,
-				       shmem->pages->sgl, shmem->pages->nents,
-				       DMA_TO_DEVICE);
+				       shmem->pages->sgl,
+				       shmem->pages->orig_nents, DMA_TO_DEVICE);
 
 	cmd_p = virtio_gpu_alloc_cmd(vgdev, &vbuf, sizeof(*cmd_p));
 	memset(cmd_p, 0, sizeof(*cmd_p));
@@ -1020,8 +1020,8 @@ void virtio_gpu_cmd_transfer_to_host_3d(struct virtio_gpu_device *vgdev,
 
 	if (use_dma_api)
 		dma_sync_sg_for_device(vgdev->vdev->dev.parent,
-				       shmem->pages->sgl, shmem->pages->nents,
-				       DMA_TO_DEVICE);
+				       shmem->pages->sgl,
+				       shmem->pages->orig_nents, DMA_TO_DEVICE);
 
 	cmd_p = virtio_gpu_alloc_cmd(vgdev, &vbuf, sizeof(*cmd_p));
 	memset(cmd_p, 0, sizeof(*cmd_p));
-- 
1.9.1

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

^ permalink raw reply related	[flat|nested] 152+ messages in thread

* [Intel-gfx] [RFC 13/17] drm: virtio: fix sg_table nents vs. orig_nents misuse
@ 2020-04-28 13:20       ` Marek Szyprowski
  0 siblings, 0 replies; 152+ messages in thread
From: Marek Szyprowski @ 2020-04-28 13:20 UTC (permalink / raw)
  To: dri-devel, iommu, linaro-mm-sig, linux-kernel
  Cc: Bartlomiej Zolnierkiewicz, David Airlie, intel-gfx, amd-gfx,
	Christoph Hellwig, Benjamin Gaignard, Robin Murphy, Sumit Semwal,
	linux-arm-kernel, Marek Szyprowski

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/virtio/virtgpu_object.c | 11 ++++++-----
 drivers/gpu/drm/virtio/virtgpu_vq.c     |  8 ++++----
 2 files changed, 10 insertions(+), 9 deletions(-)

diff --git a/drivers/gpu/drm/virtio/virtgpu_object.c b/drivers/gpu/drm/virtio/virtgpu_object.c
index 6ccbd01..12f6bee 100644
--- a/drivers/gpu/drm/virtio/virtgpu_object.c
+++ b/drivers/gpu/drm/virtio/virtgpu_object.c
@@ -73,7 +73,8 @@ void virtio_gpu_cleanup_object(struct virtio_gpu_object *bo)
 		if (shmem->pages) {
 			if (shmem->mapped) {
 				dma_unmap_sg(vgdev->vdev->dev.parent,
-					     shmem->pages->sgl, shmem->mapped,
+					     shmem->pages->sgl,
+					     shmem->pages->orig_nents,
 					     DMA_TO_DEVICE);
 				shmem->mapped = 0;
 			}
@@ -157,13 +158,13 @@ static int virtio_gpu_object_shmem_init(struct virtio_gpu_device *vgdev,
 	}
 
 	if (use_dma_api) {
-		shmem->mapped = dma_map_sg(vgdev->vdev->dev.parent,
+		shmem->pages->nents = dma_map_sg(vgdev->vdev->dev.parent,
 					   shmem->pages->sgl,
-					   shmem->pages->nents,
+					   shmem->pages->orig_nents,
 					   DMA_TO_DEVICE);
-		*nents = shmem->mapped;
+		*nents = shmem->mapped = shmem->pages->nents;
 	} else {
-		*nents = shmem->pages->nents;
+		*nents = shmem->pages->orig_nents;
 	}
 
 	*ents = kmalloc_array(*nents, sizeof(struct virtio_gpu_mem_entry),
diff --git a/drivers/gpu/drm/virtio/virtgpu_vq.c b/drivers/gpu/drm/virtio/virtgpu_vq.c
index 9e663a5..661325b 100644
--- a/drivers/gpu/drm/virtio/virtgpu_vq.c
+++ b/drivers/gpu/drm/virtio/virtgpu_vq.c
@@ -604,8 +604,8 @@ void virtio_gpu_cmd_transfer_to_host_2d(struct virtio_gpu_device *vgdev,
 
 	if (use_dma_api)
 		dma_sync_sg_for_device(vgdev->vdev->dev.parent,
-				       shmem->pages->sgl, shmem->pages->nents,
-				       DMA_TO_DEVICE);
+				       shmem->pages->sgl,
+				       shmem->pages->orig_nents, DMA_TO_DEVICE);
 
 	cmd_p = virtio_gpu_alloc_cmd(vgdev, &vbuf, sizeof(*cmd_p));
 	memset(cmd_p, 0, sizeof(*cmd_p));
@@ -1020,8 +1020,8 @@ void virtio_gpu_cmd_transfer_to_host_3d(struct virtio_gpu_device *vgdev,
 
 	if (use_dma_api)
 		dma_sync_sg_for_device(vgdev->vdev->dev.parent,
-				       shmem->pages->sgl, shmem->pages->nents,
-				       DMA_TO_DEVICE);
+				       shmem->pages->sgl,
+				       shmem->pages->orig_nents, DMA_TO_DEVICE);
 
 	cmd_p = virtio_gpu_alloc_cmd(vgdev, &vbuf, sizeof(*cmd_p));
 	memset(cmd_p, 0, sizeof(*cmd_p));
-- 
1.9.1

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

^ permalink raw reply related	[flat|nested] 152+ messages in thread

* [RFC 13/17] drm: virtio: fix sg_table nents vs. orig_nents misuse
@ 2020-04-28 13:20       ` Marek Szyprowski
  0 siblings, 0 replies; 152+ messages in thread
From: Marek Szyprowski @ 2020-04-28 13:20 UTC (permalink / raw)
  To: dri-devel, iommu, linaro-mm-sig, linux-kernel
  Cc: Daniel Vetter, Bartlomiej Zolnierkiewicz, David Airlie,
	intel-gfx, amd-gfx, Christoph Hellwig, Benjamin Gaignard,
	Robin Murphy, Sumit Semwal, linux-arm-kernel, Marek Szyprowski

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/virtio/virtgpu_object.c | 11 ++++++-----
 drivers/gpu/drm/virtio/virtgpu_vq.c     |  8 ++++----
 2 files changed, 10 insertions(+), 9 deletions(-)

diff --git a/drivers/gpu/drm/virtio/virtgpu_object.c b/drivers/gpu/drm/virtio/virtgpu_object.c
index 6ccbd01..12f6bee 100644
--- a/drivers/gpu/drm/virtio/virtgpu_object.c
+++ b/drivers/gpu/drm/virtio/virtgpu_object.c
@@ -73,7 +73,8 @@ void virtio_gpu_cleanup_object(struct virtio_gpu_object *bo)
 		if (shmem->pages) {
 			if (shmem->mapped) {
 				dma_unmap_sg(vgdev->vdev->dev.parent,
-					     shmem->pages->sgl, shmem->mapped,
+					     shmem->pages->sgl,
+					     shmem->pages->orig_nents,
 					     DMA_TO_DEVICE);
 				shmem->mapped = 0;
 			}
@@ -157,13 +158,13 @@ static int virtio_gpu_object_shmem_init(struct virtio_gpu_device *vgdev,
 	}
 
 	if (use_dma_api) {
-		shmem->mapped = dma_map_sg(vgdev->vdev->dev.parent,
+		shmem->pages->nents = dma_map_sg(vgdev->vdev->dev.parent,
 					   shmem->pages->sgl,
-					   shmem->pages->nents,
+					   shmem->pages->orig_nents,
 					   DMA_TO_DEVICE);
-		*nents = shmem->mapped;
+		*nents = shmem->mapped = shmem->pages->nents;
 	} else {
-		*nents = shmem->pages->nents;
+		*nents = shmem->pages->orig_nents;
 	}
 
 	*ents = kmalloc_array(*nents, sizeof(struct virtio_gpu_mem_entry),
diff --git a/drivers/gpu/drm/virtio/virtgpu_vq.c b/drivers/gpu/drm/virtio/virtgpu_vq.c
index 9e663a5..661325b 100644
--- a/drivers/gpu/drm/virtio/virtgpu_vq.c
+++ b/drivers/gpu/drm/virtio/virtgpu_vq.c
@@ -604,8 +604,8 @@ void virtio_gpu_cmd_transfer_to_host_2d(struct virtio_gpu_device *vgdev,
 
 	if (use_dma_api)
 		dma_sync_sg_for_device(vgdev->vdev->dev.parent,
-				       shmem->pages->sgl, shmem->pages->nents,
-				       DMA_TO_DEVICE);
+				       shmem->pages->sgl,
+				       shmem->pages->orig_nents, DMA_TO_DEVICE);
 
 	cmd_p = virtio_gpu_alloc_cmd(vgdev, &vbuf, sizeof(*cmd_p));
 	memset(cmd_p, 0, sizeof(*cmd_p));
@@ -1020,8 +1020,8 @@ void virtio_gpu_cmd_transfer_to_host_3d(struct virtio_gpu_device *vgdev,
 
 	if (use_dma_api)
 		dma_sync_sg_for_device(vgdev->vdev->dev.parent,
-				       shmem->pages->sgl, shmem->pages->nents,
-				       DMA_TO_DEVICE);
+				       shmem->pages->sgl,
+				       shmem->pages->orig_nents, DMA_TO_DEVICE);
 
 	cmd_p = virtio_gpu_alloc_cmd(vgdev, &vbuf, sizeof(*cmd_p));
 	memset(cmd_p, 0, sizeof(*cmd_p));
-- 
1.9.1

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

^ permalink raw reply related	[flat|nested] 152+ messages in thread

* [RFC 14/17] drm: vmwgfx: fix sg_table nents vs. orig_nents misuse
       [not found]   ` <CGME20200428132030eucas1p11f977e77050b5e76f580255096bb94bf@eucas1p1.samsung.com>
                         ` (3 preceding siblings ...)
  (?)
@ 2020-04-28 13:20       ` Marek Szyprowski
  0 siblings, 0 replies; 152+ messages in thread
From: Marek Szyprowski @ 2020-04-28 13:20 UTC (permalink / raw)
  To: dri-devel, iommu, linaro-mm-sig, linux-kernel
  Cc: Marek Szyprowski, Christoph Hellwig, Robin Murphy,
	Bartlomiej Zolnierkiewicz, Sumit Semwal, Benjamin Gaignard,
	intel-gfx, linux-arm-kernel, amd-gfx, David Airlie,
	Daniel Vetter

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/vmwgfx/vmwgfx_ttm_buffer.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_ttm_buffer.c b/drivers/gpu/drm/vmwgfx/vmwgfx_ttm_buffer.c
index bf0bc46..a5fd128 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_ttm_buffer.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_ttm_buffer.c
@@ -362,7 +362,7 @@ static void vmw_ttm_unmap_from_dma(struct vmw_ttm_tt *vmw_tt)
 {
 	struct device *dev = vmw_tt->dev_priv->dev->dev;
 
-	dma_unmap_sg(dev, vmw_tt->sgt.sgl, vmw_tt->sgt.nents,
+	dma_unmap_sg(dev, vmw_tt->sgt.sgl, vmw_tt->sgt.orig_nents,
 		DMA_BIDIRECTIONAL);
 	vmw_tt->sgt.nents = vmw_tt->sgt.orig_nents;
 }
@@ -449,10 +449,10 @@ static int vmw_ttm_map_dma(struct vmw_ttm_tt *vmw_tt)
 		if (unlikely(ret != 0))
 			goto out_sg_alloc_fail;
 
-		if (vsgt->num_pages > vmw_tt->sgt.nents) {
+		if (vsgt->num_pages > vmw_tt->sgt.orig_nents) {
 			uint64_t over_alloc =
 				sgl_size * (vsgt->num_pages -
-					    vmw_tt->sgt.nents);
+					    vmw_tt->sgt.orig_nents);
 
 			ttm_mem_global_free(glob, over_alloc);
 			vmw_tt->sg_alloc_size -= over_alloc;
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 152+ messages in thread

* [RFC 14/17] drm: vmwgfx: fix sg_table nents vs. orig_nents misuse
@ 2020-04-28 13:20       ` Marek Szyprowski
  0 siblings, 0 replies; 152+ messages in thread
From: Marek Szyprowski @ 2020-04-28 13:20 UTC (permalink / raw)
  To: dri-devel, iommu, linaro-mm-sig, linux-kernel
  Cc: Daniel Vetter, Bartlomiej Zolnierkiewicz, David Airlie,
	intel-gfx, amd-gfx, Christoph Hellwig, Benjamin Gaignard,
	Robin Murphy, Sumit Semwal, linux-arm-kernel

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/vmwgfx/vmwgfx_ttm_buffer.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_ttm_buffer.c b/drivers/gpu/drm/vmwgfx/vmwgfx_ttm_buffer.c
index bf0bc46..a5fd128 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_ttm_buffer.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_ttm_buffer.c
@@ -362,7 +362,7 @@ static void vmw_ttm_unmap_from_dma(struct vmw_ttm_tt *vmw_tt)
 {
 	struct device *dev = vmw_tt->dev_priv->dev->dev;
 
-	dma_unmap_sg(dev, vmw_tt->sgt.sgl, vmw_tt->sgt.nents,
+	dma_unmap_sg(dev, vmw_tt->sgt.sgl, vmw_tt->sgt.orig_nents,
 		DMA_BIDIRECTIONAL);
 	vmw_tt->sgt.nents = vmw_tt->sgt.orig_nents;
 }
@@ -449,10 +449,10 @@ static int vmw_ttm_map_dma(struct vmw_ttm_tt *vmw_tt)
 		if (unlikely(ret != 0))
 			goto out_sg_alloc_fail;
 
-		if (vsgt->num_pages > vmw_tt->sgt.nents) {
+		if (vsgt->num_pages > vmw_tt->sgt.orig_nents) {
 			uint64_t over_alloc =
 				sgl_size * (vsgt->num_pages -
-					    vmw_tt->sgt.nents);
+					    vmw_tt->sgt.orig_nents);
 
 			ttm_mem_global_free(glob, over_alloc);
 			vmw_tt->sg_alloc_size -= over_alloc;
-- 
1.9.1

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

^ permalink raw reply related	[flat|nested] 152+ messages in thread

* [RFC 14/17] drm: vmwgfx: fix sg_table nents vs. orig_nents misuse
@ 2020-04-28 13:20       ` Marek Szyprowski
  0 siblings, 0 replies; 152+ messages in thread
From: Marek Szyprowski @ 2020-04-28 13:20 UTC (permalink / raw)
  To: dri-devel, iommu, linaro-mm-sig, linux-kernel
  Cc: Daniel Vetter, Bartlomiej Zolnierkiewicz, David Airlie,
	intel-gfx, amd-gfx, Christoph Hellwig, Benjamin Gaignard,
	Robin Murphy, Sumit Semwal, linux-arm-kernel, Marek Szyprowski

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/vmwgfx/vmwgfx_ttm_buffer.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_ttm_buffer.c b/drivers/gpu/drm/vmwgfx/vmwgfx_ttm_buffer.c
index bf0bc46..a5fd128 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_ttm_buffer.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_ttm_buffer.c
@@ -362,7 +362,7 @@ static void vmw_ttm_unmap_from_dma(struct vmw_ttm_tt *vmw_tt)
 {
 	struct device *dev = vmw_tt->dev_priv->dev->dev;
 
-	dma_unmap_sg(dev, vmw_tt->sgt.sgl, vmw_tt->sgt.nents,
+	dma_unmap_sg(dev, vmw_tt->sgt.sgl, vmw_tt->sgt.orig_nents,
 		DMA_BIDIRECTIONAL);
 	vmw_tt->sgt.nents = vmw_tt->sgt.orig_nents;
 }
@@ -449,10 +449,10 @@ static int vmw_ttm_map_dma(struct vmw_ttm_tt *vmw_tt)
 		if (unlikely(ret != 0))
 			goto out_sg_alloc_fail;
 
-		if (vsgt->num_pages > vmw_tt->sgt.nents) {
+		if (vsgt->num_pages > vmw_tt->sgt.orig_nents) {
 			uint64_t over_alloc =
 				sgl_size * (vsgt->num_pages -
-					    vmw_tt->sgt.nents);
+					    vmw_tt->sgt.orig_nents);
 
 			ttm_mem_global_free(glob, over_alloc);
 			vmw_tt->sg_alloc_size -= over_alloc;
-- 
1.9.1


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

^ permalink raw reply related	[flat|nested] 152+ messages in thread

* [RFC 14/17] drm: vmwgfx: fix sg_table nents vs. orig_nents misuse
@ 2020-04-28 13:20       ` Marek Szyprowski
  0 siblings, 0 replies; 152+ messages in thread
From: Marek Szyprowski @ 2020-04-28 13:20 UTC (permalink / raw)
  To: dri-devel, iommu, linaro-mm-sig, linux-kernel
  Cc: Bartlomiej Zolnierkiewicz, David Airlie, intel-gfx, amd-gfx,
	Christoph Hellwig, Robin Murphy, linux-arm-kernel,
	Marek Szyprowski

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/vmwgfx/vmwgfx_ttm_buffer.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_ttm_buffer.c b/drivers/gpu/drm/vmwgfx/vmwgfx_ttm_buffer.c
index bf0bc46..a5fd128 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_ttm_buffer.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_ttm_buffer.c
@@ -362,7 +362,7 @@ static void vmw_ttm_unmap_from_dma(struct vmw_ttm_tt *vmw_tt)
 {
 	struct device *dev = vmw_tt->dev_priv->dev->dev;
 
-	dma_unmap_sg(dev, vmw_tt->sgt.sgl, vmw_tt->sgt.nents,
+	dma_unmap_sg(dev, vmw_tt->sgt.sgl, vmw_tt->sgt.orig_nents,
 		DMA_BIDIRECTIONAL);
 	vmw_tt->sgt.nents = vmw_tt->sgt.orig_nents;
 }
@@ -449,10 +449,10 @@ static int vmw_ttm_map_dma(struct vmw_ttm_tt *vmw_tt)
 		if (unlikely(ret != 0))
 			goto out_sg_alloc_fail;
 
-		if (vsgt->num_pages > vmw_tt->sgt.nents) {
+		if (vsgt->num_pages > vmw_tt->sgt.orig_nents) {
 			uint64_t over_alloc =
 				sgl_size * (vsgt->num_pages -
-					    vmw_tt->sgt.nents);
+					    vmw_tt->sgt.orig_nents);
 
 			ttm_mem_global_free(glob, over_alloc);
 			vmw_tt->sg_alloc_size -= over_alloc;
-- 
1.9.1

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

^ permalink raw reply related	[flat|nested] 152+ messages in thread

* [Intel-gfx] [RFC 14/17] drm: vmwgfx: fix sg_table nents vs. orig_nents misuse
@ 2020-04-28 13:20       ` Marek Szyprowski
  0 siblings, 0 replies; 152+ messages in thread
From: Marek Szyprowski @ 2020-04-28 13:20 UTC (permalink / raw)
  To: dri-devel, iommu, linaro-mm-sig, linux-kernel
  Cc: Bartlomiej Zolnierkiewicz, David Airlie, intel-gfx, amd-gfx,
	Christoph Hellwig, Benjamin Gaignard, Robin Murphy, Sumit Semwal,
	linux-arm-kernel, Marek Szyprowski

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/vmwgfx/vmwgfx_ttm_buffer.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_ttm_buffer.c b/drivers/gpu/drm/vmwgfx/vmwgfx_ttm_buffer.c
index bf0bc46..a5fd128 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_ttm_buffer.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_ttm_buffer.c
@@ -362,7 +362,7 @@ static void vmw_ttm_unmap_from_dma(struct vmw_ttm_tt *vmw_tt)
 {
 	struct device *dev = vmw_tt->dev_priv->dev->dev;
 
-	dma_unmap_sg(dev, vmw_tt->sgt.sgl, vmw_tt->sgt.nents,
+	dma_unmap_sg(dev, vmw_tt->sgt.sgl, vmw_tt->sgt.orig_nents,
 		DMA_BIDIRECTIONAL);
 	vmw_tt->sgt.nents = vmw_tt->sgt.orig_nents;
 }
@@ -449,10 +449,10 @@ static int vmw_ttm_map_dma(struct vmw_ttm_tt *vmw_tt)
 		if (unlikely(ret != 0))
 			goto out_sg_alloc_fail;
 
-		if (vsgt->num_pages > vmw_tt->sgt.nents) {
+		if (vsgt->num_pages > vmw_tt->sgt.orig_nents) {
 			uint64_t over_alloc =
 				sgl_size * (vsgt->num_pages -
-					    vmw_tt->sgt.nents);
+					    vmw_tt->sgt.orig_nents);
 
 			ttm_mem_global_free(glob, over_alloc);
 			vmw_tt->sg_alloc_size -= over_alloc;
-- 
1.9.1

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

^ permalink raw reply related	[flat|nested] 152+ messages in thread

* [RFC 14/17] drm: vmwgfx: fix sg_table nents vs. orig_nents misuse
@ 2020-04-28 13:20       ` Marek Szyprowski
  0 siblings, 0 replies; 152+ messages in thread
From: Marek Szyprowski @ 2020-04-28 13:20 UTC (permalink / raw)
  To: dri-devel, iommu, linaro-mm-sig, linux-kernel
  Cc: Daniel Vetter, Bartlomiej Zolnierkiewicz, David Airlie,
	intel-gfx, amd-gfx, Christoph Hellwig, Benjamin Gaignard,
	Robin Murphy, Sumit Semwal, linux-arm-kernel, Marek Szyprowski

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/vmwgfx/vmwgfx_ttm_buffer.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_ttm_buffer.c b/drivers/gpu/drm/vmwgfx/vmwgfx_ttm_buffer.c
index bf0bc46..a5fd128 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_ttm_buffer.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_ttm_buffer.c
@@ -362,7 +362,7 @@ static void vmw_ttm_unmap_from_dma(struct vmw_ttm_tt *vmw_tt)
 {
 	struct device *dev = vmw_tt->dev_priv->dev->dev;
 
-	dma_unmap_sg(dev, vmw_tt->sgt.sgl, vmw_tt->sgt.nents,
+	dma_unmap_sg(dev, vmw_tt->sgt.sgl, vmw_tt->sgt.orig_nents,
 		DMA_BIDIRECTIONAL);
 	vmw_tt->sgt.nents = vmw_tt->sgt.orig_nents;
 }
@@ -449,10 +449,10 @@ static int vmw_ttm_map_dma(struct vmw_ttm_tt *vmw_tt)
 		if (unlikely(ret != 0))
 			goto out_sg_alloc_fail;
 
-		if (vsgt->num_pages > vmw_tt->sgt.nents) {
+		if (vsgt->num_pages > vmw_tt->sgt.orig_nents) {
 			uint64_t over_alloc =
 				sgl_size * (vsgt->num_pages -
-					    vmw_tt->sgt.nents);
+					    vmw_tt->sgt.orig_nents);
 
 			ttm_mem_global_free(glob, over_alloc);
 			vmw_tt->sg_alloc_size -= over_alloc;
-- 
1.9.1

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

^ permalink raw reply related	[flat|nested] 152+ messages in thread

* [RFC 15/17] drm: xen: fix sg_table nents vs. orig_nents misuse
       [not found]   ` <CGME20200428132031eucas1p1e7a72bf0de5acea2af652cd8337a8ed5@eucas1p1.samsung.com>
                         ` (3 preceding siblings ...)
  (?)
@ 2020-04-28 13:20       ` Marek Szyprowski
  0 siblings, 0 replies; 152+ messages in thread
From: Marek Szyprowski @ 2020-04-28 13:20 UTC (permalink / raw)
  To: dri-devel, iommu, linaro-mm-sig, linux-kernel
  Cc: Marek Szyprowski, Christoph Hellwig, Robin Murphy,
	Bartlomiej Zolnierkiewicz, Sumit Semwal, Benjamin Gaignard,
	intel-gfx, linux-arm-kernel, amd-gfx, David Airlie,
	Daniel Vetter

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/xen/xen_drm_front_gem.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/xen/xen_drm_front_gem.c b/drivers/gpu/drm/xen/xen_drm_front_gem.c
index f0b85e0..ba4bdc5 100644
--- a/drivers/gpu/drm/xen/xen_drm_front_gem.c
+++ b/drivers/gpu/drm/xen/xen_drm_front_gem.c
@@ -215,7 +215,7 @@ struct drm_gem_object *
 		return ERR_PTR(ret);
 
 	DRM_DEBUG("Imported buffer of size %zu with nents %u\n",
-		  size, sgt->nents);
+		  size, sgt->orig_nents);
 
 	return &xen_obj->base;
 }
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 152+ messages in thread

* [RFC 15/17] drm: xen: fix sg_table nents vs. orig_nents misuse
@ 2020-04-28 13:20       ` Marek Szyprowski
  0 siblings, 0 replies; 152+ messages in thread
From: Marek Szyprowski @ 2020-04-28 13:20 UTC (permalink / raw)
  To: dri-devel, iommu, linaro-mm-sig, linux-kernel
  Cc: Daniel Vetter, Bartlomiej Zolnierkiewicz, David Airlie,
	intel-gfx, amd-gfx, Christoph Hellwig, Benjamin Gaignard,
	Robin Murphy, Sumit Semwal, linux-arm-kernel

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/xen/xen_drm_front_gem.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/xen/xen_drm_front_gem.c b/drivers/gpu/drm/xen/xen_drm_front_gem.c
index f0b85e0..ba4bdc5 100644
--- a/drivers/gpu/drm/xen/xen_drm_front_gem.c
+++ b/drivers/gpu/drm/xen/xen_drm_front_gem.c
@@ -215,7 +215,7 @@ struct drm_gem_object *
 		return ERR_PTR(ret);
 
 	DRM_DEBUG("Imported buffer of size %zu with nents %u\n",
-		  size, sgt->nents);
+		  size, sgt->orig_nents);
 
 	return &xen_obj->base;
 }
-- 
1.9.1

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

^ permalink raw reply related	[flat|nested] 152+ messages in thread

* [RFC 15/17] drm: xen: fix sg_table nents vs. orig_nents misuse
@ 2020-04-28 13:20       ` Marek Szyprowski
  0 siblings, 0 replies; 152+ messages in thread
From: Marek Szyprowski @ 2020-04-28 13:20 UTC (permalink / raw)
  To: dri-devel, iommu, linaro-mm-sig, linux-kernel
  Cc: Daniel Vetter, Bartlomiej Zolnierkiewicz, David Airlie,
	intel-gfx, amd-gfx, Christoph Hellwig, Benjamin Gaignard,
	Robin Murphy, Sumit Semwal, linux-arm-kernel, Marek Szyprowski

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/xen/xen_drm_front_gem.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/xen/xen_drm_front_gem.c b/drivers/gpu/drm/xen/xen_drm_front_gem.c
index f0b85e0..ba4bdc5 100644
--- a/drivers/gpu/drm/xen/xen_drm_front_gem.c
+++ b/drivers/gpu/drm/xen/xen_drm_front_gem.c
@@ -215,7 +215,7 @@ struct drm_gem_object *
 		return ERR_PTR(ret);
 
 	DRM_DEBUG("Imported buffer of size %zu with nents %u\n",
-		  size, sgt->nents);
+		  size, sgt->orig_nents);
 
 	return &xen_obj->base;
 }
-- 
1.9.1


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

^ permalink raw reply related	[flat|nested] 152+ messages in thread

* [RFC 15/17] drm: xen: fix sg_table nents vs. orig_nents misuse
@ 2020-04-28 13:20       ` Marek Szyprowski
  0 siblings, 0 replies; 152+ messages in thread
From: Marek Szyprowski @ 2020-04-28 13:20 UTC (permalink / raw)
  To: dri-devel, iommu, linaro-mm-sig, linux-kernel
  Cc: Bartlomiej Zolnierkiewicz, David Airlie, intel-gfx, amd-gfx,
	Christoph Hellwig, Robin Murphy, linux-arm-kernel,
	Marek Szyprowski

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/xen/xen_drm_front_gem.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/xen/xen_drm_front_gem.c b/drivers/gpu/drm/xen/xen_drm_front_gem.c
index f0b85e0..ba4bdc5 100644
--- a/drivers/gpu/drm/xen/xen_drm_front_gem.c
+++ b/drivers/gpu/drm/xen/xen_drm_front_gem.c
@@ -215,7 +215,7 @@ struct drm_gem_object *
 		return ERR_PTR(ret);
 
 	DRM_DEBUG("Imported buffer of size %zu with nents %u\n",
-		  size, sgt->nents);
+		  size, sgt->orig_nents);
 
 	return &xen_obj->base;
 }
-- 
1.9.1

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

^ permalink raw reply related	[flat|nested] 152+ messages in thread

* [Intel-gfx] [RFC 15/17] drm: xen: fix sg_table nents vs. orig_nents misuse
@ 2020-04-28 13:20       ` Marek Szyprowski
  0 siblings, 0 replies; 152+ messages in thread
From: Marek Szyprowski @ 2020-04-28 13:20 UTC (permalink / raw)
  To: dri-devel, iommu, linaro-mm-sig, linux-kernel
  Cc: Bartlomiej Zolnierkiewicz, David Airlie, intel-gfx, amd-gfx,
	Christoph Hellwig, Benjamin Gaignard, Robin Murphy, Sumit Semwal,
	linux-arm-kernel, Marek Szyprowski

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/xen/xen_drm_front_gem.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/xen/xen_drm_front_gem.c b/drivers/gpu/drm/xen/xen_drm_front_gem.c
index f0b85e0..ba4bdc5 100644
--- a/drivers/gpu/drm/xen/xen_drm_front_gem.c
+++ b/drivers/gpu/drm/xen/xen_drm_front_gem.c
@@ -215,7 +215,7 @@ struct drm_gem_object *
 		return ERR_PTR(ret);
 
 	DRM_DEBUG("Imported buffer of size %zu with nents %u\n",
-		  size, sgt->nents);
+		  size, sgt->orig_nents);
 
 	return &xen_obj->base;
 }
-- 
1.9.1

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

^ permalink raw reply related	[flat|nested] 152+ messages in thread

* [RFC 15/17] drm: xen: fix sg_table nents vs. orig_nents misuse
@ 2020-04-28 13:20       ` Marek Szyprowski
  0 siblings, 0 replies; 152+ messages in thread
From: Marek Szyprowski @ 2020-04-28 13:20 UTC (permalink / raw)
  To: dri-devel, iommu, linaro-mm-sig, linux-kernel
  Cc: Daniel Vetter, Bartlomiej Zolnierkiewicz, David Airlie,
	intel-gfx, amd-gfx, Christoph Hellwig, Benjamin Gaignard,
	Robin Murphy, Sumit Semwal, linux-arm-kernel, Marek Szyprowski

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/xen/xen_drm_front_gem.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/xen/xen_drm_front_gem.c b/drivers/gpu/drm/xen/xen_drm_front_gem.c
index f0b85e0..ba4bdc5 100644
--- a/drivers/gpu/drm/xen/xen_drm_front_gem.c
+++ b/drivers/gpu/drm/xen/xen_drm_front_gem.c
@@ -215,7 +215,7 @@ struct drm_gem_object *
 		return ERR_PTR(ret);
 
 	DRM_DEBUG("Imported buffer of size %zu with nents %u\n",
-		  size, sgt->nents);
+		  size, sgt->orig_nents);
 
 	return &xen_obj->base;
 }
-- 
1.9.1

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

^ permalink raw reply related	[flat|nested] 152+ messages in thread

* [RFC 16/17] drm: host1x: fix sg_table nents vs. orig_nents misuse
       [not found]   ` <CGME20200428132031eucas1p25bf6d0d1f24a69cc3692b2001ac0ebd1@eucas1p2.samsung.com>
                         ` (3 preceding siblings ...)
  (?)
@ 2020-04-28 13:20       ` Marek Szyprowski
  0 siblings, 0 replies; 152+ messages in thread
From: Marek Szyprowski @ 2020-04-28 13:20 UTC (permalink / raw)
  To: dri-devel, iommu, linaro-mm-sig, linux-kernel
  Cc: Marek Szyprowski, Christoph Hellwig, Robin Murphy,
	Bartlomiej Zolnierkiewicz, Sumit Semwal, Benjamin Gaignard,
	intel-gfx, linux-arm-kernel, amd-gfx, David Airlie,
	Daniel Vetter

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/host1x/job.c | 17 +++++++++--------
 1 file changed, 9 insertions(+), 8 deletions(-)

diff --git a/drivers/gpu/host1x/job.c b/drivers/gpu/host1x/job.c
index a10643a..3ea185e 100644
--- a/drivers/gpu/host1x/job.c
+++ b/drivers/gpu/host1x/job.c
@@ -166,8 +166,9 @@ static unsigned int pin_job(struct host1x *host, struct host1x_job *job)
 				goto unpin;
 			}
 
-			err = dma_map_sg(dev, sgt->sgl, sgt->nents, dir);
-			if (!err) {
+			sgt->nents = dma_map_sg(dev, sgt->sgl, sgt->orig_nents,
+						dir);
+			if (!sgt->nents) {
 				err = -ENOMEM;
 				goto unpin;
 			}
@@ -217,7 +218,7 @@ static unsigned int pin_job(struct host1x *host, struct host1x_job *job)
 		}
 
 		if (!IS_ENABLED(CONFIG_TEGRA_HOST1X_FIREWALL) && host->domain) {
-			for_each_sg(sgt->sgl, sg, sgt->nents, j)
+			for_each_sg(sgt->sgl, sg, sgt->orig_nents, j)
 				gather_size += sg->length;
 			gather_size = iova_align(&host->iova, gather_size);
 
@@ -231,7 +232,7 @@ static unsigned int pin_job(struct host1x *host, struct host1x_job *job)
 
 			err = iommu_map_sg(host->domain,
 					iova_dma_addr(&host->iova, alloc),
-					sgt->sgl, sgt->nents, IOMMU_READ);
+					sgt->sgl, sgt->orig_nents, IOMMU_READ);
 			if (err == 0) {
 				__free_iova(&host->iova, alloc);
 				err = -EINVAL;
@@ -241,9 +242,9 @@ static unsigned int pin_job(struct host1x *host, struct host1x_job *job)
 			job->unpins[job->num_unpins].size = gather_size;
 			phys_addr = iova_dma_addr(&host->iova, alloc);
 		} else if (sgt) {
-			err = dma_map_sg(host->dev, sgt->sgl, sgt->nents,
-					 DMA_TO_DEVICE);
-			if (!err) {
+			sgt->nents = dma_map_sg(host->dev, sgt->sgl,
+						sgt->orig_nents, DMA_TO_DEVICE);
+			if (!sgt->nents) {
 				err = -ENOMEM;
 				goto unpin;
 			}
@@ -647,7 +648,7 @@ void host1x_job_unpin(struct host1x_job *job)
 		}
 
 		if (unpin->dev && sgt)
-			dma_unmap_sg(unpin->dev, sgt->sgl, sgt->nents,
+			dma_unmap_sg(unpin->dev, sgt->sgl, sgt->orig_nents,
 				     unpin->dir);
 
 		host1x_bo_unpin(dev, unpin->bo, sgt);
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 152+ messages in thread

* [RFC 16/17] drm: host1x: fix sg_table nents vs. orig_nents misuse
@ 2020-04-28 13:20       ` Marek Szyprowski
  0 siblings, 0 replies; 152+ messages in thread
From: Marek Szyprowski @ 2020-04-28 13:20 UTC (permalink / raw)
  To: dri-devel, iommu, linaro-mm-sig, linux-kernel
  Cc: Daniel Vetter, Bartlomiej Zolnierkiewicz, David Airlie,
	intel-gfx, amd-gfx, Christoph Hellwig, Benjamin Gaignard,
	Robin Murphy, Sumit Semwal, linux-arm-kernel

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/host1x/job.c | 17 +++++++++--------
 1 file changed, 9 insertions(+), 8 deletions(-)

diff --git a/drivers/gpu/host1x/job.c b/drivers/gpu/host1x/job.c
index a10643a..3ea185e 100644
--- a/drivers/gpu/host1x/job.c
+++ b/drivers/gpu/host1x/job.c
@@ -166,8 +166,9 @@ static unsigned int pin_job(struct host1x *host, struct host1x_job *job)
 				goto unpin;
 			}
 
-			err = dma_map_sg(dev, sgt->sgl, sgt->nents, dir);
-			if (!err) {
+			sgt->nents = dma_map_sg(dev, sgt->sgl, sgt->orig_nents,
+						dir);
+			if (!sgt->nents) {
 				err = -ENOMEM;
 				goto unpin;
 			}
@@ -217,7 +218,7 @@ static unsigned int pin_job(struct host1x *host, struct host1x_job *job)
 		}
 
 		if (!IS_ENABLED(CONFIG_TEGRA_HOST1X_FIREWALL) && host->domain) {
-			for_each_sg(sgt->sgl, sg, sgt->nents, j)
+			for_each_sg(sgt->sgl, sg, sgt->orig_nents, j)
 				gather_size += sg->length;
 			gather_size = iova_align(&host->iova, gather_size);
 
@@ -231,7 +232,7 @@ static unsigned int pin_job(struct host1x *host, struct host1x_job *job)
 
 			err = iommu_map_sg(host->domain,
 					iova_dma_addr(&host->iova, alloc),
-					sgt->sgl, sgt->nents, IOMMU_READ);
+					sgt->sgl, sgt->orig_nents, IOMMU_READ);
 			if (err == 0) {
 				__free_iova(&host->iova, alloc);
 				err = -EINVAL;
@@ -241,9 +242,9 @@ static unsigned int pin_job(struct host1x *host, struct host1x_job *job)
 			job->unpins[job->num_unpins].size = gather_size;
 			phys_addr = iova_dma_addr(&host->iova, alloc);
 		} else if (sgt) {
-			err = dma_map_sg(host->dev, sgt->sgl, sgt->nents,
-					 DMA_TO_DEVICE);
-			if (!err) {
+			sgt->nents = dma_map_sg(host->dev, sgt->sgl,
+						sgt->orig_nents, DMA_TO_DEVICE);
+			if (!sgt->nents) {
 				err = -ENOMEM;
 				goto unpin;
 			}
@@ -647,7 +648,7 @@ void host1x_job_unpin(struct host1x_job *job)
 		}
 
 		if (unpin->dev && sgt)
-			dma_unmap_sg(unpin->dev, sgt->sgl, sgt->nents,
+			dma_unmap_sg(unpin->dev, sgt->sgl, sgt->orig_nents,
 				     unpin->dir);
 
 		host1x_bo_unpin(dev, unpin->bo, sgt);
-- 
1.9.1

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

^ permalink raw reply related	[flat|nested] 152+ messages in thread

* [RFC 16/17] drm: host1x: fix sg_table nents vs. orig_nents misuse
@ 2020-04-28 13:20       ` Marek Szyprowski
  0 siblings, 0 replies; 152+ messages in thread
From: Marek Szyprowski @ 2020-04-28 13:20 UTC (permalink / raw)
  To: dri-devel, iommu, linaro-mm-sig, linux-kernel
  Cc: Daniel Vetter, Bartlomiej Zolnierkiewicz, David Airlie,
	intel-gfx, amd-gfx, Christoph Hellwig, Benjamin Gaignard,
	Robin Murphy, Sumit Semwal, linux-arm-kernel, Marek Szyprowski

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/host1x/job.c | 17 +++++++++--------
 1 file changed, 9 insertions(+), 8 deletions(-)

diff --git a/drivers/gpu/host1x/job.c b/drivers/gpu/host1x/job.c
index a10643a..3ea185e 100644
--- a/drivers/gpu/host1x/job.c
+++ b/drivers/gpu/host1x/job.c
@@ -166,8 +166,9 @@ static unsigned int pin_job(struct host1x *host, struct host1x_job *job)
 				goto unpin;
 			}
 
-			err = dma_map_sg(dev, sgt->sgl, sgt->nents, dir);
-			if (!err) {
+			sgt->nents = dma_map_sg(dev, sgt->sgl, sgt->orig_nents,
+						dir);
+			if (!sgt->nents) {
 				err = -ENOMEM;
 				goto unpin;
 			}
@@ -217,7 +218,7 @@ static unsigned int pin_job(struct host1x *host, struct host1x_job *job)
 		}
 
 		if (!IS_ENABLED(CONFIG_TEGRA_HOST1X_FIREWALL) && host->domain) {
-			for_each_sg(sgt->sgl, sg, sgt->nents, j)
+			for_each_sg(sgt->sgl, sg, sgt->orig_nents, j)
 				gather_size += sg->length;
 			gather_size = iova_align(&host->iova, gather_size);
 
@@ -231,7 +232,7 @@ static unsigned int pin_job(struct host1x *host, struct host1x_job *job)
 
 			err = iommu_map_sg(host->domain,
 					iova_dma_addr(&host->iova, alloc),
-					sgt->sgl, sgt->nents, IOMMU_READ);
+					sgt->sgl, sgt->orig_nents, IOMMU_READ);
 			if (err == 0) {
 				__free_iova(&host->iova, alloc);
 				err = -EINVAL;
@@ -241,9 +242,9 @@ static unsigned int pin_job(struct host1x *host, struct host1x_job *job)
 			job->unpins[job->num_unpins].size = gather_size;
 			phys_addr = iova_dma_addr(&host->iova, alloc);
 		} else if (sgt) {
-			err = dma_map_sg(host->dev, sgt->sgl, sgt->nents,
-					 DMA_TO_DEVICE);
-			if (!err) {
+			sgt->nents = dma_map_sg(host->dev, sgt->sgl,
+						sgt->orig_nents, DMA_TO_DEVICE);
+			if (!sgt->nents) {
 				err = -ENOMEM;
 				goto unpin;
 			}
@@ -647,7 +648,7 @@ void host1x_job_unpin(struct host1x_job *job)
 		}
 
 		if (unpin->dev && sgt)
-			dma_unmap_sg(unpin->dev, sgt->sgl, sgt->nents,
+			dma_unmap_sg(unpin->dev, sgt->sgl, sgt->orig_nents,
 				     unpin->dir);
 
 		host1x_bo_unpin(dev, unpin->bo, sgt);
-- 
1.9.1


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

^ permalink raw reply related	[flat|nested] 152+ messages in thread

* [RFC 16/17] drm: host1x: fix sg_table nents vs. orig_nents misuse
@ 2020-04-28 13:20       ` Marek Szyprowski
  0 siblings, 0 replies; 152+ messages in thread
From: Marek Szyprowski @ 2020-04-28 13:20 UTC (permalink / raw)
  To: dri-devel, iommu, linaro-mm-sig, linux-kernel
  Cc: Bartlomiej Zolnierkiewicz, David Airlie, intel-gfx, amd-gfx,
	Christoph Hellwig, Robin Murphy, linux-arm-kernel,
	Marek Szyprowski

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/host1x/job.c | 17 +++++++++--------
 1 file changed, 9 insertions(+), 8 deletions(-)

diff --git a/drivers/gpu/host1x/job.c b/drivers/gpu/host1x/job.c
index a10643a..3ea185e 100644
--- a/drivers/gpu/host1x/job.c
+++ b/drivers/gpu/host1x/job.c
@@ -166,8 +166,9 @@ static unsigned int pin_job(struct host1x *host, struct host1x_job *job)
 				goto unpin;
 			}
 
-			err = dma_map_sg(dev, sgt->sgl, sgt->nents, dir);
-			if (!err) {
+			sgt->nents = dma_map_sg(dev, sgt->sgl, sgt->orig_nents,
+						dir);
+			if (!sgt->nents) {
 				err = -ENOMEM;
 				goto unpin;
 			}
@@ -217,7 +218,7 @@ static unsigned int pin_job(struct host1x *host, struct host1x_job *job)
 		}
 
 		if (!IS_ENABLED(CONFIG_TEGRA_HOST1X_FIREWALL) && host->domain) {
-			for_each_sg(sgt->sgl, sg, sgt->nents, j)
+			for_each_sg(sgt->sgl, sg, sgt->orig_nents, j)
 				gather_size += sg->length;
 			gather_size = iova_align(&host->iova, gather_size);
 
@@ -231,7 +232,7 @@ static unsigned int pin_job(struct host1x *host, struct host1x_job *job)
 
 			err = iommu_map_sg(host->domain,
 					iova_dma_addr(&host->iova, alloc),
-					sgt->sgl, sgt->nents, IOMMU_READ);
+					sgt->sgl, sgt->orig_nents, IOMMU_READ);
 			if (err == 0) {
 				__free_iova(&host->iova, alloc);
 				err = -EINVAL;
@@ -241,9 +242,9 @@ static unsigned int pin_job(struct host1x *host, struct host1x_job *job)
 			job->unpins[job->num_unpins].size = gather_size;
 			phys_addr = iova_dma_addr(&host->iova, alloc);
 		} else if (sgt) {
-			err = dma_map_sg(host->dev, sgt->sgl, sgt->nents,
-					 DMA_TO_DEVICE);
-			if (!err) {
+			sgt->nents = dma_map_sg(host->dev, sgt->sgl,
+						sgt->orig_nents, DMA_TO_DEVICE);
+			if (!sgt->nents) {
 				err = -ENOMEM;
 				goto unpin;
 			}
@@ -647,7 +648,7 @@ void host1x_job_unpin(struct host1x_job *job)
 		}
 
 		if (unpin->dev && sgt)
-			dma_unmap_sg(unpin->dev, sgt->sgl, sgt->nents,
+			dma_unmap_sg(unpin->dev, sgt->sgl, sgt->orig_nents,
 				     unpin->dir);
 
 		host1x_bo_unpin(dev, unpin->bo, sgt);
-- 
1.9.1

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

^ permalink raw reply related	[flat|nested] 152+ messages in thread

* [Intel-gfx] [RFC 16/17] drm: host1x: fix sg_table nents vs. orig_nents misuse
@ 2020-04-28 13:20       ` Marek Szyprowski
  0 siblings, 0 replies; 152+ messages in thread
From: Marek Szyprowski @ 2020-04-28 13:20 UTC (permalink / raw)
  To: dri-devel, iommu, linaro-mm-sig, linux-kernel
  Cc: Bartlomiej Zolnierkiewicz, David Airlie, intel-gfx, amd-gfx,
	Christoph Hellwig, Benjamin Gaignard, Robin Murphy, Sumit Semwal,
	linux-arm-kernel, Marek Szyprowski

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/host1x/job.c | 17 +++++++++--------
 1 file changed, 9 insertions(+), 8 deletions(-)

diff --git a/drivers/gpu/host1x/job.c b/drivers/gpu/host1x/job.c
index a10643a..3ea185e 100644
--- a/drivers/gpu/host1x/job.c
+++ b/drivers/gpu/host1x/job.c
@@ -166,8 +166,9 @@ static unsigned int pin_job(struct host1x *host, struct host1x_job *job)
 				goto unpin;
 			}
 
-			err = dma_map_sg(dev, sgt->sgl, sgt->nents, dir);
-			if (!err) {
+			sgt->nents = dma_map_sg(dev, sgt->sgl, sgt->orig_nents,
+						dir);
+			if (!sgt->nents) {
 				err = -ENOMEM;
 				goto unpin;
 			}
@@ -217,7 +218,7 @@ static unsigned int pin_job(struct host1x *host, struct host1x_job *job)
 		}
 
 		if (!IS_ENABLED(CONFIG_TEGRA_HOST1X_FIREWALL) && host->domain) {
-			for_each_sg(sgt->sgl, sg, sgt->nents, j)
+			for_each_sg(sgt->sgl, sg, sgt->orig_nents, j)
 				gather_size += sg->length;
 			gather_size = iova_align(&host->iova, gather_size);
 
@@ -231,7 +232,7 @@ static unsigned int pin_job(struct host1x *host, struct host1x_job *job)
 
 			err = iommu_map_sg(host->domain,
 					iova_dma_addr(&host->iova, alloc),
-					sgt->sgl, sgt->nents, IOMMU_READ);
+					sgt->sgl, sgt->orig_nents, IOMMU_READ);
 			if (err == 0) {
 				__free_iova(&host->iova, alloc);
 				err = -EINVAL;
@@ -241,9 +242,9 @@ static unsigned int pin_job(struct host1x *host, struct host1x_job *job)
 			job->unpins[job->num_unpins].size = gather_size;
 			phys_addr = iova_dma_addr(&host->iova, alloc);
 		} else if (sgt) {
-			err = dma_map_sg(host->dev, sgt->sgl, sgt->nents,
-					 DMA_TO_DEVICE);
-			if (!err) {
+			sgt->nents = dma_map_sg(host->dev, sgt->sgl,
+						sgt->orig_nents, DMA_TO_DEVICE);
+			if (!sgt->nents) {
 				err = -ENOMEM;
 				goto unpin;
 			}
@@ -647,7 +648,7 @@ void host1x_job_unpin(struct host1x_job *job)
 		}
 
 		if (unpin->dev && sgt)
-			dma_unmap_sg(unpin->dev, sgt->sgl, sgt->nents,
+			dma_unmap_sg(unpin->dev, sgt->sgl, sgt->orig_nents,
 				     unpin->dir);
 
 		host1x_bo_unpin(dev, unpin->bo, sgt);
-- 
1.9.1

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

^ permalink raw reply related	[flat|nested] 152+ messages in thread

* [RFC 16/17] drm: host1x: fix sg_table nents vs. orig_nents misuse
@ 2020-04-28 13:20       ` Marek Szyprowski
  0 siblings, 0 replies; 152+ messages in thread
From: Marek Szyprowski @ 2020-04-28 13:20 UTC (permalink / raw)
  To: dri-devel, iommu, linaro-mm-sig, linux-kernel
  Cc: Daniel Vetter, Bartlomiej Zolnierkiewicz, David Airlie,
	intel-gfx, amd-gfx, Christoph Hellwig, Benjamin Gaignard,
	Robin Murphy, Sumit Semwal, linux-arm-kernel, Marek Szyprowski

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/host1x/job.c | 17 +++++++++--------
 1 file changed, 9 insertions(+), 8 deletions(-)

diff --git a/drivers/gpu/host1x/job.c b/drivers/gpu/host1x/job.c
index a10643a..3ea185e 100644
--- a/drivers/gpu/host1x/job.c
+++ b/drivers/gpu/host1x/job.c
@@ -166,8 +166,9 @@ static unsigned int pin_job(struct host1x *host, struct host1x_job *job)
 				goto unpin;
 			}
 
-			err = dma_map_sg(dev, sgt->sgl, sgt->nents, dir);
-			if (!err) {
+			sgt->nents = dma_map_sg(dev, sgt->sgl, sgt->orig_nents,
+						dir);
+			if (!sgt->nents) {
 				err = -ENOMEM;
 				goto unpin;
 			}
@@ -217,7 +218,7 @@ static unsigned int pin_job(struct host1x *host, struct host1x_job *job)
 		}
 
 		if (!IS_ENABLED(CONFIG_TEGRA_HOST1X_FIREWALL) && host->domain) {
-			for_each_sg(sgt->sgl, sg, sgt->nents, j)
+			for_each_sg(sgt->sgl, sg, sgt->orig_nents, j)
 				gather_size += sg->length;
 			gather_size = iova_align(&host->iova, gather_size);
 
@@ -231,7 +232,7 @@ static unsigned int pin_job(struct host1x *host, struct host1x_job *job)
 
 			err = iommu_map_sg(host->domain,
 					iova_dma_addr(&host->iova, alloc),
-					sgt->sgl, sgt->nents, IOMMU_READ);
+					sgt->sgl, sgt->orig_nents, IOMMU_READ);
 			if (err == 0) {
 				__free_iova(&host->iova, alloc);
 				err = -EINVAL;
@@ -241,9 +242,9 @@ static unsigned int pin_job(struct host1x *host, struct host1x_job *job)
 			job->unpins[job->num_unpins].size = gather_size;
 			phys_addr = iova_dma_addr(&host->iova, alloc);
 		} else if (sgt) {
-			err = dma_map_sg(host->dev, sgt->sgl, sgt->nents,
-					 DMA_TO_DEVICE);
-			if (!err) {
+			sgt->nents = dma_map_sg(host->dev, sgt->sgl,
+						sgt->orig_nents, DMA_TO_DEVICE);
+			if (!sgt->nents) {
 				err = -ENOMEM;
 				goto unpin;
 			}
@@ -647,7 +648,7 @@ void host1x_job_unpin(struct host1x_job *job)
 		}
 
 		if (unpin->dev && sgt)
-			dma_unmap_sg(unpin->dev, sgt->sgl, sgt->nents,
+			dma_unmap_sg(unpin->dev, sgt->sgl, sgt->orig_nents,
 				     unpin->dir);
 
 		host1x_bo_unpin(dev, unpin->bo, sgt);
-- 
1.9.1

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

^ permalink raw reply related	[flat|nested] 152+ messages in thread

* [RFC 17/17] dmabuf: fix sg_table nents vs. orig_nents misuse
       [not found]   ` <CGME20200428132032eucas1p17c2b93daf91c95c41650e75b251d525c@eucas1p1.samsung.com>
                         ` (3 preceding siblings ...)
  (?)
@ 2020-04-28 13:20       ` Marek Szyprowski
  0 siblings, 0 replies; 152+ messages in thread
From: Marek Szyprowski @ 2020-04-28 13:20 UTC (permalink / raw)
  To: dri-devel, iommu, linaro-mm-sig, linux-kernel
  Cc: Marek Szyprowski, Christoph Hellwig, Robin Murphy,
	Bartlomiej Zolnierkiewicz, Sumit Semwal, Benjamin Gaignard,
	intel-gfx, linux-arm-kernel, amd-gfx, David Airlie,
	Daniel Vetter

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/dma-buf/heaps/heap-helpers.c | 7 ++++---
 drivers/dma-buf/udmabuf.c            | 5 +++--
 2 files changed, 7 insertions(+), 5 deletions(-)

diff --git a/drivers/dma-buf/heaps/heap-helpers.c b/drivers/dma-buf/heaps/heap-helpers.c
index 9f964ca..b923863 100644
--- a/drivers/dma-buf/heaps/heap-helpers.c
+++ b/drivers/dma-buf/heaps/heap-helpers.c
@@ -144,8 +144,9 @@ struct sg_table *dma_heap_map_dma_buf(struct dma_buf_attachment *attachment,
 
 	table = &a->table;
 
-	if (!dma_map_sg(attachment->dev, table->sgl, table->nents,
-			direction))
+	table->nents = dma_map_sg(attachment->dev, table->sgl,
+				  table->orig_nents, direction);
+	if (!table->nents)
 		table = ERR_PTR(-ENOMEM);
 	return table;
 }
@@ -154,7 +155,7 @@ static void dma_heap_unmap_dma_buf(struct dma_buf_attachment *attachment,
 				   struct sg_table *table,
 				   enum dma_data_direction direction)
 {
-	dma_unmap_sg(attachment->dev, table->sgl, table->nents, direction);
+	dma_unmap_sg(attachment->dev, table->sgl, table->orig_nents, direction);
 }
 
 static vm_fault_t dma_heap_vm_fault(struct vm_fault *vmf)
diff --git a/drivers/dma-buf/udmabuf.c b/drivers/dma-buf/udmabuf.c
index acb26c6..ea0cf71 100644
--- a/drivers/dma-buf/udmabuf.c
+++ b/drivers/dma-buf/udmabuf.c
@@ -63,7 +63,8 @@ static struct sg_table *get_sg_table(struct device *dev, struct dma_buf *buf,
 					GFP_KERNEL);
 	if (ret < 0)
 		goto err;
-	if (!dma_map_sg(dev, sg->sgl, sg->nents, direction)) {
+	sg->nents = dma_map_sg(dev, sg->sgl, sg->orig_nents, direction);
+	if (!sg->nents) {
 		ret = -EINVAL;
 		goto err;
 	}
@@ -78,7 +79,7 @@ static struct sg_table *get_sg_table(struct device *dev, struct dma_buf *buf,
 static void put_sg_table(struct device *dev, struct sg_table *sg,
 			 enum dma_data_direction direction)
 {
-	dma_unmap_sg(dev, sg->sgl, sg->nents, direction);
+	dma_unmap_sg(dev, sg->sgl, sg->orig_nents, direction);
 	sg_free_table(sg);
 	kfree(sg);
 }
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 152+ messages in thread

* [RFC 17/17] dmabuf: fix sg_table nents vs. orig_nents misuse
@ 2020-04-28 13:20       ` Marek Szyprowski
  0 siblings, 0 replies; 152+ messages in thread
From: Marek Szyprowski @ 2020-04-28 13:20 UTC (permalink / raw)
  To: dri-devel, iommu, linaro-mm-sig, linux-kernel
  Cc: Daniel Vetter, Bartlomiej Zolnierkiewicz, David Airlie,
	intel-gfx, amd-gfx, Christoph Hellwig, Benjamin Gaignard,
	Robin Murphy, Sumit Semwal, linux-arm-kernel

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/dma-buf/heaps/heap-helpers.c | 7 ++++---
 drivers/dma-buf/udmabuf.c            | 5 +++--
 2 files changed, 7 insertions(+), 5 deletions(-)

diff --git a/drivers/dma-buf/heaps/heap-helpers.c b/drivers/dma-buf/heaps/heap-helpers.c
index 9f964ca..b923863 100644
--- a/drivers/dma-buf/heaps/heap-helpers.c
+++ b/drivers/dma-buf/heaps/heap-helpers.c
@@ -144,8 +144,9 @@ struct sg_table *dma_heap_map_dma_buf(struct dma_buf_attachment *attachment,
 
 	table = &a->table;
 
-	if (!dma_map_sg(attachment->dev, table->sgl, table->nents,
-			direction))
+	table->nents = dma_map_sg(attachment->dev, table->sgl,
+				  table->orig_nents, direction);
+	if (!table->nents)
 		table = ERR_PTR(-ENOMEM);
 	return table;
 }
@@ -154,7 +155,7 @@ static void dma_heap_unmap_dma_buf(struct dma_buf_attachment *attachment,
 				   struct sg_table *table,
 				   enum dma_data_direction direction)
 {
-	dma_unmap_sg(attachment->dev, table->sgl, table->nents, direction);
+	dma_unmap_sg(attachment->dev, table->sgl, table->orig_nents, direction);
 }
 
 static vm_fault_t dma_heap_vm_fault(struct vm_fault *vmf)
diff --git a/drivers/dma-buf/udmabuf.c b/drivers/dma-buf/udmabuf.c
index acb26c6..ea0cf71 100644
--- a/drivers/dma-buf/udmabuf.c
+++ b/drivers/dma-buf/udmabuf.c
@@ -63,7 +63,8 @@ static struct sg_table *get_sg_table(struct device *dev, struct dma_buf *buf,
 					GFP_KERNEL);
 	if (ret < 0)
 		goto err;
-	if (!dma_map_sg(dev, sg->sgl, sg->nents, direction)) {
+	sg->nents = dma_map_sg(dev, sg->sgl, sg->orig_nents, direction);
+	if (!sg->nents) {
 		ret = -EINVAL;
 		goto err;
 	}
@@ -78,7 +79,7 @@ static struct sg_table *get_sg_table(struct device *dev, struct dma_buf *buf,
 static void put_sg_table(struct device *dev, struct sg_table *sg,
 			 enum dma_data_direction direction)
 {
-	dma_unmap_sg(dev, sg->sgl, sg->nents, direction);
+	dma_unmap_sg(dev, sg->sgl, sg->orig_nents, direction);
 	sg_free_table(sg);
 	kfree(sg);
 }
-- 
1.9.1

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

^ permalink raw reply related	[flat|nested] 152+ messages in thread

* [RFC 17/17] dmabuf: fix sg_table nents vs. orig_nents misuse
@ 2020-04-28 13:20       ` Marek Szyprowski
  0 siblings, 0 replies; 152+ messages in thread
From: Marek Szyprowski @ 2020-04-28 13:20 UTC (permalink / raw)
  To: dri-devel, iommu, linaro-mm-sig, linux-kernel
  Cc: Daniel Vetter, Bartlomiej Zolnierkiewicz, David Airlie,
	intel-gfx, amd-gfx, Christoph Hellwig, Benjamin Gaignard,
	Robin Murphy, Sumit Semwal, linux-arm-kernel, Marek Szyprowski

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/dma-buf/heaps/heap-helpers.c | 7 ++++---
 drivers/dma-buf/udmabuf.c            | 5 +++--
 2 files changed, 7 insertions(+), 5 deletions(-)

diff --git a/drivers/dma-buf/heaps/heap-helpers.c b/drivers/dma-buf/heaps/heap-helpers.c
index 9f964ca..b923863 100644
--- a/drivers/dma-buf/heaps/heap-helpers.c
+++ b/drivers/dma-buf/heaps/heap-helpers.c
@@ -144,8 +144,9 @@ struct sg_table *dma_heap_map_dma_buf(struct dma_buf_attachment *attachment,
 
 	table = &a->table;
 
-	if (!dma_map_sg(attachment->dev, table->sgl, table->nents,
-			direction))
+	table->nents = dma_map_sg(attachment->dev, table->sgl,
+				  table->orig_nents, direction);
+	if (!table->nents)
 		table = ERR_PTR(-ENOMEM);
 	return table;
 }
@@ -154,7 +155,7 @@ static void dma_heap_unmap_dma_buf(struct dma_buf_attachment *attachment,
 				   struct sg_table *table,
 				   enum dma_data_direction direction)
 {
-	dma_unmap_sg(attachment->dev, table->sgl, table->nents, direction);
+	dma_unmap_sg(attachment->dev, table->sgl, table->orig_nents, direction);
 }
 
 static vm_fault_t dma_heap_vm_fault(struct vm_fault *vmf)
diff --git a/drivers/dma-buf/udmabuf.c b/drivers/dma-buf/udmabuf.c
index acb26c6..ea0cf71 100644
--- a/drivers/dma-buf/udmabuf.c
+++ b/drivers/dma-buf/udmabuf.c
@@ -63,7 +63,8 @@ static struct sg_table *get_sg_table(struct device *dev, struct dma_buf *buf,
 					GFP_KERNEL);
 	if (ret < 0)
 		goto err;
-	if (!dma_map_sg(dev, sg->sgl, sg->nents, direction)) {
+	sg->nents = dma_map_sg(dev, sg->sgl, sg->orig_nents, direction);
+	if (!sg->nents) {
 		ret = -EINVAL;
 		goto err;
 	}
@@ -78,7 +79,7 @@ static struct sg_table *get_sg_table(struct device *dev, struct dma_buf *buf,
 static void put_sg_table(struct device *dev, struct sg_table *sg,
 			 enum dma_data_direction direction)
 {
-	dma_unmap_sg(dev, sg->sgl, sg->nents, direction);
+	dma_unmap_sg(dev, sg->sgl, sg->orig_nents, direction);
 	sg_free_table(sg);
 	kfree(sg);
 }
-- 
1.9.1


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

^ permalink raw reply related	[flat|nested] 152+ messages in thread

* [RFC 17/17] dmabuf: fix sg_table nents vs. orig_nents misuse
@ 2020-04-28 13:20       ` Marek Szyprowski
  0 siblings, 0 replies; 152+ messages in thread
From: Marek Szyprowski @ 2020-04-28 13:20 UTC (permalink / raw)
  To: dri-devel, iommu, linaro-mm-sig, linux-kernel
  Cc: Bartlomiej Zolnierkiewicz, David Airlie, intel-gfx, amd-gfx,
	Christoph Hellwig, Robin Murphy, linux-arm-kernel,
	Marek Szyprowski

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/dma-buf/heaps/heap-helpers.c | 7 ++++---
 drivers/dma-buf/udmabuf.c            | 5 +++--
 2 files changed, 7 insertions(+), 5 deletions(-)

diff --git a/drivers/dma-buf/heaps/heap-helpers.c b/drivers/dma-buf/heaps/heap-helpers.c
index 9f964ca..b923863 100644
--- a/drivers/dma-buf/heaps/heap-helpers.c
+++ b/drivers/dma-buf/heaps/heap-helpers.c
@@ -144,8 +144,9 @@ struct sg_table *dma_heap_map_dma_buf(struct dma_buf_attachment *attachment,
 
 	table = &a->table;
 
-	if (!dma_map_sg(attachment->dev, table->sgl, table->nents,
-			direction))
+	table->nents = dma_map_sg(attachment->dev, table->sgl,
+				  table->orig_nents, direction);
+	if (!table->nents)
 		table = ERR_PTR(-ENOMEM);
 	return table;
 }
@@ -154,7 +155,7 @@ static void dma_heap_unmap_dma_buf(struct dma_buf_attachment *attachment,
 				   struct sg_table *table,
 				   enum dma_data_direction direction)
 {
-	dma_unmap_sg(attachment->dev, table->sgl, table->nents, direction);
+	dma_unmap_sg(attachment->dev, table->sgl, table->orig_nents, direction);
 }
 
 static vm_fault_t dma_heap_vm_fault(struct vm_fault *vmf)
diff --git a/drivers/dma-buf/udmabuf.c b/drivers/dma-buf/udmabuf.c
index acb26c6..ea0cf71 100644
--- a/drivers/dma-buf/udmabuf.c
+++ b/drivers/dma-buf/udmabuf.c
@@ -63,7 +63,8 @@ static struct sg_table *get_sg_table(struct device *dev, struct dma_buf *buf,
 					GFP_KERNEL);
 	if (ret < 0)
 		goto err;
-	if (!dma_map_sg(dev, sg->sgl, sg->nents, direction)) {
+	sg->nents = dma_map_sg(dev, sg->sgl, sg->orig_nents, direction);
+	if (!sg->nents) {
 		ret = -EINVAL;
 		goto err;
 	}
@@ -78,7 +79,7 @@ static struct sg_table *get_sg_table(struct device *dev, struct dma_buf *buf,
 static void put_sg_table(struct device *dev, struct sg_table *sg,
 			 enum dma_data_direction direction)
 {
-	dma_unmap_sg(dev, sg->sgl, sg->nents, direction);
+	dma_unmap_sg(dev, sg->sgl, sg->orig_nents, direction);
 	sg_free_table(sg);
 	kfree(sg);
 }
-- 
1.9.1

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

^ permalink raw reply related	[flat|nested] 152+ messages in thread

* [Intel-gfx] [RFC 17/17] dmabuf: fix sg_table nents vs. orig_nents misuse
@ 2020-04-28 13:20       ` Marek Szyprowski
  0 siblings, 0 replies; 152+ messages in thread
From: Marek Szyprowski @ 2020-04-28 13:20 UTC (permalink / raw)
  To: dri-devel, iommu, linaro-mm-sig, linux-kernel
  Cc: Bartlomiej Zolnierkiewicz, David Airlie, intel-gfx, amd-gfx,
	Christoph Hellwig, Benjamin Gaignard, Robin Murphy, Sumit Semwal,
	linux-arm-kernel, Marek Szyprowski

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/dma-buf/heaps/heap-helpers.c | 7 ++++---
 drivers/dma-buf/udmabuf.c            | 5 +++--
 2 files changed, 7 insertions(+), 5 deletions(-)

diff --git a/drivers/dma-buf/heaps/heap-helpers.c b/drivers/dma-buf/heaps/heap-helpers.c
index 9f964ca..b923863 100644
--- a/drivers/dma-buf/heaps/heap-helpers.c
+++ b/drivers/dma-buf/heaps/heap-helpers.c
@@ -144,8 +144,9 @@ struct sg_table *dma_heap_map_dma_buf(struct dma_buf_attachment *attachment,
 
 	table = &a->table;
 
-	if (!dma_map_sg(attachment->dev, table->sgl, table->nents,
-			direction))
+	table->nents = dma_map_sg(attachment->dev, table->sgl,
+				  table->orig_nents, direction);
+	if (!table->nents)
 		table = ERR_PTR(-ENOMEM);
 	return table;
 }
@@ -154,7 +155,7 @@ static void dma_heap_unmap_dma_buf(struct dma_buf_attachment *attachment,
 				   struct sg_table *table,
 				   enum dma_data_direction direction)
 {
-	dma_unmap_sg(attachment->dev, table->sgl, table->nents, direction);
+	dma_unmap_sg(attachment->dev, table->sgl, table->orig_nents, direction);
 }
 
 static vm_fault_t dma_heap_vm_fault(struct vm_fault *vmf)
diff --git a/drivers/dma-buf/udmabuf.c b/drivers/dma-buf/udmabuf.c
index acb26c6..ea0cf71 100644
--- a/drivers/dma-buf/udmabuf.c
+++ b/drivers/dma-buf/udmabuf.c
@@ -63,7 +63,8 @@ static struct sg_table *get_sg_table(struct device *dev, struct dma_buf *buf,
 					GFP_KERNEL);
 	if (ret < 0)
 		goto err;
-	if (!dma_map_sg(dev, sg->sgl, sg->nents, direction)) {
+	sg->nents = dma_map_sg(dev, sg->sgl, sg->orig_nents, direction);
+	if (!sg->nents) {
 		ret = -EINVAL;
 		goto err;
 	}
@@ -78,7 +79,7 @@ static struct sg_table *get_sg_table(struct device *dev, struct dma_buf *buf,
 static void put_sg_table(struct device *dev, struct sg_table *sg,
 			 enum dma_data_direction direction)
 {
-	dma_unmap_sg(dev, sg->sgl, sg->nents, direction);
+	dma_unmap_sg(dev, sg->sgl, sg->orig_nents, direction);
 	sg_free_table(sg);
 	kfree(sg);
 }
-- 
1.9.1

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

^ permalink raw reply related	[flat|nested] 152+ messages in thread

* [RFC 17/17] dmabuf: fix sg_table nents vs. orig_nents misuse
@ 2020-04-28 13:20       ` Marek Szyprowski
  0 siblings, 0 replies; 152+ messages in thread
From: Marek Szyprowski @ 2020-04-28 13:20 UTC (permalink / raw)
  To: dri-devel, iommu, linaro-mm-sig, linux-kernel
  Cc: Daniel Vetter, Bartlomiej Zolnierkiewicz, David Airlie,
	intel-gfx, amd-gfx, Christoph Hellwig, Benjamin Gaignard,
	Robin Murphy, Sumit Semwal, linux-arm-kernel, Marek Szyprowski

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/dma-buf/heaps/heap-helpers.c | 7 ++++---
 drivers/dma-buf/udmabuf.c            | 5 +++--
 2 files changed, 7 insertions(+), 5 deletions(-)

diff --git a/drivers/dma-buf/heaps/heap-helpers.c b/drivers/dma-buf/heaps/heap-helpers.c
index 9f964ca..b923863 100644
--- a/drivers/dma-buf/heaps/heap-helpers.c
+++ b/drivers/dma-buf/heaps/heap-helpers.c
@@ -144,8 +144,9 @@ struct sg_table *dma_heap_map_dma_buf(struct dma_buf_attachment *attachment,
 
 	table = &a->table;
 
-	if (!dma_map_sg(attachment->dev, table->sgl, table->nents,
-			direction))
+	table->nents = dma_map_sg(attachment->dev, table->sgl,
+				  table->orig_nents, direction);
+	if (!table->nents)
 		table = ERR_PTR(-ENOMEM);
 	return table;
 }
@@ -154,7 +155,7 @@ static void dma_heap_unmap_dma_buf(struct dma_buf_attachment *attachment,
 				   struct sg_table *table,
 				   enum dma_data_direction direction)
 {
-	dma_unmap_sg(attachment->dev, table->sgl, table->nents, direction);
+	dma_unmap_sg(attachment->dev, table->sgl, table->orig_nents, direction);
 }
 
 static vm_fault_t dma_heap_vm_fault(struct vm_fault *vmf)
diff --git a/drivers/dma-buf/udmabuf.c b/drivers/dma-buf/udmabuf.c
index acb26c6..ea0cf71 100644
--- a/drivers/dma-buf/udmabuf.c
+++ b/drivers/dma-buf/udmabuf.c
@@ -63,7 +63,8 @@ static struct sg_table *get_sg_table(struct device *dev, struct dma_buf *buf,
 					GFP_KERNEL);
 	if (ret < 0)
 		goto err;
-	if (!dma_map_sg(dev, sg->sgl, sg->nents, direction)) {
+	sg->nents = dma_map_sg(dev, sg->sgl, sg->orig_nents, direction);
+	if (!sg->nents) {
 		ret = -EINVAL;
 		goto err;
 	}
@@ -78,7 +79,7 @@ static struct sg_table *get_sg_table(struct device *dev, struct dma_buf *buf,
 static void put_sg_table(struct device *dev, struct sg_table *sg,
 			 enum dma_data_direction direction)
 {
-	dma_unmap_sg(dev, sg->sgl, sg->nents, direction);
+	dma_unmap_sg(dev, sg->sgl, sg->orig_nents, direction);
 	sg_free_table(sg);
 	kfree(sg);
 }
-- 
1.9.1

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

^ permalink raw reply related	[flat|nested] 152+ messages in thread

* Re: [RFC 00/17] DRM: fix struct sg_table nents vs. orig_nents misuse
  2020-04-28 13:19   ` Marek Szyprowski
                       ` (2 preceding siblings ...)
  (?)
@ 2020-04-28 14:02     ` Christoph Hellwig
  -1 siblings, 0 replies; 152+ messages in thread
From: Christoph Hellwig @ 2020-04-28 14:02 UTC (permalink / raw)
  To: Marek Szyprowski
  Cc: dri-devel, iommu, linaro-mm-sig, linux-kernel, Christoph Hellwig,
	Robin Murphy, Bartlomiej Zolnierkiewicz, Sumit Semwal,
	Benjamin Gaignard, intel-gfx, linux-arm-kernel, amd-gfx,
	David Airlie, Daniel Vetter

On Tue, Apr 28, 2020 at 03:19:48PM +0200, Marek Szyprowski wrote:
> 1. introduce a dma_{map,sync,unmap}_sgtable() wrappers, which will use
>    a proper sg_table entries and call respective DMA-mapping functions
>    and adapt current code to it

That sounds reasonable to me.  Those could be pretty trivial wrappers.

>
> 
> 2. rename nents and orig_nents to nr_pages, nr_dmas to clearly state
>    which one refers to which part of the scatterlist; I'm open for
>    other names for those entries

nr_cpu_ents and nr_dma_ents might be better names, but it still would be
a whole lot of churn for little gain.  I think just good wrappers like
suggested above might be more helpful.

^ permalink raw reply	[flat|nested] 152+ messages in thread

* Re: [RFC 00/17] DRM: fix struct sg_table nents vs. orig_nents misuse
@ 2020-04-28 14:02     ` Christoph Hellwig
  0 siblings, 0 replies; 152+ messages in thread
From: Christoph Hellwig @ 2020-04-28 14:02 UTC (permalink / raw)
  To: Marek Szyprowski
  Cc: Daniel Vetter, Bartlomiej Zolnierkiewicz, David Airlie,
	intel-gfx, linux-kernel, dri-devel, Sumit Semwal, linaro-mm-sig,
	iommu, amd-gfx, Benjamin Gaignard, Robin Murphy,
	Christoph Hellwig, linux-arm-kernel

On Tue, Apr 28, 2020 at 03:19:48PM +0200, Marek Szyprowski wrote:
> 1. introduce a dma_{map,sync,unmap}_sgtable() wrappers, which will use
>    a proper sg_table entries and call respective DMA-mapping functions
>    and adapt current code to it

That sounds reasonable to me.  Those could be pretty trivial wrappers.

>
> 
> 2. rename nents and orig_nents to nr_pages, nr_dmas to clearly state
>    which one refers to which part of the scatterlist; I'm open for
>    other names for those entries

nr_cpu_ents and nr_dma_ents might be better names, but it still would be
a whole lot of churn for little gain.  I think just good wrappers like
suggested above might be more helpful.
_______________________________________________
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu

^ permalink raw reply	[flat|nested] 152+ messages in thread

* Re: [RFC 00/17] DRM: fix struct sg_table nents vs. orig_nents misuse
@ 2020-04-28 14:02     ` Christoph Hellwig
  0 siblings, 0 replies; 152+ messages in thread
From: Christoph Hellwig @ 2020-04-28 14:02 UTC (permalink / raw)
  To: Marek Szyprowski
  Cc: Daniel Vetter, Bartlomiej Zolnierkiewicz, David Airlie,
	intel-gfx, linux-kernel, dri-devel, Sumit Semwal, linaro-mm-sig,
	iommu, amd-gfx, Benjamin Gaignard, Robin Murphy,
	Christoph Hellwig, linux-arm-kernel

On Tue, Apr 28, 2020 at 03:19:48PM +0200, Marek Szyprowski wrote:
> 1. introduce a dma_{map,sync,unmap}_sgtable() wrappers, which will use
>    a proper sg_table entries and call respective DMA-mapping functions
>    and adapt current code to it

That sounds reasonable to me.  Those could be pretty trivial wrappers.

>
> 
> 2. rename nents and orig_nents to nr_pages, nr_dmas to clearly state
>    which one refers to which part of the scatterlist; I'm open for
>    other names for those entries

nr_cpu_ents and nr_dma_ents might be better names, but it still would be
a whole lot of churn for little gain.  I think just good wrappers like
suggested above might be more helpful.

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

^ permalink raw reply	[flat|nested] 152+ messages in thread

* Re: [Intel-gfx] [RFC 00/17] DRM: fix struct sg_table nents vs. orig_nents misuse
@ 2020-04-28 14:02     ` Christoph Hellwig
  0 siblings, 0 replies; 152+ messages in thread
From: Christoph Hellwig @ 2020-04-28 14:02 UTC (permalink / raw)
  To: Marek Szyprowski
  Cc: Bartlomiej Zolnierkiewicz, David Airlie, intel-gfx, linux-kernel,
	dri-devel, Sumit Semwal, linaro-mm-sig, iommu, amd-gfx,
	Benjamin Gaignard, Robin Murphy, Christoph Hellwig,
	linux-arm-kernel

On Tue, Apr 28, 2020 at 03:19:48PM +0200, Marek Szyprowski wrote:
> 1. introduce a dma_{map,sync,unmap}_sgtable() wrappers, which will use
>    a proper sg_table entries and call respective DMA-mapping functions
>    and adapt current code to it

That sounds reasonable to me.  Those could be pretty trivial wrappers.

>
> 
> 2. rename nents and orig_nents to nr_pages, nr_dmas to clearly state
>    which one refers to which part of the scatterlist; I'm open for
>    other names for those entries

nr_cpu_ents and nr_dma_ents might be better names, but it still would be
a whole lot of churn for little gain.  I think just good wrappers like
suggested above might be more helpful.
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 152+ messages in thread

* Re: [RFC 00/17] DRM: fix struct sg_table nents vs. orig_nents misuse
@ 2020-04-28 14:02     ` Christoph Hellwig
  0 siblings, 0 replies; 152+ messages in thread
From: Christoph Hellwig @ 2020-04-28 14:02 UTC (permalink / raw)
  To: Marek Szyprowski
  Cc: Daniel Vetter, Bartlomiej Zolnierkiewicz, David Airlie,
	intel-gfx, linux-kernel, dri-devel, Sumit Semwal, linaro-mm-sig,
	iommu, amd-gfx, Benjamin Gaignard, Robin Murphy,
	Christoph Hellwig, linux-arm-kernel

On Tue, Apr 28, 2020 at 03:19:48PM +0200, Marek Szyprowski wrote:
> 1. introduce a dma_{map,sync,unmap}_sgtable() wrappers, which will use
>    a proper sg_table entries and call respective DMA-mapping functions
>    and adapt current code to it

That sounds reasonable to me.  Those could be pretty trivial wrappers.

>
> 
> 2. rename nents and orig_nents to nr_pages, nr_dmas to clearly state
>    which one refers to which part of the scatterlist; I'm open for
>    other names for those entries

nr_cpu_ents and nr_dma_ents might be better names, but it still would be
a whole lot of churn for little gain.  I think just good wrappers like
suggested above might be more helpful.
_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

^ permalink raw reply	[flat|nested] 152+ messages in thread

* Re: [Intel-gfx] [RFC 06/17] drm: i915: fix sg_table nents vs. orig_nents misuse
  2020-04-28 13:19       ` Marek Szyprowski
                           ` (3 preceding siblings ...)
  (?)
@ 2020-04-28 14:27         ` Tvrtko Ursulin
  -1 siblings, 0 replies; 152+ messages in thread
From: Tvrtko Ursulin @ 2020-04-28 14:27 UTC (permalink / raw)
  To: Marek Szyprowski, dri-devel, iommu, linaro-mm-sig, linux-kernel
  Cc: Bartlomiej Zolnierkiewicz, David Airlie, intel-gfx, amd-gfx,
	Christoph Hellwig, Benjamin Gaignard, Robin Murphy, Sumit Semwal,
	linux-arm-kernel


On 28/04/2020 14:19, Marek Szyprowski wrote:
> 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;

A bit higher up, not shown in the patch, we have allocated a table via 
sg_alloc_table giving it a pessimistic max nents, sometimes much larger 
than the st->nents this loops will create. But orig_nents has been now 
been overwritten. Will that leak memory come sg_table_free?

As minimum it will nerf our i915_sg_trim optimization a bit lower down, 
also not shown in the diff.

Regards,

Tvrtko

> +
>   			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;
> 

^ permalink raw reply	[flat|nested] 152+ messages in thread

* Re: [Intel-gfx] [RFC 06/17] drm: i915: fix sg_table nents vs. orig_nents misuse
@ 2020-04-28 14:27         ` Tvrtko Ursulin
  0 siblings, 0 replies; 152+ messages in thread
From: Tvrtko Ursulin @ 2020-04-28 14:27 UTC (permalink / raw)
  To: Marek Szyprowski, dri-devel, iommu, linaro-mm-sig, linux-kernel
  Cc: Bartlomiej Zolnierkiewicz, David Airlie, intel-gfx, amd-gfx,
	Sumit Semwal, Benjamin Gaignard, Robin Murphy, Christoph Hellwig,
	linux-arm-kernel


On 28/04/2020 14:19, Marek Szyprowski wrote:
> 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;

A bit higher up, not shown in the patch, we have allocated a table via 
sg_alloc_table giving it a pessimistic max nents, sometimes much larger 
than the st->nents this loops will create. But orig_nents has been now 
been overwritten. Will that leak memory come sg_table_free?

As minimum it will nerf our i915_sg_trim optimization a bit lower down, 
also not shown in the diff.

Regards,

Tvrtko

> +
>   			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;
> 
_______________________________________________
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu

^ permalink raw reply	[flat|nested] 152+ messages in thread

* Re: [Intel-gfx] [RFC 06/17] drm: i915: fix sg_table nents vs. orig_nents misuse
@ 2020-04-28 14:27         ` Tvrtko Ursulin
  0 siblings, 0 replies; 152+ messages in thread
From: Tvrtko Ursulin @ 2020-04-28 14:27 UTC (permalink / raw)
  To: Marek Szyprowski, dri-devel, iommu, linaro-mm-sig, linux-kernel
  Cc: Bartlomiej Zolnierkiewicz, David Airlie, intel-gfx, amd-gfx,
	Sumit Semwal, Benjamin Gaignard, Robin Murphy, Christoph Hellwig,
	linux-arm-kernel


On 28/04/2020 14:19, Marek Szyprowski wrote:
> 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;

A bit higher up, not shown in the patch, we have allocated a table via 
sg_alloc_table giving it a pessimistic max nents, sometimes much larger 
than the st->nents this loops will create. But orig_nents has been now 
been overwritten. Will that leak memory come sg_table_free?

As minimum it will nerf our i915_sg_trim optimization a bit lower down, 
also not shown in the diff.

Regards,

Tvrtko

> +
>   			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;
> 

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

^ permalink raw reply	[flat|nested] 152+ messages in thread

* Re: [Intel-gfx] [RFC 06/17] drm: i915: fix sg_table nents vs. orig_nents misuse
@ 2020-04-28 14:27         ` Tvrtko Ursulin
  0 siblings, 0 replies; 152+ messages in thread
From: Tvrtko Ursulin @ 2020-04-28 14:27 UTC (permalink / raw)
  To: Marek Szyprowski, dri-devel, iommu, linaro-mm-sig, linux-kernel
  Cc: Bartlomiej Zolnierkiewicz, David Airlie, intel-gfx, amd-gfx,
	Robin Murphy, Christoph Hellwig, linux-arm-kernel


On 28/04/2020 14:19, Marek Szyprowski wrote:
> 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;

A bit higher up, not shown in the patch, we have allocated a table via 
sg_alloc_table giving it a pessimistic max nents, sometimes much larger 
than the st->nents this loops will create. But orig_nents has been now 
been overwritten. Will that leak memory come sg_table_free?

As minimum it will nerf our i915_sg_trim optimization a bit lower down, 
also not shown in the diff.

Regards,

Tvrtko

> +
>   			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;
> 
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 152+ messages in thread

* Re: [Intel-gfx] [RFC 06/17] drm: i915: fix sg_table nents vs. orig_nents misuse
@ 2020-04-28 14:27         ` Tvrtko Ursulin
  0 siblings, 0 replies; 152+ messages in thread
From: Tvrtko Ursulin @ 2020-04-28 14:27 UTC (permalink / raw)
  To: Marek Szyprowski, dri-devel, iommu, linaro-mm-sig, linux-kernel
  Cc: Bartlomiej Zolnierkiewicz, David Airlie, intel-gfx, amd-gfx,
	Sumit Semwal, Benjamin Gaignard, Robin Murphy, Christoph Hellwig,
	linux-arm-kernel


On 28/04/2020 14:19, Marek Szyprowski wrote:
> 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;

A bit higher up, not shown in the patch, we have allocated a table via 
sg_alloc_table giving it a pessimistic max nents, sometimes much larger 
than the st->nents this loops will create. But orig_nents has been now 
been overwritten. Will that leak memory come sg_table_free?

As minimum it will nerf our i915_sg_trim optimization a bit lower down, 
also not shown in the diff.

Regards,

Tvrtko

> +
>   			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;
> 
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 152+ messages in thread

* Re: [Intel-gfx] [RFC 06/17] drm: i915: fix sg_table nents vs. orig_nents misuse
@ 2020-04-28 14:27         ` Tvrtko Ursulin
  0 siblings, 0 replies; 152+ messages in thread
From: Tvrtko Ursulin @ 2020-04-28 14:27 UTC (permalink / raw)
  To: Marek Szyprowski, dri-devel, iommu, linaro-mm-sig, linux-kernel
  Cc: Bartlomiej Zolnierkiewicz, David Airlie, intel-gfx, amd-gfx,
	Sumit Semwal, Benjamin Gaignard, Robin Murphy, Christoph Hellwig,
	linux-arm-kernel


On 28/04/2020 14:19, Marek Szyprowski wrote:
> 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;

A bit higher up, not shown in the patch, we have allocated a table via 
sg_alloc_table giving it a pessimistic max nents, sometimes much larger 
than the st->nents this loops will create. But orig_nents has been now 
been overwritten. Will that leak memory come sg_table_free?

As minimum it will nerf our i915_sg_trim optimization a bit lower down, 
also not shown in the diff.

Regards,

Tvrtko

> +
>   			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;
> 
_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

^ permalink raw reply	[flat|nested] 152+ messages in thread

* Re: [RFC 02/17] drm: amdgpu: fix sg_table nents vs. orig_nents misuse
  2020-04-28 13:19       ` Marek Szyprowski
                           ` (3 preceding siblings ...)
  (?)
@ 2020-04-28 15:14         ` Christian König
  -1 siblings, 0 replies; 152+ messages in thread
From: Christian König @ 2020-04-28 15:14 UTC (permalink / raw)
  To: Marek Szyprowski, dri-devel, iommu, linaro-mm-sig, linux-kernel
  Cc: Daniel Vetter, Bartlomiej Zolnierkiewicz, David Airlie,
	intel-gfx, amd-gfx, Christoph Hellwig, Benjamin Gaignard,
	Robin Murphy, Sumit Semwal, linux-arm-kernel

Am 28.04.20 um 15:19 schrieb Marek Szyprowski:
> 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>

Reviewed-by: Christian König <christian.koenig@amd.com>

> ---
>   drivers/gpu/drm/amd/amdgpu/amdgpu_dma_buf.c | 7 ++++---
>   drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c     | 8 ++++----
>   2 files changed, 8 insertions(+), 7 deletions(-)
>
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_dma_buf.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_dma_buf.c
> index 43d8ed7..4df813e 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_dma_buf.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_dma_buf.c
> @@ -307,8 +307,9 @@ static struct sg_table *amdgpu_dma_buf_map(struct dma_buf_attachment *attach,
>   		if (IS_ERR(sgt))
>   			return sgt;
>   
> -		if (!dma_map_sg_attrs(attach->dev, sgt->sgl, sgt->nents, dir,
> -				      DMA_ATTR_SKIP_CPU_SYNC))
> +		sgt->nents = dma_map_sg_attrs(attach->dev, sgt->sgl, sgt->orig_nents,
> +					      dir, DMA_ATTR_SKIP_CPU_SYNC);
> +		if (!sgt->nents)
>   			goto error_free;
>   		break;
>   
> @@ -349,7 +350,7 @@ static void amdgpu_dma_buf_unmap(struct dma_buf_attachment *attach,
>   	struct amdgpu_device *adev = amdgpu_ttm_adev(bo->tbo.bdev);
>   
>   	if (sgt->sgl->page_link) {
> -		dma_unmap_sg(attach->dev, sgt->sgl, sgt->nents, dir);
> +		dma_unmap_sg(attach->dev, sgt->sgl, sgt->orig_nents, dir);
>   		sg_free_table(sgt);
>   		kfree(sgt);
>   	} else {
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
> index d5543c2..5f31585 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
> @@ -1043,7 +1043,6 @@ static int amdgpu_ttm_tt_pin_userptr(struct ttm_tt *ttm)
>   {
>   	struct amdgpu_device *adev = amdgpu_ttm_adev(ttm->bdev);
>   	struct amdgpu_ttm_tt *gtt = (void *)ttm;
> -	unsigned nents;
>   	int r;
>   
>   	int write = !(gtt->userflags & AMDGPU_GEM_USERPTR_READONLY);
> @@ -1059,8 +1058,9 @@ static int amdgpu_ttm_tt_pin_userptr(struct ttm_tt *ttm)
>   
>   	/* Map SG to device */
>   	r = -ENOMEM;
> -	nents = dma_map_sg(adev->dev, ttm->sg->sgl, ttm->sg->nents, direction);
> -	if (nents == 0)
> +	ttm->sg->nents = dma_map_sg(adev->dev, ttm->sg->sgl,
> +				    ttm->sg->orig_nents, direction);
> +	if (ttm->sg->nents == 0)
>   		goto release_sg;
>   
>   	/* convert SG to linear array of pages and dma addresses */
> @@ -1091,7 +1091,7 @@ static void amdgpu_ttm_tt_unpin_userptr(struct ttm_tt *ttm)
>   		return;
>   
>   	/* unmap the pages mapped to the device */
> -	dma_unmap_sg(adev->dev, ttm->sg->sgl, ttm->sg->nents, direction);
> +	dma_unmap_sg(adev->dev, ttm->sg->sgl, ttm->sg->orig_nents, direction);
>   
>   	sg_free_table(ttm->sg);
>   


^ permalink raw reply	[flat|nested] 152+ messages in thread

* Re: [RFC 02/17] drm: amdgpu: fix sg_table nents vs. orig_nents misuse
@ 2020-04-28 15:14         ` Christian König
  0 siblings, 0 replies; 152+ messages in thread
From: Christian König @ 2020-04-28 15:14 UTC (permalink / raw)
  To: Marek Szyprowski, dri-devel, iommu, linaro-mm-sig, linux-kernel
  Cc: Benjamin Gaignard, Bartlomiej Zolnierkiewicz, David Airlie,
	intel-gfx, amd-gfx, Sumit Semwal, Daniel Vetter, Robin Murphy,
	Christoph Hellwig, linux-arm-kernel

Am 28.04.20 um 15:19 schrieb Marek Szyprowski:
> 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>

Reviewed-by: Christian König <christian.koenig@amd.com>

> ---
>   drivers/gpu/drm/amd/amdgpu/amdgpu_dma_buf.c | 7 ++++---
>   drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c     | 8 ++++----
>   2 files changed, 8 insertions(+), 7 deletions(-)
>
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_dma_buf.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_dma_buf.c
> index 43d8ed7..4df813e 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_dma_buf.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_dma_buf.c
> @@ -307,8 +307,9 @@ static struct sg_table *amdgpu_dma_buf_map(struct dma_buf_attachment *attach,
>   		if (IS_ERR(sgt))
>   			return sgt;
>   
> -		if (!dma_map_sg_attrs(attach->dev, sgt->sgl, sgt->nents, dir,
> -				      DMA_ATTR_SKIP_CPU_SYNC))
> +		sgt->nents = dma_map_sg_attrs(attach->dev, sgt->sgl, sgt->orig_nents,
> +					      dir, DMA_ATTR_SKIP_CPU_SYNC);
> +		if (!sgt->nents)
>   			goto error_free;
>   		break;
>   
> @@ -349,7 +350,7 @@ static void amdgpu_dma_buf_unmap(struct dma_buf_attachment *attach,
>   	struct amdgpu_device *adev = amdgpu_ttm_adev(bo->tbo.bdev);
>   
>   	if (sgt->sgl->page_link) {
> -		dma_unmap_sg(attach->dev, sgt->sgl, sgt->nents, dir);
> +		dma_unmap_sg(attach->dev, sgt->sgl, sgt->orig_nents, dir);
>   		sg_free_table(sgt);
>   		kfree(sgt);
>   	} else {
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
> index d5543c2..5f31585 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
> @@ -1043,7 +1043,6 @@ static int amdgpu_ttm_tt_pin_userptr(struct ttm_tt *ttm)
>   {
>   	struct amdgpu_device *adev = amdgpu_ttm_adev(ttm->bdev);
>   	struct amdgpu_ttm_tt *gtt = (void *)ttm;
> -	unsigned nents;
>   	int r;
>   
>   	int write = !(gtt->userflags & AMDGPU_GEM_USERPTR_READONLY);
> @@ -1059,8 +1058,9 @@ static int amdgpu_ttm_tt_pin_userptr(struct ttm_tt *ttm)
>   
>   	/* Map SG to device */
>   	r = -ENOMEM;
> -	nents = dma_map_sg(adev->dev, ttm->sg->sgl, ttm->sg->nents, direction);
> -	if (nents == 0)
> +	ttm->sg->nents = dma_map_sg(adev->dev, ttm->sg->sgl,
> +				    ttm->sg->orig_nents, direction);
> +	if (ttm->sg->nents == 0)
>   		goto release_sg;
>   
>   	/* convert SG to linear array of pages and dma addresses */
> @@ -1091,7 +1091,7 @@ static void amdgpu_ttm_tt_unpin_userptr(struct ttm_tt *ttm)
>   		return;
>   
>   	/* unmap the pages mapped to the device */
> -	dma_unmap_sg(adev->dev, ttm->sg->sgl, ttm->sg->nents, direction);
> +	dma_unmap_sg(adev->dev, ttm->sg->sgl, ttm->sg->orig_nents, direction);
>   
>   	sg_free_table(ttm->sg);
>   

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

^ permalink raw reply	[flat|nested] 152+ messages in thread

* Re: [RFC 02/17] drm: amdgpu: fix sg_table nents vs. orig_nents misuse
@ 2020-04-28 15:14         ` Christian König
  0 siblings, 0 replies; 152+ messages in thread
From: Christian König @ 2020-04-28 15:14 UTC (permalink / raw)
  To: Marek Szyprowski, dri-devel, iommu, linaro-mm-sig, linux-kernel
  Cc: Benjamin Gaignard, Bartlomiej Zolnierkiewicz, David Airlie,
	intel-gfx, amd-gfx, Sumit Semwal, Daniel Vetter, Robin Murphy,
	Christoph Hellwig, linux-arm-kernel

Am 28.04.20 um 15:19 schrieb Marek Szyprowski:
> 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>

Reviewed-by: Christian König <christian.koenig@amd.com>

> ---
>   drivers/gpu/drm/amd/amdgpu/amdgpu_dma_buf.c | 7 ++++---
>   drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c     | 8 ++++----
>   2 files changed, 8 insertions(+), 7 deletions(-)
>
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_dma_buf.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_dma_buf.c
> index 43d8ed7..4df813e 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_dma_buf.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_dma_buf.c
> @@ -307,8 +307,9 @@ static struct sg_table *amdgpu_dma_buf_map(struct dma_buf_attachment *attach,
>   		if (IS_ERR(sgt))
>   			return sgt;
>   
> -		if (!dma_map_sg_attrs(attach->dev, sgt->sgl, sgt->nents, dir,
> -				      DMA_ATTR_SKIP_CPU_SYNC))
> +		sgt->nents = dma_map_sg_attrs(attach->dev, sgt->sgl, sgt->orig_nents,
> +					      dir, DMA_ATTR_SKIP_CPU_SYNC);
> +		if (!sgt->nents)
>   			goto error_free;
>   		break;
>   
> @@ -349,7 +350,7 @@ static void amdgpu_dma_buf_unmap(struct dma_buf_attachment *attach,
>   	struct amdgpu_device *adev = amdgpu_ttm_adev(bo->tbo.bdev);
>   
>   	if (sgt->sgl->page_link) {
> -		dma_unmap_sg(attach->dev, sgt->sgl, sgt->nents, dir);
> +		dma_unmap_sg(attach->dev, sgt->sgl, sgt->orig_nents, dir);
>   		sg_free_table(sgt);
>   		kfree(sgt);
>   	} else {
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
> index d5543c2..5f31585 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
> @@ -1043,7 +1043,6 @@ static int amdgpu_ttm_tt_pin_userptr(struct ttm_tt *ttm)
>   {
>   	struct amdgpu_device *adev = amdgpu_ttm_adev(ttm->bdev);
>   	struct amdgpu_ttm_tt *gtt = (void *)ttm;
> -	unsigned nents;
>   	int r;
>   
>   	int write = !(gtt->userflags & AMDGPU_GEM_USERPTR_READONLY);
> @@ -1059,8 +1058,9 @@ static int amdgpu_ttm_tt_pin_userptr(struct ttm_tt *ttm)
>   
>   	/* Map SG to device */
>   	r = -ENOMEM;
> -	nents = dma_map_sg(adev->dev, ttm->sg->sgl, ttm->sg->nents, direction);
> -	if (nents == 0)
> +	ttm->sg->nents = dma_map_sg(adev->dev, ttm->sg->sgl,
> +				    ttm->sg->orig_nents, direction);
> +	if (ttm->sg->nents == 0)
>   		goto release_sg;
>   
>   	/* convert SG to linear array of pages and dma addresses */
> @@ -1091,7 +1091,7 @@ static void amdgpu_ttm_tt_unpin_userptr(struct ttm_tt *ttm)
>   		return;
>   
>   	/* unmap the pages mapped to the device */
> -	dma_unmap_sg(adev->dev, ttm->sg->sgl, ttm->sg->nents, direction);
> +	dma_unmap_sg(adev->dev, ttm->sg->sgl, ttm->sg->orig_nents, direction);
>   
>   	sg_free_table(ttm->sg);
>   


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

^ permalink raw reply	[flat|nested] 152+ messages in thread

* Re: [RFC 02/17] drm: amdgpu: fix sg_table nents vs. orig_nents misuse
@ 2020-04-28 15:14         ` Christian König
  0 siblings, 0 replies; 152+ messages in thread
From: Christian König @ 2020-04-28 15:14 UTC (permalink / raw)
  To: Marek Szyprowski, dri-devel, iommu, linaro-mm-sig, linux-kernel
  Cc: Bartlomiej Zolnierkiewicz, David Airlie, intel-gfx, amd-gfx,
	Robin Murphy, Christoph Hellwig, linux-arm-kernel

Am 28.04.20 um 15:19 schrieb Marek Szyprowski:
> 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>

Reviewed-by: Christian König <christian.koenig@amd.com>

> ---
>   drivers/gpu/drm/amd/amdgpu/amdgpu_dma_buf.c | 7 ++++---
>   drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c     | 8 ++++----
>   2 files changed, 8 insertions(+), 7 deletions(-)
>
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_dma_buf.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_dma_buf.c
> index 43d8ed7..4df813e 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_dma_buf.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_dma_buf.c
> @@ -307,8 +307,9 @@ static struct sg_table *amdgpu_dma_buf_map(struct dma_buf_attachment *attach,
>   		if (IS_ERR(sgt))
>   			return sgt;
>   
> -		if (!dma_map_sg_attrs(attach->dev, sgt->sgl, sgt->nents, dir,
> -				      DMA_ATTR_SKIP_CPU_SYNC))
> +		sgt->nents = dma_map_sg_attrs(attach->dev, sgt->sgl, sgt->orig_nents,
> +					      dir, DMA_ATTR_SKIP_CPU_SYNC);
> +		if (!sgt->nents)
>   			goto error_free;
>   		break;
>   
> @@ -349,7 +350,7 @@ static void amdgpu_dma_buf_unmap(struct dma_buf_attachment *attach,
>   	struct amdgpu_device *adev = amdgpu_ttm_adev(bo->tbo.bdev);
>   
>   	if (sgt->sgl->page_link) {
> -		dma_unmap_sg(attach->dev, sgt->sgl, sgt->nents, dir);
> +		dma_unmap_sg(attach->dev, sgt->sgl, sgt->orig_nents, dir);
>   		sg_free_table(sgt);
>   		kfree(sgt);
>   	} else {
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
> index d5543c2..5f31585 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
> @@ -1043,7 +1043,6 @@ static int amdgpu_ttm_tt_pin_userptr(struct ttm_tt *ttm)
>   {
>   	struct amdgpu_device *adev = amdgpu_ttm_adev(ttm->bdev);
>   	struct amdgpu_ttm_tt *gtt = (void *)ttm;
> -	unsigned nents;
>   	int r;
>   
>   	int write = !(gtt->userflags & AMDGPU_GEM_USERPTR_READONLY);
> @@ -1059,8 +1058,9 @@ static int amdgpu_ttm_tt_pin_userptr(struct ttm_tt *ttm)
>   
>   	/* Map SG to device */
>   	r = -ENOMEM;
> -	nents = dma_map_sg(adev->dev, ttm->sg->sgl, ttm->sg->nents, direction);
> -	if (nents == 0)
> +	ttm->sg->nents = dma_map_sg(adev->dev, ttm->sg->sgl,
> +				    ttm->sg->orig_nents, direction);
> +	if (ttm->sg->nents == 0)
>   		goto release_sg;
>   
>   	/* convert SG to linear array of pages and dma addresses */
> @@ -1091,7 +1091,7 @@ static void amdgpu_ttm_tt_unpin_userptr(struct ttm_tt *ttm)
>   		return;
>   
>   	/* unmap the pages mapped to the device */
> -	dma_unmap_sg(adev->dev, ttm->sg->sgl, ttm->sg->nents, direction);
> +	dma_unmap_sg(adev->dev, ttm->sg->sgl, ttm->sg->orig_nents, direction);
>   
>   	sg_free_table(ttm->sg);
>   

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

^ permalink raw reply	[flat|nested] 152+ messages in thread

* Re: [Intel-gfx] [RFC 02/17] drm: amdgpu: fix sg_table nents vs. orig_nents misuse
@ 2020-04-28 15:14         ` Christian König
  0 siblings, 0 replies; 152+ messages in thread
From: Christian König @ 2020-04-28 15:14 UTC (permalink / raw)
  To: Marek Szyprowski, dri-devel, iommu, linaro-mm-sig, linux-kernel
  Cc: Benjamin Gaignard, Bartlomiej Zolnierkiewicz, David Airlie,
	intel-gfx, amd-gfx, Sumit Semwal, Robin Murphy,
	Christoph Hellwig, linux-arm-kernel

Am 28.04.20 um 15:19 schrieb Marek Szyprowski:
> 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>

Reviewed-by: Christian König <christian.koenig@amd.com>

> ---
>   drivers/gpu/drm/amd/amdgpu/amdgpu_dma_buf.c | 7 ++++---
>   drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c     | 8 ++++----
>   2 files changed, 8 insertions(+), 7 deletions(-)
>
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_dma_buf.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_dma_buf.c
> index 43d8ed7..4df813e 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_dma_buf.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_dma_buf.c
> @@ -307,8 +307,9 @@ static struct sg_table *amdgpu_dma_buf_map(struct dma_buf_attachment *attach,
>   		if (IS_ERR(sgt))
>   			return sgt;
>   
> -		if (!dma_map_sg_attrs(attach->dev, sgt->sgl, sgt->nents, dir,
> -				      DMA_ATTR_SKIP_CPU_SYNC))
> +		sgt->nents = dma_map_sg_attrs(attach->dev, sgt->sgl, sgt->orig_nents,
> +					      dir, DMA_ATTR_SKIP_CPU_SYNC);
> +		if (!sgt->nents)
>   			goto error_free;
>   		break;
>   
> @@ -349,7 +350,7 @@ static void amdgpu_dma_buf_unmap(struct dma_buf_attachment *attach,
>   	struct amdgpu_device *adev = amdgpu_ttm_adev(bo->tbo.bdev);
>   
>   	if (sgt->sgl->page_link) {
> -		dma_unmap_sg(attach->dev, sgt->sgl, sgt->nents, dir);
> +		dma_unmap_sg(attach->dev, sgt->sgl, sgt->orig_nents, dir);
>   		sg_free_table(sgt);
>   		kfree(sgt);
>   	} else {
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
> index d5543c2..5f31585 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
> @@ -1043,7 +1043,6 @@ static int amdgpu_ttm_tt_pin_userptr(struct ttm_tt *ttm)
>   {
>   	struct amdgpu_device *adev = amdgpu_ttm_adev(ttm->bdev);
>   	struct amdgpu_ttm_tt *gtt = (void *)ttm;
> -	unsigned nents;
>   	int r;
>   
>   	int write = !(gtt->userflags & AMDGPU_GEM_USERPTR_READONLY);
> @@ -1059,8 +1058,9 @@ static int amdgpu_ttm_tt_pin_userptr(struct ttm_tt *ttm)
>   
>   	/* Map SG to device */
>   	r = -ENOMEM;
> -	nents = dma_map_sg(adev->dev, ttm->sg->sgl, ttm->sg->nents, direction);
> -	if (nents == 0)
> +	ttm->sg->nents = dma_map_sg(adev->dev, ttm->sg->sgl,
> +				    ttm->sg->orig_nents, direction);
> +	if (ttm->sg->nents == 0)
>   		goto release_sg;
>   
>   	/* convert SG to linear array of pages and dma addresses */
> @@ -1091,7 +1091,7 @@ static void amdgpu_ttm_tt_unpin_userptr(struct ttm_tt *ttm)
>   		return;
>   
>   	/* unmap the pages mapped to the device */
> -	dma_unmap_sg(adev->dev, ttm->sg->sgl, ttm->sg->nents, direction);
> +	dma_unmap_sg(adev->dev, ttm->sg->sgl, ttm->sg->orig_nents, direction);
>   
>   	sg_free_table(ttm->sg);
>   

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

^ permalink raw reply	[flat|nested] 152+ messages in thread

* Re: [RFC 02/17] drm: amdgpu: fix sg_table nents vs. orig_nents misuse
@ 2020-04-28 15:14         ` Christian König
  0 siblings, 0 replies; 152+ messages in thread
From: Christian König @ 2020-04-28 15:14 UTC (permalink / raw)
  To: Marek Szyprowski, dri-devel, iommu, linaro-mm-sig, linux-kernel
  Cc: Benjamin Gaignard, Bartlomiej Zolnierkiewicz, David Airlie,
	intel-gfx, amd-gfx, Sumit Semwal, Daniel Vetter, Robin Murphy,
	Christoph Hellwig, linux-arm-kernel

Am 28.04.20 um 15:19 schrieb Marek Szyprowski:
> 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>

Reviewed-by: Christian König <christian.koenig@amd.com>

> ---
>   drivers/gpu/drm/amd/amdgpu/amdgpu_dma_buf.c | 7 ++++---
>   drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c     | 8 ++++----
>   2 files changed, 8 insertions(+), 7 deletions(-)
>
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_dma_buf.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_dma_buf.c
> index 43d8ed7..4df813e 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_dma_buf.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_dma_buf.c
> @@ -307,8 +307,9 @@ static struct sg_table *amdgpu_dma_buf_map(struct dma_buf_attachment *attach,
>   		if (IS_ERR(sgt))
>   			return sgt;
>   
> -		if (!dma_map_sg_attrs(attach->dev, sgt->sgl, sgt->nents, dir,
> -				      DMA_ATTR_SKIP_CPU_SYNC))
> +		sgt->nents = dma_map_sg_attrs(attach->dev, sgt->sgl, sgt->orig_nents,
> +					      dir, DMA_ATTR_SKIP_CPU_SYNC);
> +		if (!sgt->nents)
>   			goto error_free;
>   		break;
>   
> @@ -349,7 +350,7 @@ static void amdgpu_dma_buf_unmap(struct dma_buf_attachment *attach,
>   	struct amdgpu_device *adev = amdgpu_ttm_adev(bo->tbo.bdev);
>   
>   	if (sgt->sgl->page_link) {
> -		dma_unmap_sg(attach->dev, sgt->sgl, sgt->nents, dir);
> +		dma_unmap_sg(attach->dev, sgt->sgl, sgt->orig_nents, dir);
>   		sg_free_table(sgt);
>   		kfree(sgt);
>   	} else {
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
> index d5543c2..5f31585 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
> @@ -1043,7 +1043,6 @@ static int amdgpu_ttm_tt_pin_userptr(struct ttm_tt *ttm)
>   {
>   	struct amdgpu_device *adev = amdgpu_ttm_adev(ttm->bdev);
>   	struct amdgpu_ttm_tt *gtt = (void *)ttm;
> -	unsigned nents;
>   	int r;
>   
>   	int write = !(gtt->userflags & AMDGPU_GEM_USERPTR_READONLY);
> @@ -1059,8 +1058,9 @@ static int amdgpu_ttm_tt_pin_userptr(struct ttm_tt *ttm)
>   
>   	/* Map SG to device */
>   	r = -ENOMEM;
> -	nents = dma_map_sg(adev->dev, ttm->sg->sgl, ttm->sg->nents, direction);
> -	if (nents == 0)
> +	ttm->sg->nents = dma_map_sg(adev->dev, ttm->sg->sgl,
> +				    ttm->sg->orig_nents, direction);
> +	if (ttm->sg->nents == 0)
>   		goto release_sg;
>   
>   	/* convert SG to linear array of pages and dma addresses */
> @@ -1091,7 +1091,7 @@ static void amdgpu_ttm_tt_unpin_userptr(struct ttm_tt *ttm)
>   		return;
>   
>   	/* unmap the pages mapped to the device */
> -	dma_unmap_sg(adev->dev, ttm->sg->sgl, ttm->sg->nents, direction);
> +	dma_unmap_sg(adev->dev, ttm->sg->sgl, ttm->sg->orig_nents, direction);
>   
>   	sg_free_table(ttm->sg);
>   

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

^ permalink raw reply	[flat|nested] 152+ messages in thread

* Re: [RFC 10/17] drm: radeon: fix sg_table nents vs. orig_nents misuse
  2020-04-28 13:19       ` Marek Szyprowski
                           ` (3 preceding siblings ...)
  (?)
@ 2020-04-28 15:15         ` Christian König
  -1 siblings, 0 replies; 152+ messages in thread
From: Christian König @ 2020-04-28 15:15 UTC (permalink / raw)
  To: Marek Szyprowski, dri-devel, iommu, linaro-mm-sig, linux-kernel
  Cc: Daniel Vetter, Bartlomiej Zolnierkiewicz, David Airlie,
	intel-gfx, amd-gfx, Christoph Hellwig, Benjamin Gaignard,
	Robin Murphy, Sumit Semwal, linux-arm-kernel

Am 28.04.20 um 15:19 schrieb Marek Szyprowski:
> 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>

Reviewed-by: Christian König <christian.koenig@amd.com>

> ---
>   drivers/gpu/drm/radeon/radeon_ttm.c | 10 +++++-----
>   1 file changed, 5 insertions(+), 5 deletions(-)
>
> diff --git a/drivers/gpu/drm/radeon/radeon_ttm.c b/drivers/gpu/drm/radeon/radeon_ttm.c
> index 5d50c9e..4770880 100644
> --- a/drivers/gpu/drm/radeon/radeon_ttm.c
> +++ b/drivers/gpu/drm/radeon/radeon_ttm.c
> @@ -481,7 +481,7 @@ static int radeon_ttm_tt_pin_userptr(struct ttm_tt *ttm)
>   {
>   	struct radeon_device *rdev = radeon_get_rdev(ttm->bdev);
>   	struct radeon_ttm_tt *gtt = (void *)ttm;
> -	unsigned pinned = 0, nents;
> +	unsigned pinned = 0;
>   	int r;
>   
>   	int write = !(gtt->userflags & RADEON_GEM_USERPTR_READONLY);
> @@ -522,8 +522,8 @@ static int radeon_ttm_tt_pin_userptr(struct ttm_tt *ttm)
>   		goto release_sg;
>   
>   	r = -ENOMEM;
> -	nents = dma_map_sg(rdev->dev, ttm->sg->sgl, ttm->sg->nents, direction);
> -	if (nents == 0)
> +	ttm->sg->nents = dma_map_sg(rdev->dev, ttm->sg->sgl,
> +	if (ttm->sg->nents == 0)
>   		goto release_sg;
>   
>   	drm_prime_sg_to_page_addr_arrays(ttm->sg, ttm->pages,
> @@ -554,9 +554,9 @@ static void radeon_ttm_tt_unpin_userptr(struct ttm_tt *ttm)
>   		return;
>   
>   	/* free the sg table and pages again */
> -	dma_unmap_sg(rdev->dev, ttm->sg->sgl, ttm->sg->nents, direction);
> +	dma_unmap_sg(rdev->dev, ttm->sg->sgl, ttm->sg->orig_nents, direction);
>   
> -	for_each_sg_page(ttm->sg->sgl, &sg_iter, ttm->sg->nents, 0) {
> +	for_each_sg_page(ttm->sg->sgl, &sg_iter, ttm->sg->orig_nents, 0) {
>   		struct page *page = sg_page_iter_page(&sg_iter);
>   		if (!(gtt->userflags & RADEON_GEM_USERPTR_READONLY))
>   			set_page_dirty(page);


^ permalink raw reply	[flat|nested] 152+ messages in thread

* Re: [RFC 10/17] drm: radeon: fix sg_table nents vs. orig_nents misuse
@ 2020-04-28 15:15         ` Christian König
  0 siblings, 0 replies; 152+ messages in thread
From: Christian König @ 2020-04-28 15:15 UTC (permalink / raw)
  To: Marek Szyprowski, dri-devel, iommu, linaro-mm-sig, linux-kernel
  Cc: Benjamin Gaignard, Bartlomiej Zolnierkiewicz, David Airlie,
	intel-gfx, amd-gfx, Sumit Semwal, Daniel Vetter, Robin Murphy,
	Christoph Hellwig, linux-arm-kernel

Am 28.04.20 um 15:19 schrieb Marek Szyprowski:
> 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>

Reviewed-by: Christian König <christian.koenig@amd.com>

> ---
>   drivers/gpu/drm/radeon/radeon_ttm.c | 10 +++++-----
>   1 file changed, 5 insertions(+), 5 deletions(-)
>
> diff --git a/drivers/gpu/drm/radeon/radeon_ttm.c b/drivers/gpu/drm/radeon/radeon_ttm.c
> index 5d50c9e..4770880 100644
> --- a/drivers/gpu/drm/radeon/radeon_ttm.c
> +++ b/drivers/gpu/drm/radeon/radeon_ttm.c
> @@ -481,7 +481,7 @@ static int radeon_ttm_tt_pin_userptr(struct ttm_tt *ttm)
>   {
>   	struct radeon_device *rdev = radeon_get_rdev(ttm->bdev);
>   	struct radeon_ttm_tt *gtt = (void *)ttm;
> -	unsigned pinned = 0, nents;
> +	unsigned pinned = 0;
>   	int r;
>   
>   	int write = !(gtt->userflags & RADEON_GEM_USERPTR_READONLY);
> @@ -522,8 +522,8 @@ static int radeon_ttm_tt_pin_userptr(struct ttm_tt *ttm)
>   		goto release_sg;
>   
>   	r = -ENOMEM;
> -	nents = dma_map_sg(rdev->dev, ttm->sg->sgl, ttm->sg->nents, direction);
> -	if (nents == 0)
> +	ttm->sg->nents = dma_map_sg(rdev->dev, ttm->sg->sgl,
> +	if (ttm->sg->nents == 0)
>   		goto release_sg;
>   
>   	drm_prime_sg_to_page_addr_arrays(ttm->sg, ttm->pages,
> @@ -554,9 +554,9 @@ static void radeon_ttm_tt_unpin_userptr(struct ttm_tt *ttm)
>   		return;
>   
>   	/* free the sg table and pages again */
> -	dma_unmap_sg(rdev->dev, ttm->sg->sgl, ttm->sg->nents, direction);
> +	dma_unmap_sg(rdev->dev, ttm->sg->sgl, ttm->sg->orig_nents, direction);
>   
> -	for_each_sg_page(ttm->sg->sgl, &sg_iter, ttm->sg->nents, 0) {
> +	for_each_sg_page(ttm->sg->sgl, &sg_iter, ttm->sg->orig_nents, 0) {
>   		struct page *page = sg_page_iter_page(&sg_iter);
>   		if (!(gtt->userflags & RADEON_GEM_USERPTR_READONLY))
>   			set_page_dirty(page);

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

^ permalink raw reply	[flat|nested] 152+ messages in thread

* Re: [RFC 10/17] drm: radeon: fix sg_table nents vs. orig_nents misuse
@ 2020-04-28 15:15         ` Christian König
  0 siblings, 0 replies; 152+ messages in thread
From: Christian König @ 2020-04-28 15:15 UTC (permalink / raw)
  To: Marek Szyprowski, dri-devel, iommu, linaro-mm-sig, linux-kernel
  Cc: Benjamin Gaignard, Bartlomiej Zolnierkiewicz, David Airlie,
	intel-gfx, amd-gfx, Sumit Semwal, Daniel Vetter, Robin Murphy,
	Christoph Hellwig, linux-arm-kernel

Am 28.04.20 um 15:19 schrieb Marek Szyprowski:
> 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>

Reviewed-by: Christian König <christian.koenig@amd.com>

> ---
>   drivers/gpu/drm/radeon/radeon_ttm.c | 10 +++++-----
>   1 file changed, 5 insertions(+), 5 deletions(-)
>
> diff --git a/drivers/gpu/drm/radeon/radeon_ttm.c b/drivers/gpu/drm/radeon/radeon_ttm.c
> index 5d50c9e..4770880 100644
> --- a/drivers/gpu/drm/radeon/radeon_ttm.c
> +++ b/drivers/gpu/drm/radeon/radeon_ttm.c
> @@ -481,7 +481,7 @@ static int radeon_ttm_tt_pin_userptr(struct ttm_tt *ttm)
>   {
>   	struct radeon_device *rdev = radeon_get_rdev(ttm->bdev);
>   	struct radeon_ttm_tt *gtt = (void *)ttm;
> -	unsigned pinned = 0, nents;
> +	unsigned pinned = 0;
>   	int r;
>   
>   	int write = !(gtt->userflags & RADEON_GEM_USERPTR_READONLY);
> @@ -522,8 +522,8 @@ static int radeon_ttm_tt_pin_userptr(struct ttm_tt *ttm)
>   		goto release_sg;
>   
>   	r = -ENOMEM;
> -	nents = dma_map_sg(rdev->dev, ttm->sg->sgl, ttm->sg->nents, direction);
> -	if (nents == 0)
> +	ttm->sg->nents = dma_map_sg(rdev->dev, ttm->sg->sgl,
> +	if (ttm->sg->nents == 0)
>   		goto release_sg;
>   
>   	drm_prime_sg_to_page_addr_arrays(ttm->sg, ttm->pages,
> @@ -554,9 +554,9 @@ static void radeon_ttm_tt_unpin_userptr(struct ttm_tt *ttm)
>   		return;
>   
>   	/* free the sg table and pages again */
> -	dma_unmap_sg(rdev->dev, ttm->sg->sgl, ttm->sg->nents, direction);
> +	dma_unmap_sg(rdev->dev, ttm->sg->sgl, ttm->sg->orig_nents, direction);
>   
> -	for_each_sg_page(ttm->sg->sgl, &sg_iter, ttm->sg->nents, 0) {
> +	for_each_sg_page(ttm->sg->sgl, &sg_iter, ttm->sg->orig_nents, 0) {
>   		struct page *page = sg_page_iter_page(&sg_iter);
>   		if (!(gtt->userflags & RADEON_GEM_USERPTR_READONLY))
>   			set_page_dirty(page);


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

^ permalink raw reply	[flat|nested] 152+ messages in thread

* Re: [RFC 10/17] drm: radeon: fix sg_table nents vs. orig_nents misuse
@ 2020-04-28 15:15         ` Christian König
  0 siblings, 0 replies; 152+ messages in thread
From: Christian König @ 2020-04-28 15:15 UTC (permalink / raw)
  To: Marek Szyprowski, dri-devel, iommu, linaro-mm-sig, linux-kernel
  Cc: Bartlomiej Zolnierkiewicz, David Airlie, intel-gfx, amd-gfx,
	Robin Murphy, Christoph Hellwig, linux-arm-kernel

Am 28.04.20 um 15:19 schrieb Marek Szyprowski:
> 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>

Reviewed-by: Christian König <christian.koenig@amd.com>

> ---
>   drivers/gpu/drm/radeon/radeon_ttm.c | 10 +++++-----
>   1 file changed, 5 insertions(+), 5 deletions(-)
>
> diff --git a/drivers/gpu/drm/radeon/radeon_ttm.c b/drivers/gpu/drm/radeon/radeon_ttm.c
> index 5d50c9e..4770880 100644
> --- a/drivers/gpu/drm/radeon/radeon_ttm.c
> +++ b/drivers/gpu/drm/radeon/radeon_ttm.c
> @@ -481,7 +481,7 @@ static int radeon_ttm_tt_pin_userptr(struct ttm_tt *ttm)
>   {
>   	struct radeon_device *rdev = radeon_get_rdev(ttm->bdev);
>   	struct radeon_ttm_tt *gtt = (void *)ttm;
> -	unsigned pinned = 0, nents;
> +	unsigned pinned = 0;
>   	int r;
>   
>   	int write = !(gtt->userflags & RADEON_GEM_USERPTR_READONLY);
> @@ -522,8 +522,8 @@ static int radeon_ttm_tt_pin_userptr(struct ttm_tt *ttm)
>   		goto release_sg;
>   
>   	r = -ENOMEM;
> -	nents = dma_map_sg(rdev->dev, ttm->sg->sgl, ttm->sg->nents, direction);
> -	if (nents == 0)
> +	ttm->sg->nents = dma_map_sg(rdev->dev, ttm->sg->sgl,
> +	if (ttm->sg->nents == 0)
>   		goto release_sg;
>   
>   	drm_prime_sg_to_page_addr_arrays(ttm->sg, ttm->pages,
> @@ -554,9 +554,9 @@ static void radeon_ttm_tt_unpin_userptr(struct ttm_tt *ttm)
>   		return;
>   
>   	/* free the sg table and pages again */
> -	dma_unmap_sg(rdev->dev, ttm->sg->sgl, ttm->sg->nents, direction);
> +	dma_unmap_sg(rdev->dev, ttm->sg->sgl, ttm->sg->orig_nents, direction);
>   
> -	for_each_sg_page(ttm->sg->sgl, &sg_iter, ttm->sg->nents, 0) {
> +	for_each_sg_page(ttm->sg->sgl, &sg_iter, ttm->sg->orig_nents, 0) {
>   		struct page *page = sg_page_iter_page(&sg_iter);
>   		if (!(gtt->userflags & RADEON_GEM_USERPTR_READONLY))
>   			set_page_dirty(page);

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

^ permalink raw reply	[flat|nested] 152+ messages in thread

* Re: [Intel-gfx] [RFC 10/17] drm: radeon: fix sg_table nents vs. orig_nents misuse
@ 2020-04-28 15:15         ` Christian König
  0 siblings, 0 replies; 152+ messages in thread
From: Christian König @ 2020-04-28 15:15 UTC (permalink / raw)
  To: Marek Szyprowski, dri-devel, iommu, linaro-mm-sig, linux-kernel
  Cc: Benjamin Gaignard, Bartlomiej Zolnierkiewicz, David Airlie,
	intel-gfx, amd-gfx, Sumit Semwal, Robin Murphy,
	Christoph Hellwig, linux-arm-kernel

Am 28.04.20 um 15:19 schrieb Marek Szyprowski:
> 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>

Reviewed-by: Christian König <christian.koenig@amd.com>

> ---
>   drivers/gpu/drm/radeon/radeon_ttm.c | 10 +++++-----
>   1 file changed, 5 insertions(+), 5 deletions(-)
>
> diff --git a/drivers/gpu/drm/radeon/radeon_ttm.c b/drivers/gpu/drm/radeon/radeon_ttm.c
> index 5d50c9e..4770880 100644
> --- a/drivers/gpu/drm/radeon/radeon_ttm.c
> +++ b/drivers/gpu/drm/radeon/radeon_ttm.c
> @@ -481,7 +481,7 @@ static int radeon_ttm_tt_pin_userptr(struct ttm_tt *ttm)
>   {
>   	struct radeon_device *rdev = radeon_get_rdev(ttm->bdev);
>   	struct radeon_ttm_tt *gtt = (void *)ttm;
> -	unsigned pinned = 0, nents;
> +	unsigned pinned = 0;
>   	int r;
>   
>   	int write = !(gtt->userflags & RADEON_GEM_USERPTR_READONLY);
> @@ -522,8 +522,8 @@ static int radeon_ttm_tt_pin_userptr(struct ttm_tt *ttm)
>   		goto release_sg;
>   
>   	r = -ENOMEM;
> -	nents = dma_map_sg(rdev->dev, ttm->sg->sgl, ttm->sg->nents, direction);
> -	if (nents == 0)
> +	ttm->sg->nents = dma_map_sg(rdev->dev, ttm->sg->sgl,
> +	if (ttm->sg->nents == 0)
>   		goto release_sg;
>   
>   	drm_prime_sg_to_page_addr_arrays(ttm->sg, ttm->pages,
> @@ -554,9 +554,9 @@ static void radeon_ttm_tt_unpin_userptr(struct ttm_tt *ttm)
>   		return;
>   
>   	/* free the sg table and pages again */
> -	dma_unmap_sg(rdev->dev, ttm->sg->sgl, ttm->sg->nents, direction);
> +	dma_unmap_sg(rdev->dev, ttm->sg->sgl, ttm->sg->orig_nents, direction);
>   
> -	for_each_sg_page(ttm->sg->sgl, &sg_iter, ttm->sg->nents, 0) {
> +	for_each_sg_page(ttm->sg->sgl, &sg_iter, ttm->sg->orig_nents, 0) {
>   		struct page *page = sg_page_iter_page(&sg_iter);
>   		if (!(gtt->userflags & RADEON_GEM_USERPTR_READONLY))
>   			set_page_dirty(page);

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

^ permalink raw reply	[flat|nested] 152+ messages in thread

* Re: [RFC 10/17] drm: radeon: fix sg_table nents vs. orig_nents misuse
@ 2020-04-28 15:15         ` Christian König
  0 siblings, 0 replies; 152+ messages in thread
From: Christian König @ 2020-04-28 15:15 UTC (permalink / raw)
  To: Marek Szyprowski, dri-devel, iommu, linaro-mm-sig, linux-kernel
  Cc: Benjamin Gaignard, Bartlomiej Zolnierkiewicz, David Airlie,
	intel-gfx, amd-gfx, Sumit Semwal, Daniel Vetter, Robin Murphy,
	Christoph Hellwig, linux-arm-kernel

Am 28.04.20 um 15:19 schrieb Marek Szyprowski:
> 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>

Reviewed-by: Christian König <christian.koenig@amd.com>

> ---
>   drivers/gpu/drm/radeon/radeon_ttm.c | 10 +++++-----
>   1 file changed, 5 insertions(+), 5 deletions(-)
>
> diff --git a/drivers/gpu/drm/radeon/radeon_ttm.c b/drivers/gpu/drm/radeon/radeon_ttm.c
> index 5d50c9e..4770880 100644
> --- a/drivers/gpu/drm/radeon/radeon_ttm.c
> +++ b/drivers/gpu/drm/radeon/radeon_ttm.c
> @@ -481,7 +481,7 @@ static int radeon_ttm_tt_pin_userptr(struct ttm_tt *ttm)
>   {
>   	struct radeon_device *rdev = radeon_get_rdev(ttm->bdev);
>   	struct radeon_ttm_tt *gtt = (void *)ttm;
> -	unsigned pinned = 0, nents;
> +	unsigned pinned = 0;
>   	int r;
>   
>   	int write = !(gtt->userflags & RADEON_GEM_USERPTR_READONLY);
> @@ -522,8 +522,8 @@ static int radeon_ttm_tt_pin_userptr(struct ttm_tt *ttm)
>   		goto release_sg;
>   
>   	r = -ENOMEM;
> -	nents = dma_map_sg(rdev->dev, ttm->sg->sgl, ttm->sg->nents, direction);
> -	if (nents == 0)
> +	ttm->sg->nents = dma_map_sg(rdev->dev, ttm->sg->sgl,
> +	if (ttm->sg->nents == 0)
>   		goto release_sg;
>   
>   	drm_prime_sg_to_page_addr_arrays(ttm->sg, ttm->pages,
> @@ -554,9 +554,9 @@ static void radeon_ttm_tt_unpin_userptr(struct ttm_tt *ttm)
>   		return;
>   
>   	/* free the sg table and pages again */
> -	dma_unmap_sg(rdev->dev, ttm->sg->sgl, ttm->sg->nents, direction);
> +	dma_unmap_sg(rdev->dev, ttm->sg->sgl, ttm->sg->orig_nents, direction);
>   
> -	for_each_sg_page(ttm->sg->sgl, &sg_iter, ttm->sg->nents, 0) {
> +	for_each_sg_page(ttm->sg->sgl, &sg_iter, ttm->sg->orig_nents, 0) {
>   		struct page *page = sg_page_iter_page(&sg_iter);
>   		if (!(gtt->userflags & RADEON_GEM_USERPTR_READONLY))
>   			set_page_dirty(page);

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

^ permalink raw reply	[flat|nested] 152+ messages in thread

* Re: [RFC 00/17] DRM: fix struct sg_table nents vs. orig_nents misuse
  2020-04-28 14:02     ` Christoph Hellwig
                         ` (3 preceding siblings ...)
  (?)
@ 2020-04-28 15:32       ` Daniel Vetter
  -1 siblings, 0 replies; 152+ messages in thread
From: Daniel Vetter @ 2020-04-28 15:32 UTC (permalink / raw)
  To: Christoph Hellwig
  Cc: Marek Szyprowski, dri-devel, iommu, linaro-mm-sig, linux-kernel,
	Robin Murphy, Bartlomiej Zolnierkiewicz, Sumit Semwal,
	Benjamin Gaignard, intel-gfx, linux-arm-kernel, amd-gfx,
	David Airlie, Daniel Vetter

On Tue, Apr 28, 2020 at 04:02:57PM +0200, Christoph Hellwig wrote:
> On Tue, Apr 28, 2020 at 03:19:48PM +0200, Marek Szyprowski wrote:
> > 1. introduce a dma_{map,sync,unmap}_sgtable() wrappers, which will use
> >    a proper sg_table entries and call respective DMA-mapping functions
> >    and adapt current code to it
> 
> That sounds reasonable to me.  Those could be pretty trivial wrappers.
> 
> >
> > 
> > 2. rename nents and orig_nents to nr_pages, nr_dmas to clearly state
> >    which one refers to which part of the scatterlist; I'm open for
> >    other names for those entries
> 
> nr_cpu_ents and nr_dma_ents might be better names, but it still would be
> a whole lot of churn for little gain.  I think just good wrappers like
> suggested above might be more helpful.

I guess long-term we could aim for both? I.e. roll out better wrappers
first, once that's soaked through the tree, rename the last offenders.

Personally I like nr_cpu_ents and nr_dma_ents, that's about as clear as it
gets.
-Daniel
-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch

^ permalink raw reply	[flat|nested] 152+ messages in thread

* Re: [RFC 00/17] DRM: fix struct sg_table nents vs. orig_nents misuse
@ 2020-04-28 15:32       ` Daniel Vetter
  0 siblings, 0 replies; 152+ messages in thread
From: Daniel Vetter @ 2020-04-28 15:32 UTC (permalink / raw)
  To: Christoph Hellwig
  Cc: Daniel Vetter, Bartlomiej Zolnierkiewicz, David Airlie,
	intel-gfx, linux-kernel, dri-devel, linaro-mm-sig, iommu,
	amd-gfx, Benjamin Gaignard, Robin Murphy, Sumit Semwal,
	linux-arm-kernel

On Tue, Apr 28, 2020 at 04:02:57PM +0200, Christoph Hellwig wrote:
> On Tue, Apr 28, 2020 at 03:19:48PM +0200, Marek Szyprowski wrote:
> > 1. introduce a dma_{map,sync,unmap}_sgtable() wrappers, which will use
> >    a proper sg_table entries and call respective DMA-mapping functions
> >    and adapt current code to it
> 
> That sounds reasonable to me.  Those could be pretty trivial wrappers.
> 
> >
> > 
> > 2. rename nents and orig_nents to nr_pages, nr_dmas to clearly state
> >    which one refers to which part of the scatterlist; I'm open for
> >    other names for those entries
> 
> nr_cpu_ents and nr_dma_ents might be better names, but it still would be
> a whole lot of churn for little gain.  I think just good wrappers like
> suggested above might be more helpful.

I guess long-term we could aim for both? I.e. roll out better wrappers
first, once that's soaked through the tree, rename the last offenders.

Personally I like nr_cpu_ents and nr_dma_ents, that's about as clear as it
gets.
-Daniel
-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch
_______________________________________________
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu

^ permalink raw reply	[flat|nested] 152+ messages in thread

* Re: [RFC 00/17] DRM: fix struct sg_table nents vs. orig_nents misuse
@ 2020-04-28 15:32       ` Daniel Vetter
  0 siblings, 0 replies; 152+ messages in thread
From: Daniel Vetter @ 2020-04-28 15:32 UTC (permalink / raw)
  To: Christoph Hellwig
  Cc: Daniel Vetter, Bartlomiej Zolnierkiewicz, David Airlie,
	intel-gfx, linux-kernel, dri-devel, linaro-mm-sig, iommu,
	amd-gfx, Benjamin Gaignard, Robin Murphy, Sumit Semwal,
	linux-arm-kernel, Marek Szyprowski

On Tue, Apr 28, 2020 at 04:02:57PM +0200, Christoph Hellwig wrote:
> On Tue, Apr 28, 2020 at 03:19:48PM +0200, Marek Szyprowski wrote:
> > 1. introduce a dma_{map,sync,unmap}_sgtable() wrappers, which will use
> >    a proper sg_table entries and call respective DMA-mapping functions
> >    and adapt current code to it
> 
> That sounds reasonable to me.  Those could be pretty trivial wrappers.
> 
> >
> > 
> > 2. rename nents and orig_nents to nr_pages, nr_dmas to clearly state
> >    which one refers to which part of the scatterlist; I'm open for
> >    other names for those entries
> 
> nr_cpu_ents and nr_dma_ents might be better names, but it still would be
> a whole lot of churn for little gain.  I think just good wrappers like
> suggested above might be more helpful.

I guess long-term we could aim for both? I.e. roll out better wrappers
first, once that's soaked through the tree, rename the last offenders.

Personally I like nr_cpu_ents and nr_dma_ents, that's about as clear as it
gets.
-Daniel
-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch

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

^ permalink raw reply	[flat|nested] 152+ messages in thread

* Re: [RFC 00/17] DRM: fix struct sg_table nents vs. orig_nents misuse
@ 2020-04-28 15:32       ` Daniel Vetter
  0 siblings, 0 replies; 152+ messages in thread
From: Daniel Vetter @ 2020-04-28 15:32 UTC (permalink / raw)
  To: Christoph Hellwig
  Cc: Bartlomiej Zolnierkiewicz, David Airlie, intel-gfx, linux-kernel,
	dri-devel, linaro-mm-sig, iommu, amd-gfx, Robin Murphy,
	linux-arm-kernel, Marek Szyprowski

On Tue, Apr 28, 2020 at 04:02:57PM +0200, Christoph Hellwig wrote:
> On Tue, Apr 28, 2020 at 03:19:48PM +0200, Marek Szyprowski wrote:
> > 1. introduce a dma_{map,sync,unmap}_sgtable() wrappers, which will use
> >    a proper sg_table entries and call respective DMA-mapping functions
> >    and adapt current code to it
> 
> That sounds reasonable to me.  Those could be pretty trivial wrappers.
> 
> >
> > 
> > 2. rename nents and orig_nents to nr_pages, nr_dmas to clearly state
> >    which one refers to which part of the scatterlist; I'm open for
> >    other names for those entries
> 
> nr_cpu_ents and nr_dma_ents might be better names, but it still would be
> a whole lot of churn for little gain.  I think just good wrappers like
> suggested above might be more helpful.

I guess long-term we could aim for both? I.e. roll out better wrappers
first, once that's soaked through the tree, rename the last offenders.

Personally I like nr_cpu_ents and nr_dma_ents, that's about as clear as it
gets.
-Daniel
-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 152+ messages in thread

* Re: [Intel-gfx] [RFC 00/17] DRM: fix struct sg_table nents vs. orig_nents misuse
@ 2020-04-28 15:32       ` Daniel Vetter
  0 siblings, 0 replies; 152+ messages in thread
From: Daniel Vetter @ 2020-04-28 15:32 UTC (permalink / raw)
  To: Christoph Hellwig
  Cc: Bartlomiej Zolnierkiewicz, David Airlie, intel-gfx, linux-kernel,
	dri-devel, linaro-mm-sig, iommu, amd-gfx, Benjamin Gaignard,
	Robin Murphy, Sumit Semwal, linux-arm-kernel, Marek Szyprowski

On Tue, Apr 28, 2020 at 04:02:57PM +0200, Christoph Hellwig wrote:
> On Tue, Apr 28, 2020 at 03:19:48PM +0200, Marek Szyprowski wrote:
> > 1. introduce a dma_{map,sync,unmap}_sgtable() wrappers, which will use
> >    a proper sg_table entries and call respective DMA-mapping functions
> >    and adapt current code to it
> 
> That sounds reasonable to me.  Those could be pretty trivial wrappers.
> 
> >
> > 
> > 2. rename nents and orig_nents to nr_pages, nr_dmas to clearly state
> >    which one refers to which part of the scatterlist; I'm open for
> >    other names for those entries
> 
> nr_cpu_ents and nr_dma_ents might be better names, but it still would be
> a whole lot of churn for little gain.  I think just good wrappers like
> suggested above might be more helpful.

I guess long-term we could aim for both? I.e. roll out better wrappers
first, once that's soaked through the tree, rename the last offenders.

Personally I like nr_cpu_ents and nr_dma_ents, that's about as clear as it
gets.
-Daniel
-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 152+ messages in thread

* Re: [RFC 00/17] DRM: fix struct sg_table nents vs. orig_nents misuse
@ 2020-04-28 15:32       ` Daniel Vetter
  0 siblings, 0 replies; 152+ messages in thread
From: Daniel Vetter @ 2020-04-28 15:32 UTC (permalink / raw)
  To: Christoph Hellwig
  Cc: Daniel Vetter, Bartlomiej Zolnierkiewicz, David Airlie,
	intel-gfx, linux-kernel, dri-devel, linaro-mm-sig, iommu,
	amd-gfx, Benjamin Gaignard, Robin Murphy, Sumit Semwal,
	linux-arm-kernel, Marek Szyprowski

On Tue, Apr 28, 2020 at 04:02:57PM +0200, Christoph Hellwig wrote:
> On Tue, Apr 28, 2020 at 03:19:48PM +0200, Marek Szyprowski wrote:
> > 1. introduce a dma_{map,sync,unmap}_sgtable() wrappers, which will use
> >    a proper sg_table entries and call respective DMA-mapping functions
> >    and adapt current code to it
> 
> That sounds reasonable to me.  Those could be pretty trivial wrappers.
> 
> >
> > 
> > 2. rename nents and orig_nents to nr_pages, nr_dmas to clearly state
> >    which one refers to which part of the scatterlist; I'm open for
> >    other names for those entries
> 
> nr_cpu_ents and nr_dma_ents might be better names, but it still would be
> a whole lot of churn for little gain.  I think just good wrappers like
> suggested above might be more helpful.

I guess long-term we could aim for both? I.e. roll out better wrappers
first, once that's soaked through the tree, rename the last offenders.

Personally I like nr_cpu_ents and nr_dma_ents, that's about as clear as it
gets.
-Daniel
-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch
_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

^ permalink raw reply	[flat|nested] 152+ messages in thread

* Re: [RFC 00/17] DRM: fix struct sg_table nents vs. orig_nents misuse
  2020-04-28 15:32       ` Daniel Vetter
                           ` (3 preceding siblings ...)
  (?)
@ 2020-04-28 16:02         ` Robin Murphy
  -1 siblings, 0 replies; 152+ messages in thread
From: Robin Murphy @ 2020-04-28 16:02 UTC (permalink / raw)
  To: Christoph Hellwig, Marek Szyprowski, dri-devel, iommu,
	linaro-mm-sig, linux-kernel, Bartlomiej Zolnierkiewicz,
	Sumit Semwal, Benjamin Gaignard, intel-gfx, linux-arm-kernel,
	amd-gfx, David Airlie

On 2020-04-28 4:32 pm, Daniel Vetter wrote:
> On Tue, Apr 28, 2020 at 04:02:57PM +0200, Christoph Hellwig wrote:
>> On Tue, Apr 28, 2020 at 03:19:48PM +0200, Marek Szyprowski wrote:
>>> 1. introduce a dma_{map,sync,unmap}_sgtable() wrappers, which will use
>>>     a proper sg_table entries and call respective DMA-mapping functions
>>>     and adapt current code to it
>>
>> That sounds reasonable to me.  Those could be pretty trivial wrappers.
>>
>>>
>>>
>>> 2. rename nents and orig_nents to nr_pages, nr_dmas to clearly state
>>>     which one refers to which part of the scatterlist; I'm open for
>>>     other names for those entries
>>
>> nr_cpu_ents and nr_dma_ents might be better names, but it still would be
>> a whole lot of churn for little gain.  I think just good wrappers like
>> suggested above might be more helpful.
> 
> I guess long-term we could aim for both? I.e. roll out better wrappers
> first, once that's soaked through the tree, rename the last offenders.

Yes, that's what I was thinking too - most of these uses are just 
passing them in and out of the DMA APIs, and thus would be subsumed into 
the wrappers anyway, then in the relatively few remaining places where 
the table is actually iterated for one reason or the other, renaming 
would stand to help review and maintenance in terms of making it far 
more obvious when the implementation and the intent don't match.

Robin.

^ permalink raw reply	[flat|nested] 152+ messages in thread

* Re: [RFC 00/17] DRM: fix struct sg_table nents vs. orig_nents misuse
@ 2020-04-28 16:02         ` Robin Murphy
  0 siblings, 0 replies; 152+ messages in thread
From: Robin Murphy @ 2020-04-28 16:02 UTC (permalink / raw)
  To: Christoph Hellwig, Marek Szyprowski, dri-devel, iommu,
	linaro-mm-sig, linux-kernel, Bartlomiej Zolnierkiewicz,
	Sumit Semwal, Benjamin Gaignard, intel-gfx, linux-arm-kernel,
	amd-gfx, David Airlie

On 2020-04-28 4:32 pm, Daniel Vetter wrote:
> On Tue, Apr 28, 2020 at 04:02:57PM +0200, Christoph Hellwig wrote:
>> On Tue, Apr 28, 2020 at 03:19:48PM +0200, Marek Szyprowski wrote:
>>> 1. introduce a dma_{map,sync,unmap}_sgtable() wrappers, which will use
>>>     a proper sg_table entries and call respective DMA-mapping functions
>>>     and adapt current code to it
>>
>> That sounds reasonable to me.  Those could be pretty trivial wrappers.
>>
>>>
>>>
>>> 2. rename nents and orig_nents to nr_pages, nr_dmas to clearly state
>>>     which one refers to which part of the scatterlist; I'm open for
>>>     other names for those entries
>>
>> nr_cpu_ents and nr_dma_ents might be better names, but it still would be
>> a whole lot of churn for little gain.  I think just good wrappers like
>> suggested above might be more helpful.
> 
> I guess long-term we could aim for both? I.e. roll out better wrappers
> first, once that's soaked through the tree, rename the last offenders.

Yes, that's what I was thinking too - most of these uses are just 
passing them in and out of the DMA APIs, and thus would be subsumed into 
the wrappers anyway, then in the relatively few remaining places where 
the table is actually iterated for one reason or the other, renaming 
would stand to help review and maintenance in terms of making it far 
more obvious when the implementation and the intent don't match.

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

^ permalink raw reply	[flat|nested] 152+ messages in thread

* Re: [RFC 00/17] DRM: fix struct sg_table nents vs. orig_nents misuse
@ 2020-04-28 16:02         ` Robin Murphy
  0 siblings, 0 replies; 152+ messages in thread
From: Robin Murphy @ 2020-04-28 16:02 UTC (permalink / raw)
  To: Christoph Hellwig, Marek Szyprowski, dri-devel, iommu,
	linaro-mm-sig, linux-kernel, Bartlomiej Zolnierkiewicz,
	Sumit Semwal, Benjamin Gaignard, intel-gfx, linux-arm-kernel,
	amd-gfx, David Airlie

On 2020-04-28 4:32 pm, Daniel Vetter wrote:
> On Tue, Apr 28, 2020 at 04:02:57PM +0200, Christoph Hellwig wrote:
>> On Tue, Apr 28, 2020 at 03:19:48PM +0200, Marek Szyprowski wrote:
>>> 1. introduce a dma_{map,sync,unmap}_sgtable() wrappers, which will use
>>>     a proper sg_table entries and call respective DMA-mapping functions
>>>     and adapt current code to it
>>
>> That sounds reasonable to me.  Those could be pretty trivial wrappers.
>>
>>>
>>>
>>> 2. rename nents and orig_nents to nr_pages, nr_dmas to clearly state
>>>     which one refers to which part of the scatterlist; I'm open for
>>>     other names for those entries
>>
>> nr_cpu_ents and nr_dma_ents might be better names, but it still would be
>> a whole lot of churn for little gain.  I think just good wrappers like
>> suggested above might be more helpful.
> 
> I guess long-term we could aim for both? I.e. roll out better wrappers
> first, once that's soaked through the tree, rename the last offenders.

Yes, that's what I was thinking too - most of these uses are just 
passing them in and out of the DMA APIs, and thus would be subsumed into 
the wrappers anyway, then in the relatively few remaining places where 
the table is actually iterated for one reason or the other, renaming 
would stand to help review and maintenance in terms of making it far 
more obvious when the implementation and the intent don't match.

Robin.

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

^ permalink raw reply	[flat|nested] 152+ messages in thread

* Re: [RFC 00/17] DRM: fix struct sg_table nents vs. orig_nents misuse
@ 2020-04-28 16:02         ` Robin Murphy
  0 siblings, 0 replies; 152+ messages in thread
From: Robin Murphy @ 2020-04-28 16:02 UTC (permalink / raw)
  To: Christoph Hellwig, Marek Szyprowski, dri-devel, iommu,
	linaro-mm-sig, linux-kernel, Bartlomiej Zolnierkiewicz,
	Sumit Semwal, Benjamin Gaignard, intel-gfx, linux-arm-kernel,
	amd-gfx, David Airlie

On 2020-04-28 4:32 pm, Daniel Vetter wrote:
> On Tue, Apr 28, 2020 at 04:02:57PM +0200, Christoph Hellwig wrote:
>> On Tue, Apr 28, 2020 at 03:19:48PM +0200, Marek Szyprowski wrote:
>>> 1. introduce a dma_{map,sync,unmap}_sgtable() wrappers, which will use
>>>     a proper sg_table entries and call respective DMA-mapping functions
>>>     and adapt current code to it
>>
>> That sounds reasonable to me.  Those could be pretty trivial wrappers.
>>
>>>
>>>
>>> 2. rename nents and orig_nents to nr_pages, nr_dmas to clearly state
>>>     which one refers to which part of the scatterlist; I'm open for
>>>     other names for those entries
>>
>> nr_cpu_ents and nr_dma_ents might be better names, but it still would be
>> a whole lot of churn for little gain.  I think just good wrappers like
>> suggested above might be more helpful.
> 
> I guess long-term we could aim for both? I.e. roll out better wrappers
> first, once that's soaked through the tree, rename the last offenders.

Yes, that's what I was thinking too - most of these uses are just 
passing them in and out of the DMA APIs, and thus would be subsumed into 
the wrappers anyway, then in the relatively few remaining places where 
the table is actually iterated for one reason or the other, renaming 
would stand to help review and maintenance in terms of making it far 
more obvious when the implementation and the intent don't match.

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

^ permalink raw reply	[flat|nested] 152+ messages in thread

* Re: [Intel-gfx] [RFC 00/17] DRM: fix struct sg_table nents vs. orig_nents misuse
@ 2020-04-28 16:02         ` Robin Murphy
  0 siblings, 0 replies; 152+ messages in thread
From: Robin Murphy @ 2020-04-28 16:02 UTC (permalink / raw)
  To: Christoph Hellwig, Marek Szyprowski, dri-devel, iommu,
	linaro-mm-sig, linux-kernel, Bartlomiej Zolnierkiewicz,
	Sumit Semwal, Benjamin Gaignard, intel-gfx, linux-arm-kernel,
	amd-gfx, David Airlie

On 2020-04-28 4:32 pm, Daniel Vetter wrote:
> On Tue, Apr 28, 2020 at 04:02:57PM +0200, Christoph Hellwig wrote:
>> On Tue, Apr 28, 2020 at 03:19:48PM +0200, Marek Szyprowski wrote:
>>> 1. introduce a dma_{map,sync,unmap}_sgtable() wrappers, which will use
>>>     a proper sg_table entries and call respective DMA-mapping functions
>>>     and adapt current code to it
>>
>> That sounds reasonable to me.  Those could be pretty trivial wrappers.
>>
>>>
>>>
>>> 2. rename nents and orig_nents to nr_pages, nr_dmas to clearly state
>>>     which one refers to which part of the scatterlist; I'm open for
>>>     other names for those entries
>>
>> nr_cpu_ents and nr_dma_ents might be better names, but it still would be
>> a whole lot of churn for little gain.  I think just good wrappers like
>> suggested above might be more helpful.
> 
> I guess long-term we could aim for both? I.e. roll out better wrappers
> first, once that's soaked through the tree, rename the last offenders.

Yes, that's what I was thinking too - most of these uses are just 
passing them in and out of the DMA APIs, and thus would be subsumed into 
the wrappers anyway, then in the relatively few remaining places where 
the table is actually iterated for one reason or the other, renaming 
would stand to help review and maintenance in terms of making it far 
more obvious when the implementation and the intent don't match.

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

^ permalink raw reply	[flat|nested] 152+ messages in thread

* Re: [RFC 00/17] DRM: fix struct sg_table nents vs. orig_nents misuse
@ 2020-04-28 16:02         ` Robin Murphy
  0 siblings, 0 replies; 152+ messages in thread
From: Robin Murphy @ 2020-04-28 16:02 UTC (permalink / raw)
  To: Christoph Hellwig, Marek Szyprowski, dri-devel, iommu,
	linaro-mm-sig, linux-kernel, Bartlomiej Zolnierkiewicz,
	Sumit Semwal, Benjamin Gaignard, intel-gfx, linux-arm-kernel,
	amd-gfx, David Airlie

On 2020-04-28 4:32 pm, Daniel Vetter wrote:
> On Tue, Apr 28, 2020 at 04:02:57PM +0200, Christoph Hellwig wrote:
>> On Tue, Apr 28, 2020 at 03:19:48PM +0200, Marek Szyprowski wrote:
>>> 1. introduce a dma_{map,sync,unmap}_sgtable() wrappers, which will use
>>>     a proper sg_table entries and call respective DMA-mapping functions
>>>     and adapt current code to it
>>
>> That sounds reasonable to me.  Those could be pretty trivial wrappers.
>>
>>>
>>>
>>> 2. rename nents and orig_nents to nr_pages, nr_dmas to clearly state
>>>     which one refers to which part of the scatterlist; I'm open for
>>>     other names for those entries
>>
>> nr_cpu_ents and nr_dma_ents might be better names, but it still would be
>> a whole lot of churn for little gain.  I think just good wrappers like
>> suggested above might be more helpful.
> 
> I guess long-term we could aim for both? I.e. roll out better wrappers
> first, once that's soaked through the tree, rename the last offenders.

Yes, that's what I was thinking too - most of these uses are just 
passing them in and out of the DMA APIs, and thus would be subsumed into 
the wrappers anyway, then in the relatively few remaining places where 
the table is actually iterated for one reason or the other, renaming 
would stand to help review and maintenance in terms of making it far 
more obvious when the implementation and the intent don't match.

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

^ permalink raw reply	[flat|nested] 152+ messages in thread

* Re: [RFC 05/17] drm: exynos: fix sg_table nents vs. orig_nents misuse
  2020-04-28 13:19       ` Marek Szyprowski
                         ` (4 preceding siblings ...)
  (?)
@ 2020-04-28 21:59       ` kbuild test robot
  -1 siblings, 0 replies; 152+ messages in thread
From: kbuild test robot @ 2020-04-28 21:59 UTC (permalink / raw)
  To: kbuild-all

[-- Attachment #1: Type: text/plain, Size: 6186 bytes --]

Hi Marek,

[FYI, it's a private test report for your RFC patch.]
[auto build test ERROR on drm-exynos/exynos-drm-next]
[also build test ERROR on next-20200428]
[cannot apply to drm-intel/for-linux-next tegra-drm/drm/tegra/for-next linus/master v5.7-rc3]
[if your patch is applied to the wrong git tree, please drop us a note to help
improve the system. BTW, we also suggest to use '--base' option to specify the
base tree in git format-patch, please see https://stackoverflow.com/a/37406982]

url:    https://github.com/0day-ci/linux/commits/Marek-Szyprowski/DRM-fix-struct-sg_table-nents-vs-orig_nents-misuse/20200429-040352
base:   https://git.kernel.org/pub/scm/linux/kernel/git/daeinki/drm-exynos.git exynos-drm-next
config: m68k-allmodconfig (attached as .config)
compiler: m68k-linux-gcc (GCC) 9.3.0
reproduce:
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # save the attached .config to linux build tree
        COMPILER_INSTALL_PATH=$HOME/0day GCC_VERSION=9.3.0 make.cross ARCH=m68k 

If you fix the issue, kindly add following tag as appropriate
Reported-by: kbuild test robot <lkp@intel.com>

All errors (new ones prefixed by >>):

   drivers/gpu/drm/exynos/exynos_drm_g2d.c: In function 'g2d_userptr_get_dma_addr':
>> drivers/gpu/drm/exynos/exynos_drm_g2d.c:516:2: error: expected ';' before 'if'
     516 |  if (!sgt->nents) {
         |  ^~
   drivers/gpu/drm/exynos/exynos_drm_g2d.c:536:1: warning: label 'err_sg_free_table' defined but not used [-Wunused-label]
     536 | err_sg_free_table:
         | ^~~~~~~~~~~~~~~~~

vim +516 drivers/gpu/drm/exynos/exynos_drm_g2d.c

   418	
   419	static dma_addr_t *g2d_userptr_get_dma_addr(struct g2d_data *g2d,
   420						unsigned long userptr,
   421						unsigned long size,
   422						struct drm_file *filp,
   423						void **obj)
   424	{
   425		struct drm_exynos_file_private *file_priv = filp->driver_priv;
   426		struct g2d_cmdlist_userptr *g2d_userptr;
   427		struct sg_table	*sgt;
   428		unsigned long start, end;
   429		unsigned int npages, offset;
   430		int ret;
   431	
   432		if (!size) {
   433			DRM_DEV_ERROR(g2d->dev, "invalid userptr size.\n");
   434			return ERR_PTR(-EINVAL);
   435		}
   436	
   437		/* check if userptr already exists in userptr_list. */
   438		list_for_each_entry(g2d_userptr, &file_priv->userptr_list, list) {
   439			if (g2d_userptr->userptr == userptr) {
   440				/*
   441				 * also check size because there could be same address
   442				 * and different size.
   443				 */
   444				if (g2d_userptr->size == size) {
   445					atomic_inc(&g2d_userptr->refcount);
   446					*obj = g2d_userptr;
   447	
   448					return &g2d_userptr->dma_addr;
   449				}
   450	
   451				/*
   452				 * at this moment, maybe g2d dma is accessing this
   453				 * g2d_userptr memory region so just remove this
   454				 * g2d_userptr object from userptr_list not to be
   455				 * referred again and also except it the userptr
   456				 * pool to be released after the dma access completion.
   457				 */
   458				g2d_userptr->out_of_list = true;
   459				g2d_userptr->in_pool = false;
   460				list_del_init(&g2d_userptr->list);
   461	
   462				break;
   463			}
   464		}
   465	
   466		g2d_userptr = kzalloc(sizeof(*g2d_userptr), GFP_KERNEL);
   467		if (!g2d_userptr)
   468			return ERR_PTR(-ENOMEM);
   469	
   470		atomic_set(&g2d_userptr->refcount, 1);
   471		g2d_userptr->size = size;
   472	
   473		start = userptr & PAGE_MASK;
   474		offset = userptr & ~PAGE_MASK;
   475		end = PAGE_ALIGN(userptr + size);
   476		npages = (end - start) >> PAGE_SHIFT;
   477		g2d_userptr->vec = frame_vector_create(npages);
   478		if (!g2d_userptr->vec) {
   479			ret = -ENOMEM;
   480			goto err_free;
   481		}
   482	
   483		ret = get_vaddr_frames(start, npages, FOLL_FORCE | FOLL_WRITE,
   484			g2d_userptr->vec);
   485		if (ret != npages) {
   486			DRM_DEV_ERROR(g2d->dev,
   487				      "failed to get user pages from userptr.\n");
   488			if (ret < 0)
   489				goto err_destroy_framevec;
   490			ret = -EFAULT;
   491			goto err_put_framevec;
   492		}
   493		if (frame_vector_to_pages(g2d_userptr->vec) < 0) {
   494			ret = -EFAULT;
   495			goto err_put_framevec;
   496		}
   497	
   498		sgt = kzalloc(sizeof(*sgt), GFP_KERNEL);
   499		if (!sgt) {
   500			ret = -ENOMEM;
   501			goto err_put_framevec;
   502		}
   503	
   504		ret = sg_alloc_table_from_pages(sgt,
   505						frame_vector_pages(g2d_userptr->vec),
   506						npages, offset, size, GFP_KERNEL);
   507		if (ret < 0) {
   508			DRM_DEV_ERROR(g2d->dev, "failed to get sgt from pages.\n");
   509			goto err_free_sgt;
   510		}
   511	
   512		g2d_userptr->sgt = sgt;
   513	
   514		sgt->nents = dma_map_sg(to_dma_dev(g2d->drm_dev), sgt->sgl,
   515					sgt->orig_nents, DMA_BIDIRECTIONAL)
 > 516		if (!sgt->nents) {
   517			DRM_DEV_ERROR(g2d->dev, "failed to map sgt with dma region.\n");
   518			ret = -ENOMEM;
   519			goto err_sg_free_table;
   520		}
   521	
   522		g2d_userptr->dma_addr = sgt->sgl[0].dma_address;
   523		g2d_userptr->userptr = userptr;
   524	
   525		list_add_tail(&g2d_userptr->list, &file_priv->userptr_list);
   526	
   527		if (g2d->current_pool + (npages << PAGE_SHIFT) < g2d->max_pool) {
   528			g2d->current_pool += npages << PAGE_SHIFT;
   529			g2d_userptr->in_pool = true;
   530		}
   531	
   532		*obj = g2d_userptr;
   533	
   534		return &g2d_userptr->dma_addr;
   535	
   536	err_sg_free_table:
   537		sg_free_table(sgt);
   538	
   539	err_free_sgt:
   540		kfree(sgt);
   541	
   542	err_put_framevec:
   543		put_vaddr_frames(g2d_userptr->vec);
   544	
   545	err_destroy_framevec:
   546		frame_vector_destroy(g2d_userptr->vec);
   547	
   548	err_free:
   549		kfree(g2d_userptr);
   550	
   551		return ERR_PTR(ret);
   552	}
   553	

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all(a)lists.01.org

[-- Attachment #2: config.gz --]
[-- Type: application/gzip, Size: 53996 bytes --]

^ permalink raw reply	[flat|nested] 152+ messages in thread

* Re: [RFC 06/17] drm: i915: fix sg_table nents vs. orig_nents misuse
  2020-04-28 13:19       ` Marek Szyprowski
                         ` (5 preceding siblings ...)
  (?)
@ 2020-04-28 23:04       ` kbuild test robot
  -1 siblings, 0 replies; 152+ messages in thread
From: kbuild test robot @ 2020-04-28 23:04 UTC (permalink / raw)
  To: kbuild-all

[-- Attachment #1: Type: text/plain, Size: 2635 bytes --]

Hi Marek,

[FYI, it's a private test report for your RFC patch.]
[auto build test ERROR on drm-exynos/exynos-drm-next]
[also build test ERROR on next-20200428]
[cannot apply to drm-intel/for-linux-next tegra-drm/drm/tegra/for-next linus/master v5.7-rc3]
[if your patch is applied to the wrong git tree, please drop us a note to help
improve the system. BTW, we also suggest to use '--base' option to specify the
base tree in git format-patch, please see https://stackoverflow.com/a/37406982]

url:    https://github.com/0day-ci/linux/commits/Marek-Szyprowski/DRM-fix-struct-sg_table-nents-vs-orig_nents-misuse/20200429-040352
base:   https://git.kernel.org/pub/scm/linux/kernel/git/daeinki/drm-exynos.git exynos-drm-next
config: x86_64-defconfig (attached as .config)
compiler: gcc-7 (Ubuntu 7.5.0-6ubuntu2) 7.5.0
reproduce:
        # save the attached .config to linux build tree
        make ARCH=x86_64 

If you fix the issue, kindly add following tag as appropriate
Reported-by: kbuild test robot <lkp@intel.com>

All errors (new ones prefixed by >>):

   drivers/gpu/drm/i915/i915_gem_gtt.c: In function 'i915_gem_gtt_prepare_pages':
>> drivers/gpu/drm/i915/i915_gem_gtt.c:35:7: error: 'page' undeclared (first use in this function)
      if (page->nents)
          ^~~~
   drivers/gpu/drm/i915/i915_gem_gtt.c:35:7: note: each undeclared identifier is reported only once for each function it appears in

vim +/page +35 drivers/gpu/drm/i915/i915_gem_gtt.c

    26	
    27	int i915_gem_gtt_prepare_pages(struct drm_i915_gem_object *obj,
    28				       struct sg_table *pages)
    29	{
    30		do {
    31			pages->nents = dma_map_sg_attrs(&obj->base.dev->pdev->dev,
    32							pages->sgl, pages->orig_nents,
    33							PCI_DMA_BIDIRECTIONAL,
    34							DMA_ATTR_NO_WARN);
  > 35			if (page->nents)
    36				return 0;
    37	
    38			/*
    39			 * If the DMA remap fails, one cause can be that we have
    40			 * too many objects pinned in a small remapping table,
    41			 * such as swiotlb. Incrementally purge all other objects and
    42			 * try again - if there are no more pages to remove from
    43			 * the DMA remapper, i915_gem_shrink will return 0.
    44			 */
    45			GEM_BUG_ON(obj->mm.pages == pages);
    46		} while (i915_gem_shrink(to_i915(obj->base.dev),
    47					 obj->base.size >> PAGE_SHIFT, NULL,
    48					 I915_SHRINK_BOUND |
    49					 I915_SHRINK_UNBOUND));
    50	
    51		return -ENOSPC;
    52	}
    53	

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all(a)lists.01.org

[-- Attachment #2: config.gz --]
[-- Type: application/gzip, Size: 28978 bytes --]

^ permalink raw reply	[flat|nested] 152+ messages in thread

* Re: [RFC 06/17] drm: i915: fix sg_table nents vs. orig_nents misuse
  2020-04-28 13:19       ` Marek Szyprowski
                         ` (6 preceding siblings ...)
  (?)
@ 2020-04-29  3:21       ` kbuild test robot
  -1 siblings, 0 replies; 152+ messages in thread
From: kbuild test robot @ 2020-04-29  3:21 UTC (permalink / raw)
  To: kbuild-all

[-- Attachment #1: Type: text/plain, Size: 4383 bytes --]

Hi Marek,

[FYI, it's a private test report for your RFC patch.]
[auto build test WARNING on drm-exynos/exynos-drm-next]
[also build test WARNING on next-20200428]
[cannot apply to drm-intel/for-linux-next tegra-drm/drm/tegra/for-next linus/master v5.7-rc3]
[if your patch is applied to the wrong git tree, please drop us a note to help
improve the system. BTW, we also suggest to use '--base' option to specify the
base tree in git format-patch, please see https://stackoverflow.com/a/37406982]

url:    https://github.com/0day-ci/linux/commits/Marek-Szyprowski/DRM-fix-struct-sg_table-nents-vs-orig_nents-misuse/20200429-040352
base:   https://git.kernel.org/pub/scm/linux/kernel/git/daeinki/drm-exynos.git exynos-drm-next
config: x86_64-randconfig-g003-20200428 (attached as .config)
compiler: gcc-7 (Ubuntu 7.5.0-6ubuntu2) 7.5.0
reproduce:
        # save the attached .config to linux build tree
        make ARCH=x86_64 

If you fix the issue, kindly add following tag as appropriate
Reported-by: kbuild test robot <lkp@intel.com>

All warnings (new ones prefixed by >>):

   In file included from include/asm-generic/bug.h:5:0,
                    from arch/x86/include/asm/bug.h:83,
                    from include/linux/bug.h:5,
                    from include/linux/mmdebug.h:5,
                    from include/linux/gfp.h:5,
                    from include/linux/slab.h:15,
                    from drivers/gpu/drm/i915/i915_gem_gtt.c:7:
   drivers/gpu/drm/i915/i915_gem_gtt.c: In function 'i915_gem_gtt_prepare_pages':
   drivers/gpu/drm/i915/i915_gem_gtt.c:35:7: error: 'page' undeclared (first use in this function)
      if (page->nents)
          ^
   include/linux/compiler.h:58:52: note: in definition of macro '__trace_if_var'
    #define __trace_if_var(cond) (__builtin_constant_p(cond) ? (cond) : __trace_if_value(cond))
                                                       ^~~~
>> drivers/gpu/drm/i915/i915_gem_gtt.c:35:3: note: in expansion of macro 'if'
      if (page->nents)
      ^~
   drivers/gpu/drm/i915/i915_gem_gtt.c:35:7: note: each undeclared identifier is reported only once for each function it appears in
      if (page->nents)
          ^
   include/linux/compiler.h:58:52: note: in definition of macro '__trace_if_var'
    #define __trace_if_var(cond) (__builtin_constant_p(cond) ? (cond) : __trace_if_value(cond))
                                                       ^~~~
>> drivers/gpu/drm/i915/i915_gem_gtt.c:35:3: note: in expansion of macro 'if'
      if (page->nents)
      ^~

vim +/if +35 drivers/gpu/drm/i915/i915_gem_gtt.c

   > 7	#include <linux/slab.h> /* fault-inject.h is not standalone! */
     8	
     9	#include <linux/fault-inject.h>
    10	#include <linux/log2.h>
    11	#include <linux/random.h>
    12	#include <linux/seq_file.h>
    13	#include <linux/stop_machine.h>
    14	
    15	#include <asm/set_memory.h>
    16	#include <asm/smp.h>
    17	
    18	#include "display/intel_frontbuffer.h"
    19	#include "gt/intel_gt.h"
    20	#include "gt/intel_gt_requests.h"
    21	
    22	#include "i915_drv.h"
    23	#include "i915_scatterlist.h"
    24	#include "i915_trace.h"
    25	#include "i915_vgpu.h"
    26	
    27	int i915_gem_gtt_prepare_pages(struct drm_i915_gem_object *obj,
    28				       struct sg_table *pages)
    29	{
    30		do {
    31			pages->nents = dma_map_sg_attrs(&obj->base.dev->pdev->dev,
    32							pages->sgl, pages->orig_nents,
    33							PCI_DMA_BIDIRECTIONAL,
    34							DMA_ATTR_NO_WARN);
  > 35			if (page->nents)
    36				return 0;
    37	
    38			/*
    39			 * If the DMA remap fails, one cause can be that we have
    40			 * too many objects pinned in a small remapping table,
    41			 * such as swiotlb. Incrementally purge all other objects and
    42			 * try again - if there are no more pages to remove from
    43			 * the DMA remapper, i915_gem_shrink will return 0.
    44			 */
    45			GEM_BUG_ON(obj->mm.pages == pages);
    46		} while (i915_gem_shrink(to_i915(obj->base.dev),
    47					 obj->base.size >> PAGE_SHIFT, NULL,
    48					 I915_SHRINK_BOUND |
    49					 I915_SHRINK_UNBOUND));
    50	
    51		return -ENOSPC;
    52	}
    53	

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all(a)lists.01.org

[-- Attachment #2: config.gz --]
[-- Type: application/gzip, Size: 37022 bytes --]

^ permalink raw reply	[flat|nested] 152+ messages in thread

* Re: [Intel-gfx] [RFC 06/17] drm: i915: fix sg_table nents vs. orig_nents misuse
  2020-04-28 14:27         ` Tvrtko Ursulin
                             ` (3 preceding siblings ...)
  (?)
@ 2020-04-30 14:17           ` Marek Szyprowski
  -1 siblings, 0 replies; 152+ messages in thread
From: Marek Szyprowski @ 2020-04-30 14:17 UTC (permalink / raw)
  To: Tvrtko Ursulin, dri-devel, iommu, linaro-mm-sig, linux-kernel
  Cc: Bartlomiej Zolnierkiewicz, David Airlie, intel-gfx, amd-gfx,
	Christoph Hellwig, Benjamin Gaignard, Robin Murphy, Sumit Semwal,
	linux-arm-kernel

Hi

On 28.04.2020 16:27, Tvrtko Ursulin wrote:
>
> On 28/04/2020 14:19, Marek Szyprowski wrote:
>> 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;
>
> A bit higher up, not shown in the patch, we have allocated a table via 
> sg_alloc_table giving it a pessimistic max nents, sometimes much 
> larger than the st->nents this loops will create. But orig_nents has 
> been now been overwritten. Will that leak memory come sg_table_free?

Indeed this will leak memory. I'm missed that sg_trim() will adjust 
nents and orig_nents.

I will drop those changes as they are only a creative (or hacky) way of 
using sg_table and scatterlists.

> As minimum it will nerf our i915_sg_trim optimization a bit lower 
> down, also not shown in the diff.
>
> > [...]

Best regards
-- 
Marek Szyprowski, PhD
Samsung R&D Institute Poland


^ permalink raw reply	[flat|nested] 152+ messages in thread

* Re: [Intel-gfx] [RFC 06/17] drm: i915: fix sg_table nents vs. orig_nents misuse
@ 2020-04-30 14:17           ` Marek Szyprowski
  0 siblings, 0 replies; 152+ messages in thread
From: Marek Szyprowski @ 2020-04-30 14:17 UTC (permalink / raw)
  To: Tvrtko Ursulin, dri-devel, iommu, linaro-mm-sig, linux-kernel
  Cc: Bartlomiej Zolnierkiewicz, David Airlie, intel-gfx, amd-gfx,
	Sumit Semwal, Benjamin Gaignard, Robin Murphy, Christoph Hellwig,
	linux-arm-kernel

Hi

On 28.04.2020 16:27, Tvrtko Ursulin wrote:
>
> On 28/04/2020 14:19, Marek Szyprowski wrote:
>> 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;
>
> A bit higher up, not shown in the patch, we have allocated a table via 
> sg_alloc_table giving it a pessimistic max nents, sometimes much 
> larger than the st->nents this loops will create. But orig_nents has 
> been now been overwritten. Will that leak memory come sg_table_free?

Indeed this will leak memory. I'm missed that sg_trim() will adjust 
nents and orig_nents.

I will drop those changes as they are only a creative (or hacky) way of 
using sg_table and scatterlists.

> As minimum it will nerf our i915_sg_trim optimization a bit lower 
> down, also not shown in the diff.
>
> > [...]

Best regards
-- 
Marek Szyprowski, PhD
Samsung R&D Institute Poland

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

^ permalink raw reply	[flat|nested] 152+ messages in thread

* Re: [Intel-gfx] [RFC 06/17] drm: i915: fix sg_table nents vs. orig_nents misuse
@ 2020-04-30 14:17           ` Marek Szyprowski
  0 siblings, 0 replies; 152+ messages in thread
From: Marek Szyprowski @ 2020-04-30 14:17 UTC (permalink / raw)
  To: Tvrtko Ursulin, dri-devel, iommu, linaro-mm-sig, linux-kernel
  Cc: Bartlomiej Zolnierkiewicz, David Airlie, intel-gfx, amd-gfx,
	Sumit Semwal, Benjamin Gaignard, Robin Murphy, Christoph Hellwig,
	linux-arm-kernel

Hi

On 28.04.2020 16:27, Tvrtko Ursulin wrote:
>
> On 28/04/2020 14:19, Marek Szyprowski wrote:
>> 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;
>
> A bit higher up, not shown in the patch, we have allocated a table via 
> sg_alloc_table giving it a pessimistic max nents, sometimes much 
> larger than the st->nents this loops will create. But orig_nents has 
> been now been overwritten. Will that leak memory come sg_table_free?

Indeed this will leak memory. I'm missed that sg_trim() will adjust 
nents and orig_nents.

I will drop those changes as they are only a creative (or hacky) way of 
using sg_table and scatterlists.

> As minimum it will nerf our i915_sg_trim optimization a bit lower 
> down, also not shown in the diff.
>
> > [...]

Best regards
-- 
Marek Szyprowski, PhD
Samsung R&D Institute Poland


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

^ permalink raw reply	[flat|nested] 152+ messages in thread

* Re: [Intel-gfx] [RFC 06/17] drm: i915: fix sg_table nents vs. orig_nents misuse
@ 2020-04-30 14:17           ` Marek Szyprowski
  0 siblings, 0 replies; 152+ messages in thread
From: Marek Szyprowski @ 2020-04-30 14:17 UTC (permalink / raw)
  To: Tvrtko Ursulin, dri-devel, iommu, linaro-mm-sig, linux-kernel
  Cc: Bartlomiej Zolnierkiewicz, David Airlie, intel-gfx, amd-gfx,
	Robin Murphy, Christoph Hellwig, linux-arm-kernel

Hi

On 28.04.2020 16:27, Tvrtko Ursulin wrote:
>
> On 28/04/2020 14:19, Marek Szyprowski wrote:
>> 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;
>
> A bit higher up, not shown in the patch, we have allocated a table via 
> sg_alloc_table giving it a pessimistic max nents, sometimes much 
> larger than the st->nents this loops will create. But orig_nents has 
> been now been overwritten. Will that leak memory come sg_table_free?

Indeed this will leak memory. I'm missed that sg_trim() will adjust 
nents and orig_nents.

I will drop those changes as they are only a creative (or hacky) way of 
using sg_table and scatterlists.

> As minimum it will nerf our i915_sg_trim optimization a bit lower 
> down, also not shown in the diff.
>
> > [...]

Best regards
-- 
Marek Szyprowski, PhD
Samsung R&D Institute Poland

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

^ permalink raw reply	[flat|nested] 152+ messages in thread

* Re: [Intel-gfx] [RFC 06/17] drm: i915: fix sg_table nents vs. orig_nents misuse
@ 2020-04-30 14:17           ` Marek Szyprowski
  0 siblings, 0 replies; 152+ messages in thread
From: Marek Szyprowski @ 2020-04-30 14:17 UTC (permalink / raw)
  To: Tvrtko Ursulin, dri-devel, iommu, linaro-mm-sig, linux-kernel
  Cc: Bartlomiej Zolnierkiewicz, David Airlie, intel-gfx, amd-gfx,
	Sumit Semwal, Benjamin Gaignard, Robin Murphy, Christoph Hellwig,
	linux-arm-kernel

Hi

On 28.04.2020 16:27, Tvrtko Ursulin wrote:
>
> On 28/04/2020 14:19, Marek Szyprowski wrote:
>> 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;
>
> A bit higher up, not shown in the patch, we have allocated a table via 
> sg_alloc_table giving it a pessimistic max nents, sometimes much 
> larger than the st->nents this loops will create. But orig_nents has 
> been now been overwritten. Will that leak memory come sg_table_free?

Indeed this will leak memory. I'm missed that sg_trim() will adjust 
nents and orig_nents.

I will drop those changes as they are only a creative (or hacky) way of 
using sg_table and scatterlists.

> As minimum it will nerf our i915_sg_trim optimization a bit lower 
> down, also not shown in the diff.
>
> > [...]

Best regards
-- 
Marek Szyprowski, PhD
Samsung R&D Institute Poland

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

^ permalink raw reply	[flat|nested] 152+ messages in thread

* Re: [Intel-gfx] [RFC 06/17] drm: i915: fix sg_table nents vs. orig_nents misuse
@ 2020-04-30 14:17           ` Marek Szyprowski
  0 siblings, 0 replies; 152+ messages in thread
From: Marek Szyprowski @ 2020-04-30 14:17 UTC (permalink / raw)
  To: Tvrtko Ursulin, dri-devel, iommu, linaro-mm-sig, linux-kernel
  Cc: Bartlomiej Zolnierkiewicz, David Airlie, intel-gfx, amd-gfx,
	Sumit Semwal, Benjamin Gaignard, Robin Murphy, Christoph Hellwig,
	linux-arm-kernel

Hi

On 28.04.2020 16:27, Tvrtko Ursulin wrote:
>
> On 28/04/2020 14:19, Marek Szyprowski wrote:
>> 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;
>
> A bit higher up, not shown in the patch, we have allocated a table via 
> sg_alloc_table giving it a pessimistic max nents, sometimes much 
> larger than the st->nents this loops will create. But orig_nents has 
> been now been overwritten. Will that leak memory come sg_table_free?

Indeed this will leak memory. I'm missed that sg_trim() will adjust 
nents and orig_nents.

I will drop those changes as they are only a creative (or hacky) way of 
using sg_table and scatterlists.

> As minimum it will nerf our i915_sg_trim optimization a bit lower 
> down, also not shown in the diff.
>
> > [...]

Best regards
-- 
Marek Szyprowski, PhD
Samsung R&D Institute Poland

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

^ permalink raw reply	[flat|nested] 152+ messages in thread

end of thread, other threads:[~2020-04-30 14:18 UTC | newest]

Thread overview: 152+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
     [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     ` [RFC 06/17] drm: i915: " 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 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

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.