From patchwork Wed Nov 19 13:01:24 2014 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: 5337121 Return-Path: X-Original-To: patchwork-dri-devel@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork2.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.19.201]) by patchwork2.web.kernel.org (Postfix) with ESMTP id 4B244C11AC for ; Wed, 19 Nov 2014 13:01:46 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 111472012B for ; Wed, 19 Nov 2014 13:01:45 +0000 (UTC) Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) by mail.kernel.org (Postfix) with ESMTP id 5C24220103 for ; Wed, 19 Nov 2014 13:01:43 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id CB2816EDCA; Wed, 19 Nov 2014 05:01:41 -0800 (PST) X-Original-To: dri-devel@lists.freedesktop.org Delivered-To: dri-devel@lists.freedesktop.org Received: from pegasos-out.vodafone.de (pegasos-out.vodafone.de [80.84.1.38]) by gabe.freedesktop.org (Postfix) with ESMTP id C46416EDD6 for ; Wed, 19 Nov 2014 05:01:40 -0800 (PST) Received: from localhost (localhost.localdomain [127.0.0.1]) by pegasos-out.vodafone.de (Rohrpostix1 Daemon) with ESMTP id 0BA5C261390; Wed, 19 Nov 2014 14:01:39 +0100 (CET) X-Virus-Scanned: amavisd-new at vodafone.de X-Spam-Score: 0.202 X-Spam-Level: X-Spam-Status: No, score=-4.1 required=5.0 tests=BAYES_00,DKIM_SIGNED, FREEMAIL_FROM,RCVD_IN_DNSWL_MED,T_DKIM_INVALID,T_RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 Authentication-Results: rohrpostix1.prod.vfnet.de (amavisd-new); dkim=pass header.i=@vodafone.de Received: from pegasos-out.vodafone.de ([127.0.0.1]) by localhost (rohrpostix1.prod.vfnet.de [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id 1CwdkZVV-oEx; Wed, 19 Nov 2014 14:01:37 +0100 (CET) Received: from smtp-01.vodafone.de (xsmail-dmz5.prod.vfnet.de [10.215.254.36]) by pegasos-out.vodafone.de (Rohrpostix1 Daemon) with ESMTP id E10202613C1; Wed, 19 Nov 2014 14:01:36 +0100 (CET) X-DKIM: OpenDKIM Filter v2.6.8 pegasos-out.vodafone.de E10202613C1 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=vodafone.de; s=mail; t=1416402096; bh=aWLpfHt/ZxNSvIV9TRw++hCgYeXUHy7DJVhEGAHLo5I=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=GtLNK/muRjHmMgI8gPnyDKgXXgGZeXS0xf8PyrC28Q2Yjq79RPrh5WCWFK7qZMvbd emBL7/Ola7mGnxc7uSJC/12AdWfxe4+yDYdsd1/D3b48j+a+hG+VUNZgeI+0/EI9Vb YQDjaN2G8m1bf6BqsgezsYrNSoAENRO56xNEqzfY= X-DKIM: OpenDKIM Filter v2.0.2 smtp-01.vodafone.de 72B3DE5A53 X-Virus-Scanned: amavisd-new at vodafone.de Received: from smtp-01.vodafone.de ([127.0.0.1]) by localhost (xsmail-dmz5.prod.vfnet.de [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id HYaxuEcTc-Zm; Wed, 19 Nov 2014 14:01:30 +0100 (CET) From: =?UTF-8?q?Christian=20K=C3=B6nig?= To: alexdeucher@gmail.com Subject: [PATCH 06/11] drm/radeon: track VM update fences separately Date: Wed, 19 Nov 2014 14:01:24 +0100 Message-Id: <1416402089-2366-6-git-send-email-deathsimple@vodafone.de> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1416402089-2366-1-git-send-email-deathsimple@vodafone.de> References: <1416402089-2366-1-git-send-email-deathsimple@vodafone.de> MIME-Version: 1.0 Cc: dri-devel@lists.freedesktop.org X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: Christian König Note for each fence if it's a VM page table update or not. This allows us to determine the last VM update in a sync object and so to figure out if we need to flush the TLB or not. Signed-off-by: Christian König --- drivers/gpu/drm/radeon/radeon.h | 18 ++++++++++-------- drivers/gpu/drm/radeon/radeon_fence.c | 1 + drivers/gpu/drm/radeon/radeon_ib.c | 3 ++- drivers/gpu/drm/radeon/radeon_sync.c | 7 +++++++ drivers/gpu/drm/radeon/radeon_vm.c | 25 +++++++++++++------------ 5 files changed, 33 insertions(+), 21 deletions(-) diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h index 5e88e75..ac4660a 100644 --- a/drivers/gpu/drm/radeon/radeon.h +++ b/drivers/gpu/drm/radeon/radeon.h @@ -360,14 +360,15 @@ struct radeon_fence_driver { }; struct radeon_fence { - struct fence base; + struct fence base; - struct radeon_device *rdev; - uint64_t seq; + struct radeon_device *rdev; + uint64_t seq; /* RB, DMA, etc. */ - unsigned ring; + unsigned ring; + bool is_vm_update; - wait_queue_t fence_wake; + wait_queue_t fence_wake; }; int radeon_fence_driver_start_ring(struct radeon_device *rdev, int ring); @@ -594,6 +595,7 @@ void radeon_semaphore_free(struct radeon_device *rdev, struct radeon_sync { struct radeon_semaphore *semaphores[RADEON_NUM_SYNCS]; struct radeon_fence *sync_to[RADEON_NUM_RINGS]; + struct radeon_fence *last_vm_update; }; void radeon_sync_create(struct radeon_sync *sync); @@ -922,8 +924,8 @@ struct radeon_vm { struct mutex mutex; /* last fence for cs using this vm */ struct radeon_fence *fence; - /* last flush or NULL if we still need to flush */ - struct radeon_fence *last_flush; + /* last flushed PD/PT update */ + struct radeon_fence *flushed_updates; /* last use of vmid */ struct radeon_fence *last_id_use; }; @@ -2961,7 +2963,7 @@ struct radeon_fence *radeon_vm_grab_id(struct radeon_device *rdev, struct radeon_vm *vm, int ring); void radeon_vm_flush(struct radeon_device *rdev, struct radeon_vm *vm, - int ring); + int ring, struct radeon_fence *fence); void radeon_vm_fence(struct radeon_device *rdev, struct radeon_vm *vm, struct radeon_fence *fence); diff --git a/drivers/gpu/drm/radeon/radeon_fence.c b/drivers/gpu/drm/radeon/radeon_fence.c index 9951670..d13d1b5 100644 --- a/drivers/gpu/drm/radeon/radeon_fence.c +++ b/drivers/gpu/drm/radeon/radeon_fence.c @@ -140,6 +140,7 @@ int radeon_fence_emit(struct radeon_device *rdev, (*fence)->rdev = rdev; (*fence)->seq = seq; (*fence)->ring = ring; + (*fence)->is_vm_update = false; fence_init(&(*fence)->base, &radeon_fence_ops, &rdev->fence_queue.lock, rdev->fence_context + ring, seq); radeon_fence_ring_emit(rdev, ring, *fence); diff --git a/drivers/gpu/drm/radeon/radeon_ib.c b/drivers/gpu/drm/radeon/radeon_ib.c index 56a1704..c39ce1f 100644 --- a/drivers/gpu/drm/radeon/radeon_ib.c +++ b/drivers/gpu/drm/radeon/radeon_ib.c @@ -154,7 +154,8 @@ int radeon_ib_schedule(struct radeon_device *rdev, struct radeon_ib *ib, } if (ib->vm) - radeon_vm_flush(rdev, ib->vm, ib->ring); + radeon_vm_flush(rdev, ib->vm, ib->ring, + ib->sync.last_vm_update); if (const_ib) { radeon_ring_ib_execute(rdev, const_ib->ring, const_ib); diff --git a/drivers/gpu/drm/radeon/radeon_sync.c b/drivers/gpu/drm/radeon/radeon_sync.c index ddd88fb..02ac8a1 100644 --- a/drivers/gpu/drm/radeon/radeon_sync.c +++ b/drivers/gpu/drm/radeon/radeon_sync.c @@ -48,6 +48,8 @@ void radeon_sync_create(struct radeon_sync *sync) for (i = 0; i < RADEON_NUM_RINGS; ++i) sync->sync_to[i] = NULL; + + sync->last_vm_update = NULL; } /** @@ -68,6 +70,11 @@ void radeon_sync_fence(struct radeon_sync *sync, other = sync->sync_to[fence->ring]; sync->sync_to[fence->ring] = radeon_fence_later(fence, other); + + if (fence->is_vm_update) { + other = sync->last_vm_update; + sync->last_vm_update = radeon_fence_later(fence, other); + } } /** diff --git a/drivers/gpu/drm/radeon/radeon_vm.c b/drivers/gpu/drm/radeon/radeon_vm.c index 4ca2779..6ff5741 100644 --- a/drivers/gpu/drm/radeon/radeon_vm.c +++ b/drivers/gpu/drm/radeon/radeon_vm.c @@ -190,7 +190,7 @@ struct radeon_fence *radeon_vm_grab_id(struct radeon_device *rdev, return NULL; /* we definately need to flush */ - radeon_fence_unref(&vm->last_flush); + vm->pd_gpu_addr = ~0ll; /* skip over VMID 0, since it is the system VM */ for (i = 1; i < rdev->vm_manager.nvm; ++i) { @@ -228,6 +228,7 @@ struct radeon_fence *radeon_vm_grab_id(struct radeon_device *rdev, * @rdev: radeon_device pointer * @vm: vm we want to flush * @ring: ring to use for flush + * @updates: last vm update that is waited for * * Flush the vm (cayman+). * @@ -235,13 +236,16 @@ struct radeon_fence *radeon_vm_grab_id(struct radeon_device *rdev, */ void radeon_vm_flush(struct radeon_device *rdev, struct radeon_vm *vm, - int ring) + int ring, struct radeon_fence *updates) { uint64_t pd_addr = radeon_bo_gpu_offset(vm->page_directory); - /* if we can't remember our last VM flush then flush now! */ - if (!vm->last_flush || pd_addr != vm->pd_gpu_addr) { + if (pd_addr != vm->pd_gpu_addr || !vm->flushed_updates || + radeon_fence_is_earlier(vm->flushed_updates, updates)) { + trace_radeon_vm_flush(pd_addr, ring, vm->id); + radeon_fence_unref(&vm->flushed_updates); + vm->flushed_updates = radeon_fence_ref(updates); vm->pd_gpu_addr = pd_addr; radeon_ring_vm_flush(rdev, &rdev->ring[ring], vm->id, vm->pd_gpu_addr); @@ -272,10 +276,6 @@ void radeon_vm_fence(struct radeon_device *rdev, radeon_fence_unref(&vm->last_id_use); vm->last_id_use = radeon_fence_ref(fence); - - /* we just flushed the VM, remember that */ - if (!vm->last_flush) - vm->last_flush = radeon_fence_ref(fence); } /** @@ -418,6 +418,7 @@ static int radeon_vm_clear_bo(struct radeon_device *rdev, if (r) goto error_free; + ib.fence->is_vm_update = true; radeon_bo_fence(bo, ib.fence, false); error_free: @@ -697,10 +698,10 @@ int radeon_vm_update_page_directory(struct radeon_device *rdev, radeon_ib_free(rdev, &ib); return r; } + ib.fence->is_vm_update = true; radeon_bo_fence(pd, ib.fence, false); radeon_fence_unref(&vm->fence); vm->fence = radeon_fence_ref(ib.fence); - radeon_fence_unref(&vm->last_flush); } radeon_ib_free(rdev, &ib); @@ -989,11 +990,11 @@ int radeon_vm_bo_update(struct radeon_device *rdev, radeon_ib_free(rdev, &ib); return r; } + ib.fence->is_vm_update = true; radeon_vm_fence_pts(vm, bo_va->it.start, bo_va->it.last + 1, ib.fence); radeon_fence_unref(&vm->fence); vm->fence = radeon_fence_ref(ib.fence); radeon_ib_free(rdev, &ib); - radeon_fence_unref(&vm->last_flush); return 0; } @@ -1124,7 +1125,7 @@ int radeon_vm_init(struct radeon_device *rdev, struct radeon_vm *vm) vm->id = 0; vm->ib_bo_va = NULL; vm->fence = NULL; - vm->last_flush = NULL; + vm->flushed_updates = NULL; vm->last_id_use = NULL; mutex_init(&vm->mutex); vm->va = RB_ROOT; @@ -1196,7 +1197,7 @@ void radeon_vm_fini(struct radeon_device *rdev, struct radeon_vm *vm) radeon_bo_unref(&vm->page_directory); radeon_fence_unref(&vm->fence); - radeon_fence_unref(&vm->last_flush); + radeon_fence_unref(&vm->flushed_updates); radeon_fence_unref(&vm->last_id_use); mutex_destroy(&vm->mutex);