From patchwork Mon Jul 9 10:41:59 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Christian_K=C3=B6nig?= X-Patchwork-Id: 1172501 Return-Path: X-Original-To: patchwork-dri-devel@patchwork.kernel.org Delivered-To: patchwork-process-083081@patchwork1.kernel.org Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) by patchwork1.kernel.org (Postfix) with ESMTP id D4C2040B18 for ; Mon, 9 Jul 2012 10:59:01 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id B00B79F4FF for ; Mon, 9 Jul 2012 03:54:01 -0700 (PDT) X-Original-To: dri-devel@lists.freedesktop.org Delivered-To: dri-devel@lists.freedesktop.org Received: from outgoing.email.vodafone.de (outgoing.email.vodafone.de [139.7.28.128]) by gabe.freedesktop.org (Postfix) with ESMTP id 1300B9F3B3 for ; Mon, 9 Jul 2012 03:42:14 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed; d=vodafone.de; h=from:to:subject:date:message-id:in-reply-to:references:mime-version:content-type:content-transfer-encoding; s=out; bh=6995qeRcB5NWyAxU7U0hUYg5pEJH0zjPxBzfPDf6e2Y=; b=u/Bcr2zykiShAsM1/cnL4L5TQ/inIHS2oTAx5UlnTlQ1cNzYB9eRbwnyuzN5P3jJMoRYRxag0AVkhxnbYtE1gdEaKgew5q5NRTARL984Xjr4aImKDNygkO6AcluF1Uq9GRis+q4pS9yPcBEks6Ztmwt/hmKyzGMihqRUtfp8ve0= X-Authentication-Info: Sender authenticated as deathsimple@vodafone.de (using DIGEST-MD5) Received: from dslb-084-060-204-186.pools.arcor-ip.net ([84.60.204.186] helo=localhost.localdomain envelope-sender=) by SMTPIN-02.smtp.email.vodafone.de with ESMTPA id 4FFAB586.25863.928031; Mon, 09 Jul 2012 12:42:14 +0200 From: =?UTF-8?q?Christian=20K=C3=B6nig?= To: dri-devel@lists.freedesktop.org Subject: [PATCH 12/16] drm/radeon: remove vm_manager start/suspend Date: Mon, 9 Jul 2012 12:41:59 +0200 Message-Id: <1341830523-30320-13-git-send-email-deathsimple@vodafone.de> X-Mailer: git-send-email 1.7.9.5 In-Reply-To: <1341830523-30320-1-git-send-email-deathsimple@vodafone.de> References: <1341830523-30320-1-git-send-email-deathsimple@vodafone.de> MIME-Version: 1.0 X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.13 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: dri-devel-bounces+patchwork-dri-devel=patchwork.kernel.org@lists.freedesktop.org Errors-To: dri-devel-bounces+patchwork-dri-devel=patchwork.kernel.org@lists.freedesktop.org Just restore the page table instead. Addressing three problem with this change: 1. Calling vm_manager_suspend in the suspend path is problematic cause it wants to wait for the VM use to end, which in case of a lockup never happens. 2. In case of a locked up memory controller unbinding the VM seems to make it even more unstable, creating an unrecoverable lockup in the end. 3. If we want to backup/restore the leftover ring content we must not unbind VMs in between. Signed-off-by: Christian König --- drivers/gpu/drm/radeon/ni.c | 12 ++--- drivers/gpu/drm/radeon/radeon.h | 2 - drivers/gpu/drm/radeon/radeon_gart.c | 83 +++++++++++++++++++++------------- drivers/gpu/drm/radeon/si.c | 12 ++--- 4 files changed, 59 insertions(+), 50 deletions(-) diff --git a/drivers/gpu/drm/radeon/ni.c b/drivers/gpu/drm/radeon/ni.c index 4004376..ec5307c 100644 --- a/drivers/gpu/drm/radeon/ni.c +++ b/drivers/gpu/drm/radeon/ni.c @@ -1280,9 +1280,11 @@ static int cayman_startup(struct radeon_device *rdev) if (r) return r; - r = radeon_vm_manager_start(rdev); - if (r) + r = radeon_vm_manager_init(rdev); + if (r) { + dev_err(rdev->dev, "vm manager initialization failed (%d).\n", r); return r; + } r = r600_audio_init(rdev); if (r) @@ -1315,7 +1317,6 @@ int cayman_resume(struct radeon_device *rdev) int cayman_suspend(struct radeon_device *rdev) { r600_audio_fini(rdev); - radeon_vm_manager_suspend(rdev); cayman_cp_enable(rdev, false); rdev->ring[RADEON_RING_TYPE_GFX_INDEX].ready = false; evergreen_irq_suspend(rdev); @@ -1392,11 +1393,6 @@ int cayman_init(struct radeon_device *rdev) return r; rdev->accel_working = true; - r = radeon_vm_manager_init(rdev); - if (r) { - dev_err(rdev->dev, "vm manager initialization failed (%d).\n", r); - } - r = cayman_startup(rdev); if (r) { dev_err(rdev->dev, "disabling GPU acceleration\n"); diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h index 8a8c3f8..872270c 100644 --- a/drivers/gpu/drm/radeon/radeon.h +++ b/drivers/gpu/drm/radeon/radeon.h @@ -1759,8 +1759,6 @@ extern void radeon_ttm_set_active_vram_size(struct radeon_device *rdev, u64 size */ int radeon_vm_manager_init(struct radeon_device *rdev); void radeon_vm_manager_fini(struct radeon_device *rdev); -int radeon_vm_manager_start(struct radeon_device *rdev); -int radeon_vm_manager_suspend(struct radeon_device *rdev); int radeon_vm_init(struct radeon_device *rdev, struct radeon_vm *vm); void radeon_vm_fini(struct radeon_device *rdev, struct radeon_vm *vm); int radeon_vm_bind(struct radeon_device *rdev, struct radeon_vm *vm); diff --git a/drivers/gpu/drm/radeon/radeon_gart.c b/drivers/gpu/drm/radeon/radeon_gart.c index ee11c50..56752da 100644 --- a/drivers/gpu/drm/radeon/radeon_gart.c +++ b/drivers/gpu/drm/radeon/radeon_gart.c @@ -282,27 +282,58 @@ void radeon_gart_fini(struct radeon_device *rdev) * * TODO bind a default page at vm initialization for default address */ + int radeon_vm_manager_init(struct radeon_device *rdev) { + struct radeon_vm *vm; + struct radeon_bo_va *bo_va; int r; - rdev->vm_manager.enabled = false; + if (!rdev->vm_manager.enabled) { + /* mark first vm as always in use, it's the system one */ + r = radeon_sa_bo_manager_init(rdev, &rdev->vm_manager.sa_manager, + rdev->vm_manager.max_pfn * 8, + RADEON_GEM_DOMAIN_VRAM); + if (r) { + dev_err(rdev->dev, "failed to allocate vm bo (%dKB)\n", + (rdev->vm_manager.max_pfn * 8) >> 10); + return r; + } - /* mark first vm as always in use, it's the system one */ - r = radeon_sa_bo_manager_init(rdev, &rdev->vm_manager.sa_manager, - rdev->vm_manager.max_pfn * 8, - RADEON_GEM_DOMAIN_VRAM); - if (r) { - dev_err(rdev->dev, "failed to allocate vm bo (%dKB)\n", - (rdev->vm_manager.max_pfn * 8) >> 10); - return r; + r = rdev->vm_manager.funcs->init(rdev); + if (r) + return r; + + rdev->vm_manager.enabled = true; + + r = radeon_sa_bo_manager_start(rdev, &rdev->vm_manager.sa_manager); + if (r) + return r; } - r = rdev->vm_manager.funcs->init(rdev); - if (r == 0) - rdev->vm_manager.enabled = true; + /* restore page table */ + list_for_each_entry(vm, &rdev->vm_manager.lru_vm, list) { + if (vm->id == -1) + continue; - return r; + list_for_each_entry(bo_va, &vm->va, vm_list) { + struct ttm_mem_reg *mem = NULL; + if (bo_va->valid) + mem = &bo_va->bo->tbo.mem; + + bo_va->valid = false; + r = radeon_vm_bo_update_pte(rdev, vm, bo_va->bo, mem); + if (r) { + DRM_ERROR("Failed to update pte for vm %d!\n", vm->id); + } + } + + r = rdev->vm_manager.funcs->bind(rdev, vm, vm->id); + if (r) { + DRM_ERROR("Failed to bind vm %d!\n", vm->id); + } + } + return 0; } /* global mutex must be lock */ @@ -347,26 +378,11 @@ static void radeon_vm_unbind_locked(struct radeon_device *rdev, void radeon_vm_manager_fini(struct radeon_device *rdev) { - if (rdev->vm_manager.sa_manager.bo == NULL) - return; - radeon_vm_manager_suspend(rdev); - rdev->vm_manager.funcs->fini(rdev); - radeon_sa_bo_manager_fini(rdev, &rdev->vm_manager.sa_manager); - rdev->vm_manager.enabled = false; -} - -int radeon_vm_manager_start(struct radeon_device *rdev) -{ - if (rdev->vm_manager.sa_manager.bo == NULL) { - return -EINVAL; - } - return radeon_sa_bo_manager_start(rdev, &rdev->vm_manager.sa_manager); -} - -int radeon_vm_manager_suspend(struct radeon_device *rdev) -{ struct radeon_vm *vm, *tmp; + if (!rdev->vm_manager.enabled) + return; + mutex_lock(&rdev->vm_manager.lock); /* unbind all active vm */ list_for_each_entry_safe(vm, tmp, &rdev->vm_manager.lru_vm, list) { @@ -374,7 +390,10 @@ int radeon_vm_manager_suspend(struct radeon_device *rdev) } rdev->vm_manager.funcs->fini(rdev); mutex_unlock(&rdev->vm_manager.lock); - return radeon_sa_bo_manager_suspend(rdev, &rdev->vm_manager.sa_manager); + + radeon_sa_bo_manager_suspend(rdev, &rdev->vm_manager.sa_manager); + radeon_sa_bo_manager_fini(rdev, &rdev->vm_manager.sa_manager); + rdev->vm_manager.enabled = false; } /* global mutex must be locked */ diff --git a/drivers/gpu/drm/radeon/si.c b/drivers/gpu/drm/radeon/si.c index 7c2618b..2b691ab 100644 --- a/drivers/gpu/drm/radeon/si.c +++ b/drivers/gpu/drm/radeon/si.c @@ -3777,9 +3777,11 @@ static int si_startup(struct radeon_device *rdev) return r; } - r = radeon_vm_manager_start(rdev); - if (r) + r = radeon_vm_manager_init(rdev); + if (r) { + dev_err(rdev->dev, "vm manager initialization failed (%d).\n", r); return r; + } return 0; } @@ -3809,7 +3811,6 @@ int si_resume(struct radeon_device *rdev) int si_suspend(struct radeon_device *rdev) { - radeon_vm_manager_suspend(rdev); si_cp_enable(rdev, false); rdev->ring[RADEON_RING_TYPE_GFX_INDEX].ready = false; rdev->ring[CAYMAN_RING_TYPE_CP1_INDEX].ready = false; @@ -3899,11 +3900,6 @@ int si_init(struct radeon_device *rdev) return r; rdev->accel_working = true; - r = radeon_vm_manager_init(rdev); - if (r) { - dev_err(rdev->dev, "vm manager initialization failed (%d).\n", r); - } - r = si_startup(rdev); if (r) { dev_err(rdev->dev, "disabling GPU acceleration\n");