From nobody Mon Nov 25 14:34:53 2024 Received: from out-186.mta1.migadu.com (out-186.mta1.migadu.com [95.215.58.186]) (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 5589121B869 for ; Fri, 25 Oct 2024 20:44:24 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=95.215.58.186 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1729889067; cv=none; b=o0nLbzR0YsmG+5eeou6TxEth9Uk+HqnLb9J6yWBYnTiAwXub5ZiZ6X+Y+amOyYwDf3ylFuJuDso4oovMkhBbC3psnaf2WWkcqACNVRc07Q/tX2+GHbJ6asvD8c+u+yFEnyVi724nBonYSwiZzIAqetIQu9n/zK7dFKkH5aKp5eQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1729889067; c=relaxed/simple; bh=1lo+2ZAWIVTEzvTgK6f3rEjm39eSxI9TvPWMmnp0I9E=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=PFDjzwdDaiFGiZ3C1MCm3aXgSbP8psq66kltSNqBMN1JrCXyVGBe8bOApyiSIlxw20xG1Ot4bPQHMeo+/jXhNK9Ga/VYR04MWSHN1l/DymrIWr+94IZJcr5THG9cbrVEkafTaFhG7ABsUhmlypTVslFjWTTqY2LuY8Qdp5F3Ex8= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.dev; spf=pass smtp.mailfrom=linux.dev; dkim=pass (1024-bit key) header.d=linux.dev header.i=@linux.dev header.b=RMf1+1cU; arc=none smtp.client-ip=95.215.58.186 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.dev Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linux.dev Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linux.dev header.i=@linux.dev header.b="RMf1+1cU" X-Report-Abuse: Please report any abuse attempt to abuse@migadu.com and include these headers. DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.dev; s=key1; t=1729889062; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=5eq6rCpBAPmzmyxJglOaWNSiBf8ToRPx9PYPV/1RZ4g=; b=RMf1+1cUzaAn7JLUa/8/psmRY+Z1jlrGLLsBvMdFK0dgZne5gxZWRpNg4QbaYKIgaarx4O pEmqUhjhmwd7obKJTR6jQBYn82Ky73sO2FO7vyiXYVRe0cYEWoL4kD7QZgVbpYCRyE9fJI GxMHVIps7t0GYwTK5l7ExPmfbCAASMo= From: Sui Jingfeng To: Lucas Stach , Russell King , Christian Gmeiner Cc: David Airlie , Simona Vetter , etnaviv@lists.freedesktop.org, dri-devel@lists.freedesktop.org, linux-kernel@vger.kernel.org, Sui Jingfeng Subject: [PATCH v2 1/2] drm/etnaviv: Record GPU visible size of GEM BO separately Date: Sat, 26 Oct 2024 04:43:54 +0800 Message-Id: <20241025204355.595805-2-sui.jingfeng@linux.dev> In-Reply-To: <20241025204355.595805-1-sui.jingfeng@linux.dev> References: <20241025204355.595805-1-sui.jingfeng@linux.dev> 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 X-Migadu-Flow: FLOW_OUT Content-Type: text/plain; charset="utf-8" The GPU visible size of a GEM BO is not necessarily PAGE_SIZE aligned, which happens when CPU page size is not equal to GPU page size. Extra precious resources such as GPU page tables and GPU TLBs may being paid because of this but never get used. Track the size of GPU visible part of GEM BO separately, ensure no GPUVA range wasting by aligning that size to GPU page size. Signed-off-by: Sui Jingfeng --- drivers/gpu/drm/etnaviv/etnaviv_gem.c | 11 +++++------ drivers/gpu/drm/etnaviv/etnaviv_gem.h | 5 +++++ 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/etnaviv/etnaviv_gem.c b/drivers/gpu/drm/etnavi= v/etnaviv_gem.c index 5c0c9d4e3be1..fabcaa3b9b25 100644 --- a/drivers/gpu/drm/etnaviv/etnaviv_gem.c +++ b/drivers/gpu/drm/etnaviv/etnaviv_gem.c @@ -543,7 +543,7 @@ static const struct drm_gem_object_funcs etnaviv_gem_ob= ject_funcs =3D { .vm_ops =3D &vm_ops, }; =20 -static int etnaviv_gem_new_impl(struct drm_device *dev, u32 flags, +static int etnaviv_gem_new_impl(struct drm_device *dev, u32 size, u32 flag= s, const struct etnaviv_gem_ops *ops, struct drm_gem_object **obj) { struct etnaviv_gem_object *etnaviv_obj; @@ -570,6 +570,7 @@ static int etnaviv_gem_new_impl(struct drm_device *dev,= u32 flags, if (!etnaviv_obj) return -ENOMEM; =20 + etnaviv_obj->size =3D ALIGN(size, SZ_4K); etnaviv_obj->flags =3D flags; etnaviv_obj->ops =3D ops; =20 @@ -590,15 +591,13 @@ int etnaviv_gem_new_handle(struct drm_device *dev, st= ruct drm_file *file, struct drm_gem_object *obj =3D NULL; int ret; =20 - size =3D PAGE_ALIGN(size); - - ret =3D etnaviv_gem_new_impl(dev, flags, &etnaviv_gem_shmem_ops, &obj); + ret =3D etnaviv_gem_new_impl(dev, size, flags, &etnaviv_gem_shmem_ops, &o= bj); if (ret) goto fail; =20 lockdep_set_class(&to_etnaviv_bo(obj)->lock, &etnaviv_shm_lock_class); =20 - ret =3D drm_gem_object_init(dev, obj, size); + ret =3D drm_gem_object_init(dev, obj, PAGE_ALIGN(size)); if (ret) goto fail; =20 @@ -627,7 +626,7 @@ int etnaviv_gem_new_private(struct drm_device *dev, siz= e_t size, u32 flags, struct drm_gem_object *obj; int ret; =20 - ret =3D etnaviv_gem_new_impl(dev, flags, ops, &obj); + ret =3D etnaviv_gem_new_impl(dev, size, flags, ops, &obj); if (ret) return ret; =20 diff --git a/drivers/gpu/drm/etnaviv/etnaviv_gem.h b/drivers/gpu/drm/etnavi= v/etnaviv_gem.h index a42d260cac2c..687555aae807 100644 --- a/drivers/gpu/drm/etnaviv/etnaviv_gem.h +++ b/drivers/gpu/drm/etnaviv/etnaviv_gem.h @@ -36,6 +36,11 @@ struct etnaviv_gem_object { const struct etnaviv_gem_ops *ops; struct mutex lock; =20 + /* + * The actual size that is visible to the GPU, not necessarily + * PAGE_SIZE aligned, but should be aligned to GPU page size. + */ + u32 size; u32 flags; =20 struct list_head gem_node; --=20 2.34.1 From nobody Mon Nov 25 14:34:53 2024 Received: from out-178.mta1.migadu.com (out-178.mta1.migadu.com [95.215.58.178]) (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 6A9B921E609 for ; Fri, 25 Oct 2024 20:44:27 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=95.215.58.178 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1729889071; cv=none; b=PAWnOsW+Mp3YF4L37caKMe2rxuJ96ILGaEvo68FnviXtlJOZvUyZhtJpnywDdh1hgh6hjjQSLV+dTp2SNLHXAYJCYV6o/25wXZJQsI7VAiZIyLuIgpDopqWEGpf2s3AEPDX0EA/SMqNFK2bLMHE/qrHxJkpusfGeGg1PqOqSIlI= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1729889071; c=relaxed/simple; bh=k4f66iZ2fv4fhq1QRX1Ek1uZ0lHnBYAvCswuVJMJc5o=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=ttyVlVMjwXxUlN4Mi7bdfg9ilApxHg9c1fXI4cZDYbzyOt/D/y3HaqPCriiUamMqlST6UN0gcIwcCjaBDR7OP7SJRExE3LNRHiL3DY2d699+jN/aJ/yJ2wpTSVCJ6FFj9OY4f3FgS3btE1FwTe7cBBBiO+dEw7IteOAX37KLYbo= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.dev; spf=pass smtp.mailfrom=linux.dev; dkim=pass (1024-bit key) header.d=linux.dev header.i=@linux.dev header.b=QoeNWVEt; arc=none smtp.client-ip=95.215.58.178 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.dev Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linux.dev Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linux.dev header.i=@linux.dev header.b="QoeNWVEt" X-Report-Abuse: Please report any abuse attempt to abuse@migadu.com and include these headers. DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.dev; s=key1; t=1729889065; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=+962+r2Cmig/FghXZjEwbQhCwYeyPYtwliaBbnwkoQA=; b=QoeNWVEt8LiByi9WMf3TXS8kEmo3fnlbfDJ4UlLhi1KXnCSB8EIN96t4ucyc3iPDbEYA9k sjqsMKNMZhlFevVDZ190+PuEStPiQKfCw7/5q3uaLJy7NYx/jiCkDLTIPlqsX2DN8G2bJt BsL8BzOiwVCePd+bKrdYK+Hcq7xymFY= From: Sui Jingfeng To: Lucas Stach , Russell King , Christian Gmeiner Cc: David Airlie , Simona Vetter , etnaviv@lists.freedesktop.org, dri-devel@lists.freedesktop.org, linux-kernel@vger.kernel.org, Sui Jingfeng Subject: [PATCH v2 2/2] drm/etnaviv: Map and unmap GPUVA range with respect to the GPUVA size Date: Sat, 26 Oct 2024 04:43:55 +0800 Message-Id: <20241025204355.595805-3-sui.jingfeng@linux.dev> In-Reply-To: <20241025204355.595805-1-sui.jingfeng@linux.dev> References: <20241025204355.595805-1-sui.jingfeng@linux.dev> 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 X-Migadu-Flow: FLOW_OUT Content-Type: text/plain; charset="utf-8" Etnaviv assumes that GPU page size is 4KiB, however, GPUVA ranges collision when using softpin capable GPUs on a non 4KiB CPU page size configuration. The root cause is that kernel side BO takes up bigger address space than userspace expect, the size of backing memory of GEM buffer objects are required to align to the CPU PAGE_SIZE. Therefore, results in userspace allocated GPUVA range fails to be inserted to the specified hole exactly. To solve this problem, record the GPU visiable size of a BO firstly, then map and unmap the SG entry strictly with respect to the total GPUVA size. Signed-off-by: Sui Jingfeng --- drivers/gpu/drm/etnaviv/etnaviv_mmu.c | 36 +++++++++------------------ 1 file changed, 12 insertions(+), 24 deletions(-) diff --git a/drivers/gpu/drm/etnaviv/etnaviv_mmu.c b/drivers/gpu/drm/etnavi= v/etnaviv_mmu.c index 1661d589bf3e..a2cd64bd2dc0 100644 --- a/drivers/gpu/drm/etnaviv/etnaviv_mmu.c +++ b/drivers/gpu/drm/etnaviv/etnaviv_mmu.c @@ -70,8 +70,10 @@ static int etnaviv_context_map(struct etnaviv_iommu_cont= ext *context, } =20 static int etnaviv_iommu_map(struct etnaviv_iommu_context *context, u32 io= va, + unsigned int va_len, struct sg_table *sgt, int prot) -{ struct scatterlist *sg; +{ + struct scatterlist *sg; unsigned int da =3D iova; unsigned int i; int ret; @@ -81,14 +83,16 @@ static int etnaviv_iommu_map(struct etnaviv_iommu_conte= xt *context, u32 iova, =20 for_each_sgtable_dma_sg(sgt, sg, i) { phys_addr_t pa =3D sg_dma_address(sg) - sg->offset; - size_t bytes =3D sg_dma_len(sg) + sg->offset; + unsigned int da_len =3D sg_dma_len(sg) + sg->offset; + unsigned int bytes =3D min_t(unsigned int, da_len, va_len); =20 - VERB("map[%d]: %08x %pap(%zx)", i, iova, &pa, bytes); + VERB("map[%d]: %08x %pap(%x)", i, iova, &pa, bytes); =20 ret =3D etnaviv_context_map(context, da, pa, bytes, prot); if (ret) goto fail; =20 + va_len -=3D bytes; da +=3D bytes; } =20 @@ -104,21 +108,7 @@ static int etnaviv_iommu_map(struct etnaviv_iommu_cont= ext *context, u32 iova, static void etnaviv_iommu_unmap(struct etnaviv_iommu_context *context, u32= iova, struct sg_table *sgt, unsigned len) { - struct scatterlist *sg; - unsigned int da =3D iova; - int i; - - for_each_sgtable_dma_sg(sgt, sg, i) { - size_t bytes =3D sg_dma_len(sg) + sg->offset; - - etnaviv_context_unmap(context, da, bytes); - - VERB("unmap[%d]: %08x(%zx)", i, iova, bytes); - - BUG_ON(!PAGE_ALIGNED(bytes)); - - da +=3D bytes; - } + etnaviv_context_unmap(context, iova, len); =20 context->flush_seq++; } @@ -131,7 +121,7 @@ static void etnaviv_iommu_remove_mapping(struct etnaviv= _iommu_context *context, lockdep_assert_held(&context->lock); =20 etnaviv_iommu_unmap(context, mapping->vram_node.start, - etnaviv_obj->sgt, etnaviv_obj->base.size); + etnaviv_obj->sgt, etnaviv_obj->size); drm_mm_remove_node(&mapping->vram_node); } =20 @@ -305,16 +295,14 @@ int etnaviv_iommu_map_gem(struct etnaviv_iommu_contex= t *context, node =3D &mapping->vram_node; =20 if (va) - ret =3D etnaviv_iommu_insert_exact(context, node, - etnaviv_obj->base.size, va); + ret =3D etnaviv_iommu_insert_exact(context, node, etnaviv_obj->size, va); else - ret =3D etnaviv_iommu_find_iova(context, node, - etnaviv_obj->base.size); + ret =3D etnaviv_iommu_find_iova(context, node, etnaviv_obj->size); if (ret < 0) goto unlock; =20 mapping->iova =3D node->start; - ret =3D etnaviv_iommu_map(context, node->start, sgt, + ret =3D etnaviv_iommu_map(context, node->start, etnaviv_obj->size, sgt, ETNAVIV_PROT_READ | ETNAVIV_PROT_WRITE); =20 if (ret < 0) { --=20 2.34.1