From nobody Tue Feb 10 02:46:24 2026 Received: from sender4-pp-f112.zoho.com (sender4-pp-f112.zoho.com [136.143.188.112]) (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 A0B471DE4EA for ; Tue, 18 Feb 2025 23:29:23 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=pass smtp.client-ip=136.143.188.112 ARC-Seal: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1739921365; cv=pass; b=Bn7UI5SSO+N8qWlDp2foTy63ZTLndho3o5aw5QLLGFK2Nph3oJiW27aHjf/vSpSM32gZCdw+k76wRs3O7ztyMYH/VYWjOU0sGEqNHZyj0oeLYe4cJW9XNwWnn6nIBu9hgiuhOtI27EklvyW3lsfWosd5Llt7SuL/8CBD137nTFU= ARC-Message-Signature: i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1739921365; c=relaxed/simple; bh=0rrbFhPeDnBvIhYQOXOX3p6n4uxnsW//+9av7ugA6mU=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=R6lTXLV2kEES/vj9b7ph8LnwlrUhbVskJPS1hX+nkwWVJ/NET7jVmUKv0Ncng9E2jc0yEXkOCOspSiRqPxknrXWi/+QfaRcP1ndPHlJQFw5ocWT6mksBgdq3qmn2oIcHPcXmztu8LCBuSm7/oXPK7oOem5XzFBor1bNqEhCS+WU= ARC-Authentication-Results: i=2; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=collabora.com; spf=pass smtp.mailfrom=collabora.com; dkim=pass (1024-bit key) header.d=collabora.com header.i=adrian.larumbe@collabora.com header.b=LPRN0EBK; arc=pass smtp.client-ip=136.143.188.112 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 (1024-bit key) header.d=collabora.com header.i=adrian.larumbe@collabora.com header.b="LPRN0EBK" ARC-Seal: i=1; a=rsa-sha256; t=1739921346; cv=none; d=zohomail.com; s=zohoarc; b=Qifcp8XYul+frmQSo8lIl216jfu1LGHu/smbtO+yxc8piOwYPhaM/2+MdAUrj/r9TYV8Y37/HVQ/wFjQ5X+fNvBZU7z2BTaPBqyOc+4PLJeIfRUGWEIefTtKDFx1ulK4d0RAXu8A+cz5KdqZi+qMXbGpTAgodM8EbDAXGjcydTI= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1739921346; h=Content-Type:Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:MIME-Version:Message-ID:References:Subject:Subject:To:To:Message-Id:Reply-To; bh=XNOD0+zkb7PNYrrdBX15Ic1+43Bxv9rI1DSYcDxeTZE=; b=i+A8U+2f+RILhuuDeJ0Q6I8b33LJ64AXfwpznqQS0PTWRUiF51IQ2N3ZF3Io3hoKEmy5qEDOtnQwBuVHqj9KG74TbdbOIHkMcHVtwIHz+cFclZtTeq6nL8PPHpMA2SLkc/FJUCvgCV/sAPFd0Sl0lEZmZJaViJ5GfPMbC7dYqac= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass header.i=collabora.com; spf=pass smtp.mailfrom=adrian.larumbe@collabora.com; dmarc=pass header.from= DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; t=1739921346; s=zohomail; d=collabora.com; i=adrian.larumbe@collabora.com; h=From:From:To:To:Cc:Cc:Subject:Subject:Date:Date:Message-ID:In-Reply-To:References:MIME-Version:Content-Type:Content-Transfer-Encoding:Message-Id:Reply-To; bh=XNOD0+zkb7PNYrrdBX15Ic1+43Bxv9rI1DSYcDxeTZE=; b=LPRN0EBKk3GnEYb72Xr1ToNxXHID31v1QyhTh8veT/Euxg9bRaoKE5ihT7mSArwg 0z+fJwEi9dpTY+NHLpw7tghrabCPmF2V94CmZuNtP1crATAaQ1RwpjwDbZXDPTrfMEP xDymQHBUabu0ibUTHVS+O50I5lZs+e9XuuDBDNbM= Received: by mx.zohomail.com with SMTPS id 1739921345075345.4757482949359; Tue, 18 Feb 2025 15:29:05 -0800 (PST) From: =?UTF-8?q?Adri=C3=A1n=20Larumbe?= To: dri-devel@lists.freedesktop.org, linux-kernel@vger.kernel.org, Boris Brezillon , Steven Price , Rob Herring , Maarten Lankhorst , Maxime Ripard , Thomas Zimmermann , David Airlie , Simona Vetter Cc: kernel@collabora.com, =?UTF-8?q?Adri=C3=A1n=20Larumbe?= Subject: [RFC PATCH 6/7] drm/panfrost: Use shmem sparse allocation for heap BOs Date: Tue, 18 Feb 2025 23:25:36 +0000 Message-ID: <20250218232552.3450939-7-adrian.larumbe@collabora.com> X-Mailer: git-send-email 2.47.1 In-Reply-To: <20250218232552.3450939-1-adrian.larumbe@collabora.com> References: <20250218232552.3450939-1-adrian.larumbe@collabora.com> 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 Panfrost heap BOs grow on demand when the GPU triggers a page fault after accessing an address within the BO's virtual range. We still store the sgts we get back from the shmem sparse allocation functi= on, since it was decided management of sparse memory SGTs should be done by cli= ent drivers rather than the shmem subsystem. Signed-off-by: Adri=C3=A1n Larumbe --- drivers/gpu/drm/panfrost/panfrost_gem.c | 12 ++-- drivers/gpu/drm/panfrost/panfrost_gem.h | 2 +- drivers/gpu/drm/panfrost/panfrost_mmu.c | 85 +++++-------------------- 3 files changed, 25 insertions(+), 74 deletions(-) diff --git a/drivers/gpu/drm/panfrost/panfrost_gem.c b/drivers/gpu/drm/panf= rost/panfrost_gem.c index 8e0ff3efede7..0cda2c4e524f 100644 --- a/drivers/gpu/drm/panfrost/panfrost_gem.c +++ b/drivers/gpu/drm/panfrost/panfrost_gem.c @@ -40,10 +40,10 @@ static void panfrost_gem_free_object(struct drm_gem_obj= ect *obj) int n_sgt =3D bo->base.base.size / SZ_2M; =20 for (i =3D 0; i < n_sgt; i++) { - if (bo->sgts[i].sgl) { - dma_unmap_sgtable(pfdev->dev, &bo->sgts[i], + if (bo->sgts[i]) { + dma_unmap_sgtable(pfdev->dev, bo->sgts[i], DMA_BIDIRECTIONAL, 0); - sg_free_table(&bo->sgts[i]); + sg_free_table(bo->sgts[i]); } } kvfree(bo->sgts); @@ -274,7 +274,11 @@ panfrost_gem_create(struct drm_device *dev, size_t siz= e, u32 flags) if (flags & PANFROST_BO_HEAP) size =3D roundup(size, SZ_2M); =20 - shmem =3D drm_gem_shmem_create(dev, size); + if (flags & PANFROST_BO_HEAP) + shmem =3D drm_gem_shmem_create_sparse(dev, size); + else + shmem =3D drm_gem_shmem_create(dev, size); + if (IS_ERR(shmem)) return ERR_CAST(shmem); =20 diff --git a/drivers/gpu/drm/panfrost/panfrost_gem.h b/drivers/gpu/drm/panf= rost/panfrost_gem.h index 7516b7ecf7fe..2a8d0752011e 100644 --- a/drivers/gpu/drm/panfrost/panfrost_gem.h +++ b/drivers/gpu/drm/panfrost/panfrost_gem.h @@ -11,7 +11,7 @@ struct panfrost_mmu; =20 struct panfrost_gem_object { struct drm_gem_shmem_object base; - struct sg_table *sgts; + struct sg_table **sgts; =20 /* * Use a list for now. If searching a mapping ever becomes the diff --git a/drivers/gpu/drm/panfrost/panfrost_mmu.c b/drivers/gpu/drm/panf= rost/panfrost_mmu.c index b91019cd5acb..4a78ff9ca293 100644 --- a/drivers/gpu/drm/panfrost/panfrost_mmu.c +++ b/drivers/gpu/drm/panfrost/panfrost_mmu.c @@ -441,14 +441,11 @@ addr_to_mapping(struct panfrost_device *pfdev, int as= , u64 addr) static int panfrost_mmu_map_fault_addr(struct panfrost_device *pfdev, int = as, u64 addr) { - int ret, i; struct panfrost_gem_mapping *bomapping; struct panfrost_gem_object *bo; - struct address_space *mapping; - struct drm_gem_object *obj; pgoff_t page_offset; struct sg_table *sgt; - struct page **pages; + int ret =3D 0; =20 bomapping =3D addr_to_mapping(pfdev, as, addr); if (!bomapping) @@ -459,94 +456,44 @@ static int panfrost_mmu_map_fault_addr(struct panfros= t_device *pfdev, int as, dev_WARN(pfdev->dev, "matching BO is not heap type (GPU VA =3D %llx)", bomapping->mmnode.start << PAGE_SHIFT); ret =3D -EINVAL; - goto err_bo; + goto fault_out; } WARN_ON(bomapping->mmu->as !=3D as); =20 /* Assume 2MB alignment and size multiple */ addr &=3D ~((u64)SZ_2M - 1); - page_offset =3D addr >> PAGE_SHIFT; - page_offset -=3D bomapping->mmnode.start; + page_offset =3D (addr >> PAGE_SHIFT) - bomapping->mmnode.start; =20 - obj =3D &bo->base.base; - - dma_resv_lock(obj->resv, NULL); - - if (!bo->base.pages) { + if (!bo->sgts) { bo->sgts =3D kvmalloc_array(bo->base.base.size / SZ_2M, - sizeof(struct sg_table), GFP_KERNEL | __GFP_ZERO); + sizeof(struct sg_table *), GFP_KERNEL | __GFP_ZERO); if (!bo->sgts) { ret =3D -ENOMEM; - goto err_unlock; - } - - pages =3D kvmalloc_array(bo->base.base.size >> PAGE_SHIFT, - sizeof(struct page *), GFP_KERNEL | __GFP_ZERO); - if (!pages) { - kvfree(bo->sgts); - bo->sgts =3D NULL; - ret =3D -ENOMEM; - goto err_unlock; - } - bo->base.pages =3D pages; - bo->base.pages_use_count =3D 1; - } else { - pages =3D bo->base.pages; - if (pages[page_offset]) { - /* Pages are already mapped, bail out. */ - goto out; + goto fault_out; } } =20 - mapping =3D bo->base.base.filp->f_mapping; - mapping_set_unevictable(mapping); + sgt =3D drm_gem_shmem_get_sparse_pages_sgt(&bo->base, NUM_FAULT_PAGES, pa= ge_offset); + if (IS_ERR(sgt)) { + if (WARN_ON(PTR_ERR(sgt) !=3D -EEXIST)) + ret =3D PTR_ERR(sgt); + else + ret =3D 0; =20 - for (i =3D page_offset; i < page_offset + NUM_FAULT_PAGES; i++) { - /* Can happen if the last fault only partially filled this - * section of the pages array before failing. In that case - * we skip already filled pages. - */ - if (pages[i]) - continue; - - pages[i] =3D shmem_read_mapping_page(mapping, i); - if (IS_ERR(pages[i])) { - ret =3D PTR_ERR(pages[i]); - pages[i] =3D NULL; - goto err_unlock; - } + goto fault_out; } =20 - sgt =3D &bo->sgts[page_offset / (SZ_2M / PAGE_SIZE)]; - ret =3D sg_alloc_table_from_pages(sgt, pages + page_offset, - NUM_FAULT_PAGES, 0, SZ_2M, GFP_KERNEL); - if (ret) - goto err_unlock; - - ret =3D dma_map_sgtable(pfdev->dev, sgt, DMA_BIDIRECTIONAL, 0); - if (ret) - goto err_map; - mmu_map_sg(pfdev, bomapping->mmu, addr, IOMMU_WRITE | IOMMU_READ | IOMMU_NOEXEC, sgt); =20 + bo->sgts[page_offset / (SZ_2M / PAGE_SIZE)] =3D sgt; + bomapping->active =3D true; bo->heap_rss_size +=3D SZ_2M; =20 dev_dbg(pfdev->dev, "mapped page fault @ AS%d %llx", as, addr); =20 -out: - dma_resv_unlock(obj->resv); - - panfrost_gem_mapping_put(bomapping); - - return 0; - -err_map: - sg_free_table(sgt); -err_unlock: - dma_resv_unlock(obj->resv); -err_bo: +fault_out: panfrost_gem_mapping_put(bomapping); return ret; } --=20 2.47.1