From nobody Tue Oct 7 18:26:05 2025 Received: from bali.collaboradmins.com (bali.collaboradmins.com [148.251.105.195]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 1DEF022A4D5 for ; Mon, 7 Jul 2025 17:04:59 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=148.251.105.195 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1751907903; cv=none; b=jELO0dyWWLfgiaux97TGg7lwkXtDcmXSnS48BZqbQUHsCGz5gq5Zat19N4ouQkocya2FgUp39xSByw0X5XPuctveePYFyPegeAiXtzfRO01a4zUxEyErG3nhLU/Hurd3U5jgOuzu2u6wsCAYee3rAW6SC27xt3BCDaglbcsNH88= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1751907903; c=relaxed/simple; bh=FOaQz9yaCvy1/2Vwv0qrZqa1ge0RIimLRi6ujZFVbh0=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=bU6h+TZ922GE0GQISikJ/+P6su9S1mFmDFS/ng7qzL18KPtrn+7ZlpBq2/uba35xtxlvPhxcAQYssT3DZ34HW0Tp219beTAfd9WIBm8z5laAF+8VD3HmjgJlzQbYOl6no8dvvwpiS0/TjH/HQYJr9pzN1bytDkRc1MdMDrb7F3c= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=collabora.com; spf=pass smtp.mailfrom=collabora.com; dkim=pass (2048-bit key) header.d=collabora.com header.i=@collabora.com header.b=cvCUG8ND; arc=none smtp.client-ip=148.251.105.195 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=collabora.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=collabora.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=collabora.com header.i=@collabora.com header.b="cvCUG8ND" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=collabora.com; s=mail; t=1751907898; bh=FOaQz9yaCvy1/2Vwv0qrZqa1ge0RIimLRi6ujZFVbh0=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=cvCUG8NDdhfUrzy4R+HKnEle9E6kC6N9rw5zxQ9ozeSl6ZQeqCVLMfVSRPHRuAg4z wnhuMvLbjUBklwtZ8XYxS00uub1IAGW3D6Dv5aGwCeH/Fv7kbY3KjVHH9h4dT6NqV6 vyXtb+h6fl5mse3+CYqfGBLfek963gyPamVid0zcddqnElQXQLRGmIgeM+aOjLft+6 HSUJXwLFiSVhJGHmER0dF+tFLgDOnpT+LkeBygmpAhd3GbRICzYqeZDyrCuylFsY/r 5xHkyudNoHO6kGajUSFcWqxTrDK65cEvpxWlKCBy7/GpX0x2H+0cdqmEnFWBOr8TLQ qkDqkuikdSzuA== Received: from debian-rockchip-rock5b-rk3588.. (unknown [90.168.160.154]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) (Authenticated sender: nanokatze) by bali.collaboradmins.com (Postfix) with ESMTPSA id E70F717E04EE; Mon, 7 Jul 2025 19:04:56 +0200 (CEST) From: Caterina Shablia To: "Maarten Lankhorst" , "Maxime Ripard" , "Thomas Zimmermann" , "David Airlie" , "Simona Vetter" , "Frank Binns" , "Matt Coster" , "Karol Herbst" , "Lyude Paul" , "Danilo Krummrich" , "Boris Brezillon" , "Steven Price" , "Liviu Dudau" , "Lucas De Marchi" , =?UTF-8?q?Thomas=20Hellstr=C3=B6m?= , "Rodrigo Vivi" Cc: dri-devel@lists.freedesktop.org, linux-kernel@vger.kernel.org, nouveau@lists.freedesktop.org, intel-xe@lists.freedesktop.org, asahi@lists.linux.dev, Asahi Lina , Caterina Shablia Subject: [PATCH v4 1/7] drm/panthor: Add support for atomic page table updates Date: Mon, 7 Jul 2025 17:04:27 +0000 Message-ID: <20250707170442.1437009-2-caterina.shablia@collabora.com> X-Mailer: git-send-email 2.47.2 In-Reply-To: <20250707170442.1437009-1-caterina.shablia@collabora.com> References: <20250707170442.1437009-1-caterina.shablia@collabora.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Boris Brezillon Move the lock/flush_mem operations around the gpuvm_sm_map() calls so we can implement true atomic page updates, where any access in the locked range done by the GPU has to wait for the page table updates to land before proceeding. This is needed for vkQueueBindSparse(), so we can replace the dummy page mapped over the entire object by actual BO backed pages in an atomic way. Signed-off-by: Boris Brezillon Signed-off-by: Caterina Shablia --- drivers/gpu/drm/panthor/panthor_mmu.c | 65 +++++++++++++++++++++++++-- 1 file changed, 62 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/panthor/panthor_mmu.c b/drivers/gpu/drm/pantho= r/panthor_mmu.c index b39ea6acc6a9..9caaba03c5eb 100644 --- a/drivers/gpu/drm/panthor/panthor_mmu.c +++ b/drivers/gpu/drm/panthor/panthor_mmu.c @@ -387,6 +387,15 @@ struct panthor_vm { * flagged as faulty as a result. */ bool unhandled_fault; + + /** @locked_region: Information about the currently locked region current= ly. */ + struct { + /** @locked_region.start: Start of the locked region. */ + u64 start; + + /** @locked_region.size: Size of the locked region. */ + u64 size; + } locked_region; }; =20 /** @@ -775,6 +784,10 @@ int panthor_vm_active(struct panthor_vm *vm) } =20 ret =3D panthor_mmu_as_enable(vm->ptdev, vm->as.id, transtab, transcfg, v= m->memattr); + if (!ret && vm->locked_region.size) { + lock_region(ptdev, vm->as.id, vm->locked_region.start, vm->locked_region= .size); + ret =3D wait_ready(ptdev, vm->as.id); + } =20 out_make_active: if (!ret) { @@ -902,6 +915,9 @@ static int panthor_vm_unmap_pages(struct panthor_vm *vm= , u64 iova, u64 size) struct io_pgtable_ops *ops =3D vm->pgtbl_ops; u64 offset =3D 0; =20 + drm_WARN_ON(&ptdev->base, + (iova < vm->locked_region.start) || + (iova + size > vm->locked_region.start + vm->locked_region.size)); drm_dbg(&ptdev->base, "unmap: as=3D%d, iova=3D%llx, len=3D%llx", vm->as.i= d, iova, size); =20 while (offset < size) { @@ -915,13 +931,12 @@ static int panthor_vm_unmap_pages(struct panthor_vm *= vm, u64 iova, u64 size) iova + offset + unmapped_sz, iova + offset + pgsize * pgcount, iova, iova + size); - panthor_vm_flush_range(vm, iova, offset + unmapped_sz); return -EINVAL; } offset +=3D unmapped_sz; } =20 - return panthor_vm_flush_range(vm, iova, size); + return 0; } =20 static int @@ -938,6 +953,10 @@ panthor_vm_map_pages(struct panthor_vm *vm, u64 iova, = int prot, if (!size) return 0; =20 + drm_WARN_ON(&ptdev->base, + (iova < vm->locked_region.start) || + (iova + size > vm->locked_region.start + vm->locked_region.size)); + for_each_sgtable_dma_sg(sgt, sgl, count) { dma_addr_t paddr =3D sg_dma_address(sgl); size_t len =3D sg_dma_len(sgl); @@ -985,7 +1004,7 @@ panthor_vm_map_pages(struct panthor_vm *vm, u64 iova, = int prot, offset =3D 0; } =20 - return panthor_vm_flush_range(vm, start_iova, iova - start_iova); + return 0; } =20 static int flags_to_prot(u32 flags) @@ -1654,6 +1673,38 @@ static const char *access_type_name(struct panthor_d= evice *ptdev, } } =20 +static int panthor_vm_lock_region(struct panthor_vm *vm, u64 start, u64 si= ze) +{ + struct panthor_device *ptdev =3D vm->ptdev; + int ret =3D 0; + + mutex_lock(&ptdev->mmu->as.slots_lock); + drm_WARN_ON(&ptdev->base, vm->locked_region.start || vm->locked_region.si= ze); + vm->locked_region.start =3D start; + vm->locked_region.size =3D size; + if (vm->as.id >=3D 0) { + lock_region(ptdev, vm->as.id, start, size); + ret =3D wait_ready(ptdev, vm->as.id); + } + mutex_unlock(&ptdev->mmu->as.slots_lock); + + return ret; +} + +static void panthor_vm_unlock_region(struct panthor_vm *vm) +{ + struct panthor_device *ptdev =3D vm->ptdev; + + mutex_lock(&ptdev->mmu->as.slots_lock); + if (vm->as.id >=3D 0) { + write_cmd(ptdev, vm->as.id, AS_COMMAND_FLUSH_MEM); + drm_WARN_ON(&ptdev->base, wait_ready(ptdev, vm->as.id)); + } + vm->locked_region.start =3D 0; + vm->locked_region.size =3D 0; + mutex_unlock(&ptdev->mmu->as.slots_lock); +} + static void panthor_mmu_irq_handler(struct panthor_device *ptdev, u32 stat= us) { bool has_unhandled_faults =3D false; @@ -2179,6 +2230,11 @@ panthor_vm_exec_op(struct panthor_vm *vm, struct pan= thor_vm_op_ctx *op, =20 mutex_lock(&vm->op_lock); vm->op_ctx =3D op; + + ret =3D panthor_vm_lock_region(vm, op->va.addr, op->va.range); + if (ret) + goto out; + switch (op_type) { case DRM_PANTHOR_VM_BIND_OP_TYPE_MAP: if (vm->unusable) { @@ -2199,6 +2255,9 @@ panthor_vm_exec_op(struct panthor_vm *vm, struct pant= hor_vm_op_ctx *op, break; } =20 + panthor_vm_unlock_region(vm); + +out: if (ret && flag_vm_unusable_on_failure) vm->unusable =3D true; =20 --=20 2.47.2 From nobody Tue Oct 7 18:26:05 2025 Received: from bali.collaboradmins.com (bali.collaboradmins.com [148.251.105.195]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 1A53A2E7F30 for ; Mon, 7 Jul 2025 17:05:01 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=148.251.105.195 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1751907903; cv=none; b=dHsNRb0IBwfjOkroP331lrgUwdIe5kRbL6mwr5VYcwxSnU1q5Jxs6kKQfTEqG8eZOLEKoB88Q9aJSbFj0BSqAINmER89XKTpszSHTFhQYZTbRFzKmGV2AXftX9bNp3EvOmvdcMF5oq6zWTFFsDanKAuAEawSIoVTellHzUCjl1U= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1751907903; c=relaxed/simple; bh=tFEfKWU89/mON7YzWM3EMlN8oEIpH8lGXHI+RwQ0Q3c=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=GFunltaRD/QGxAq/Y/52EZo3XS73+n7LEVutAPlTXZqWky3KcPiajlKFTdxrG7mpyWBk8QKeLkmKFlHnzM8NCaVliH5XPlhDJD7mUYRylUF92p4KOILABloP9pXHdF1L7NpIZVug/WNN2mas5W8nfQ+EXMI2x4IpMYKUzjVK4T8= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=collabora.com; spf=pass smtp.mailfrom=collabora.com; dkim=pass (2048-bit key) header.d=collabora.com header.i=@collabora.com header.b=n7n70BCD; arc=none smtp.client-ip=148.251.105.195 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=collabora.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=collabora.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=collabora.com header.i=@collabora.com header.b="n7n70BCD" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=collabora.com; s=mail; t=1751907900; bh=tFEfKWU89/mON7YzWM3EMlN8oEIpH8lGXHI+RwQ0Q3c=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=n7n70BCDxisniIGY2xV5BT0kJwI6+FT9EYhUlSlrgwWBtC14ct6tP5zLmJ2pGqQAp PsoAlGjij8YQHwQBRFZ90jt7lvchD7LnDSfm59S4cPjVBmfoJNJkQLTgs25FyT/Pyk 1PmDx6WgIEFUNnJqZIk3OwiJRp0DRHQJEZBM6MP90sAjgfQusLMvo7eCwAFlYV7KVD SllOFwjc782HARnVigbOjVN18UrK9Um60z3UMgpzd637TO8CstAiED0l2yer8NO0tN 9gJh4BCblu4SQKGRehX7jnN//hJSjizp81wq6qoOFQjOqM6jeibzVHN/rNfXjNA7rk lSUC+PzoFC9FQ== Received: from debian-rockchip-rock5b-rk3588.. (unknown [90.168.160.154]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) (Authenticated sender: nanokatze) by bali.collaboradmins.com (Postfix) with ESMTPSA id 2E46F17E1083; Mon, 7 Jul 2025 19:04:59 +0200 (CEST) From: Caterina Shablia To: "Maarten Lankhorst" , "Maxime Ripard" , "Thomas Zimmermann" , "David Airlie" , "Simona Vetter" , "Frank Binns" , "Matt Coster" , "Karol Herbst" , "Lyude Paul" , "Danilo Krummrich" , "Boris Brezillon" , "Steven Price" , "Liviu Dudau" , "Lucas De Marchi" , =?UTF-8?q?Thomas=20Hellstr=C3=B6m?= , "Rodrigo Vivi" Cc: dri-devel@lists.freedesktop.org, linux-kernel@vger.kernel.org, nouveau@lists.freedesktop.org, intel-xe@lists.freedesktop.org, asahi@lists.linux.dev, Asahi Lina , Caterina Shablia Subject: [PATCH v4 2/7] drm/gpuvm: Kill drm_gpuva_init() Date: Mon, 7 Jul 2025 17:04:28 +0000 Message-ID: <20250707170442.1437009-3-caterina.shablia@collabora.com> X-Mailer: git-send-email 2.47.2 In-Reply-To: <20250707170442.1437009-1-caterina.shablia@collabora.com> References: <20250707170442.1437009-1-caterina.shablia@collabora.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Boris Brezillon drm_gpuva_init() only has one internal user, and given we are about to add new optional fields, it only add maintenance burden for no real benefit, so let's kill the thing now. Signed-off-by: Boris Brezillon Signed-off-by: Caterina Shablia Acked-by: Danilo Krummrich --- include/drm/drm_gpuvm.h | 15 ++++----------- 1 file changed, 4 insertions(+), 11 deletions(-) diff --git a/include/drm/drm_gpuvm.h b/include/drm/drm_gpuvm.h index 2a9629377633..6fdf2aff3e90 100644 --- a/include/drm/drm_gpuvm.h +++ b/include/drm/drm_gpuvm.h @@ -160,15 +160,6 @@ struct drm_gpuva *drm_gpuva_find_first(struct drm_gpuv= m *gpuvm, struct drm_gpuva *drm_gpuva_find_prev(struct drm_gpuvm *gpuvm, u64 start); struct drm_gpuva *drm_gpuva_find_next(struct drm_gpuvm *gpuvm, u64 end); =20 -static inline void drm_gpuva_init(struct drm_gpuva *va, u64 addr, u64 rang= e, - struct drm_gem_object *obj, u64 offset) -{ - va->va.addr =3D addr; - va->va.range =3D range; - va->gem.obj =3D obj; - va->gem.offset =3D offset; -} - /** * drm_gpuva_invalidate() - sets whether the backing GEM of this &drm_gpuv= a is * invalidated @@ -1079,8 +1070,10 @@ void drm_gpuva_ops_free(struct drm_gpuvm *gpuvm, static inline void drm_gpuva_init_from_op(struct drm_gpuva *va, struct drm_gpuva_op_map *op) { - drm_gpuva_init(va, op->va.addr, op->va.range, - op->gem.obj, op->gem.offset); + va->va.addr =3D op->va.addr; + va->va.range =3D op->va.range; + va->gem.obj =3D op->gem.obj; + va->gem.offset =3D op->gem.offset; } =20 /** --=20 2.47.2 From nobody Tue Oct 7 18:26:05 2025 Received: from bali.collaboradmins.com (bali.collaboradmins.com [148.251.105.195]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id E279E2E8DED for ; Mon, 7 Jul 2025 17:05:05 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=148.251.105.195 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1751907909; cv=none; b=QSBZTOKmKY5iYqqALCNaQFpGNkluwgky2vGVNk+1dEJf80Eg8fm9LOC6iQ3Fy2sZku42nZLf/t6UeQu7O/DpGi9oSDv1SPS0Pvvwwdd5HGDVrW022e+DGL32CGdhOxYP9pnchX/AQRae8GfGWlgXl3iiHqRMm+esP+jG+Ya2vLI= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1751907909; c=relaxed/simple; bh=U6tH5JNsDZZ8W2DW5sPnRjMGj7Yfzjgw1c3fBhEpw6U=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=Wl2+VJCY/ST+tun7jIGOnNd5Lel5crWC1X6Vy4wWMQE9uZaCAWncsfMQCgDlFT3D9OsBjzSODCBUocHWlfKxBulzBJQtchOwPc/JGpIPrX6R+5GOGHcL2EgvXZQKU+OYVF0GN5EJEs26LsH9AscibvmdohLaWbtYHuFtJhxwIs0= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=collabora.com; spf=pass smtp.mailfrom=collabora.com; dkim=pass (2048-bit key) header.d=collabora.com header.i=@collabora.com header.b=WXBgAhPx; arc=none smtp.client-ip=148.251.105.195 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=collabora.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=collabora.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=collabora.com header.i=@collabora.com header.b="WXBgAhPx" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=collabora.com; s=mail; t=1751907904; bh=U6tH5JNsDZZ8W2DW5sPnRjMGj7Yfzjgw1c3fBhEpw6U=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=WXBgAhPx5rjM20qfPDh14rICaGQ6kRpWOs0mUGc6IKi5LW8P5RAaNAU7850njqZfI GEYlbICxkOT0lDrvNxuOU4G16vPx23T7oqYFzSMrfgsFG/bIEflbspfCB+gLhz+jPj A3gaTeB3x45znZz6XybgrMTZD7kLiDuvE0Op3+AsNvCQmQtFyGQ5VUhVSWN0PgHc98 Tt1cvF1pBxIGZKDPNLn7symMW5sKE7n4sfuT2jy3Kd+WfCdt6eWNRVivhFkESP0o3t WfXGPgZfH07zim8SKWvtiz/KFjEUSE5lxl3RU8HjxyeVAGnqhi3M/f7PGXN0342G8W 1rhmrP7Ivi+Tw== Received: from debian-rockchip-rock5b-rk3588.. (unknown [90.168.160.154]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) (Authenticated sender: nanokatze) by bali.collaboradmins.com (Postfix) with ESMTPSA id EED0617E108A; Mon, 7 Jul 2025 19:05:02 +0200 (CEST) From: Caterina Shablia To: "Maarten Lankhorst" , "Maxime Ripard" , "Thomas Zimmermann" , "David Airlie" , "Simona Vetter" , "Frank Binns" , "Matt Coster" , "Karol Herbst" , "Lyude Paul" , "Danilo Krummrich" , "Boris Brezillon" , "Steven Price" , "Liviu Dudau" , "Lucas De Marchi" , =?UTF-8?q?Thomas=20Hellstr=C3=B6m?= , "Rodrigo Vivi" Cc: dri-devel@lists.freedesktop.org, linux-kernel@vger.kernel.org, nouveau@lists.freedesktop.org, intel-xe@lists.freedesktop.org, asahi@lists.linux.dev, Asahi Lina , Caterina Shablia Subject: [PATCH v4 3/7] drm/gpuvm: Pass map arguments through a struct Date: Mon, 7 Jul 2025 17:04:29 +0000 Message-ID: <20250707170442.1437009-4-caterina.shablia@collabora.com> X-Mailer: git-send-email 2.47.2 In-Reply-To: <20250707170442.1437009-1-caterina.shablia@collabora.com> References: <20250707170442.1437009-1-caterina.shablia@collabora.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Boris Brezillon We are about to pass more arguments to drm_gpuvm_sm_map[_ops_create](), so, before we do that, let's pass arguments through a struct instead of changing each call site every time a new optional argument is added. Signed-off-by: Boris Brezillon Signed-off-by: Caterina Shablia --- drivers/gpu/drm/drm_gpuvm.c | 76 ++++++++++---------------- drivers/gpu/drm/imagination/pvr_vm.c | 15 +++-- drivers/gpu/drm/nouveau/nouveau_uvmm.c | 11 ++-- drivers/gpu/drm/panthor/panthor_mmu.c | 13 ++++- drivers/gpu/drm/xe/xe_vm.c | 13 ++++- include/drm/drm_gpuvm.h | 34 ++++++++++-- 6 files changed, 97 insertions(+), 65 deletions(-) diff --git a/drivers/gpu/drm/drm_gpuvm.c b/drivers/gpu/drm/drm_gpuvm.c index e89b932e987c..05978c5c38b1 100644 --- a/drivers/gpu/drm/drm_gpuvm.c +++ b/drivers/gpu/drm/drm_gpuvm.c @@ -2054,16 +2054,15 @@ EXPORT_SYMBOL_GPL(drm_gpuva_unmap); =20 static int op_map_cb(const struct drm_gpuvm_ops *fn, void *priv, - u64 addr, u64 range, - struct drm_gem_object *obj, u64 offset) + const struct drm_gpuvm_map_req *req) { struct drm_gpuva_op op =3D {}; =20 op.op =3D DRM_GPUVA_OP_MAP; - op.map.va.addr =3D addr; - op.map.va.range =3D range; - op.map.gem.obj =3D obj; - op.map.gem.offset =3D offset; + op.map.va.addr =3D req->va.addr; + op.map.va.range =3D req->va.range; + op.map.gem.obj =3D req->gem.obj; + op.map.gem.offset =3D req->gem.offset; =20 return fn->sm_step_map(&op, priv); } @@ -2102,17 +2101,16 @@ op_unmap_cb(const struct drm_gpuvm_ops *fn, void *p= riv, static int __drm_gpuvm_sm_map(struct drm_gpuvm *gpuvm, const struct drm_gpuvm_ops *ops, void *priv, - u64 req_addr, u64 req_range, - struct drm_gem_object *req_obj, u64 req_offset) + const struct drm_gpuvm_map_req *req) { struct drm_gpuva *va, *next; - u64 req_end =3D req_addr + req_range; + u64 req_end =3D req->va.addr + req->va.range; int ret; =20 - if (unlikely(!drm_gpuvm_range_valid(gpuvm, req_addr, req_range))) + if (unlikely(!drm_gpuvm_range_valid(gpuvm, req->va.addr, req->va.range))) return -EINVAL; =20 - drm_gpuvm_for_each_va_range_safe(va, next, gpuvm, req_addr, req_end) { + drm_gpuvm_for_each_va_range_safe(va, next, gpuvm, req->va.addr, req_end) { struct drm_gem_object *obj =3D va->gem.obj; u64 offset =3D va->gem.offset; u64 addr =3D va->va.addr; @@ -2120,9 +2118,9 @@ __drm_gpuvm_sm_map(struct drm_gpuvm *gpuvm, u64 end =3D addr + range; bool merge =3D !!va->gem.obj; =20 - if (addr =3D=3D req_addr) { - merge &=3D obj =3D=3D req_obj && - offset =3D=3D req_offset; + if (addr =3D=3D req->va.addr) { + merge &=3D obj =3D=3D req->gem.obj && + offset =3D=3D req->gem.offset; =20 if (end =3D=3D req_end) { ret =3D op_unmap_cb(ops, priv, va, merge); @@ -2141,9 +2139,9 @@ __drm_gpuvm_sm_map(struct drm_gpuvm *gpuvm, if (end > req_end) { struct drm_gpuva_op_map n =3D { .va.addr =3D req_end, - .va.range =3D range - req_range, + .va.range =3D range - req->va.range, .gem.obj =3D obj, - .gem.offset =3D offset + req_range, + .gem.offset =3D offset + req->va.range, }; struct drm_gpuva_op_unmap u =3D { .va =3D va, @@ -2155,8 +2153,8 @@ __drm_gpuvm_sm_map(struct drm_gpuvm *gpuvm, return ret; break; } - } else if (addr < req_addr) { - u64 ls_range =3D req_addr - addr; + } else if (addr < req->va.addr) { + u64 ls_range =3D req->va.addr - addr; struct drm_gpuva_op_map p =3D { .va.addr =3D addr, .va.range =3D ls_range, @@ -2165,8 +2163,8 @@ __drm_gpuvm_sm_map(struct drm_gpuvm *gpuvm, }; struct drm_gpuva_op_unmap u =3D { .va =3D va }; =20 - merge &=3D obj =3D=3D req_obj && - offset + ls_range =3D=3D req_offset; + merge &=3D obj =3D=3D req->gem.obj && + offset + ls_range =3D=3D req->gem.offset; u.keep =3D merge; =20 if (end =3D=3D req_end) { @@ -2189,7 +2187,7 @@ __drm_gpuvm_sm_map(struct drm_gpuvm *gpuvm, .va.range =3D end - req_end, .gem.obj =3D obj, .gem.offset =3D offset + ls_range + - req_range, + req->va.range, }; =20 ret =3D op_remap_cb(ops, priv, &p, &n, &u); @@ -2197,10 +2195,10 @@ __drm_gpuvm_sm_map(struct drm_gpuvm *gpuvm, return ret; break; } - } else if (addr > req_addr) { - merge &=3D obj =3D=3D req_obj && - offset =3D=3D req_offset + - (addr - req_addr); + } else if (addr > req->va.addr) { + merge &=3D obj =3D=3D req->gem.obj && + offset =3D=3D req->gem.offset + + (addr - req->va.addr); =20 if (end =3D=3D req_end) { ret =3D op_unmap_cb(ops, priv, va, merge); @@ -2236,9 +2234,7 @@ __drm_gpuvm_sm_map(struct drm_gpuvm *gpuvm, } } =20 - return op_map_cb(ops, priv, - req_addr, req_range, - req_obj, req_offset); + return op_map_cb(ops, priv, req); } =20 static int @@ -2302,11 +2298,8 @@ __drm_gpuvm_sm_unmap(struct drm_gpuvm *gpuvm, /** * drm_gpuvm_sm_map() - creates the &drm_gpuva_op split/merge steps * @gpuvm: the &drm_gpuvm representing the GPU VA space - * @req_addr: the start address of the new mapping - * @req_range: the range of the new mapping - * @req_obj: the &drm_gem_object to map - * @req_offset: the offset within the &drm_gem_object * @priv: pointer to a driver private data structure + * @req: map request information * * This function iterates the given range of the GPU VA space. It utilizes= the * &drm_gpuvm_ops to call back into the driver providing the split and mer= ge @@ -2333,8 +2326,7 @@ __drm_gpuvm_sm_unmap(struct drm_gpuvm *gpuvm, */ int drm_gpuvm_sm_map(struct drm_gpuvm *gpuvm, void *priv, - u64 req_addr, u64 req_range, - struct drm_gem_object *req_obj, u64 req_offset) + const struct drm_gpuvm_map_req *req) { const struct drm_gpuvm_ops *ops =3D gpuvm->ops; =20 @@ -2343,9 +2335,7 @@ drm_gpuvm_sm_map(struct drm_gpuvm *gpuvm, void *priv, ops->sm_step_unmap))) return -EINVAL; =20 - return __drm_gpuvm_sm_map(gpuvm, ops, priv, - req_addr, req_range, - req_obj, req_offset); + return __drm_gpuvm_sm_map(gpuvm, ops, priv, req); } EXPORT_SYMBOL_GPL(drm_gpuvm_sm_map); =20 @@ -2485,10 +2475,7 @@ static const struct drm_gpuvm_ops gpuvm_list_ops =3D= { /** * drm_gpuvm_sm_map_ops_create() - creates the &drm_gpuva_ops to split and= merge * @gpuvm: the &drm_gpuvm representing the GPU VA space - * @req_addr: the start address of the new mapping - * @req_range: the range of the new mapping - * @req_obj: the &drm_gem_object to map - * @req_offset: the offset within the &drm_gem_object + * @req: map request arguments * * This function creates a list of operations to perform splitting and mer= ging * of existent mapping(s) with the newly requested one. @@ -2516,8 +2503,7 @@ static const struct drm_gpuvm_ops gpuvm_list_ops =3D { */ struct drm_gpuva_ops * drm_gpuvm_sm_map_ops_create(struct drm_gpuvm *gpuvm, - u64 req_addr, u64 req_range, - struct drm_gem_object *req_obj, u64 req_offset) + const struct drm_gpuvm_map_req *req) { struct drm_gpuva_ops *ops; struct { @@ -2535,9 +2521,7 @@ drm_gpuvm_sm_map_ops_create(struct drm_gpuvm *gpuvm, args.vm =3D gpuvm; args.ops =3D ops; =20 - ret =3D __drm_gpuvm_sm_map(gpuvm, &gpuvm_list_ops, &args, - req_addr, req_range, - req_obj, req_offset); + ret =3D __drm_gpuvm_sm_map(gpuvm, &gpuvm_list_ops, &args, req); if (ret) goto err_free_ops; =20 diff --git a/drivers/gpu/drm/imagination/pvr_vm.c b/drivers/gpu/drm/imagina= tion/pvr_vm.c index 2896fa7501b1..abfdcd279363 100644 --- a/drivers/gpu/drm/imagination/pvr_vm.c +++ b/drivers/gpu/drm/imagination/pvr_vm.c @@ -185,12 +185,17 @@ struct pvr_vm_bind_op { static int pvr_vm_bind_op_exec(struct pvr_vm_bind_op *bind_op) { switch (bind_op->type) { - case PVR_VM_BIND_TYPE_MAP: + case PVR_VM_BIND_TYPE_MAP: { + const struct drm_gpuvm_map_req map_req =3D { + .va.addr =3D bind_op->device_addr, + .va.range =3D bind_op->size, + .gem.obj =3D gem_from_pvr_gem(bind_op->pvr_obj), + .gem.offset =3D bind_op->offset, + }; + return drm_gpuvm_sm_map(&bind_op->vm_ctx->gpuvm_mgr, - bind_op, bind_op->device_addr, - bind_op->size, - gem_from_pvr_gem(bind_op->pvr_obj), - bind_op->offset); + bind_op, &map_req); + } =20 case PVR_VM_BIND_TYPE_UNMAP: return drm_gpuvm_sm_unmap(&bind_op->vm_ctx->gpuvm_mgr, diff --git a/drivers/gpu/drm/nouveau/nouveau_uvmm.c b/drivers/gpu/drm/nouve= au/nouveau_uvmm.c index 48f105239f42..b481700be666 100644 --- a/drivers/gpu/drm/nouveau/nouveau_uvmm.c +++ b/drivers/gpu/drm/nouveau/nouveau_uvmm.c @@ -1276,6 +1276,12 @@ nouveau_uvmm_bind_job_submit(struct nouveau_job *job, break; case OP_MAP: { struct nouveau_uvma_region *reg; + struct drm_gpuvm_map_req map_req =3D { + .va.addr =3D op->va.addr, + .va.range =3D op->va.range, + .gem.obj =3D op->gem.obj, + .gem.offset =3D op->gem.offset, + }; =20 reg =3D nouveau_uvma_region_find_first(uvmm, op->va.addr, @@ -1301,10 +1307,7 @@ nouveau_uvmm_bind_job_submit(struct nouveau_job *job, } =20 op->ops =3D drm_gpuvm_sm_map_ops_create(&uvmm->base, - op->va.addr, - op->va.range, - op->gem.obj, - op->gem.offset); + &map_req); if (IS_ERR(op->ops)) { ret =3D PTR_ERR(op->ops); goto unwind_continue; diff --git a/drivers/gpu/drm/panthor/panthor_mmu.c b/drivers/gpu/drm/pantho= r/panthor_mmu.c index 9caaba03c5eb..f0a22b775958 100644 --- a/drivers/gpu/drm/panthor/panthor_mmu.c +++ b/drivers/gpu/drm/panthor/panthor_mmu.c @@ -2236,15 +2236,22 @@ panthor_vm_exec_op(struct panthor_vm *vm, struct pa= nthor_vm_op_ctx *op, goto out; =20 switch (op_type) { - case DRM_PANTHOR_VM_BIND_OP_TYPE_MAP: + case DRM_PANTHOR_VM_BIND_OP_TYPE_MAP: { + const struct drm_gpuvm_map_req map_req =3D { + .va.addr =3D op->va.addr, + .va.range =3D op->va.range, + .gem.obj =3D op->map.vm_bo->obj, + .gem.offset =3D op->map.bo_offset, + }; + if (vm->unusable) { ret =3D -EINVAL; break; } =20 - ret =3D drm_gpuvm_sm_map(&vm->base, vm, op->va.addr, op->va.range, - op->map.vm_bo->obj, op->map.bo_offset); + ret =3D drm_gpuvm_sm_map(&vm->base, vm, &map_req); break; + } =20 case DRM_PANTHOR_VM_BIND_OP_TYPE_UNMAP: ret =3D drm_gpuvm_sm_unmap(&vm->base, vm, op->va.addr, op->va.range); diff --git a/drivers/gpu/drm/xe/xe_vm.c b/drivers/gpu/drm/xe/xe_vm.c index 861577746929..80bc741bdb6b 100644 --- a/drivers/gpu/drm/xe/xe_vm.c +++ b/drivers/gpu/drm/xe/xe_vm.c @@ -2246,10 +2246,17 @@ vm_bind_ioctl_ops_create(struct xe_vm *vm, struct x= e_bo *bo, =20 switch (operation) { case DRM_XE_VM_BIND_OP_MAP: - case DRM_XE_VM_BIND_OP_MAP_USERPTR: - ops =3D drm_gpuvm_sm_map_ops_create(&vm->gpuvm, addr, range, - obj, bo_offset_or_userptr); + case DRM_XE_VM_BIND_OP_MAP_USERPTR: { + struct drm_gpuvm_map_req map_req =3D { + .va.addr =3D addr, + .va.range =3D range, + .gem.obj =3D obj, + .gem.offset =3D bo_offset_or_userptr, + }; + + ops =3D drm_gpuvm_sm_map_ops_create(&vm->gpuvm, &map_req); break; + } case DRM_XE_VM_BIND_OP_UNMAP: ops =3D drm_gpuvm_sm_unmap_ops_create(&vm->gpuvm, addr, range); break; diff --git a/include/drm/drm_gpuvm.h b/include/drm/drm_gpuvm.h index 6fdf2aff3e90..a6e6c33fc10b 100644 --- a/include/drm/drm_gpuvm.h +++ b/include/drm/drm_gpuvm.h @@ -1049,10 +1049,37 @@ struct drm_gpuva_ops { */ #define drm_gpuva_next_op(op) list_next_entry(op, entry) =20 +/** + * struct drm_gpuvm_map_req - arguments passed to drm_gpuvm_sm_map[_ops_cr= eate]() + */ +struct drm_gpuvm_map_req { + /** @va: virtual address related fields */ + struct { + /** @va.addr: start of the virtual address range to map to */ + u64 addr; + + /** @va.size: size of the virtual address range to map to */ + u64 range; + } va; + + /** @gem: GEM related fields */ + struct { + /** + * @obj: GEM object to map. + * + * Can be NULL if the virtual range is not backed by a GEM object. + */ + struct drm_gem_object *obj; + + /** @offset: offset in the GEM */ + u64 offset; + } gem; +}; + struct drm_gpuva_ops * drm_gpuvm_sm_map_ops_create(struct drm_gpuvm *gpuvm, - u64 addr, u64 range, - struct drm_gem_object *obj, u64 offset); + const struct drm_gpuvm_map_req *req); + struct drm_gpuva_ops * drm_gpuvm_sm_unmap_ops_create(struct drm_gpuvm *gpuvm, u64 addr, u64 range); @@ -1198,8 +1225,7 @@ struct drm_gpuvm_ops { }; =20 int drm_gpuvm_sm_map(struct drm_gpuvm *gpuvm, void *priv, - u64 addr, u64 range, - struct drm_gem_object *obj, u64 offset); + const struct drm_gpuvm_map_req *req); =20 int drm_gpuvm_sm_unmap(struct drm_gpuvm *gpuvm, void *priv, u64 addr, u64 range); --=20 2.47.2 From nobody Tue Oct 7 18:26:05 2025 Received: from bali.collaboradmins.com (bali.collaboradmins.com [148.251.105.195]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 2C6932E7F20 for ; Mon, 7 Jul 2025 17:05:07 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=148.251.105.195 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1751907910; cv=none; b=nLUVlHbYXQ66JpUlY6Lw24CCdoQ8Iqy3hW7MdUzVxkvDXOPi2NJYWV9apIwMHG08rGq3zyRNW1TaEiBnQOgM8shheI7+EqkrWfGI8qR3sq0vtrmGUxC4yn0OjPQ/HKxAIQG0oVUT3MSrOSEAvKtaxiizC2m7JEXdVQyh30DUGmk= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1751907910; c=relaxed/simple; bh=9A/8qRN3N5EQ/idueTkzfofxl+ak2m/9E8a9eLvVQf4=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=S1ohwckNqh+lORr3/RGiDpucxABSgskXFsp0NGVXO+MWniJgpLsbOXNV7AtnqBAyA5HrsdalP64dujIl+VMyterBwpigu87wYUv6LI97m08RDdClsf2HLYVS2ZSwVbaL+oP9Td+cMMb2lOBJLOt0yu9f88H+lZkjFAC+IpPMnRU= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=collabora.com; spf=pass smtp.mailfrom=collabora.com; dkim=pass (2048-bit key) header.d=collabora.com header.i=@collabora.com header.b=Xfptt2Oz; arc=none smtp.client-ip=148.251.105.195 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=collabora.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=collabora.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=collabora.com header.i=@collabora.com header.b="Xfptt2Oz" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=collabora.com; s=mail; t=1751907906; bh=9A/8qRN3N5EQ/idueTkzfofxl+ak2m/9E8a9eLvVQf4=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=Xfptt2Ozmxd3hEOz3iPMnAdT2OgLJ67BhOzhLVH1DaZHv4cY93DBHb9MuYx719idr bTNOpCFUG6QcvKMkxIS3TFCYdFkL3GpiSn168zCoXHnHhft96WEDHo9qo+UaNVWco7 7bc3ZzwfoDOxBBwyMtu8HqRJNtV3OrSUm/cSbtTsGNBU0p1+cxJ/NlhnaXJIfdavBH WVgkw2pf9OXaFEvvpAF7mHMmrJHz6NmnS8SOct2sRzCBzj/xVCNdCMNae6Kzt1F0r5 9doJGxlJaEPVGG01YzvvNaCnQiy3v2r7gqHzvzk4xwDICDS5Ia/zeWj6mtkc0rZx7h fz0DbgSM2wTtA== Received: from debian-rockchip-rock5b-rk3588.. (unknown [90.168.160.154]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) (Authenticated sender: nanokatze) by bali.collaboradmins.com (Postfix) with ESMTPSA id 3C59C17E046D; Mon, 7 Jul 2025 19:05:05 +0200 (CEST) From: Caterina Shablia To: "Maarten Lankhorst" , "Maxime Ripard" , "Thomas Zimmermann" , "David Airlie" , "Simona Vetter" , "Frank Binns" , "Matt Coster" , "Karol Herbst" , "Lyude Paul" , "Danilo Krummrich" , "Boris Brezillon" , "Steven Price" , "Liviu Dudau" , "Lucas De Marchi" , =?UTF-8?q?Thomas=20Hellstr=C3=B6m?= , "Rodrigo Vivi" Cc: dri-devel@lists.freedesktop.org, linux-kernel@vger.kernel.org, nouveau@lists.freedesktop.org, intel-xe@lists.freedesktop.org, asahi@lists.linux.dev, Asahi Lina , Caterina Shablia Subject: [PATCH v4 4/7] drm/gpuvm: Add a helper to check if two VA can be merged Date: Mon, 7 Jul 2025 17:04:30 +0000 Message-ID: <20250707170442.1437009-5-caterina.shablia@collabora.com> X-Mailer: git-send-email 2.47.2 In-Reply-To: <20250707170442.1437009-1-caterina.shablia@collabora.com> References: <20250707170442.1437009-1-caterina.shablia@collabora.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Boris Brezillon We are going to add flags/properties that will impact the VA merging ability. Instead of sprinkling tests all over the place in __drm_gpuvm_sm_map(), let's add a helper aggregating all these checks can call it for every existing VA we walk through in the __drm_gpuvm_sm_map() loop. Signed-off-by: Boris Brezillon Signed-off-by: Caterina Shablia --- drivers/gpu/drm/drm_gpuvm.c | 47 +++++++++++++++++++++++++++++-------- 1 file changed, 37 insertions(+), 10 deletions(-) diff --git a/drivers/gpu/drm/drm_gpuvm.c b/drivers/gpu/drm/drm_gpuvm.c index 05978c5c38b1..dc3c2f906400 100644 --- a/drivers/gpu/drm/drm_gpuvm.c +++ b/drivers/gpu/drm/drm_gpuvm.c @@ -2098,12 +2098,48 @@ op_unmap_cb(const struct drm_gpuvm_ops *fn, void *p= riv, return fn->sm_step_unmap(&op, priv); } =20 +static bool can_merge(struct drm_gpuvm *gpuvm, const struct drm_gpuva *a, + const struct drm_gpuva *b) +{ + /* Only GEM-based mappings can be merged, and they must point to + * the same GEM object. + */ + if (a->gem.obj !=3D b->gem.obj || !a->gem.obj) + return false; + + /* Let's keep things simple for now and force all flags to match. */ + if (a->flags !=3D b->flags) + return false; + + /* Order VAs for the rest of the checks. */ + if (a->va.addr > b->va.addr) + swap(a, b); + + /* We assume the caller already checked that VAs overlap or are + * contiguous. + */ + if (drm_WARN_ON(gpuvm->drm, b->va.addr > a->va.addr + a->va.range)) + return false; + + /* We intentionally ignore u64 underflows because all we care about + * here is whether the VA diff matches the GEM offset diff. + */ + return b->va.addr - a->va.addr =3D=3D b->gem.offset - a->gem.offset; +} + static int __drm_gpuvm_sm_map(struct drm_gpuvm *gpuvm, const struct drm_gpuvm_ops *ops, void *priv, const struct drm_gpuvm_map_req *req) { struct drm_gpuva *va, *next; + struct drm_gpuva reqva =3D { + .va.addr =3D req->va.addr, + .va.range =3D req->va.range, + .gem.offset =3D req->gem.offset, + .gem.obj =3D req->gem.obj, + .flags =3D req->flags, + }; u64 req_end =3D req->va.addr + req->va.range; int ret; =20 @@ -2116,12 +2152,9 @@ __drm_gpuvm_sm_map(struct drm_gpuvm *gpuvm, u64 addr =3D va->va.addr; u64 range =3D va->va.range; u64 end =3D addr + range; - bool merge =3D !!va->gem.obj; + bool merge =3D can_merge(gpuvm, va, &reqva); =20 if (addr =3D=3D req->va.addr) { - merge &=3D obj =3D=3D req->gem.obj && - offset =3D=3D req->gem.offset; - if (end =3D=3D req_end) { ret =3D op_unmap_cb(ops, priv, va, merge); if (ret) @@ -2163,8 +2196,6 @@ __drm_gpuvm_sm_map(struct drm_gpuvm *gpuvm, }; struct drm_gpuva_op_unmap u =3D { .va =3D va }; =20 - merge &=3D obj =3D=3D req->gem.obj && - offset + ls_range =3D=3D req->gem.offset; u.keep =3D merge; =20 if (end =3D=3D req_end) { @@ -2196,10 +2227,6 @@ __drm_gpuvm_sm_map(struct drm_gpuvm *gpuvm, break; } } else if (addr > req->va.addr) { - merge &=3D obj =3D=3D req->gem.obj && - offset =3D=3D req->gem.offset + - (addr - req->va.addr); - if (end =3D=3D req_end) { ret =3D op_unmap_cb(ops, priv, va, merge); if (ret) --=20 2.47.2 From nobody Tue Oct 7 18:26:06 2025 Received: from bali.collaboradmins.com (bali.collaboradmins.com [148.251.105.195]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id B667B2E7F28 for ; Mon, 7 Jul 2025 17:05:10 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=148.251.105.195 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1751907912; cv=none; b=JhUPoJZbE8O0G46t6zZVvkb6Dd64tdmcBhIJZ0uVzeOo3mejXIes1qTngo+ONqTCB80XiP2j05rs81LqjlGkrF4yc0quOUBHytcALAIcU4vR1qbzpNLFSUUCP8UVPfWIWEooKv5y+3HAiclVUAkgjMPXYI3i3ABKggor5T5+Z7w= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1751907912; c=relaxed/simple; bh=akBcOMf2yaT9+54T4JiDFinAfyszlhXfN+hd5VU7pxs=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=RZusYNdjdHjhKRESgpTmo6IO03zRx03ukNzgKJZRv/ZVNhaXM1Oxo/r9XgZEyQfEj2sCrMOS0fkoaz0qLtmFbr2loFd5zmpe5YQIa58pdK3YgkfGUL+3iXt9sroxFGcYA4Lji4jiG7VdMA4a6e0myuh6Gmi/iL0n+Zo20uHbJf0= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=collabora.com; spf=pass smtp.mailfrom=collabora.com; dkim=pass (2048-bit key) header.d=collabora.com header.i=@collabora.com header.b=DSU8wyYl; arc=none smtp.client-ip=148.251.105.195 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=collabora.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=collabora.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=collabora.com header.i=@collabora.com header.b="DSU8wyYl" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=collabora.com; s=mail; t=1751907909; bh=akBcOMf2yaT9+54T4JiDFinAfyszlhXfN+hd5VU7pxs=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=DSU8wyYlQCn+tAXjJkoR0l9B3baQkuzMRCWFSTvbZLnJkWcQn4EMH16aRsXZHzUjY vGB9yIYtgtfr6C292lr613erbe6MiXDfHNOr5vaYShYuLNaiQceSd6bsshYP/7m8Mi HDhqmbk4dvPLZhgVQUpryMSQMpMwMft6zrIYMxAoI2EguuCGVn84skj8rTcGab0ulV XUa95uZBp58lQRRN4cmxamBonkUAZyJeMv2IZIuVZbVegk95k6+VaSRgayneK3cxre O2UqKnSOFKjU6VmAAhdAiFaNbz8otuDUFrtUHO2Uxt3sex2GhEJa4q7oPUbVlWRbR7 5zQBMdIRFVUig== Received: from debian-rockchip-rock5b-rk3588.. (unknown [90.168.160.154]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) (Authenticated sender: nanokatze) by bali.collaboradmins.com (Postfix) with ESMTPSA id B8EC417E04EE; Mon, 7 Jul 2025 19:05:07 +0200 (CEST) From: Caterina Shablia To: "Maarten Lankhorst" , "Maxime Ripard" , "Thomas Zimmermann" , "David Airlie" , "Simona Vetter" , "Frank Binns" , "Matt Coster" , "Karol Herbst" , "Lyude Paul" , "Danilo Krummrich" , "Boris Brezillon" , "Steven Price" , "Liviu Dudau" , "Lucas De Marchi" , =?UTF-8?q?Thomas=20Hellstr=C3=B6m?= , "Rodrigo Vivi" Cc: dri-devel@lists.freedesktop.org, linux-kernel@vger.kernel.org, nouveau@lists.freedesktop.org, intel-xe@lists.freedesktop.org, asahi@lists.linux.dev, Asahi Lina , Caterina Shablia Subject: [PATCH v4 5/7] drm/gpuvm: Add a flags field to drm_gpuvm_map_req/drm_gpuva_op_map Date: Mon, 7 Jul 2025 17:04:31 +0000 Message-ID: <20250707170442.1437009-6-caterina.shablia@collabora.com> X-Mailer: git-send-email 2.47.2 In-Reply-To: <20250707170442.1437009-1-caterina.shablia@collabora.com> References: <20250707170442.1437009-1-caterina.shablia@collabora.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Asahi Lina drm_gpuva objects have a flags field. Currently, this can be managed by drivers out-of-band, without any special handling in drm_gpuvm. To be able to introduce flags that do affect the logic in the drm_gpuvm core, we need to plumb it through the map calls. This will allow the core to check the flags on map and alter the merge/split logic depending on the requested flags and the flags of the existing drm_gpuva ranges that are being split. Signed-off-by: Asahi Lina Signed-off-by: Caterina Shablia Acked-by: Danilo Krummrich --- drivers/gpu/drm/drm_gpuvm.c | 7 +++++++ include/drm/drm_gpuvm.h | 9 +++++++++ 2 files changed, 16 insertions(+) diff --git a/drivers/gpu/drm/drm_gpuvm.c b/drivers/gpu/drm/drm_gpuvm.c index dc3c2f906400..dd949a8853b0 100644 --- a/drivers/gpu/drm/drm_gpuvm.c +++ b/drivers/gpu/drm/drm_gpuvm.c @@ -2063,6 +2063,7 @@ op_map_cb(const struct drm_gpuvm_ops *fn, void *priv, op.map.va.range =3D req->va.range; op.map.gem.obj =3D req->gem.obj; op.map.gem.offset =3D req->gem.offset; + op.map.flags =3D req->flags; =20 return fn->sm_step_map(&op, priv); } @@ -2175,6 +2176,7 @@ __drm_gpuvm_sm_map(struct drm_gpuvm *gpuvm, .va.range =3D range - req->va.range, .gem.obj =3D obj, .gem.offset =3D offset + req->va.range, + .flags =3D va->flags, }; struct drm_gpuva_op_unmap u =3D { .va =3D va, @@ -2193,6 +2195,7 @@ __drm_gpuvm_sm_map(struct drm_gpuvm *gpuvm, .va.range =3D ls_range, .gem.obj =3D obj, .gem.offset =3D offset, + .flags =3D va->flags, }; struct drm_gpuva_op_unmap u =3D { .va =3D va }; =20 @@ -2219,6 +2222,7 @@ __drm_gpuvm_sm_map(struct drm_gpuvm *gpuvm, .gem.obj =3D obj, .gem.offset =3D offset + ls_range + req->va.range, + .flags =3D va->flags, }; =20 ret =3D op_remap_cb(ops, priv, &p, &n, &u); @@ -2247,6 +2251,7 @@ __drm_gpuvm_sm_map(struct drm_gpuvm *gpuvm, .va.range =3D end - req_end, .gem.obj =3D obj, .gem.offset =3D offset + req_end - addr, + .flags =3D va->flags, }; struct drm_gpuva_op_unmap u =3D { .va =3D va, @@ -2290,6 +2295,7 @@ __drm_gpuvm_sm_unmap(struct drm_gpuvm *gpuvm, prev.va.range =3D req_addr - addr; prev.gem.obj =3D obj; prev.gem.offset =3D offset; + prev.flags =3D va->flags; =20 prev_split =3D true; } @@ -2299,6 +2305,7 @@ __drm_gpuvm_sm_unmap(struct drm_gpuvm *gpuvm, next.va.range =3D end - req_end; next.gem.obj =3D obj; next.gem.offset =3D offset + (req_end - addr); + next.flags =3D va->flags; =20 next_split =3D true; } diff --git a/include/drm/drm_gpuvm.h b/include/drm/drm_gpuvm.h index a6e6c33fc10b..f77a89e791f1 100644 --- a/include/drm/drm_gpuvm.h +++ b/include/drm/drm_gpuvm.h @@ -847,6 +847,11 @@ struct drm_gpuva_op_map { */ struct drm_gem_object *obj; } gem; + + /** + * @flags: requested flags for the &drm_gpuva for this mapping + */ + enum drm_gpuva_flags flags; }; =20 /** @@ -1074,6 +1079,9 @@ struct drm_gpuvm_map_req { /** @offset: offset in the GEM */ u64 offset; } gem; + + /** @flags: combination of DRM_GPUVA_ flags describing the mapping proper= ties. */ + enum drm_gpuva_flags flags; }; =20 struct drm_gpuva_ops * @@ -1097,6 +1105,7 @@ void drm_gpuva_ops_free(struct drm_gpuvm *gpuvm, static inline void drm_gpuva_init_from_op(struct drm_gpuva *va, struct drm_gpuva_op_map *op) { + va->flags =3D op->flags; va->va.addr =3D op->va.addr; va->va.range =3D op->va.range; va->gem.obj =3D op->gem.obj; --=20 2.47.2 From nobody Tue Oct 7 18:26:06 2025 Received: from bali.collaboradmins.com (bali.collaboradmins.com [148.251.105.195]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 8537A2E92B3 for ; Mon, 7 Jul 2025 17:05:13 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=148.251.105.195 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1751907915; cv=none; b=A9V3rrdFmIxzO6nKLJ4AQoF94Wr4U9DXeAtB8llKZ+pQYuniL17olCYQ6b+cyip47+n1B8KZGpVAk8mm+KcQ7Z1bqnNByljaImKOFr7LmfGy8cR1jW+fgk1Fa+1w8DAAxbF3i2lzRj9GZXwPr7mLBcCUW2aCQpMj2b2PPDFS3x4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1751907915; c=relaxed/simple; bh=G3A5FBsbv4BYX27PARvCtZt9U4rLROG1uyOLU0aWViQ=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=j/TCXsi9eDnQTIMWPSSZ6Id9QWVCyQZXVaIbf0OmLB2h8ouBDAyL3Tv5PQy/EXpKJvSgnwSjZ21eNNLQOiqFCNpKHNduNQGA8qJ2X2cdzowkH/gSzc2YYOc/iWAHloFLy5wYUXjOlts5pdC32RSdM2byBJt6U9JD/uI1kIfhHxc= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=collabora.com; spf=pass smtp.mailfrom=collabora.com; dkim=pass (2048-bit key) header.d=collabora.com header.i=@collabora.com header.b=eNsXYVk7; arc=none smtp.client-ip=148.251.105.195 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=collabora.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=collabora.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=collabora.com header.i=@collabora.com header.b="eNsXYVk7" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=collabora.com; s=mail; t=1751907911; bh=G3A5FBsbv4BYX27PARvCtZt9U4rLROG1uyOLU0aWViQ=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=eNsXYVk7jC3tmwdIhNzjhJWQ4DR6sct7O1/M+jaR590v7SgivZJszQt2H3kkd7C6q DaPzGjtaf9CR3lp6LjtBO6ZtC8FEBY7fYs6nPJqGCjphDx/acZB92t4Ve2n3S61KIO k8BU6aZn09iU2aNXpxbP1a99V2GBtEDuEfU34JllEUyZjVMiiQEdELaodI1qxIG3Py s7uRXHBzW6FUS+yxhGtb2LUkVXIGbiS8O8HJW0uxFe63zwYX1qKDDkk8dUwdZcVf1R g6tFD/c90V987OHeqJ9oGfouXoFonQE7DvPGd68yQ3e2/ulTndEih0m8anV2RdzKyM fk62V20igRNmQ== Received: from debian-rockchip-rock5b-rk3588.. (unknown [90.168.160.154]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) (Authenticated sender: nanokatze) by bali.collaboradmins.com (Postfix) with ESMTPSA id 7F31317E10D0; Mon, 7 Jul 2025 19:05:10 +0200 (CEST) From: Caterina Shablia To: "Maarten Lankhorst" , "Maxime Ripard" , "Thomas Zimmermann" , "David Airlie" , "Simona Vetter" , "Frank Binns" , "Matt Coster" , "Karol Herbst" , "Lyude Paul" , "Danilo Krummrich" , "Boris Brezillon" , "Steven Price" , "Liviu Dudau" , "Lucas De Marchi" , =?UTF-8?q?Thomas=20Hellstr=C3=B6m?= , "Rodrigo Vivi" Cc: dri-devel@lists.freedesktop.org, linux-kernel@vger.kernel.org, nouveau@lists.freedesktop.org, intel-xe@lists.freedesktop.org, asahi@lists.linux.dev, Asahi Lina , Caterina Shablia , Asahi Lina Subject: [PATCH v4 6/7] drm/gpuvm: Add DRM_GPUVA_REPEAT flag and logic Date: Mon, 7 Jul 2025 17:04:32 +0000 Message-ID: <20250707170442.1437009-7-caterina.shablia@collabora.com> X-Mailer: git-send-email 2.47.2 In-Reply-To: <20250707170442.1437009-1-caterina.shablia@collabora.com> References: <20250707170442.1437009-1-caterina.shablia@collabora.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Asahi Lina To be able to support "fake sparse" mappings without relying on GPU page fault handling, drivers may need to create large (e.g. 4GiB) mappings of the same page repeatedly (or same range of pages). Doing this through individual mappings would be very wasteful. This can be handled better by using a flag on map creation, but to do it safely, drm_gpuvm needs to be aware of this special case. Add a flag that signals that a given mapping is a page mapping, which is repeated all over the entire requested VA range. This tweaks the sm_map() logic to treat the GEM offsets differently when mappings are a repeated ones so they are not incremented as they would be with regular mappings. The size of the GEM portion to repeat is passed through drm_gpuva::gem::range. Most of the time it will be a page size, but it can be bigger as long as it's less that drm_gpuva::va::range, and drm_gpuva::gem::range is a multiple of drm_gpuva::va::range. Signed-off-by: Asahi Lina Signed-off-by: Caterina Shablia --- drivers/gpu/drm/drm_gpuvm.c | 72 +++++++++++++++++++++++++++++++++---- include/drm/drm_gpuvm.h | 43 +++++++++++++++++++++- 2 files changed, 108 insertions(+), 7 deletions(-) diff --git a/drivers/gpu/drm/drm_gpuvm.c b/drivers/gpu/drm/drm_gpuvm.c index dd949a8853b0..817393596149 100644 --- a/drivers/gpu/drm/drm_gpuvm.c +++ b/drivers/gpu/drm/drm_gpuvm.c @@ -2063,6 +2063,7 @@ op_map_cb(const struct drm_gpuvm_ops *fn, void *priv, op.map.va.range =3D req->va.range; op.map.gem.obj =3D req->gem.obj; op.map.gem.offset =3D req->gem.offset; + op.map.gem.range =3D req->gem.range; op.map.flags =3D req->flags; =20 return fn->sm_step_map(&op, priv); @@ -2122,12 +2123,53 @@ static bool can_merge(struct drm_gpuvm *gpuvm, cons= t struct drm_gpuva *a, if (drm_WARN_ON(gpuvm->drm, b->va.addr > a->va.addr + a->va.range)) return false; =20 + if (a->flags & DRM_GPUVA_REPEAT) { + u64 va_diff =3D b->va.addr - a->va.addr; + + /* If this is a repeated mapping, both the GEM range + * and offset must match. + */ + if (a->gem.range !=3D b->gem.range || + a->gem.offset !=3D b->gem.offset) + return false; + + /* The difference between the VA addresses must be a + * multiple of the repeated range, otherwise there's + * a shift. + */ + if (do_div(va_diff, a->gem.range)) + return false; + + return true; + } + /* We intentionally ignore u64 underflows because all we care about * here is whether the VA diff matches the GEM offset diff. */ return b->va.addr - a->va.addr =3D=3D b->gem.offset - a->gem.offset; } =20 +static int check_map_req(struct drm_gpuvm *gpuvm, + const struct drm_gpuvm_map_req *req) +{ + if (unlikely(!drm_gpuvm_range_valid(gpuvm, req->va.addr, req->va.range))) + return -EINVAL; + + if (req->flags & DRM_GPUVA_REPEAT) { + u64 va_range =3D req->va.range; + + /* For a repeated mapping, GEM range must be > 0 + * and a multiple of the VA range. + */ + if (unlikely(!req->gem.range || + va_range < req->gem.range || + do_div(va_range, req->gem.range))) + return -EINVAL; + } + + return 0; +} + static int __drm_gpuvm_sm_map(struct drm_gpuvm *gpuvm, const struct drm_gpuvm_ops *ops, void *priv, @@ -2137,6 +2179,7 @@ __drm_gpuvm_sm_map(struct drm_gpuvm *gpuvm, struct drm_gpuva reqva =3D { .va.addr =3D req->va.addr, .va.range =3D req->va.range, + .gem.range =3D req->gem.range, .gem.offset =3D req->gem.offset, .gem.obj =3D req->gem.obj, .flags =3D req->flags, @@ -2144,7 +2187,8 @@ __drm_gpuvm_sm_map(struct drm_gpuvm *gpuvm, u64 req_end =3D req->va.addr + req->va.range; int ret; =20 - if (unlikely(!drm_gpuvm_range_valid(gpuvm, req->va.addr, req->va.range))) + ret =3D check_map_req(gpuvm, req); + if (unlikely(ret)) return -EINVAL; =20 drm_gpuvm_for_each_va_range_safe(va, next, gpuvm, req->va.addr, req_end) { @@ -2175,7 +2219,8 @@ __drm_gpuvm_sm_map(struct drm_gpuvm *gpuvm, .va.addr =3D req_end, .va.range =3D range - req->va.range, .gem.obj =3D obj, - .gem.offset =3D offset + req->va.range, + .gem.range =3D va->gem.range, + .gem.offset =3D offset, .flags =3D va->flags, }; struct drm_gpuva_op_unmap u =3D { @@ -2183,6 +2228,9 @@ __drm_gpuvm_sm_map(struct drm_gpuvm *gpuvm, .keep =3D merge, }; =20 + if (!(va->flags & DRM_GPUVA_REPEAT)) + n.gem.offset +=3D req->va.range; + ret =3D op_remap_cb(ops, priv, NULL, &n, &u); if (ret) return ret; @@ -2194,6 +2242,7 @@ __drm_gpuvm_sm_map(struct drm_gpuvm *gpuvm, .va.addr =3D addr, .va.range =3D ls_range, .gem.obj =3D obj, + .gem.range =3D va->gem.range, .gem.offset =3D offset, .flags =3D va->flags, }; @@ -2220,11 +2269,14 @@ __drm_gpuvm_sm_map(struct drm_gpuvm *gpuvm, .va.addr =3D req_end, .va.range =3D end - req_end, .gem.obj =3D obj, - .gem.offset =3D offset + ls_range + - req->va.range, + .gem.range =3D va->gem.range, + .gem.offset =3D offset, .flags =3D va->flags, }; =20 + if (!(va->flags & DRM_GPUVA_REPEAT)) + n.gem.offset +=3D ls_range + req->va.range; + ret =3D op_remap_cb(ops, priv, &p, &n, &u); if (ret) return ret; @@ -2250,7 +2302,8 @@ __drm_gpuvm_sm_map(struct drm_gpuvm *gpuvm, .va.addr =3D req_end, .va.range =3D end - req_end, .gem.obj =3D obj, - .gem.offset =3D offset + req_end - addr, + .gem.range =3D va->gem.range, + .gem.offset =3D offset, .flags =3D va->flags, }; struct drm_gpuva_op_unmap u =3D { @@ -2258,6 +2311,9 @@ __drm_gpuvm_sm_map(struct drm_gpuvm *gpuvm, .keep =3D merge, }; =20 + if (!(va->flags & DRM_GPUVA_REPEAT)) + n.gem.offset +=3D req_end - addr; + ret =3D op_remap_cb(ops, priv, NULL, &n, &u); if (ret) return ret; @@ -2294,6 +2350,7 @@ __drm_gpuvm_sm_unmap(struct drm_gpuvm *gpuvm, prev.va.addr =3D addr; prev.va.range =3D req_addr - addr; prev.gem.obj =3D obj; + prev.gem.range =3D va->gem.range; prev.gem.offset =3D offset; prev.flags =3D va->flags; =20 @@ -2304,7 +2361,10 @@ __drm_gpuvm_sm_unmap(struct drm_gpuvm *gpuvm, next.va.addr =3D req_end; next.va.range =3D end - req_end; next.gem.obj =3D obj; - next.gem.offset =3D offset + (req_end - addr); + prev.gem.range =3D va->gem.range; + next.gem.offset =3D offset; + if (!(va->flags & DRM_GPUVA_REPEAT)) + next.gem.offset +=3D req_end - addr; next.flags =3D va->flags; =20 next_split =3D true; diff --git a/include/drm/drm_gpuvm.h b/include/drm/drm_gpuvm.h index f77a89e791f1..629e8508f99f 100644 --- a/include/drm/drm_gpuvm.h +++ b/include/drm/drm_gpuvm.h @@ -56,10 +56,19 @@ enum drm_gpuva_flags { */ DRM_GPUVA_SPARSE =3D (1 << 1), =20 + /** + * @DRM_GPUVA_REPEAT: + * + * Flag indicating that the &drm_gpuva is a mapping of a GEM + * portion repeated multiple times to fill the virtual address + * range. + */ + DRM_GPUVA_REPEAT =3D (1 << 2), + /** * @DRM_GPUVA_USERBITS: user defined bits */ - DRM_GPUVA_USERBITS =3D (1 << 2), + DRM_GPUVA_USERBITS =3D (1 << 3), }; =20 /** @@ -111,6 +120,18 @@ struct drm_gpuva { */ u64 offset; =20 + /* + * @gem.range: the range of the GEM that is mapped + * + * When dealing with normal mappings, this must be zero. + * When flags has DRM_GPUVA_REPEAT set, this field must be + * smaller than va.range and va.range must be a multiple of + * gem.range. + * This is a u32 not a u64 because we expect repeated mappings + * to be pointing to relatively small portions of a GEM object. + */ + u32 range; + /** * @gem.obj: the mapped &drm_gem_object */ @@ -842,6 +863,17 @@ struct drm_gpuva_op_map { */ u64 offset; =20 + /* + * @gem.range: the range of the GEM that is mapped + * + * When dealing with normal mappings, this must be zero. + * When flags has DRM_GPUVA_REPEAT set, it must be smaller + * and be a multiple of va.range. This is a u32 not a u64 + * because we expect repeated mappings to be pointing to + * a relatively small portion of a GEM object. + */ + u32 range; + /** * @gem.obj: the &drm_gem_object to map */ @@ -1078,6 +1110,15 @@ struct drm_gpuvm_map_req { =20 /** @offset: offset in the GEM */ u64 offset; + + /** + * @range: size of the range of the GEM object to map + * + * Must be zero unless flags has DRM_GPUVA_REPEAT set. + * If DRM_GPUVA_REPEAT is set, this field must be less than va.range, + * and va.range must be a multiple of gem.range. + */ + u32 range; } gem; =20 /** @flags: combination of DRM_GPUVA_ flags describing the mapping proper= ties. */ --=20 2.47.2 From nobody Tue Oct 7 18:26:06 2025 Received: from bali.collaboradmins.com (bali.collaboradmins.com [148.251.105.195]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 3F1592E92DC for ; Mon, 7 Jul 2025 17:05:16 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=148.251.105.195 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1751907918; cv=none; b=awklF5CniZwWMgGupz6eaSeUr9Xf8ONZzg/KxtCXR6ZXORYcMFGhE2KRUt37meGxmaVMWU8XKcSjXjZyhEVsLyMgiChjW1KZTAa3PYprrPdMQNLPQ8g5j8NARK4w6ta4cIc5yKpFL8gNdGlOrnL1zg29aRSG+z9T7F3G/4SjnoY= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1751907918; c=relaxed/simple; bh=4ZCZQkyTb+SlHV2coiacmUH1fpzz9WLEXU3y+sU4p2k=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=MV8SmWYRD+uKD52LhguEbYkGqA739JvsFQrBNpBpE+EY+pr3HCE9mAnug5NuJBo62/PLfofT9D/Y31NlAbMYsAQtFumo1cE7cMWEcaX4s1MxD8MASxWHgHV0oloqwhTCQcI0Acuh9TiwpqStT2lQ8YgoXRvg37n1tZOT/PR7Pmo= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=collabora.com; spf=pass smtp.mailfrom=collabora.com; dkim=pass (2048-bit key) header.d=collabora.com header.i=@collabora.com header.b=ghNAlyIp; arc=none smtp.client-ip=148.251.105.195 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=collabora.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=collabora.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=collabora.com header.i=@collabora.com header.b="ghNAlyIp" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=collabora.com; s=mail; t=1751907914; bh=4ZCZQkyTb+SlHV2coiacmUH1fpzz9WLEXU3y+sU4p2k=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=ghNAlyIpJPqzidm+VRdktp31HxW+FbhFfOzT2HhW3mZPBgDUzJjtuw5vDHjexhz3Y FcXFTslLzvUBTL5snHlOeWmfZg6rypsgTDzY15qxQedxwSfya2yAwqaTvwkJdcVFoJ xVlM3PVSHK2Ih2AlRa6MQawtZ15RpLsYAi1120CEkBZ7aO3EuShDix1Goa8wm/J7Wz qMaeyrQTK15i65KLQav6MZTyACKcwAPxpf3/oG/mGpy76wiIfkFcBoBanaQZw0nlFX kZBrZjfhSE9MfbuXuDGRTAZt7qK343QCgPRBVIrQTdzCAwdwTIfXb3xfEkkZOFXPZE v0yr1l/7hlYtQ== Received: from debian-rockchip-rock5b-rk3588.. (unknown [90.168.160.154]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) (Authenticated sender: nanokatze) by bali.collaboradmins.com (Postfix) with ESMTPSA id 6A7EE17E046D; Mon, 7 Jul 2025 19:05:13 +0200 (CEST) From: Caterina Shablia To: "Maarten Lankhorst" , "Maxime Ripard" , "Thomas Zimmermann" , "David Airlie" , "Simona Vetter" , "Frank Binns" , "Matt Coster" , "Karol Herbst" , "Lyude Paul" , "Danilo Krummrich" , "Boris Brezillon" , "Steven Price" , "Liviu Dudau" , "Lucas De Marchi" , =?UTF-8?q?Thomas=20Hellstr=C3=B6m?= , "Rodrigo Vivi" Cc: dri-devel@lists.freedesktop.org, linux-kernel@vger.kernel.org, nouveau@lists.freedesktop.org, intel-xe@lists.freedesktop.org, asahi@lists.linux.dev, Asahi Lina , Caterina Shablia Subject: [PATCH v4 7/7] drm/panthor: Add support for repeated mappings Date: Mon, 7 Jul 2025 17:04:33 +0000 Message-ID: <20250707170442.1437009-8-caterina.shablia@collabora.com> X-Mailer: git-send-email 2.47.2 In-Reply-To: <20250707170442.1437009-1-caterina.shablia@collabora.com> References: <20250707170442.1437009-1-caterina.shablia@collabora.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Boris Brezillon This allows us to optimize mapping of a relatively small portion of a BO over and over in a large VA range, which is useful to support Vulkan sparse bindings in an efficient way. Signed-off-by: Boris Brezillon Co-developed-by: Caterina Shablia Signed-off-by: Caterina Shablia --- drivers/gpu/drm/panthor/panthor_drv.c | 3 +- drivers/gpu/drm/panthor/panthor_mmu.c | 78 ++++++++++++++++++++++++--- include/uapi/drm/panthor_drm.h | 23 ++++++++ 3 files changed, 95 insertions(+), 9 deletions(-) diff --git a/drivers/gpu/drm/panthor/panthor_drv.c b/drivers/gpu/drm/pantho= r/panthor_drv.c index 1116f2d2826e..585c07b07c42 100644 --- a/drivers/gpu/drm/panthor/panthor_drv.c +++ b/drivers/gpu/drm/panthor/panthor_drv.c @@ -1608,6 +1608,7 @@ static void panthor_debugfs_init(struct drm_minor *mi= nor) * - 1.3 - adds DRM_PANTHOR_GROUP_STATE_INNOCENT flag * - 1.4 - adds DRM_IOCTL_PANTHOR_BO_SET_LABEL ioctl * - 1.5 - adds DRM_PANTHOR_SET_USER_MMIO_OFFSET ioctl + * - 1.6 - adds DRM_PANTHOR_VM_BIND_OP_MAP_REPEAT flag */ static const struct drm_driver panthor_drm_driver =3D { .driver_features =3D DRIVER_RENDER | DRIVER_GEM | DRIVER_SYNCOBJ | @@ -1621,7 +1622,7 @@ static const struct drm_driver panthor_drm_driver =3D= { .name =3D "panthor", .desc =3D "Panthor DRM driver", .major =3D 1, - .minor =3D 5, + .minor =3D 6, =20 .gem_create_object =3D panthor_gem_create_object, .gem_prime_import_sg_table =3D drm_gem_shmem_prime_import_sg_table, diff --git a/drivers/gpu/drm/panthor/panthor_mmu.c b/drivers/gpu/drm/pantho= r/panthor_mmu.c index f0a22b775958..4ce9fff67d69 100644 --- a/drivers/gpu/drm/panthor/panthor_mmu.c +++ b/drivers/gpu/drm/panthor/panthor_mmu.c @@ -202,6 +202,9 @@ struct panthor_vm_op_ctx { /** @map.bo_offset: Offset in the buffer object. */ u64 bo_offset; =20 + /** @map.bo_repeat_range: Repeated BO range. */ + u32 bo_repeat_range; + /** * @map.sgt: sg-table pointing to pages backing the GEM object. * @@ -1007,6 +1010,26 @@ panthor_vm_map_pages(struct panthor_vm *vm, u64 iova= , int prot, return 0; } =20 +static int +panthor_vm_repeated_map_pages(struct panthor_vm *vm, u64 iova, int prot, + struct sg_table *sgt, u64 offset, u64 size, + u64 count) +{ + /* FIXME: we really need to optimize this at the io_pgtable level. */ + for (u64 i =3D 0; i < count; i++) { + int ret; + + ret =3D panthor_vm_map_pages(vm, iova + (size * i), prot, + sgt, offset, size); + if (ret) { + panthor_vm_unmap_pages(vm, iova, size * (i - 1)); + return ret; + } + } + + return 0; +} + static int flags_to_prot(u32 flags) { int prot =3D 0; @@ -1203,12 +1226,14 @@ panthor_vm_op_ctx_prealloc_vmas(struct panthor_vm_o= p_ctx *op_ctx) (DRM_PANTHOR_VM_BIND_OP_MAP_READONLY | \ DRM_PANTHOR_VM_BIND_OP_MAP_NOEXEC | \ DRM_PANTHOR_VM_BIND_OP_MAP_UNCACHED | \ + DRM_PANTHOR_VM_BIND_OP_MAP_REPEAT | \ DRM_PANTHOR_VM_BIND_OP_TYPE_MASK) =20 static int panthor_vm_prepare_map_op_ctx(struct panthor_vm_op_ctx *op_ctx, struct panthor_vm *vm, struct panthor_gem_object *bo, u64 offset, + u32 repeat_range, u64 size, u64 va, u32 flags) { @@ -1224,9 +1249,22 @@ static int panthor_vm_prepare_map_op_ctx(struct pant= hor_vm_op_ctx *op_ctx, (flags & DRM_PANTHOR_VM_BIND_OP_TYPE_MASK) !=3D DRM_PANTHOR_VM_BIND_O= P_TYPE_MAP) return -EINVAL; =20 - /* Make sure the VA and size are aligned and in-bounds. */ - if (size > bo->base.base.size || offset > bo->base.base.size - size) - return -EINVAL; + if (!(flags & DRM_PANTHOR_VM_BIND_OP_MAP_REPEAT)) { + /* Make sure the VA and size are in-bounds. */ + if (size > bo->base.base.size || offset > bo->base.base.size - size) + return -EINVAL; + } else { + /* Make sure the repeat_range is in-bounds. */ + if (repeat_range > bo->base.base.size || offset > bo->base.base.size - r= epeat_range) + return -EINVAL; + + /* Make sure size is a multiple of repeat_range */ + + u64 repeat_count =3D size; + + if (do_div(repeat_count, repeat_range)) + return -EINVAL; + } =20 /* If the BO has an exclusive VM attached, it can't be mapped to other VM= s. */ if (bo->exclusive_vm_root_gem && @@ -1295,6 +1333,7 @@ static int panthor_vm_prepare_map_op_ctx(struct panth= or_vm_op_ctx *op_ctx, drm_gem_shmem_unpin(&bo->base); =20 op_ctx->map.bo_offset =3D offset; + op_ctx->map.bo_repeat_range =3D repeat_range; =20 /* L1, L2 and L3 page tables. * We could optimize L3 allocation by iterating over the sgt and merging @@ -2112,9 +2151,22 @@ static int panthor_gpuva_sm_step_map(struct drm_gpuv= a_op *op, void *priv) =20 panthor_vma_init(vma, op_ctx->flags & PANTHOR_VM_MAP_FLAGS); =20 - ret =3D panthor_vm_map_pages(vm, op->map.va.addr, flags_to_prot(vma->flag= s), - op_ctx->map.sgt, op->map.gem.offset, - op->map.va.range); + if (op_ctx->flags & DRM_PANTHOR_VM_BIND_OP_MAP_REPEAT) { + u64 repeat_count =3D op->map.va.range; + + do_div(repeat_count, op->map.gem.range); + ret =3D panthor_vm_repeated_map_pages(vm, op->map.va.addr, + flags_to_prot(vma->flags), + op_ctx->map.sgt, + op->map.gem.offset, + op->map.gem.range, + repeat_count); + } else { + ret =3D panthor_vm_map_pages(vm, op->map.va.addr, + flags_to_prot(vma->flags), + op_ctx->map.sgt, op->map.gem.offset, + op->map.va.range); + } if (ret) return ret; =20 @@ -2237,7 +2289,7 @@ panthor_vm_exec_op(struct panthor_vm *vm, struct pant= hor_vm_op_ctx *op, =20 switch (op_type) { case DRM_PANTHOR_VM_BIND_OP_TYPE_MAP: { - const struct drm_gpuvm_map_req map_req =3D { + struct drm_gpuvm_map_req map_req =3D { .va.addr =3D op->va.addr, .va.range =3D op->va.range, .gem.obj =3D op->map.vm_bo->obj, @@ -2249,6 +2301,11 @@ panthor_vm_exec_op(struct panthor_vm *vm, struct pan= thor_vm_op_ctx *op, break; } =20 + if (op->flags & DRM_PANTHOR_VM_BIND_OP_MAP_REPEAT) { + map_req.flags |=3D DRM_GPUVA_REPEAT; + map_req.gem.range =3D op->map.bo_repeat_range; + } + ret =3D drm_gpuvm_sm_map(&vm->base, vm, &map_req); break; } @@ -2497,6 +2554,7 @@ panthor_vm_bind_prepare_op_ctx(struct drm_file *file, ret =3D panthor_vm_prepare_map_op_ctx(op_ctx, vm, gem ? to_panthor_bo(gem) : NULL, op->bo_offset, + op->bo_repeat_range, op->size, op->va, op->flags); @@ -2698,7 +2756,11 @@ int panthor_vm_map_bo_range(struct panthor_vm *vm, s= truct panthor_gem_object *bo struct panthor_vm_op_ctx op_ctx; int ret; =20 - ret =3D panthor_vm_prepare_map_op_ctx(&op_ctx, vm, bo, offset, size, va, = flags); + /* TODO: would be nice to replace with assert instead */ + if (flags & DRM_PANTHOR_VM_BIND_OP_MAP_REPEAT) + return -EINVAL; + + ret =3D panthor_vm_prepare_map_op_ctx(&op_ctx, vm, bo, offset, 0, size, v= a, flags); if (ret) return ret; =20 diff --git a/include/uapi/drm/panthor_drm.h b/include/uapi/drm/panthor_drm.h index e1f43deb7eca..ad278bc234b0 100644 --- a/include/uapi/drm/panthor_drm.h +++ b/include/uapi/drm/panthor_drm.h @@ -496,6 +496,17 @@ enum drm_panthor_vm_bind_op_flags { */ DRM_PANTHOR_VM_BIND_OP_MAP_UNCACHED =3D 1 << 2, =20 + /** + * @DRM_PANTHOR_VM_BIND_OP_MAP_REPEAT: Repeat a BO range + * + * Only valid with DRM_PANTHOR_VM_BIND_OP_TYPE_MAP. + * + * When this is set, a BO range is repeated over the VA range. + * drm_panthor_vm_bind_op::bo_repeat_range defines the size of the + * BO range to repeat. + */ + DRM_PANTHOR_VM_BIND_OP_MAP_REPEAT =3D 1 << 3, + /** * @DRM_PANTHOR_VM_BIND_OP_TYPE_MASK: Mask used to determine the type of = operation. */ @@ -560,6 +571,18 @@ struct drm_panthor_vm_bind_op { */ struct drm_panthor_obj_array syncs; =20 + /** + * @bo_repeat_range: The size of the range to be repeated. + * + * Must be zero if DRM_PANTHOR_VM_BIND_OP_MAP_REPEAT is not set in + * flags. + * + * Size must be a multiple of bo_repeat_range. + */ + __u32 bo_repeat_range; + + /** @pad: Padding field. MBZ. */ + __u32 pad; }; =20 /** --=20 2.47.2