mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: Rob Clark <robin.clark@oss.qualcomm.com>
To: dri-devel@lists.freedesktop.org
Cc: linux-arm-msm@vger.kernel.org, freedreno@lists.freedesktop.org,
	Connor Abbott <cwabbott0@gmail.com>,
	Antonino Maniscalco <antomani103@gmail.com>,
	Danilo Krummrich <dakr@redhat.com>,
	Rob Clark <robdclark@chromium.org>,
	Rob Clark <robin.clark@oss.qualcomm.com>,
	Sean Paul <sean@poorly.run>,
	Konrad Dybcio <konradybcio@kernel.org>,
	Dmitry Baryshkov <lumag@kernel.org>,
	Abhinav Kumar <abhinav.kumar@linux.dev>,
	Jessica Zhang <jessica.zhang@oss.qualcomm.com>,
	Marijn Suijten <marijn.suijten@somainline.org>,
	David Airlie <airlied@gmail.com>, Simona Vetter <simona@ffwll.ch>,
	Maarten Lankhorst <maarten.lankhorst@linux.intel.com>,
	Maxime Ripard <mripard@kernel.org>,
	Thomas Zimmermann <tzimmermann@suse.de>,
	linux-kernel@vger.kernel.org (open list)
Subject: [PATCH v9 18/42] drm/msm: Add PRR support
Date: Sun, 29 Jun 2025 13:13:01 -0700	[thread overview]
Message-ID: <20250629201530.25775-19-robin.clark@oss.qualcomm.com> (raw)
In-Reply-To: <20250629201530.25775-1-robin.clark@oss.qualcomm.com>

From: Rob Clark <robdclark@chromium.org>

Add PRR (Partial Resident Region) is a bypass address which make GPU
writes go to /dev/null and reads return zero.  This is used to implement
vulkan sparse residency.

To support PRR/NULL mappings, we allocate a page to reserve a physical
address which we know will not be used as part of a GEM object, and
configure the SMMU to use this address for PRR/NULL mappings.

Signed-off-by: Rob Clark <robdclark@chromium.org>
Signed-off-by: Rob Clark <robin.clark@oss.qualcomm.com>
Tested-by: Antonino Maniscalco <antomani103@gmail.com>
Reviewed-by: Antonino Maniscalco <antomani103@gmail.com>
---
 drivers/gpu/drm/msm/adreno/adreno_gpu.c | 10 ++++
 drivers/gpu/drm/msm/msm_iommu.c         | 62 ++++++++++++++++++++++++-
 include/uapi/drm/msm_drm.h              |  2 +
 3 files changed, 73 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/msm/adreno/adreno_gpu.c b/drivers/gpu/drm/msm/adreno/adreno_gpu.c
index 676fc078d545..12bf39c0516c 100644
--- a/drivers/gpu/drm/msm/adreno/adreno_gpu.c
+++ b/drivers/gpu/drm/msm/adreno/adreno_gpu.c
@@ -357,6 +357,13 @@ int adreno_fault_handler(struct msm_gpu *gpu, unsigned long iova, int flags,
 	return 0;
 }
 
+static bool
+adreno_smmu_has_prr(struct msm_gpu *gpu)
+{
+	struct adreno_smmu_priv *adreno_smmu = dev_get_drvdata(&gpu->pdev->dev);
+	return adreno_smmu && adreno_smmu->set_prr_addr;
+}
+
 int adreno_get_param(struct msm_gpu *gpu, struct msm_context *ctx,
 		     uint32_t param, uint64_t *value, uint32_t *len)
 {
@@ -440,6 +447,9 @@ int adreno_get_param(struct msm_gpu *gpu, struct msm_context *ctx,
 	case MSM_PARAM_UCHE_TRAP_BASE:
 		*value = adreno_gpu->uche_trap_base;
 		return 0;
+	case MSM_PARAM_HAS_PRR:
+		*value = adreno_smmu_has_prr(gpu);
+		return 0;
 	default:
 		return UERR(EINVAL, drm, "%s: invalid param: %u", gpu->name, param);
 	}
diff --git a/drivers/gpu/drm/msm/msm_iommu.c b/drivers/gpu/drm/msm/msm_iommu.c
index 3c2eb59bfd49..a0c74ecdb11b 100644
--- a/drivers/gpu/drm/msm/msm_iommu.c
+++ b/drivers/gpu/drm/msm/msm_iommu.c
@@ -13,6 +13,7 @@ struct msm_iommu {
 	struct msm_mmu base;
 	struct iommu_domain *domain;
 	atomic_t pagetables;
+	struct page *prr_page;
 };
 
 #define to_msm_iommu(x) container_of(x, struct msm_iommu, base)
@@ -112,6 +113,36 @@ static int msm_iommu_pagetable_unmap(struct msm_mmu *mmu, u64 iova,
 	return (size == 0) ? 0 : -EINVAL;
 }
 
+static int msm_iommu_pagetable_map_prr(struct msm_mmu *mmu, u64 iova, size_t len, int prot)
+{
+	struct msm_iommu_pagetable *pagetable = to_pagetable(mmu);
+	struct io_pgtable_ops *ops = pagetable->pgtbl_ops;
+	struct msm_iommu *iommu = to_msm_iommu(pagetable->parent);
+	phys_addr_t phys = page_to_phys(iommu->prr_page);
+	u64 addr = iova;
+
+	while (len) {
+		size_t mapped = 0;
+		size_t size = PAGE_SIZE;
+		int ret;
+
+		ret = ops->map_pages(ops, addr, phys, size, 1, prot, GFP_KERNEL, &mapped);
+
+		/* map_pages could fail after mapping some of the pages,
+		 * so update the counters before error handling.
+		 */
+		addr += mapped;
+		len  -= mapped;
+
+		if (ret) {
+			msm_iommu_pagetable_unmap(mmu, iova, addr - iova);
+			return -EINVAL;
+		}
+	}
+
+	return 0;
+}
+
 static int msm_iommu_pagetable_map(struct msm_mmu *mmu, u64 iova,
 				   struct sg_table *sgt, size_t off, size_t len,
 				   int prot)
@@ -122,6 +153,9 @@ static int msm_iommu_pagetable_map(struct msm_mmu *mmu, u64 iova,
 	u64 addr = iova;
 	unsigned int i;
 
+	if (!sgt)
+		return msm_iommu_pagetable_map_prr(mmu, iova, len, prot);
+
 	for_each_sgtable_sg(sgt, sg, i) {
 		size_t size = sg->length;
 		phys_addr_t phys = sg_phys(sg);
@@ -177,9 +211,16 @@ static void msm_iommu_pagetable_destroy(struct msm_mmu *mmu)
 	 * If this is the last attached pagetable for the parent,
 	 * disable TTBR0 in the arm-smmu driver
 	 */
-	if (atomic_dec_return(&iommu->pagetables) == 0)
+	if (atomic_dec_return(&iommu->pagetables) == 0) {
 		adreno_smmu->set_ttbr0_cfg(adreno_smmu->cookie, NULL);
 
+		if (adreno_smmu->set_prr_bit) {
+			adreno_smmu->set_prr_bit(adreno_smmu->cookie, false);
+			__free_page(iommu->prr_page);
+			iommu->prr_page = NULL;
+		}
+	}
+
 	free_io_pgtable_ops(pagetable->pgtbl_ops);
 	kfree(pagetable);
 }
@@ -336,6 +377,25 @@ struct msm_mmu *msm_iommu_pagetable_create(struct msm_mmu *parent)
 			kfree(pagetable);
 			return ERR_PTR(ret);
 		}
+
+		BUG_ON(iommu->prr_page);
+		if (adreno_smmu->set_prr_bit) {
+			/*
+			 * We need a zero'd page for two reasons:
+			 *
+			 * 1) Reserve a known physical address to use when
+			 *    mapping NULL / sparsely resident regions
+			 * 2) Read back zero
+			 *
+			 * It appears the hw drops writes to the PRR region
+			 * on the floor, but reads actually return whatever
+			 * is in the PRR page.
+			 */
+			iommu->prr_page = alloc_page(GFP_KERNEL | __GFP_ZERO);
+			adreno_smmu->set_prr_addr(adreno_smmu->cookie,
+						  page_to_phys(iommu->prr_page));
+			adreno_smmu->set_prr_bit(adreno_smmu->cookie, true);
+		}
 	}
 
 	/* Needed later for TLB flush */
diff --git a/include/uapi/drm/msm_drm.h b/include/uapi/drm/msm_drm.h
index 2342cb90857e..5bc5e4526ccf 100644
--- a/include/uapi/drm/msm_drm.h
+++ b/include/uapi/drm/msm_drm.h
@@ -91,6 +91,8 @@ struct drm_msm_timespec {
 #define MSM_PARAM_UBWC_SWIZZLE 0x12 /* RO */
 #define MSM_PARAM_MACROTILE_MODE 0x13 /* RO */
 #define MSM_PARAM_UCHE_TRAP_BASE 0x14 /* RO */
+/* PRR (Partially Resident Region) is required for sparse residency: */
+#define MSM_PARAM_HAS_PRR    0x15  /* RO */
 
 /* For backwards compat.  The original support for preemption was based on
  * a single ring per priority level so # of priority levels equals the #
-- 
2.50.0


  parent reply	other threads:[~2025-06-29 20:16 UTC|newest]

Thread overview: 45+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-06-29 20:12 [PATCH v9 00/42] drm/msm: sparse / "VM_BIND" support Rob Clark
2025-06-29 20:12 ` [PATCH v9 01/42] drm/gpuvm: Fix doc comments Rob Clark
2025-06-29 20:12 ` [PATCH v9 02/42] drm/gpuvm: Add locking helpers Rob Clark
2025-06-29 20:12 ` [PATCH v9 03/42] drm/gem: Add ww_acquire_ctx support to drm_gem_lru_scan() Rob Clark
2025-06-29 20:12 ` [PATCH v9 04/42] drm/msm: Rename msm_file_private -> msm_context Rob Clark
2025-06-29 20:12 ` [PATCH v9 05/42] drm/msm: Improve msm_context comments Rob Clark
2025-06-29 20:12 ` [PATCH v9 06/42] drm/msm: Rename msm_gem_address_space -> msm_gem_vm Rob Clark
2025-06-29 20:12 ` [PATCH v9 07/42] drm/msm: Remove vram carveout support Rob Clark
2025-06-29 20:12 ` [PATCH v9 08/42] drm/msm: Collapse vma allocation and initialization Rob Clark
2025-06-29 20:12 ` [PATCH v9 09/42] drm/msm: Collapse vma close and delete Rob Clark
2025-06-29 20:12 ` [PATCH v9 10/42] drm/msm: Don't close VMAs on purge Rob Clark
2025-06-29 20:12 ` [PATCH v9 11/42] drm/msm: Stop passing vm to msm_framebuffer Rob Clark
2025-06-29 20:12 ` [PATCH v9 12/42] drm/msm: Refcount framebuffer pins Rob Clark
2025-06-29 20:12 ` [PATCH v9 13/42] drm/msm: drm_gpuvm conversion Rob Clark
2025-06-29 20:12 ` [PATCH v9 14/42] drm/msm: Convert vm locking Rob Clark
2025-08-12  8:58   ` Danilo Krummrich
2025-08-13  1:52     ` Rob Clark
2025-06-29 20:12 ` [PATCH v9 15/42] drm/msm: Use drm_gpuvm types more Rob Clark
2025-06-29 20:12 ` [PATCH v9 16/42] drm/msm: Split out helper to get iommu prot flags Rob Clark
2025-06-29 20:13 ` [PATCH v9 17/42] drm/msm: Add mmu support for non-zero offset Rob Clark
2025-06-29 20:13 ` Rob Clark [this message]
2025-06-29 20:13 ` [PATCH v9 19/42] drm/msm: Rename msm_gem_vma_purge() -> _unmap() Rob Clark
2025-06-29 20:13 ` [PATCH v9 20/42] drm/msm: Drop queued submits on lastclose() Rob Clark
2025-06-29 20:13 ` [PATCH v9 21/42] drm/msm: Lazily create context VM Rob Clark
2025-06-29 20:13 ` [PATCH v9 22/42] drm/msm: Add opt-in for VM_BIND Rob Clark
2025-06-29 20:13 ` [PATCH v9 23/42] drm/msm: Mark VM as unusable on GPU hangs Rob Clark
2025-06-29 20:13 ` [PATCH v9 24/42] drm/msm: Add _NO_SHARE flag Rob Clark
2025-06-29 20:13 ` [PATCH v9 25/42] drm/msm: Crashdump prep for sparse mappings Rob Clark
2025-06-29 20:13 ` [PATCH v9 26/42] drm/msm: rd dumping " Rob Clark
2025-06-29 20:13 ` [PATCH v9 27/42] drm/msm: Crashdump support for sparse Rob Clark
2025-06-29 20:13 ` [PATCH v9 28/42] drm/msm: rd dumping " Rob Clark
2025-06-29 20:13 ` [PATCH v9 29/42] drm/msm: Extract out syncobj helpers Rob Clark
2025-06-29 20:13 ` [PATCH v9 30/42] drm/msm: Use DMA_RESV_USAGE_BOOKKEEP/KERNEL Rob Clark
2025-06-29 20:13 ` [PATCH v9 31/42] drm/msm: Add VM_BIND submitqueue Rob Clark
2025-06-29 20:13 ` [PATCH v9 32/42] drm/msm: Support IO_PGTABLE_QUIRK_NO_WARN_ON Rob Clark
2025-06-29 20:13 ` [PATCH v9 33/42] drm/msm: Support pgtable preallocation Rob Clark
2025-06-29 20:13 ` [PATCH v9 34/42] drm/msm: Split out map/unmap ops Rob Clark
2025-06-29 20:13 ` [PATCH v9 35/42] drm/msm: Add VM_BIND ioctl Rob Clark
2025-06-29 20:13 ` [PATCH v9 36/42] drm/msm: Add VM logging for VM_BIND updates Rob Clark
2025-06-29 20:13 ` [PATCH v9 37/42] drm/msm: Add VMA unmap reason Rob Clark
2025-06-29 20:13 ` [PATCH v9 38/42] drm/msm: Add mmu prealloc tracepoint Rob Clark
2025-06-29 20:13 ` [PATCH v9 39/42] drm/msm: use trylock for debugfs Rob Clark
2025-06-29 20:13 ` [PATCH v9 40/42] drm/msm: Bump UAPI version Rob Clark
2025-06-29 20:13 ` [PATCH v9 41/42] drm/msm: Defer VMA unmap for fb unpins Rob Clark
2025-06-29 20:13 ` [PATCH v9 42/42] drm/msm: Add VM_BIND throttling Rob Clark

Reply instructions:

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

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

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

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

  git send-email \
    --in-reply-to=20250629201530.25775-19-robin.clark@oss.qualcomm.com \
    --to=robin.clark@oss.qualcomm.com \
    --cc=abhinav.kumar@linux.dev \
    --cc=airlied@gmail.com \
    --cc=antomani103@gmail.com \
    --cc=cwabbott0@gmail.com \
    --cc=dakr@redhat.com \
    --cc=dri-devel@lists.freedesktop.org \
    --cc=freedreno@lists.freedesktop.org \
    --cc=jessica.zhang@oss.qualcomm.com \
    --cc=konradybcio@kernel.org \
    --cc=linux-arm-msm@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=lumag@kernel.org \
    --cc=maarten.lankhorst@linux.intel.com \
    --cc=marijn.suijten@somainline.org \
    --cc=mripard@kernel.org \
    --cc=robdclark@chromium.org \
    --cc=sean@poorly.run \
    --cc=simona@ffwll.ch \
    --cc=tzimmermann@suse.de \
    /path/to/YOUR_REPLY

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

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

all inboxes | Powered by JetHome®