From patchwork Fri Jul 17 14:33:31 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: John Harrison X-Patchwork-Id: 6816431 Return-Path: X-Original-To: patchwork-intel-gfx@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork2.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork2.web.kernel.org (Postfix) with ESMTP id D5003C05AD for ; Fri, 17 Jul 2015 14:34:21 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id C0EE520687 for ; Fri, 17 Jul 2015 14:34:20 +0000 (UTC) Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) by mail.kernel.org (Postfix) with ESMTP id B378120670 for ; Fri, 17 Jul 2015 14:34:19 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 976586ED6D; Fri, 17 Jul 2015 07:34:18 -0700 (PDT) X-Original-To: Intel-GFX@lists.freedesktop.org Delivered-To: Intel-GFX@lists.freedesktop.org Received: from mga11.intel.com (mga11.intel.com [192.55.52.93]) by gabe.freedesktop.org (Postfix) with ESMTP id D18006E4FD for ; Fri, 17 Jul 2015 07:34:15 -0700 (PDT) Received: from orsmga002.jf.intel.com ([10.7.209.21]) by fmsmga102.fm.intel.com with ESMTP; 17 Jul 2015 07:34:15 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.15,497,1432623600"; d="scan'208";a="766366748" Received: from johnharr-linux.isw.intel.com ([10.102.226.190]) by orsmga002.jf.intel.com with ESMTP; 17 Jul 2015 07:34:14 -0700 From: John.C.Harrison@Intel.com To: Intel-GFX@Lists.FreeDesktop.Org Date: Fri, 17 Jul 2015 15:33:31 +0100 Message-Id: <1437143628-6329-23-git-send-email-John.C.Harrison@Intel.com> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1437143628-6329-1-git-send-email-John.C.Harrison@Intel.com> References: <1437143628-6329-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 22/39] drm/i915: Add scheduler hook to GPU reset X-BeenThere: intel-gfx@lists.freedesktop.org X-Mailman-Version: 2.1.18 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=-5.4 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_MED, 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 When the watchdog resets the GPU, the scheduler needs to know so that it can clean up it's view of the world. All in flight nodes must be marked as dead so that the scheduler does not wait forever for them to complete. Also, all queued nodes must be marked as dead so that the scheduler does not dead lock the reset code by saying that the ring can not be idled and it must come back again later. Change-Id: I184eb59c5c1a1385f9c17db66c7cc46f8904eebd For: VIZ-1587 Signed-off-by: John Harrison --- drivers/gpu/drm/i915/i915_gem.c | 2 ++ drivers/gpu/drm/i915/i915_scheduler.c | 63 ++++++++++++++++++++++++++++++++--- drivers/gpu/drm/i915/i915_scheduler.h | 8 ++++- 3 files changed, 68 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 6142e68..6d72caa 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -3187,6 +3187,8 @@ void i915_gem_reset(struct drm_device *dev) struct intel_engine_cs *ring; int i; + i915_scheduler_kill_all(dev); + /* * Before we free the objects from the requests, we need to inspect * them for finding the guilty party. As the requests only borrow diff --git a/drivers/gpu/drm/i915/i915_scheduler.c b/drivers/gpu/drm/i915/i915_scheduler.c index 73c9ba6..3155f42 100644 --- a/drivers/gpu/drm/i915/i915_scheduler.c +++ b/drivers/gpu/drm/i915/i915_scheduler.c @@ -341,6 +341,56 @@ static void i915_scheduler_node_kill(struct i915_scheduler_queue_entry *node) node->status = i915_sqs_dead; } +/* Abandon a queued node completely. For example because the driver is being + * reset and it is not valid to preserve absolutely any state at all across the + * reinitialisation sequence. */ +static void i915_scheduler_node_kill_queued(struct i915_scheduler_queue_entry *node) +{ + BUG_ON(!node); + BUG_ON(!I915_SQS_IS_QUEUED(node)); + + node->status = i915_sqs_dead; +} + +/* The system is toast. Terminate all nodes with extreme prejudice. */ +void i915_scheduler_kill_all(struct drm_device *dev) +{ + struct i915_scheduler_queue_entry *node; + struct drm_i915_private *dev_priv = dev->dev_private; + struct i915_scheduler *scheduler = dev_priv->scheduler; + unsigned long flags; + int r; + + spin_lock_irqsave(&scheduler->lock, flags); + + for (r = 0; r < I915_NUM_RINGS; r++) { + list_for_each_entry(node, &scheduler->node_queue[r], link) { + switch (node->status) { + case I915_SQS_CASE_COMPLETE: + break; + + case I915_SQS_CASE_FLYING: + i915_scheduler_node_kill(node); + break; + + case I915_SQS_CASE_QUEUED: + i915_scheduler_node_kill_queued(node); + break; + + default: + /* Wot no state?! */ + BUG(); + } + } + } + + memset(scheduler->last_irq_seqno, 0x00, sizeof(scheduler->last_irq_seqno)); + + spin_unlock_irqrestore(&scheduler->lock, flags); + + queue_work(dev_priv->wq, &dev_priv->mm.scheduler_work); +} + /* * The batch tagged with the indicated seqence number has completed. * Search the queue for it, update its status and those of any batches @@ -912,7 +962,7 @@ static int i915_scheduler_submit(struct intel_engine_cs *ring, bool was_locked) scheduler->flags[ring->id] &= ~i915_sf_submitting; if (ret) { - bool requeue = true; + int requeue = 1; /* Oh dear! Either the node is broken or the ring is * busy. So need to kill the node or requeue it and try @@ -922,7 +972,7 @@ static int i915_scheduler_submit(struct intel_engine_cs *ring, bool was_locked) case ENODEV: case ENOENT: /* Fatal errors. Kill the node. */ - requeue = false; + requeue = -1; break; case EAGAIN: @@ -941,13 +991,18 @@ static int i915_scheduler_submit(struct intel_engine_cs *ring, bool was_locked) break; } - if (requeue) { + /* Check that the watchdog/reset code has not nuked + * the node while we weren't looking: */ + if (node->status == i915_sqs_dead) + requeue = 0; + + if (requeue == 1) { i915_scheduler_node_requeue(node); /* No point spinning if the ring is currently * unavailable so just give up and come back * later. */ break; - } else + } else if (requeue == -1) i915_scheduler_node_kill(node); } diff --git a/drivers/gpu/drm/i915/i915_scheduler.h b/drivers/gpu/drm/i915/i915_scheduler.h index 5e094d5..b440e62 100644 --- a/drivers/gpu/drm/i915/i915_scheduler.h +++ b/drivers/gpu/drm/i915/i915_scheduler.h @@ -36,7 +36,7 @@ enum i915_scheduler_queue_status { i915_sqs_flying, /* Finished processing on the hardware: */ i915_sqs_complete, - /* Killed by catastrophic submission failure: */ + /* Killed by watchdog or catastrophic submission failure: */ i915_sqs_dead, /* Limit value for use with arrays/loops */ i915_sqs_MAX @@ -47,6 +47,11 @@ enum i915_scheduler_queue_status { #define I915_SQS_IS_COMPLETE(node) (((node)->status == i915_sqs_complete) || \ ((node)->status == i915_sqs_dead)) +#define I915_SQS_CASE_QUEUED i915_sqs_queued +#define I915_SQS_CASE_FLYING i915_sqs_flying +#define I915_SQS_CASE_COMPLETE i915_sqs_complete: \ + case i915_sqs_dead + struct i915_scheduler_obj_entry { struct drm_i915_gem_object *obj; }; @@ -91,6 +96,7 @@ int i915_scheduler_closefile(struct drm_device *dev, void i915_gem_scheduler_clean_node(struct i915_scheduler_queue_entry *node); int i915_scheduler_queue_execbuffer(struct i915_scheduler_queue_entry *qe); int i915_scheduler_handle_irq(struct intel_engine_cs *ring); +void i915_scheduler_kill_all(struct drm_device *dev); void i915_gem_scheduler_work_handler(struct work_struct *work); int i915_scheduler_flush(struct intel_engine_cs *ring, bool is_locked); int i915_scheduler_flush_request(struct drm_i915_gem_request *req,