From nobody Tue Feb 10 01:15:41 2026 Received: from mail.marcansoft.com (marcansoft.com [212.63.210.85]) (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 D5A941E7C3E for ; Sun, 2 Feb 2025 13:45:18 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=212.63.210.85 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1738503920; cv=none; b=gh2WL8MJiW0vrU79xOjeS9ssxZBZho2SCkM9NESMZIqydJbE766wNUYFjKJHyode6TZ9lfxifdVL+uSAbTPYWYpJP17TAIepMs6Soxod1/pmiwa+zKwwEAO/qiRyrjQYtz1YJB7NIfQCgC0HcJoWLAxAnhJuZ9JHDqi4GGJV5jo= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1738503920; c=relaxed/simple; bh=OLGzWIkyIZHxUGup6PI174LIKXzrBy2ulBvLvPIQBVU=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=ullwIclU5jLHJPYEjjoJSy8ELJwXmnpFfCZsWaJ+8mmtCDHXIA/6+MdGsArZB2b3ZDgIgBbOdrGu5JsuDHHE5UIKM+SUzWhnpECKTUAmhRpWFiLCUJ8zKsSz4gmFuyQruWKqQWX8VufYEtkeQ0mMB+iRpPhN3cFX4f37soMS390= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=asahilina.net; spf=pass smtp.mailfrom=asahilina.net; dkim=pass (2048-bit key) header.d=asahilina.net header.i=@asahilina.net header.b=dODRLE/Y; arc=none smtp.client-ip=212.63.210.85 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=asahilina.net Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=asahilina.net Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=asahilina.net header.i=@asahilina.net header.b="dODRLE/Y" Received: from [127.0.0.1] (localhost [127.0.0.1]) (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: sendonly@marcansoft.com) by mail.marcansoft.com (Postfix) with ESMTPSA id 2040542A28; Sun, 2 Feb 2025 13:45:15 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=asahilina.net; s=default; t=1738503917; bh=OLGzWIkyIZHxUGup6PI174LIKXzrBy2ulBvLvPIQBVU=; h=From:Date:Subject:References:In-Reply-To:To:Cc; b=dODRLE/YYhpd1VLINJf+HOKqWPI6mmFrs7q7hUhu0i27Tqczy0ZhuyURvQWYbmMW6 tqUj3T9wCleVIM5I6kAWvzbPjtR5hnd81k18bucIhD5uG1wfrLf8BONRJWzV9pzI8q Zu0YyCqg6kWW5EQcAcFNeSdPMYncNoZkbaFV8h1IYPSBi8lIeGqvudnBmNGPCHxCV6 aojGx3PX8rzeU2xQjS7fgYcQ9oVTKaz50GEFJpkJgAgdGfbIxlQ2B+50b0zZWYm+lN tPcNks7AtZb4kej3KjvT26Y9mqcUCN0efvoakw6Yxn8YP55bRo512VEN0B1DFkhfwS ZCPtH5kE0paXA== From: Asahi Lina Date: Sun, 02 Feb 2025 22:34:52 +0900 Subject: [PATCH 3/4] drm/gpuvm: Add DRM_GPUVA_SINGLE_PAGE flag and logic Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20250202-gpuvm-single-page-v1-3-8cbd44fdcbd4@asahilina.net> References: <20250202-gpuvm-single-page-v1-0-8cbd44fdcbd4@asahilina.net> In-Reply-To: <20250202-gpuvm-single-page-v1-0-8cbd44fdcbd4@asahilina.net> 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_Hellstr=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 X-Mailer: b4 0.14.2 X-Developer-Signature: v=1; a=ed25519-sha256; t=1738503908; l=5308; i=lina@asahilina.net; s=20240902; h=from:subject:message-id; bh=OLGzWIkyIZHxUGup6PI174LIKXzrBy2ulBvLvPIQBVU=; b=yHAWee7eKfU/M+siam2O4ZurfxGe7VrVpVlxV/3l/qgXoL/GSNoRZlwmnckTKPVaKRYnqfcN8 d0RhFTj/uVzC+NljuXzK9PCUP8z0302kuahenSXQB0FEMqee/8Xff2R X-Developer-Key: i=lina@asahilina.net; a=ed25519; pk=tpv7cWfUnHNw5jwf6h4t0gGgglt3/xcwlfs0+A/uUu8= 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. Doing this through individual single-page 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 single page mapping, which is repeated all over the entire requested VA range. This does two things in drm_gpuvm: - Restricts the merge logic, so only drm_gpuvas with the same flag state are considered "mergeable" (both SINGLE_PAGE or both not) - Removes the GEM buffer offset logic for SINGLE_PAGE mappings. Since a single page from the buffer is repeatedly mapped across the entire VA range, the offset never needs to have an offset added to it when mappings are split. Note that this does not require drm_gpuva to know anything about the page size. Signed-off-by: Asahi Lina --- drivers/gpu/drm/drm_gpuvm.c | 44 ++++++++++++++++++++++++++++++++++-------= --- include/drm/drm_gpuvm.h | 9 ++++++++- 2 files changed, 42 insertions(+), 11 deletions(-) diff --git a/drivers/gpu/drm/drm_gpuvm.c b/drivers/gpu/drm/drm_gpuvm.c index 7443be1fe4de4653ec40ca4b874df30297af7faf..51429d90875e3f2370c4f8975d6= fd813842b8976 100644 --- a/drivers/gpu/drm/drm_gpuvm.c +++ b/drivers/gpu/drm/drm_gpuvm.c @@ -670,6 +670,12 @@ * } */ =20 +/** + * Mask of flags which must match to consider a drm_gpuva eligible for mer= ging + * with a new overlaid mapping. + */ +#define DRM_GPUVA_UNMERGEABLE_FLAGS DRM_GPUVA_SINGLE_PAGE + /** * get_next_vm_bo_from_list() - get the next vm_bo element * @__gpuvm: the &drm_gpuvm @@ -2121,6 +2127,9 @@ __drm_gpuvm_sm_map(struct drm_gpuvm *gpuvm, u64 range =3D va->va.range; u64 end =3D addr + range; bool merge =3D !!va->gem.obj; + bool single_page =3D va->flags & DRM_GPUVA_SINGLE_PAGE; + + merge &=3D !((va->flags ^ req_flags) & DRM_GPUVA_UNMERGEABLE_FLAGS); =20 if (addr =3D=3D req_addr) { merge &=3D obj =3D=3D req_obj && @@ -2145,7 +2154,8 @@ __drm_gpuvm_sm_map(struct drm_gpuvm *gpuvm, .va.addr =3D req_end, .va.range =3D range - req_range, .gem.obj =3D obj, - .gem.offset =3D offset + req_range, + .gem.offset =3D offset + + (single_page ? 0 : req_range), .flags =3D va->flags, }; struct drm_gpuva_op_unmap u =3D { @@ -2169,8 +2179,12 @@ __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_obj; + if (single_page) + merge &=3D offset =3D=3D req_offset; + else + merge &=3D offset + ls_range =3D=3D req_offset; + u.keep =3D merge; =20 if (end =3D=3D req_end) { @@ -2192,8 +2206,9 @@ __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_range, + .gem.offset =3D offset + + (single_page ? 0 : + ls_range + req_range), .flags =3D va->flags, }; =20 @@ -2203,9 +2218,13 @@ __drm_gpuvm_sm_map(struct drm_gpuvm *gpuvm, break; } } else if (addr > req_addr) { - merge &=3D obj =3D=3D req_obj && - offset =3D=3D req_offset + - (addr - req_addr); + merge &=3D obj =3D=3D req_obj; + + if (single_page) + merge &=3D offset =3D=3D req_offset; + else + merge &=3D offset =3D=3D req_offset + + (addr - req_addr); =20 if (end =3D=3D req_end) { ret =3D op_unmap_cb(ops, priv, va, merge); @@ -2226,7 +2245,9 @@ __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.offset =3D offset + + (single_page ? 0 : + req_end - addr), .flags =3D va->flags, }; struct drm_gpuva_op_unmap u =3D { @@ -2268,6 +2289,7 @@ __drm_gpuvm_sm_unmap(struct drm_gpuvm *gpuvm, u64 addr =3D va->va.addr; u64 range =3D va->va.range; u64 end =3D addr + range; + bool single_page =3D va->flags & DRM_GPUVA_SINGLE_PAGE; =20 if (addr < req_addr) { prev.va.addr =3D addr; @@ -2283,7 +2305,9 @@ __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); + next.gem.offset =3D offset; + if (!single_page) + 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 42b29adfabdaf193b1e1a02f9ab48ab0dd0e60d4..dfeec61908b1a8295ae08b26bef= 211d3d4fda85b 100644 --- a/include/drm/drm_gpuvm.h +++ b/include/drm/drm_gpuvm.h @@ -56,10 +56,17 @@ enum drm_gpuva_flags { */ DRM_GPUVA_SPARSE =3D (1 << 1), =20 + /** + * @DRM_GPUVA_SINGLE_PAGE: + * + * Flag indicating that the &drm_gpuva is a single-page mapping. + */ + DRM_GPUVA_SINGLE_PAGE =3D (1 << 2), + /** * @DRM_GPUVA_USERBITS: user defined bits */ - DRM_GPUVA_USERBITS =3D (1 << 2), + DRM_GPUVA_USERBITS =3D (1 << 3), }; =20 /** --=20 2.47.1