From patchwork Thu Jun 26 17:24:02 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: John Harrison X-Patchwork-Id: 4429121 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.19.201]) by patchwork1.web.kernel.org (Postfix) with ESMTP id 97C829FBC3 for ; Thu, 26 Jun 2014 17:25:49 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 241022039D for ; Thu, 26 Jun 2014 17:25:47 +0000 (UTC) Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) by mail.kernel.org (Postfix) with ESMTP id D1B4020306 for ; Thu, 26 Jun 2014 17:25:40 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id B4DA76E247; Thu, 26 Jun 2014 10:25:38 -0700 (PDT) X-Original-To: Intel-GFX@lists.freedesktop.org Delivered-To: Intel-GFX@lists.freedesktop.org Received: from mga01.intel.com (mga01.intel.com [192.55.52.88]) by gabe.freedesktop.org (Postfix) with ESMTP id AA5406E1D4 for ; Thu, 26 Jun 2014 10:25:28 -0700 (PDT) Received: from fmsmga002.fm.intel.com ([10.253.24.26]) by fmsmga101.fm.intel.com with ESMTP; 26 Jun 2014 10:25:28 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.01,554,1400050800"; d="scan'208";a="561434615" Received: from johnharr-linux.iwi.intel.com ([172.28.253.52]) by fmsmga002.fm.intel.com with ESMTP; 26 Jun 2014 10:25:06 -0700 From: John.C.Harrison@Intel.com To: Intel-GFX@lists.freedesktop.org Date: Thu, 26 Jun 2014 18:24:02 +0100 Message-Id: <1403803475-16337-12-git-send-email-John.C.Harrison@Intel.com> X-Mailer: git-send-email 1.7.9.5 In-Reply-To: <1403803475-16337-1-git-send-email-John.C.Harrison@Intel.com> References: <1403803475-16337-1-git-send-email-John.C.Harrison@Intel.com> Organization: Intel Corporation (UK) Ltd. - Co. Reg. #1134945 - Pipers Way, Swindon SN3 1RJ Subject: [Intel-gfx] [RFC 11/44] drm/i915: Added scheduler hook into i915_seqno_passed() X-BeenThere: intel-gfx@lists.freedesktop.org X-Mailman-Version: 2.1.15 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 From: John Harrison The GPU scheduler can cause seqno values to become out of order. This means that a straight forward 'is seqno X > seqno Y' test is no longer valid. Instead, a call into the scheduler must be made to see if the value being queried is known to be out of order. --- drivers/gpu/drm/i915/i915_drv.h | 23 ++++++++++++++++++++++- drivers/gpu/drm/i915/i915_gem.c | 14 +++++++------- drivers/gpu/drm/i915/i915_irq.c | 4 ++-- drivers/gpu/drm/i915/i915_scheduler.c | 20 ++++++++++++++++++++ drivers/gpu/drm/i915/i915_scheduler.h | 3 +++ 5 files changed, 54 insertions(+), 10 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 6e592d3..0977653 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -2214,14 +2214,35 @@ int i915_gem_dumb_create(struct drm_file *file_priv, struct drm_mode_create_dumb *args); int i915_gem_mmap_gtt(struct drm_file *file_priv, struct drm_device *dev, uint32_t handle, uint64_t *offset); + +bool i915_scheduler_is_seqno_in_flight(struct intel_engine_cs *ring, + uint32_t seqno, bool *completed); + /** * Returns true if seq1 is later than seq2. */ static inline bool -i915_seqno_passed(uint32_t seq1, uint32_t seq2) +i915_seqno_passed(struct intel_engine_cs *ring, uint32_t seq1, uint32_t seq2) { +#ifdef CONFIG_DRM_I915_SCHEDULER + bool completed; + + if (i915_scheduler_is_seqno_in_flight(ring, seq2, &completed)) + return completed; +#endif + return (int32_t)(seq1 - seq2) >= 0; } +static inline int32_t +i915_compare_seqno_values(uint32_t seq1, uint32_t seq2) +{ + int32_t diff = seq1 - seq2; + + if (!diff) + return 0; + + return (diff > 0) ? 1 : -1; +} int __must_check i915_gem_get_seqno(struct drm_device *dev, u32 *seqno); int __must_check i915_gem_set_seqno(struct drm_device *dev, u32 seqno); diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 7e53446..fece5e7 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -1165,7 +1165,7 @@ static int __wait_seqno(struct intel_engine_cs *ring, u32 seqno, WARN(dev_priv->pm.irqs_disabled, "IRQs disabled\n"); - if (i915_seqno_passed(ring->get_seqno(ring, true), seqno)) + if (i915_seqno_passed(ring, ring->get_seqno(ring, true), seqno)) return 0; timeout_expire = timeout ? jiffies + timespec_to_jiffies_timeout(timeout) : 0; @@ -1201,7 +1201,7 @@ static int __wait_seqno(struct intel_engine_cs *ring, u32 seqno, break; } - if (i915_seqno_passed(ring->get_seqno(ring, false), seqno)) { + if (i915_seqno_passed(ring, ring->get_seqno(ring, false), seqno)) { ret = 0; break; } @@ -2243,7 +2243,7 @@ i915_gem_object_retire(struct drm_i915_gem_object *obj) if (ring == NULL) return; - if (i915_seqno_passed(ring->get_seqno(ring, true), + if (i915_seqno_passed(ring, ring->get_seqno(ring, true), obj->last_read_seqno)) i915_gem_object_move_to_inactive(obj); } @@ -2489,7 +2489,7 @@ i915_gem_find_active_request(struct intel_engine_cs *ring) completed_seqno = ring->get_seqno(ring, false); list_for_each_entry(request, &ring->request_list, list) { - if (i915_seqno_passed(completed_seqno, request->seqno)) + if (i915_seqno_passed(ring, completed_seqno, request->seqno)) continue; return request; @@ -2620,7 +2620,7 @@ i915_gem_retire_requests_ring(struct intel_engine_cs *ring) */ list_for_each_entry_safe(req, req_next, &ring->request_list, list) { - if (!i915_seqno_passed(seqno, req->seqno)) + if (!i915_seqno_passed(ring, seqno, req->seqno)) continue; trace_i915_gem_request_retire(ring, req->seqno); @@ -2639,14 +2639,14 @@ i915_gem_retire_requests_ring(struct intel_engine_cs *ring) * before we free the context associated with the requests. */ list_for_each_entry_safe(obj, obj_next, &ring->active_list, ring_list) { - if (!i915_seqno_passed(seqno, obj->last_read_seqno)) + if (!i915_seqno_passed(ring, seqno, obj->last_read_seqno)) continue; i915_gem_object_move_to_inactive(obj); } if (unlikely(ring->trace_irq_seqno && - i915_seqno_passed(seqno, ring->trace_irq_seqno))) { + i915_seqno_passed(ring, seqno, ring->trace_irq_seqno))) { ring->irq_put(ring); ring->trace_irq_seqno = 0; } diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index 00358f9..eff08a3e 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -2750,7 +2750,7 @@ static bool ring_idle(struct intel_engine_cs *ring, u32 seqno) { return (list_empty(&ring->request_list) || - i915_seqno_passed(seqno, ring_last_seqno(ring))); + i915_seqno_passed(ring, seqno, ring_last_seqno(ring))); } static bool @@ -2862,7 +2862,7 @@ static int semaphore_passed(struct intel_engine_cs *ring) if (ctl & RING_WAIT_SEMAPHORE && semaphore_passed(signaller) < 0) return -1; - return i915_seqno_passed(signaller->get_seqno(signaller, false), seqno); + return i915_seqno_passed(ring, signaller->get_seqno(signaller, false), seqno); } static void semaphore_clear_deadlocks(struct drm_i915_private *dev_priv) diff --git a/drivers/gpu/drm/i915/i915_scheduler.c b/drivers/gpu/drm/i915/i915_scheduler.c index 9ec0225..e9aa566 100644 --- a/drivers/gpu/drm/i915/i915_scheduler.c +++ b/drivers/gpu/drm/i915/i915_scheduler.c @@ -49,6 +49,26 @@ int i915_scheduler_init(struct drm_device *dev) return 0; } +bool i915_scheduler_is_seqno_in_flight(struct intel_engine_cs *ring, + uint32_t seqno, bool *completed) +{ + struct drm_i915_private *dev_priv = ring->dev->dev_private; + struct i915_scheduler *scheduler = dev_priv->scheduler; + bool found = false; + unsigned long flags; + + if (!scheduler) + return false; + + spin_lock_irqsave(&scheduler->lock, flags); + + /* Do stuff... */ + + spin_unlock_irqrestore(&scheduler->lock, flags); + + return found; +} + #else /* CONFIG_DRM_I915_SCHEDULER */ int i915_scheduler_init(struct drm_device *dev) diff --git a/drivers/gpu/drm/i915/i915_scheduler.h b/drivers/gpu/drm/i915/i915_scheduler.h index bbe1934..67260b7 100644 --- a/drivers/gpu/drm/i915/i915_scheduler.h +++ b/drivers/gpu/drm/i915/i915_scheduler.h @@ -35,6 +35,9 @@ struct i915_scheduler { uint32_t index; }; +bool i915_scheduler_is_seqno_in_flight(struct intel_engine_cs *ring, + uint32_t seqno, bool *completed); + #endif /* CONFIG_DRM_I915_SCHEDULER */ #endif /* _I915_SCHEDULER_H_ */