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.5 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 809F2C47431 for ; Fri, 2 Oct 2020 12:22:48 +0000 (UTC) Received: from kanga.kvack.org (kanga.kvack.org [205.233.56.17]) by mail.kernel.org (Postfix) with ESMTP id 19B3020719 for ; Fri, 2 Oct 2020 12:22:48 +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="wEYR4zDt" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 19B3020719 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 84CA290000B; Fri, 2 Oct 2020 08:22:33 -0400 (EDT) Received: by kanga.kvack.org (Postfix, from userid 40) id 7D3C6900009; Fri, 2 Oct 2020 08:22:33 -0400 (EDT) X-Delivered-To: int-list-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix, from userid 63042) id 600DD90000B; Fri, 2 Oct 2020 08:22:33 -0400 (EDT) X-Delivered-To: linux-mm@kvack.org Received: from forelay.hostedemail.com (smtprelay0100.hostedemail.com [216.40.44.100]) by kanga.kvack.org (Postfix) with ESMTP id 094AE900009 for ; Fri, 2 Oct 2020 08:22:32 -0400 (EDT) Received: from smtpin23.hostedemail.com (10.5.19.251.rfc1918.com [10.5.19.251]) by forelay03.hostedemail.com (Postfix) with ESMTP id 875968249980 for ; Fri, 2 Oct 2020 12:22:32 +0000 (UTC) X-FDA: 77326898544.23.kite44_4215d2c271a4 Received: from filter.hostedemail.com (10.5.16.251.rfc1918.com [10.5.16.251]) by smtpin23.hostedemail.com (Postfix) with ESMTP id 643523760C for ; Fri, 2 Oct 2020 12:22:32 +0000 (UTC) X-HE-Tag: kite44_4215d2c271a4 X-Filterd-Recvd-Size: 8666 Received: from casper.infradead.org (casper.infradead.org [90.155.50.34]) by imf38.hostedemail.com (Postfix) with ESMTP for ; Fri, 2 Oct 2020 12:22:31 +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=CnZvH3y9ZKFn7BHhh1hHnXEglNnxRMJ6++dbgBNxsaA=; b=wEYR4zDtkU0e31wuybXa3t0si8 j25UL7GpUbh11fVdTW3LoaXZAfP7qiqyxjE1RXpcuEO3HhcCtrlYAsckRXMdnShsOU3d8gmcR55q2 L0NsLiVx8xjjQEFoMQ4uOQuvnBkkdz+AJLpVrLFfe4NsPWdAhG0EflGapb/ePS0/weV2DpOroCkK6 qqV061i4RwJrGFi3Vn9Sg4HFKTM0nTGaZY8lLbpTSqEg8khPRcpBTR4rss8tfbAhdoSwU0xlMxSw9 IepKlrjkujAD2CsUecn6BZMcSxGImtaoWTD7tU8kS4Oi8//3yuVxsxjTYWMoF63tWc/2dJxYc5Nc5 +R6tfRMQ==; Received: from [2001:4bb8:180:7b62:f738:1861:1acc:15c8] (helo=localhost) by casper.infradead.org with esmtpsa (Exim 4.92.3 #3 (Red Hat Linux)) id 1kOK4m-0003Mg-NL; Fri, 02 Oct 2020 12:22:17 +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 08/11] drm/i915: use vmap in i915_gem_object_map Date: Fri, 2 Oct 2020 14:22:01 +0200 Message-Id: <20201002122204.1534411-9-hch@lst.de> X-Mailer: git-send-email 2.28.0 In-Reply-To: <20201002122204.1534411-1-hch@lst.de> References: <20201002122204.1534411-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 | 127 ++++++++++------------ 2 files changed, 60 insertions(+), 68 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 6550c0bc824ea2..f60ca6dc911f29 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_pages.c +++ b/drivers/gpu/drm/i915/gem/i915_gem_pages.c @@ -232,34 +232,21 @@ 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; + void *vaddr; =20 - if (!i915_gem_object_has_struct_page(obj) && type !=3D I915_MAP_WC) - return NULL; - - if (GEM_WARN_ON(type =3D=3D I915_MAP_WC && - !static_cpu_has(X86_FEATURE_PAT))) - return NULL; - - /* A single page can always be kmapped */ - if (n_pte =3D=3D 1 && type =3D=3D I915_MAP_WB) { - struct page *page =3D sg_page(sgt->sgl); - + switch (type) { + default: + MISSING_CASE(type); + fallthrough; /* to use PAGE_KERNEL anyway */ + case I915_MAP_WB: /* * On 32b, highmem using a finite set of indirect PTE (i.e. * vmap) to provide virtual mappings of the high pages. @@ -277,30 +264,8 @@ static void *i915_gem_object_map(struct drm_i915_gem= _object *obj, * So if the page is beyond the 32b boundary, make an explicit * vmap. */ - if (!PageHighMem(page)) - return page_address(page); - } - - 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; - } - - switch (type) { - default: - MISSING_CASE(type); - fallthrough; /* to use PAGE_KERNEL anyway */ - case I915_MAP_WB: + if (n_pages =3D=3D 1 && !PageHighMem(sg_page(obj->mm.pages->sgl))) + return page_address(sg_page(obj->mm.pages->sgl)); pgprot =3D PAGE_KERNEL; break; case I915_MAP_WC: @@ -308,30 +273,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 */ @@ -383,7 +368,13 @@ 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 (GEM_WARN_ON(type =3D=3D I915_MAP_WC && + !static_cpu_has(X86_FEATURE_PAT))) + ptr =3D NULL; + else 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