From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-12.8 required=3.0 tests=BAYES_00,DKIM_INVALID, DKIM_SIGNED,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_PATCH,MAILING_LIST_MULTI, SIGNED_OFF_BY,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED,USER_AGENT_GIT autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id B71AFC4741F for ; Wed, 30 Sep 2020 17:52:07 +0000 (UTC) Received: from kanga.kvack.org (kanga.kvack.org [205.233.56.17]) by mail.kernel.org (Postfix) with ESMTP id 53FE1207F7 for ; Wed, 30 Sep 2020 17:52:07 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=fail reason="signature verification failed" (2048-bit key) header.d=infradead.org header.i=@infradead.org header.b="gc8Cu/9E" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 53FE1207F7 Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=lst.de Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=owner-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix) id 60D46900004; Wed, 30 Sep 2020 13:52:03 -0400 (EDT) Received: by kanga.kvack.org (Postfix, from userid 40) id 5C59F900002; Wed, 30 Sep 2020 13:52:03 -0400 (EDT) X-Delivered-To: int-list-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix, from userid 63042) id 29458900005; Wed, 30 Sep 2020 13:52:03 -0400 (EDT) X-Delivered-To: linux-mm@kvack.org Received: from forelay.hostedemail.com (smtprelay0143.hostedemail.com [216.40.44.143]) by kanga.kvack.org (Postfix) with ESMTP id 06943900004 for ; Wed, 30 Sep 2020 13:52:03 -0400 (EDT) Received: from smtpin23.hostedemail.com (10.5.19.251.rfc1918.com [10.5.19.251]) by forelay04.hostedemail.com (Postfix) with ESMTP id BC6F93D0F for ; Wed, 30 Sep 2020 17:52:02 +0000 (UTC) X-FDA: 77320471284.23.pin61_3300a3e27194 Received: from filter.hostedemail.com (10.5.16.251.rfc1918.com [10.5.16.251]) by smtpin23.hostedemail.com (Postfix) with ESMTP id AC3E337610 for ; Wed, 30 Sep 2020 17:52:02 +0000 (UTC) X-HE-Tag: pin61_3300a3e27194 X-Filterd-Recvd-Size: 7892 Received: from casper.infradead.org (casper.infradead.org [90.155.50.34]) by imf39.hostedemail.com (Postfix) with ESMTP for ; Wed, 30 Sep 2020 17:52:02 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=infradead.org; s=casper.20170209; h=Content-Transfer-Encoding:MIME-Version: References:In-Reply-To:Message-Id:Date:Subject:Cc:To:From:Sender:Reply-To: Content-Type:Content-ID:Content-Description; bh=giWGs+AwTWNV8LHpMiZma9cexmVqWf+SNEc+oXKQq0g=; b=gc8Cu/9Ep04/cNHhtVAeFa674D zmMnmMz0pFOZAswMboW9Wz7S7p/nm0RwMrBEiA1m1mLUFlbYp5G1UqNu5uGVVUqpdf5h2iMYVsyzS nTYpVR1f6i6LfcxhN8x77KKOnmNA6wQQ8sZYhH06NEL60WIhblkDoHJR5m9y4NXHDOLiAXfWntVTx QKMWe5aQlsxGdcTFNj53XhspaqiR5soZ8sPBUwgsTi5vAhPXxCiOiX9K4u5IGC+1P8VvevgsLCzRG Ns26rIc3Gx62UuCNirjJCIVCe7AuoBSq/0P5Q38CkkrBhcIWx7wUqGLGDsphbtE6XLrY8d+tPZT5E Q+ZGTjSg==; Received: from [2001:4bb8:180:7b62:c70:4a89:bc61:4] (helo=localhost) by casper.infradead.org with esmtpsa (Exim 4.92.3 #3 (Red Hat Linux)) id 1kNgGW-0001Cd-FB; Wed, 30 Sep 2020 17:51:45 +0000 From: Christoph Hellwig To: Andrew Morton Cc: Peter Zijlstra , Boris Ostrovsky , Juergen Gross , Stefano Stabellini , Jani Nikula , Joonas Lahtinen , Tvrtko Ursulin , Chris Wilson , Matthew Auld , Rodrigo Vivi , Minchan Kim , Matthew Wilcox , Nitin Gupta , x86@kernel.org, xen-devel@lists.xenproject.org, linux-kernel@vger.kernel.org, intel-gfx@lists.freedesktop.org, dri-devel@lists.freedesktop.org, linux-mm@kvack.org, Tvrtko Ursulin Subject: [PATCH 07/10] drm/i915: use vmap in i915_gem_object_map Date: Wed, 30 Sep 2020 19:51:30 +0200 Message-Id: <20200930175133.1252382-8-hch@lst.de> X-Mailer: git-send-email 2.28.0 In-Reply-To: <20200930175133.1252382-1-hch@lst.de> References: <20200930175133.1252382-1-hch@lst.de> MIME-Version: 1.0 X-SRS-Rewrite: SMTP reverse-path rewritten from by casper.infradead.org. See http://www.infradead.org/rpr.html Content-Transfer-Encoding: quoted-printable X-Bogosity: Ham, tests=bogofilter, spamicity=0.000000, version=1.2.4 Sender: owner-linux-mm@kvack.org Precedence: bulk X-Loop: owner-majordomo@kvack.org List-ID: i915_gem_object_map implements fairly low-level vmap functionality in a driver. Split it into two helpers, one for remapping kernel memory which can use vmap, and one for I/O memory that uses vmap_pfn. The only practical difference is that alloc_vm_area prefeaults the vmalloc area PTEs, which doesn't seem to be required here for the kernel memory case (and could be added to vmap using a flag if actually required). Signed-off-by: Christoph Hellwig Reviewed-by: Tvrtko Ursulin --- drivers/gpu/drm/i915/Kconfig | 1 + drivers/gpu/drm/i915/gem/i915_gem_pages.c | 106 +++++++++++----------- 2 files changed, 52 insertions(+), 55 deletions(-) diff --git a/drivers/gpu/drm/i915/Kconfig b/drivers/gpu/drm/i915/Kconfig index 9afa5c4a6bf006..1e1cb245fca778 100644 --- a/drivers/gpu/drm/i915/Kconfig +++ b/drivers/gpu/drm/i915/Kconfig @@ -25,6 +25,7 @@ config DRM_I915 select CRC32 select SND_HDA_I915 if SND_HDA_CORE select CEC_CORE if CEC_NOTIFIER + select VMAP_PFN help Choose this option if you have a system that has "Intel Graphics Media Accelerator" or "HD Graphics" integrated graphics, diff --git a/drivers/gpu/drm/i915/gem/i915_gem_pages.c b/drivers/gpu/drm/= i915/gem/i915_gem_pages.c index e8a083743e0927..5c290cb3bada50 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_pages.c +++ b/drivers/gpu/drm/i915/gem/i915_gem_pages.c @@ -234,50 +234,23 @@ int __i915_gem_object_put_pages(struct drm_i915_gem= _object *obj) return err; } =20 -static inline pte_t iomap_pte(resource_size_t base, - dma_addr_t offset, - pgprot_t prot) -{ - return pte_mkspecial(pfn_pte((base + offset) >> PAGE_SHIFT, prot)); -} - /* The 'mapping' part of i915_gem_object_pin_map() below */ -static void *i915_gem_object_map(struct drm_i915_gem_object *obj, - enum i915_map_type type) +static void *i915_gem_object_map_page(struct drm_i915_gem_object *obj, + enum i915_map_type type) { - unsigned long n_pte =3D obj->base.size >> PAGE_SHIFT; - struct sg_table *sgt =3D obj->mm.pages; - pte_t *stack[32], **mem; - struct vm_struct *area; + unsigned long n_pages =3D obj->base.size >> PAGE_SHIFT, i; + struct page *stack[32], **pages =3D stack, *page; + struct sgt_iter iter; pgprot_t pgprot; - - if (!i915_gem_object_has_struct_page(obj) && type !=3D I915_MAP_WC) - return NULL; - - /* A single page can always be kmapped */ - if (n_pte =3D=3D 1 && type =3D=3D I915_MAP_WB) - return kmap(sg_page(sgt->sgl)); - - mem =3D stack; - if (n_pte > ARRAY_SIZE(stack)) { - /* Too big for stack -- allocate temporary array instead */ - mem =3D kvmalloc_array(n_pte, sizeof(*mem), GFP_KERNEL); - if (!mem) - return NULL; - } - - area =3D alloc_vm_area(obj->base.size, mem); - if (!area) { - if (mem !=3D stack) - kvfree(mem); - return NULL; - } + void *vaddr; =20 switch (type) { default: MISSING_CASE(type); fallthrough; /* to use PAGE_KERNEL anyway */ case I915_MAP_WB: + if (n_pages =3D=3D 1) + return kmap(sg_page(obj->mm.pages->sgl)); pgprot =3D PAGE_KERNEL; break; case I915_MAP_WC: @@ -285,30 +258,50 @@ static void *i915_gem_object_map(struct drm_i915_ge= m_object *obj, break; } =20 - if (i915_gem_object_has_struct_page(obj)) { - struct sgt_iter iter; - struct page *page; - pte_t **ptes =3D mem; + if (n_pages > ARRAY_SIZE(stack)) { + /* Too big for stack -- allocate temporary array instead */ + pages =3D kvmalloc_array(n_pages, sizeof(*pages), GFP_KERNEL); + if (!pages) + return NULL; + } =20 - for_each_sgt_page(page, iter, sgt) - **ptes++ =3D mk_pte(page, pgprot); - } else { - resource_size_t iomap; - struct sgt_iter iter; - pte_t **ptes =3D mem; - dma_addr_t addr; + i =3D 0; + for_each_sgt_page(page, iter, obj->mm.pages) + pages[i++] =3D page; + vaddr =3D vmap(pages, n_pages, 0, pgprot); + if (pages !=3D stack) + kvfree(pages); + return vaddr; +} =20 - iomap =3D obj->mm.region->iomap.base; - iomap -=3D obj->mm.region->region.start; +static void *i915_gem_object_map_pfn(struct drm_i915_gem_object *obj, + enum i915_map_type type) +{ + resource_size_t iomap =3D obj->mm.region->iomap.base - + obj->mm.region->region.start; + unsigned long n_pfn =3D obj->base.size >> PAGE_SHIFT; + unsigned long stack[32], *pfns =3D stack, i; + struct sgt_iter iter; + dma_addr_t addr; + void *vaddr; + + if (type !=3D I915_MAP_WC) + return NULL; =20 - for_each_sgt_daddr(addr, iter, sgt) - **ptes++ =3D iomap_pte(iomap, addr, pgprot); + if (n_pfn > ARRAY_SIZE(stack)) { + /* Too big for stack -- allocate temporary array instead */ + pfns =3D kvmalloc_array(n_pfn, sizeof(*pfns), GFP_KERNEL); + if (!pfns) + return NULL; } =20 - if (mem !=3D stack) - kvfree(mem); - - return area->addr; + i =3D 0; + for_each_sgt_daddr(addr, iter, obj->mm.pages) + pfns[i++] =3D (iomap + addr) >> PAGE_SHIFT; + vaddr =3D vmap_pfn(pfns, n_pfn, pgprot_writecombine(PAGE_KERNEL_IO)); + if (pfns !=3D stack) + kvfree(pfns); + return vaddr; } =20 /* get, pin, and map the pages of the object into kernel space */ @@ -360,7 +353,10 @@ void *i915_gem_object_pin_map(struct drm_i915_gem_ob= ject *obj, } =20 if (!ptr) { - ptr =3D i915_gem_object_map(obj, type); + if (i915_gem_object_has_struct_page(obj)) + ptr =3D i915_gem_object_map_page(obj, type); + else + ptr =3D i915_gem_object_map_pfn(obj, type); if (!ptr) { err =3D -ENOMEM; goto err_unpin; --=20 2.28.0