From c79ee7d8c6cba8775b842063cf5bcdf101dc1e36 Mon Sep 17 00:00:00 2001 From: Monk Liu Date: Tue, 14 Nov 2017 11:52:35 +0800 Subject: drm/amdgpu:cleanup GMC & gart garbage function MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit for gart_ram_alloc/free, they are never used in driver thus ripe them out totally. for gart_vram_pin/unpin, they are not needed becuase we can use bo_creat_kernel/free to replace the original manual way in the gart_vram_alloc/free, thus gart_vram_pin/unpin can also be riped out. Signed-off-by: Monk Liu Reviewed-by: Christian König Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/amdgpu_gart.c | 136 ++----------------------------- 1 file changed, 6 insertions(+), 130 deletions(-) (limited to 'drivers/gpu/drm/amd/amdgpu/amdgpu_gart.c') diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gart.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_gart.c index fe818501c520..10eeb307700c 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gart.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gart.c @@ -56,63 +56,6 @@ * Common GART table functions. */ -/** - * amdgpu_gart_table_ram_alloc - allocate system ram for gart page table - * - * @adev: amdgpu_device pointer - * - * Allocate system memory for GART page table - * (r1xx-r3xx, non-pcie r4xx, rs400). These asics require the - * gart table to be in system memory. - * Returns 0 for success, -ENOMEM for failure. - */ -int amdgpu_gart_table_ram_alloc(struct amdgpu_device *adev) -{ - void *ptr; - - ptr = pci_alloc_consistent(adev->pdev, adev->gart.table_size, - &adev->gart.table_addr); - if (ptr == NULL) { - return -ENOMEM; - } -#ifdef CONFIG_X86 - if (0) { - set_memory_uc((unsigned long)ptr, - adev->gart.table_size >> PAGE_SHIFT); - } -#endif - adev->gart.ptr = ptr; - memset((void *)adev->gart.ptr, 0, adev->gart.table_size); - return 0; -} - -/** - * amdgpu_gart_table_ram_free - free system ram for gart page table - * - * @adev: amdgpu_device pointer - * - * Free system memory for GART page table - * (r1xx-r3xx, non-pcie r4xx, rs400). These asics require the - * gart table to be in system memory. - */ -void amdgpu_gart_table_ram_free(struct amdgpu_device *adev) -{ - if (adev->gart.ptr == NULL) { - return; - } -#ifdef CONFIG_X86 - if (0) { - set_memory_wb((unsigned long)adev->gart.ptr, - adev->gart.table_size >> PAGE_SHIFT); - } -#endif - pci_free_consistent(adev->pdev, adev->gart.table_size, - (void *)adev->gart.ptr, - adev->gart.table_addr); - adev->gart.ptr = NULL; - adev->gart.table_addr = 0; -} - /** * amdgpu_gart_table_vram_alloc - allocate vram for gart page table * @@ -125,75 +68,9 @@ void amdgpu_gart_table_ram_free(struct amdgpu_device *adev) */ int amdgpu_gart_table_vram_alloc(struct amdgpu_device *adev) { - int r; - - if (adev->gart.robj == NULL) { - r = amdgpu_bo_create(adev, adev->gart.table_size, - PAGE_SIZE, true, AMDGPU_GEM_DOMAIN_VRAM, - AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED | - AMDGPU_GEM_CREATE_VRAM_CONTIGUOUS, - NULL, NULL, 0, &adev->gart.robj); - if (r) { - return r; - } - } - return 0; -} - -/** - * amdgpu_gart_table_vram_pin - pin gart page table in vram - * - * @adev: amdgpu_device pointer - * - * Pin the GART page table in vram so it will not be moved - * by the memory manager (pcie r4xx, r5xx+). These asics require the - * gart table to be in video memory. - * Returns 0 for success, error for failure. - */ -int amdgpu_gart_table_vram_pin(struct amdgpu_device *adev) -{ - uint64_t gpu_addr; - int r; - - r = amdgpu_bo_reserve(adev->gart.robj, false); - if (unlikely(r != 0)) - return r; - r = amdgpu_bo_pin(adev->gart.robj, - AMDGPU_GEM_DOMAIN_VRAM, &gpu_addr); - if (r) { - amdgpu_bo_unreserve(adev->gart.robj); - return r; - } - r = amdgpu_bo_kmap(adev->gart.robj, &adev->gart.ptr); - if (r) - amdgpu_bo_unpin(adev->gart.robj); - amdgpu_bo_unreserve(adev->gart.robj); - adev->gart.table_addr = gpu_addr; - return r; -} - -/** - * amdgpu_gart_table_vram_unpin - unpin gart page table in vram - * - * @adev: amdgpu_device pointer - * - * Unpin the GART page table in vram (pcie r4xx, r5xx+). - * These asics require the gart table to be in video memory. - */ -void amdgpu_gart_table_vram_unpin(struct amdgpu_device *adev) -{ - int r; - - if (adev->gart.robj == NULL) { - return; - } - r = amdgpu_bo_reserve(adev->gart.robj, true); - if (likely(r == 0)) { - amdgpu_bo_kunmap(adev->gart.robj); - amdgpu_bo_unpin(adev->gart.robj); - amdgpu_bo_unreserve(adev->gart.robj); - adev->gart.ptr = NULL; - } + return amdgpu_bo_create_kernel(adev, adev->gart.table_size, PAGE_SIZE, + AMDGPU_GEM_DOMAIN_VRAM, &adev->gart.robj, + &adev->gart.table_addr, &adev->gart.ptr); } /** @@ -207,10 +84,9 @@ void amdgpu_gart_table_vram_unpin(struct amdgpu_device *adev) */ void amdgpu_gart_table_vram_free(struct amdgpu_device *adev) { - if (adev->gart.robj == NULL) { - return; - } - amdgpu_bo_unref(&adev->gart.robj); + amdgpu_bo_free_kernel(&adev->gart.robj, + &adev->gart.table_addr, + &adev->gart.ptr); } /* -- cgit v1.2.1 From f59548c8824c8e361120bf87a12fc3a68f17a1ce Mon Sep 17 00:00:00 2001 From: Monk Liu Date: Tue, 14 Nov 2017 11:55:50 +0800 Subject: drm/amdgpu:fix NULL pointer access during drv remove MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit NULL pointer is because original logic will step into set_pde_pte() even after the gart.ptr is freed due to there are twice gart_unbind() on all gart area. also, there are other minor fixes: 1,since gart_init only create dummy page, the corresponding gart_fini shouldn't do more like unbinding all GART, this is unnecessary because in driver fini stage all GART unbinding had already been done during each IP's SW_FINI (GMC's SW_FINI is the last one called), so remove the step for the GART unbinding in gart_fini(). 2,gart_fini() is already invoked during each GMC IP's gart_fini routine,e.g. gmc_vx_0_gart_fini(), so no need to manually call it during ttm_fini(). 3,amdgpu_gem_force_release() should be put ahead of amdgpu_vm_manager_fini() Signed-off-by: Monk Liu Reviewed-by: Christian König Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/amdgpu_gart.c | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) (limited to 'drivers/gpu/drm/amd/amdgpu/amdgpu_gart.c') diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gart.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_gart.c index 10eeb307700c..707f85825996 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gart.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gart.c @@ -253,10 +253,8 @@ int amdgpu_gart_init(struct amdgpu_device *adev) #ifdef CONFIG_DRM_AMDGPU_GART_DEBUGFS /* Allocate pages table */ adev->gart.pages = vzalloc(sizeof(void *) * adev->gart.num_cpu_pages); - if (adev->gart.pages == NULL) { - amdgpu_gart_fini(adev); + if (adev->gart.pages == NULL) return -ENOMEM; - } #endif return 0; @@ -271,11 +269,6 @@ int amdgpu_gart_init(struct amdgpu_device *adev) */ void amdgpu_gart_fini(struct amdgpu_device *adev) { - if (adev->gart.ready) { - /* unbind pages */ - amdgpu_gart_unbind(adev, 0, adev->gart.num_cpu_pages); - } - adev->gart.ready = false; #ifdef CONFIG_DRM_AMDGPU_GART_DEBUGFS vfree(adev->gart.pages); adev->gart.pages = NULL; -- cgit v1.2.1 From ce1b1b66cd5ec60927c575858430c099b8b4bceb Mon Sep 17 00:00:00 2001 From: Monk Liu Date: Tue, 21 Nov 2017 13:29:14 +0800 Subject: drm/amdgpu:partially revert 1cfd8e237f0318e330190ac21d63c58ae6a1f66c MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit found RING0 test fail after S3 resume regression, which is introduced by 1cfd8e237f0318e330190ac21d63c58ae6a1f66c Because after suspend VRAM will be cleared, so driver must unpin the GART table(resident in VRAM) during suspend so it can be evicted to system ram and must correspondingly pin it during resume so the GART table could be restored to VRAM. Signed-off-by: Monk Liu Reviewed-by: Christian König Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/amdgpu_gart.c | 79 +++++++++++++++++++++++++++++--- 1 file changed, 73 insertions(+), 6 deletions(-) (limited to 'drivers/gpu/drm/amd/amdgpu/amdgpu_gart.c') diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gart.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_gart.c index 707f85825996..1f51897acc5b 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gart.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gart.c @@ -68,9 +68,75 @@ */ int amdgpu_gart_table_vram_alloc(struct amdgpu_device *adev) { - return amdgpu_bo_create_kernel(adev, adev->gart.table_size, PAGE_SIZE, - AMDGPU_GEM_DOMAIN_VRAM, &adev->gart.robj, - &adev->gart.table_addr, &adev->gart.ptr); + int r; + + if (adev->gart.robj == NULL) { + r = amdgpu_bo_create(adev, adev->gart.table_size, + PAGE_SIZE, true, AMDGPU_GEM_DOMAIN_VRAM, + AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED | + AMDGPU_GEM_CREATE_VRAM_CONTIGUOUS, + NULL, NULL, 0, &adev->gart.robj); + if (r) { + return r; + } + } + return 0; +} + +/** + * amdgpu_gart_table_vram_pin - pin gart page table in vram + * + * @adev: amdgpu_device pointer + * + * Pin the GART page table in vram so it will not be moved + * by the memory manager (pcie r4xx, r5xx+). These asics require the + * gart table to be in video memory. + * Returns 0 for success, error for failure. + */ +int amdgpu_gart_table_vram_pin(struct amdgpu_device *adev) +{ + uint64_t gpu_addr; + int r; + + r = amdgpu_bo_reserve(adev->gart.robj, false); + if (unlikely(r != 0)) + return r; + r = amdgpu_bo_pin(adev->gart.robj, + AMDGPU_GEM_DOMAIN_VRAM, &gpu_addr); + if (r) { + amdgpu_bo_unreserve(adev->gart.robj); + return r; + } + r = amdgpu_bo_kmap(adev->gart.robj, &adev->gart.ptr); + if (r) + amdgpu_bo_unpin(adev->gart.robj); + amdgpu_bo_unreserve(adev->gart.robj); + adev->gart.table_addr = gpu_addr; + return r; +} + +/** + * amdgpu_gart_table_vram_unpin - unpin gart page table in vram + * + * @adev: amdgpu_device pointer + * + * Unpin the GART page table in vram (pcie r4xx, r5xx+). + * These asics require the gart table to be in video memory. + */ +void amdgpu_gart_table_vram_unpin(struct amdgpu_device *adev) +{ + int r; + + if (adev->gart.robj == NULL) { + return; + } + r = amdgpu_bo_reserve(adev->gart.robj, true); + if (likely(r == 0)) { + amdgpu_bo_kunmap(adev->gart.robj); + amdgpu_bo_unpin(adev->gart.robj); + amdgpu_bo_unreserve(adev->gart.robj); + adev->gart.ptr = NULL; + } } /** @@ -84,9 +150,10 @@ int amdgpu_gart_table_vram_alloc(struct amdgpu_device *adev) */ void amdgpu_gart_table_vram_free(struct amdgpu_device *adev) { - amdgpu_bo_free_kernel(&adev->gart.robj, - &adev->gart.table_addr, - &adev->gart.ptr); + if (adev->gart.robj == NULL) { + return; + } + amdgpu_bo_unref(&adev->gart.robj); } /* -- cgit v1.2.1 From 55e0037aab6503453eef663eded60e530896eaef Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Fri, 15 Dec 2017 16:28:33 -0500 Subject: drm/amdgpu: move dummy page functions to amdgpu_gart.c MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit It's the only place they are used. Acked-by: Christian König Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/amdgpu_gart.c | 49 ++++++++++++++++++++++++++++++-- 1 file changed, 47 insertions(+), 2 deletions(-) (limited to 'drivers/gpu/drm/amd/amdgpu/amdgpu_gart.c') diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gart.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_gart.c index 1f51897acc5b..0a4f34afaaaa 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gart.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gart.c @@ -56,6 +56,51 @@ * Common GART table functions. */ +/** + * amdgpu_dummy_page_init - init dummy page used by the driver + * + * @adev: amdgpu_device pointer + * + * Allocate the dummy page used by the driver (all asics). + * This dummy page is used by the driver as a filler for gart entries + * when pages are taken out of the GART + * Returns 0 on sucess, -ENOMEM on failure. + */ +static int amdgpu_gart_dummy_page_init(struct amdgpu_device *adev) +{ + if (adev->dummy_page.page) + return 0; + adev->dummy_page.page = alloc_page(GFP_DMA32 | GFP_KERNEL | __GFP_ZERO); + if (adev->dummy_page.page == NULL) + return -ENOMEM; + adev->dummy_page.addr = pci_map_page(adev->pdev, adev->dummy_page.page, + 0, PAGE_SIZE, PCI_DMA_BIDIRECTIONAL); + if (pci_dma_mapping_error(adev->pdev, adev->dummy_page.addr)) { + dev_err(&adev->pdev->dev, "Failed to DMA MAP the dummy page\n"); + __free_page(adev->dummy_page.page); + adev->dummy_page.page = NULL; + return -ENOMEM; + } + return 0; +} + +/** + * amdgpu_dummy_page_fini - free dummy page used by the driver + * + * @adev: amdgpu_device pointer + * + * Frees the dummy page used by the driver (all asics). + */ +static void amdgpu_gart_dummy_page_fini(struct amdgpu_device *adev) +{ + if (adev->dummy_page.page == NULL) + return; + pci_unmap_page(adev->pdev, adev->dummy_page.addr, + PAGE_SIZE, PCI_DMA_BIDIRECTIONAL); + __free_page(adev->dummy_page.page); + adev->dummy_page.page = NULL; +} + /** * amdgpu_gart_table_vram_alloc - allocate vram for gart page table * @@ -308,7 +353,7 @@ int amdgpu_gart_init(struct amdgpu_device *adev) DRM_ERROR("Page size is smaller than GPU page size!\n"); return -EINVAL; } - r = amdgpu_dummy_page_init(adev); + r = amdgpu_gart_dummy_page_init(adev); if (r) return r; /* Compute table size */ @@ -340,5 +385,5 @@ void amdgpu_gart_fini(struct amdgpu_device *adev) vfree(adev->gart.pages); adev->gart.pages = NULL; #endif - amdgpu_dummy_page_fini(adev); + amdgpu_gart_dummy_page_fini(adev); } -- cgit v1.2.1