From patchwork Tue May 26 14:21:17 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Michel Thierry X-Patchwork-Id: 6482201 Return-Path: X-Original-To: patchwork-intel-gfx@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork1.web.kernel.org (Postfix) with ESMTP id BAD199F74E for ; Tue, 26 May 2015 14:21:45 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id AA08420621 for ; Tue, 26 May 2015 14:21:44 +0000 (UTC) Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) by mail.kernel.org (Postfix) with ESMTP id 039552062A for ; Tue, 26 May 2015 14:21:43 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 36662720F9; Tue, 26 May 2015 07:21:41 -0700 (PDT) X-Original-To: intel-gfx@lists.freedesktop.org Delivered-To: intel-gfx@lists.freedesktop.org Received: from mga11.intel.com (mga11.intel.com [192.55.52.93]) by gabe.freedesktop.org (Postfix) with ESMTP id A93A8720EA for ; Tue, 26 May 2015 07:21:30 -0700 (PDT) Received: from fmsmga001.fm.intel.com ([10.253.24.23]) by fmsmga102.fm.intel.com with ESMTP; 26 May 2015 07:21:30 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.13,498,1427785200"; d="scan'208";a="715735006" Received: from michelth-linux.isw.intel.com ([10.102.226.66]) by fmsmga001.fm.intel.com with ESMTP; 26 May 2015 07:21:30 -0700 From: Michel Thierry To: intel-gfx@lists.freedesktop.org Date: Tue, 26 May 2015 15:21:17 +0100 Message-Id: <1432650084-24491-11-git-send-email-michel.thierry@intel.com> X-Mailer: git-send-email 2.4.0 In-Reply-To: <1432650084-24491-1-git-send-email-michel.thierry@intel.com> References: <1432650084-24491-1-git-send-email-michel.thierry@intel.com> Cc: akash.goel@intel.com Subject: [Intel-gfx] [PATCH 10/16] drm/i915/gen8: Initialize PDPs X-BeenThere: intel-gfx@lists.freedesktop.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: Intel graphics driver community testing & development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: intel-gfx-bounces@lists.freedesktop.org Sender: "Intel-gfx" X-Spam-Status: No, score=-4.2 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_MED, T_RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Similar to PDs, while setting up a page directory pointer, make all entries of the pdp point to the scratch pdp before mapping (and make all its entries point to the scratch page); this is to be safe in case of out of bound access or proactive prefetch. Systems without LLC require an explicit flush. This commit also moves gen8_initialize_pt next to the other initialize page functions. v2: Handle scratch_pdp allocation failure correctly, and keep initialize_px functions together (Akash) Suggested-by: Akash Goel Signed-off-by: Michel Thierry --- drivers/gpu/drm/i915/i915_gem_gtt.c | 108 ++++++++++++++++++++++++++++-------- drivers/gpu/drm/i915/i915_gem_gtt.h | 1 + 2 files changed, 86 insertions(+), 23 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c b/drivers/gpu/drm/i915/i915_gem_gtt.c index dbbf367..df37c84 100644 --- a/drivers/gpu/drm/i915/i915_gem_gtt.c +++ b/drivers/gpu/drm/i915/i915_gem_gtt.c @@ -365,24 +365,6 @@ static void unmap_and_free_pt(struct i915_page_table *pt, kfree(pt); } -static void gen8_initialize_pt(struct i915_address_space *vm, - struct i915_page_table *pt) -{ - gen8_pte_t *pt_vaddr, scratch_pte; - int i; - - pt_vaddr = kmap_atomic(pt->page); - scratch_pte = gen8_pte_encode(vm->scratch.addr, - I915_CACHE_LLC, true); - - for (i = 0; i < GEN8_PTES; i++) - pt_vaddr[i] = scratch_pte; - - if (!HAS_LLC(vm->dev)) - drm_clflush_virt_range(pt_vaddr, PAGE_SIZE); - kunmap_atomic(pt_vaddr); -} - static struct i915_page_table *alloc_pt_single(struct drm_device *dev) { struct i915_page_table *pt; @@ -521,7 +503,7 @@ i915_page_directory_pointer *alloc_pdp_single(struct i915_hw_ppgtt *ppgtt) if (!pdp) return ERR_PTR(-ENOMEM); - pdp->page = alloc_page(GFP_KERNEL | GFP_DMA32 | __GFP_ZERO); + pdp->page = alloc_page(GFP_KERNEL | GFP_DMA32); if (!pdp->page) { kfree(pdp); return ERR_PTR(-ENOMEM); @@ -761,6 +743,24 @@ static void __gen8_do_map_pt(gen8_pde_t * const pde, *pde = entry; } +static void gen8_initialize_pt(struct i915_address_space *vm, + struct i915_page_table *pt) +{ + gen8_pte_t *pt_vaddr, scratch_pte; + int i; + + pt_vaddr = kmap_atomic(pt->page); + scratch_pte = gen8_pte_encode(vm->scratch.addr, + I915_CACHE_LLC, true); + + for (i = 0; i < GEN8_PTES; i++) + pt_vaddr[i] = scratch_pte; + + if (!HAS_LLC(vm->dev)) + drm_clflush_virt_range(pt_vaddr, PAGE_SIZE); + kunmap_atomic(pt_vaddr); +} + static void gen8_initialize_pd(struct i915_address_space *vm, struct i915_page_directory *pd) { @@ -782,6 +782,55 @@ static void gen8_initialize_pd(struct i915_address_space *vm, kunmap_atomic(page_directory); } +static void gen8_initialize_pdp(struct i915_address_space *vm, + struct i915_page_directory_pointer *pdp) +{ + struct i915_hw_ppgtt *ppgtt = + container_of(vm, struct i915_hw_ppgtt, base); + gen8_ppgtt_pdpe_t *page_directorypo; + struct i915_page_directory *pd; + int i; + + page_directorypo = kmap_atomic(pdp->page); + pd = (struct i915_page_directory *)ppgtt->scratch_pd; + for (i = 0; i < I915_PDPES_PER_PDP(vm->dev); i++) { + /* Map the PDPE to the page directory */ + gen8_ppgtt_pdpe_t entry = + gen8_pdpe_encode(vm->dev, pd->daddr, I915_CACHE_LLC); + page_directorypo[i] = entry; + } + + if (!HAS_LLC(vm->dev)) + drm_clflush_virt_range(page_directorypo, PAGE_SIZE); + + kunmap_atomic(page_directorypo); +} + +static void gen8_initialize_pml4(struct i915_address_space *vm, + struct i915_pml4 *pml4) +{ + struct i915_hw_ppgtt *ppgtt = + container_of(vm, struct i915_hw_ppgtt, base); + gen8_ppgtt_pml4e_t *page_maplevel4; + struct i915_page_directory_pointer *pdp; + int i; + + page_maplevel4 = kmap_atomic(pml4->page); + pdp = (struct i915_page_directory_pointer *)ppgtt->scratch_pdp; + for (i = 0; i < GEN8_PML4ES_PER_PML4; i++) { + /* Map the PML4E to the page directory pointer */ + gen8_ppgtt_pml4e_t entry = + gen8_pml4e_encode(vm->dev, pdp->daddr, + I915_CACHE_LLC); + page_maplevel4[i] = entry; + } + + if (!HAS_LLC(vm->dev)) + drm_clflush_virt_range(page_maplevel4, PAGE_SIZE); + + kunmap_atomic(page_maplevel4); +} + static void pml4_fini(struct i915_pml4 *pml4) { struct i915_hw_ppgtt *ppgtt = @@ -795,10 +844,12 @@ static int pml4_init(struct i915_hw_ppgtt *ppgtt) { struct i915_pml4 *pml4 = &ppgtt->pml4; - pml4->page = alloc_page(GFP_KERNEL | __GFP_ZERO); + pml4->page = alloc_page(GFP_KERNEL | GFP_DMA32); if (!pml4->page) return -ENOMEM; + gen8_initialize_pml4(&ppgtt->base, pml4); + i915_dma_map_single(pml4, ppgtt->base.dev); return 0; @@ -913,6 +964,7 @@ static void gen8_ppgtt_cleanup_4lvl(struct i915_hw_ppgtt *ppgtt) } pml4_fini(&ppgtt->pml4); + unmap_and_free_pdp(ppgtt->scratch_pdp, ppgtt->base.dev); } static void gen8_ppgtt_cleanup(struct i915_address_space *vm) @@ -1220,12 +1272,12 @@ static int __gen8_alloc_vma_range_4lvl(struct i915_address_space *vm, * and 4 level code. Just allocate the pdps. */ gen8_for_each_pml4e(pdp, pml4, start, length, temp, pml4e) { - if (!pdp) { - WARN_ON(test_bit(pml4e, pml4->used_pml4es)); + if (!test_bit(pml4e, pml4->used_pml4es)) { pdp = alloc_pdp_single(ppgtt); if (IS_ERR(pdp)) goto err_out; + gen8_initialize_pdp(vm, pdp); pml4->pdps[pml4e] = pdp; set_bit(pml4e, new_pdps); trace_i915_page_directory_pointer_entry_alloc(&ppgtt->base, pml4e, @@ -1301,9 +1353,17 @@ static int gen8_ppgtt_init(struct i915_hw_ppgtt *ppgtt) gen8_initialize_pd(&ppgtt->base, ppgtt->scratch_pd); if (USES_FULL_48BIT_PPGTT(ppgtt->base.dev)) { + ppgtt->scratch_pdp = alloc_pdp_single(ppgtt); + if (IS_ERR(ppgtt->scratch_pdp)) { + ret = PTR_ERR(ppgtt->scratch_pdp); + goto err_out; + } + + gen8_initialize_pdp(&ppgtt->base, ppgtt->scratch_pdp); + ret = pml4_init(ppgtt); if (ret) - goto err_out; + goto err_pdp_out; ppgtt->base.total = 1ULL << 48; ppgtt->switch_mm = gen8_48b_mm_switch; @@ -1327,6 +1387,8 @@ static int gen8_ppgtt_init(struct i915_hw_ppgtt *ppgtt) return 0; +err_pdp_out: + unmap_and_free_pdp(ppgtt->scratch_pdp, ppgtt->base.dev); err_out: unmap_and_free_pd(ppgtt->scratch_pd, ppgtt->base.dev); unmap_and_free_pt(ppgtt->scratch_pt, ppgtt->base.dev); diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.h b/drivers/gpu/drm/i915/i915_gem_gtt.h index 9af33b2..6e2f39c 100644 --- a/drivers/gpu/drm/i915/i915_gem_gtt.h +++ b/drivers/gpu/drm/i915/i915_gem_gtt.h @@ -358,6 +358,7 @@ struct i915_hw_ppgtt { struct i915_page_table *scratch_pt; struct i915_page_directory *scratch_pd; + struct i915_page_directory_pointer *scratch_pdp; struct drm_i915_file_private *file_priv;