From patchwork Fri Jun 29 07:53:29 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Chris Wilson X-Patchwork-Id: 10495705 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 96E6B6016C for ; Fri, 29 Jun 2018 07:54:57 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 7D20A29120 for ; Fri, 29 Jun 2018 07:54:57 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 702AE2912F; Fri, 29 Jun 2018 07:54:57 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-5.2 required=2.0 tests=BAYES_00, MAILING_LIST_MULTI, RCVD_IN_DNSWL_MED autolearn=ham version=3.3.1 Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher DHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id F420929120 for ; Fri, 29 Jun 2018 07:54:56 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id EA3606EF80; Fri, 29 Jun 2018 07:54:55 +0000 (UTC) X-Original-To: intel-gfx@lists.freedesktop.org Delivered-To: intel-gfx@lists.freedesktop.org Received: from fireflyinternet.com (mail.fireflyinternet.com [109.228.58.192]) by gabe.freedesktop.org (Postfix) with ESMTPS id 6A24C6EF6E for ; Fri, 29 Jun 2018 07:54:37 +0000 (UTC) X-Default-Received-SPF: pass (skip=forwardok (res=PASS)) x-ip-name=78.156.65.138; Received: from haswell.alporthouse.com (unverified [78.156.65.138]) by fireflyinternet.com (Firefly Internet (M1)) with ESMTP id 12195510-1500050 for multiple; Fri, 29 Jun 2018 08:54:28 +0100 Received: by haswell.alporthouse.com (sSMTP sendmail emulation); Fri, 29 Jun 2018 08:54:28 +0100 From: Chris Wilson To: intel-gfx@lists.freedesktop.org Date: Fri, 29 Jun 2018 08:53:29 +0100 Message-Id: <20180629075348.27358-18-chris@chris-wilson.co.uk> X-Mailer: git-send-email 2.18.0 In-Reply-To: <20180629075348.27358-1-chris@chris-wilson.co.uk> References: <20180629075348.27358-1-chris@chris-wilson.co.uk> X-Originating-IP: 78.156.65.138 X-Country: code=GB country="United Kingdom" ip=78.156.65.138 Subject: [Intel-gfx] [PATCH 18/37] drm/i915: Track the last-active inside the i915_vma X-BeenThere: intel-gfx@lists.freedesktop.org X-Mailman-Version: 2.1.23 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-Virus-Scanned: ClamAV using ClamSMTP Using a VMA on more than one timeline concurrently is the exception rather than the rule (using it concurrently on multiple engines). As we expect to only use one active tracker, store the most recently used tracker inside the i915_vma itself and only fallback to the radixtree if we need a second or more concurrent active trackers. Signed-off-by: Chris Wilson --- drivers/gpu/drm/i915/i915_vma.c | 46 ++++++++++++++++++++++++++------- drivers/gpu/drm/i915/i915_vma.h | 1 + 2 files changed, 38 insertions(+), 9 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_vma.c b/drivers/gpu/drm/i915/i915_vma.c index 23852417dcbd..42b9e0659945 100644 --- a/drivers/gpu/drm/i915/i915_vma.c +++ b/drivers/gpu/drm/i915/i915_vma.c @@ -121,6 +121,12 @@ i915_vma_retire(struct i915_gem_active *base, struct i915_request *rq) __i915_vma_retire(vma, rq); } +static void +i915_vma_last_retire(struct i915_gem_active *base, struct i915_request *rq) +{ + __i915_vma_retire(container_of(base, struct i915_vma, last_active), rq); +} + static struct i915_vma * vma_create(struct drm_i915_gem_object *obj, struct i915_address_space *vm, @@ -138,6 +144,7 @@ vma_create(struct drm_i915_gem_object *obj, INIT_RADIX_TREE(&vma->active_rt, GFP_KERNEL); + init_request_active(&vma->last_active, i915_vma_last_retire); init_request_active(&vma->last_fence, NULL); vma->vm = vm; vma->ops = &vm->vma_ops; @@ -903,8 +910,14 @@ static void export_fence(struct i915_vma *vma, static struct i915_gem_active *lookup_active(struct i915_vma *vma, u64 idx) { struct i915_vma_active *active; + struct i915_request *old; int err; + old = i915_gem_active_raw(&vma->last_active, + &vma->vm->i915->drm.struct_mutex); + if (!old || old->fence.context == idx) + goto out; + /* * XXX Note that the radix_tree uses unsigned longs for it indices, * a problem for us on i386 with 32bit longs. However, the likelihood @@ -912,13 +925,9 @@ static struct i915_gem_active *lookup_active(struct i915_vma *vma, u64 idx) * and further reduced by that both timelines must be active * simultaneously to confuse us. */ - active = radix_tree_lookup(&vma->active_rt, idx); - if (likely(active)) { - GEM_BUG_ON(i915_gem_active_isset(&active->base) && - idx != i915_gem_active_peek(&active->base, - &vma->vm->i915->drm.struct_mutex)->fence.context); - return &active->base; - } + active = radix_tree_lookup(&vma->active_rt, old->fence.context); + if (likely(active)) + goto replace; active = kmalloc(sizeof(*active), GFP_KERNEL); if (unlikely(!active)) @@ -927,13 +936,27 @@ static struct i915_gem_active *lookup_active(struct i915_vma *vma, u64 idx) init_request_active(&active->base, i915_vma_retire); active->vma = vma; - err = radix_tree_insert(&vma->active_rt, idx, active); + err = radix_tree_insert(&vma->active_rt, old->fence.context, active); if (unlikely(err)) { kfree(active); return ERR_PTR(err); } - return &active->base; +replace: + if (i915_gem_active_isset(&active->base)) { + GEM_BUG_ON(old->fence.context != + i915_gem_active_raw(&active->base, + &vma->vm->i915->drm.struct_mutex)->fence.context); + __list_del_entry(&active->base.link); + vma->active_count--; + GEM_BUG_ON(!vma->active_count); + } + GEM_BUG_ON(list_empty(&vma->last_active.link)); + list_replace_init(&vma->last_active.link, &active->base.link); + active->base.request = fetch_and_zero(&vma->last_active.request); + +out: + return &vma->last_active; } int i915_vma_move_to_active(struct i915_vma *vma, @@ -1014,6 +1037,11 @@ int i915_vma_unbind(struct i915_vma *vma) */ __i915_vma_pin(vma); + ret = i915_gem_active_retire(&vma->last_active, + &vma->vm->i915->drm.struct_mutex); + if (ret) + goto unpin; + rcu_read_lock(); radix_tree_for_each_slot(slot, &vma->active_rt, &iter, 0) { struct i915_vma_active *active = diff --git a/drivers/gpu/drm/i915/i915_vma.h b/drivers/gpu/drm/i915/i915_vma.h index 94fdf4917e95..1d3080603a18 100644 --- a/drivers/gpu/drm/i915/i915_vma.h +++ b/drivers/gpu/drm/i915/i915_vma.h @@ -97,6 +97,7 @@ struct i915_vma { unsigned int active_count; struct radix_tree_root active_rt; + struct i915_gem_active last_active; struct i915_gem_active last_fence; /**