From patchwork Thu Jun 27 23:30:38 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ben Widawsky X-Patchwork-Id: 2796351 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 01C9E9F245 for ; Thu, 27 Jun 2013 23:46:30 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id DF3182020E for ; Thu, 27 Jun 2013 23:46:28 +0000 (UTC) Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) by mail.kernel.org (Postfix) with ESMTP id D61D32020C for ; Thu, 27 Jun 2013 23:46:27 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id AE245E6461 for ; Thu, 27 Jun 2013 16:46:27 -0700 (PDT) X-Original-To: intel-gfx@lists.freedesktop.org Delivered-To: intel-gfx@lists.freedesktop.org Received: from shiva.localdomain (unknown [209.20.75.48]) by gabe.freedesktop.org (Postfix) with ESMTP id 894F1E62A5 for ; Thu, 27 Jun 2013 16:28:30 -0700 (PDT) Received: by shiva.localdomain (Postfix, from userid 99) id 5978A886AD; Thu, 27 Jun 2013 23:28:30 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Spam-Level: X-Spam-Status: No, score=-5.5 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_MED, RP_MATCHES_RCVD,UNPARSEABLE_RELAY autolearn=ham version=3.3.1 Received: from lundgren.jf.intel.com (jfdmzpr02-ext.jf.intel.com [134.134.137.71]) by shiva.localdomain (Postfix) with ESMTPSA id 2AF73886A7; Thu, 27 Jun 2013 23:28:28 +0000 (UTC) From: Ben Widawsky To: Intel GFX Date: Thu, 27 Jun 2013 16:30:38 -0700 Message-Id: <1372375867-1003-38-git-send-email-ben@bwidawsk.net> X-Mailer: git-send-email 1.8.3.1 In-Reply-To: <1372375867-1003-1-git-send-email-ben@bwidawsk.net> References: <1372375867-1003-1-git-send-email-ben@bwidawsk.net> Cc: Ben Widawsky Subject: [Intel-gfx] [PATCH 37/66] drm/i915: Create VMAs (part 6) - finish error plumbing X-BeenThere: intel-gfx@lists.freedesktop.org X-Mailman-Version: 2.1.13 Precedence: list List-Id: Intel graphics driver community testing & development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: intel-gfx-bounces+patchwork-intel-gfx=patchwork.kernel.org@lists.freedesktop.org Errors-To: intel-gfx-bounces+patchwork-intel-gfx=patchwork.kernel.org@lists.freedesktop.org X-Virus-Scanned: ClamAV using ClamSMTP Signed-off-by: Ben Widawsky --- drivers/gpu/drm/i915/i915_irq.c | 53 ++++++++++++++++++++++++++++------------- 1 file changed, 37 insertions(+), 16 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index 28880bf..e1653fd 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -1499,6 +1499,7 @@ static void i915_get_extra_instdone(struct drm_device *dev, static struct drm_i915_error_object * i915_error_object_create_sized(struct drm_i915_private *dev_priv, struct drm_i915_gem_object *src, + struct i915_address_space *vm, const int num_pages) { struct drm_i915_error_object *dst; @@ -1512,8 +1513,7 @@ i915_error_object_create_sized(struct drm_i915_private *dev_priv, if (dst == NULL) return NULL; - /* FIXME: must handle per faulty VM */ - reloc_offset = i915_gem_ggtt_offset(src); + reloc_offset = i915_gem_obj_offset(src, vm); for (i = 0; i < num_pages; i++) { unsigned long flags; void *d; @@ -1565,7 +1565,7 @@ i915_error_object_create_sized(struct drm_i915_private *dev_priv, reloc_offset += PAGE_SIZE; } dst->page_count = num_pages; - dst->gtt_offset = i915_gem_ggtt_offset(src); + dst->gtt_offset = i915_gem_obj_offset(src, vm); return dst; @@ -1575,8 +1575,9 @@ unwind: kfree(dst); return NULL; } -#define i915_error_object_create(dev_priv, src) \ +#define i915_error_object_create(dev_priv, src, vm) \ i915_error_object_create_sized((dev_priv), (src), \ + vm, \ (src)->base.size>>PAGE_SHIFT) static void @@ -1617,14 +1618,14 @@ i915_error_state_free(struct kref *error_ref) kfree(error); } static void capture_bo(struct drm_i915_error_buffer *err, - struct drm_i915_gem_object *obj) + struct drm_i915_gem_object *obj, + struct i915_address_space *vm) { err->size = obj->base.size; err->name = obj->base.name; err->rseqno = obj->last_read_seqno; err->wseqno = obj->last_write_seqno; - /* FIXME: plumb the actual context into here to pull the right VM */ - err->gtt_offset = i915_gem_ggtt_offset(obj); + err->gtt_offset = i915_gem_obj_offset(obj, vm); err->read_domains = obj->base.read_domains; err->write_domain = obj->base.write_domain; err->fence_reg = obj->fence_reg; @@ -1647,7 +1648,7 @@ static u32 capture_active_bo(struct drm_i915_error_buffer *err, int i = 0; list_for_each_entry(vma, head, mm_list) { - capture_bo(err++, vma->obj); + capture_bo(err++, vma->obj, vma->vm); if (++i == count) break; } @@ -1662,10 +1663,14 @@ static u32 capture_pinned_bo(struct drm_i915_error_buffer *err, int i = 0; list_for_each_entry(obj, head, global_list) { + struct i915_vma *vma; if (obj->pin_count == 0) continue; - capture_bo(err++, obj); + /* Object may be pinned in multiple VMs, just take first */ + vma = list_first_entry(&obj->vma_list, struct i915_vma, + vma_link); + capture_bo(err++, obj, vma->vm); if (++i == count) break; } @@ -1713,6 +1718,7 @@ i915_error_first_batchbuffer(struct drm_i915_private *dev_priv, struct i915_vma *vma; struct drm_i915_gem_object *obj; u32 seqno; + u32 pp_db; if (!ring->get_seqno) return NULL; @@ -1729,11 +1735,19 @@ i915_error_first_batchbuffer(struct drm_i915_private *dev_priv, obj = ring->private; if (acthd >= i915_gem_ggtt_offset(obj) && acthd < i915_gem_ggtt_offset(obj) + obj->base.size) - return i915_error_object_create(dev_priv, obj); + return i915_error_object_create(dev_priv, obj, + &dev_priv->gtt.base); } + pp_db = I915_READ(RING_PP_DIR_BASE(ring)); seqno = ring->get_seqno(ring, false); + list_for_each_entry(vm, &dev_priv->vm_list, global_link) { + struct i915_hw_ppgtt *ppgtt = + container_of(vm, struct i915_hw_ppgtt, base); + if (!is_i915_ggtt(vm) && pp_db >> 10 != ppgtt->pd_offset) + continue; + list_for_each_entry(vma, &vm->active_list, mm_list) { obj = vma->obj; if (obj->ring != ring) @@ -1749,7 +1763,7 @@ i915_error_first_batchbuffer(struct drm_i915_private *dev_priv, * simplest method to avoid being overwritten by * userspace. */ - return i915_error_object_create(dev_priv, obj); + return i915_error_object_create(dev_priv, obj, vm); } } @@ -1806,6 +1820,7 @@ static void i915_gem_record_active_context(struct intel_ring_buffer *ring, struct drm_i915_error_ring *ering) { struct drm_i915_private *dev_priv = ring->dev->dev_private; + struct i915_address_space *ggtt = &dev_priv->gtt.base; struct drm_i915_gem_object *obj; /* Currently render ring is the only HW context user */ @@ -1813,9 +1828,14 @@ static void i915_gem_record_active_context(struct intel_ring_buffer *ring, return; list_for_each_entry(obj, &dev_priv->mm.bound_list, global_list) { + if (!i915_gem_obj_bound(obj, ggtt)) + continue; + if ((error->ccid & PAGE_MASK) == i915_gem_ggtt_offset(obj)) { ering->ctx = i915_error_object_create_sized(dev_priv, - obj, 1); + obj, + ggtt, + 1); } } } @@ -1835,8 +1855,8 @@ static void i915_gem_record_rings(struct drm_device *dev, i915_error_first_batchbuffer(dev_priv, ring); error->ring[i].ringbuffer = - i915_error_object_create(dev_priv, ring->obj); - + i915_error_object_create(dev_priv, ring->obj, + &dev_priv->gtt.base); i915_gem_record_active_context(ring, error, &error->ring[i]); @@ -1912,7 +1932,7 @@ static void i915_gem_capture_buffers(struct drm_i915_private *dev_priv, struct drm_i915_error_state *error) { struct i915_address_space *vm; - int cnt = 0; + int cnt = 0, i = 0; list_for_each_entry(vm, &dev_priv->vm_list, global_link) cnt++; @@ -1929,7 +1949,8 @@ static void i915_gem_capture_buffers(struct drm_i915_private *dev_priv, error->pinned_bo_count = kcalloc(cnt, sizeof(*error->pinned_bo_count), GFP_ATOMIC); - i915_gem_capture_vm(dev_priv, error, vm, 0); + list_for_each_entry(vm, &dev_priv->vm_list, global_link) + i915_gem_capture_vm(dev_priv, error, vm, i++); } /**