From patchwork Fri May 9 12:08:55 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: oscar.mateo@intel.com X-Patchwork-Id: 4142381 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 C760D9F1E1 for ; Fri, 9 May 2014 12:14:57 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id D7257201B4 for ; Fri, 9 May 2014 12:14:56 +0000 (UTC) Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) by mail.kernel.org (Postfix) with ESMTP id CB9562026C for ; Fri, 9 May 2014 12:14:54 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 5362E6EF7E; Fri, 9 May 2014 05:14:54 -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 2E5DC4A05A for ; Fri, 9 May 2014 05:14:53 -0700 (PDT) Received: from fmsmga001.fm.intel.com ([10.253.24.23]) by fmsmga101.fm.intel.com with ESMTP; 09 May 2014 05:14:53 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos; i="4.97,1018,1389772800"; d="scan'208"; a="529106995" Received: from omateolo-linux2.iwi.intel.com ([172.28.253.145]) by fmsmga001.fm.intel.com with ESMTP; 09 May 2014 05:14:51 -0700 From: oscar.mateo@intel.com To: intel-gfx@lists.freedesktop.org Date: Fri, 9 May 2014 13:08:55 +0100 Message-Id: <1399637360-4277-26-git-send-email-oscar.mateo@intel.com> X-Mailer: git-send-email 1.9.0 In-Reply-To: <1399637360-4277-1-git-send-email-oscar.mateo@intel.com> References: <1399637360-4277-1-git-send-email-oscar.mateo@intel.com> Subject: [Intel-gfx] [PATCH 25/50] drm/i915/bdw: Deferred creation of user-created LRCs 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.8 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: Oscar Mateo The backing objects for user-created contexts (either via open fd or create context ioctl) are actually empty until the user starts sending execbuffers to them. We do this because, at create time, we really don't know which engine is going to be used with the context later on. Signed-off-by: Oscar Mateo --- drivers/gpu/drm/i915/i915_drv.h | 3 +++ drivers/gpu/drm/i915/i915_gem_context.c | 31 +++++++++++++++++---------- drivers/gpu/drm/i915/i915_gem_execbuffer.c | 5 ++++- drivers/gpu/drm/i915/intel_lrc.c | 34 ++++++++++++++++++++++++++++++ 4 files changed, 61 insertions(+), 12 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 4d58167..7d06a66 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -2431,6 +2431,9 @@ int gen8_gem_context_init(struct drm_device *dev); int gen8_create_lr_context(struct i915_hw_context *ctx, struct intel_engine *ring, struct drm_i915_file_private *file_priv); +struct i915_hw_context * +gen8_gem_validate_context(struct drm_device *dev, struct drm_file *file, + struct intel_engine *ring, const u32 ctx_id); /* i915_gem_evict.c */ int __must_check i915_gem_evict_something(struct drm_device *dev, diff --git a/drivers/gpu/drm/i915/i915_gem_context.c b/drivers/gpu/drm/i915/i915_gem_context.c index e4e616d..d4c6863 100644 --- a/drivers/gpu/drm/i915/i915_gem_context.c +++ b/drivers/gpu/drm/i915/i915_gem_context.c @@ -181,6 +181,7 @@ void i915_gem_context_free(struct kref *ctx_ref) struct i915_hw_context *ctx = container_of(ctx_ref, typeof(*ctx), ref); struct i915_hw_ppgtt *ppgtt = NULL; + bool ppgtt_unref = false; int i; for (i = 0; i < I915_NUM_RINGS; i++) { @@ -188,12 +189,12 @@ void i915_gem_context_free(struct kref *ctx_ref) struct intel_ringbuffer *ringbuf = ctx->engine[i].ringbuf; if (ctx_obj) { - if (i == RCS) { - /* We refcount even the aliasing PPGTT to keep the - * code symmetric */ - if (USES_PPGTT(ctx_obj->base.dev)) - ppgtt = ctx_to_ppgtt(ctx); - } + struct drm_device *dev = ctx_obj->base.dev; + struct drm_i915_private *dev_priv = to_i915(dev); + ppgtt_unref = USES_PPGTT(dev); + + if (dev_priv->lrc_enabled && ctx->file_priv) + i915_gem_object_ggtt_unpin(ctx_obj); /* XXX: Free up the object before tearing down the address * space, in case we're bound in the PPGTT */ @@ -207,8 +208,13 @@ void i915_gem_context_free(struct kref *ctx_ref) } } - if (ppgtt) - kref_put(&ppgtt->ref, ppgtt_release); + if (ppgtt_unref) { + /* We refcount even the aliasing PPGTT to keep the + * code symmetric */ + ppgtt = ctx_to_ppgtt(ctx); + if (ppgtt) + kref_put(&ppgtt->ref, ppgtt_release); + } list_del(&ctx->link); kfree(ctx); } @@ -550,12 +556,13 @@ static int context_idr_cleanup(int id, void *p, void *data) int i915_gem_context_open(struct drm_device *dev, struct drm_file *file) { struct drm_i915_file_private *file_priv = file->driver_priv; + struct drm_i915_private *dev_priv = to_i915(dev); idr_init(&file_priv->context_idr); mutex_lock(&dev->struct_mutex); - file_priv->private_default_ctx = - i915_gem_create_context(dev, file_priv, USES_FULL_PPGTT(dev), true); + file_priv->private_default_ctx = i915_gem_create_context(dev, file_priv, + USES_FULL_PPGTT(dev), !dev_priv->lrc_enabled); mutex_unlock(&dev->struct_mutex); if (IS_ERR(file_priv->private_default_ctx)) { @@ -801,6 +808,7 @@ int i915_gem_context_create_ioctl(struct drm_device *dev, void *data, { struct drm_i915_gem_context_create *args = data; struct drm_i915_file_private *file_priv = file->driver_priv; + struct drm_i915_private *dev_priv = to_i915(dev); struct i915_hw_context *ctx; int ret; @@ -811,7 +819,8 @@ int i915_gem_context_create_ioctl(struct drm_device *dev, void *data, if (ret) return ret; - ctx = i915_gem_create_context(dev, file_priv, USES_FULL_PPGTT(dev), true); + ctx = i915_gem_create_context(dev, file_priv, USES_FULL_PPGTT(dev), + !dev_priv->lrc_enabled); mutex_unlock(&dev->struct_mutex); if (IS_ERR(ctx)) return PTR_ERR(ctx); diff --git a/drivers/gpu/drm/i915/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/i915_gem_execbuffer.c index 823ad3d..f7dad8c 100644 --- a/drivers/gpu/drm/i915/i915_gem_execbuffer.c +++ b/drivers/gpu/drm/i915/i915_gem_execbuffer.c @@ -1190,7 +1190,10 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data, goto pre_mutex_err; } - ctx = i915_gem_validate_context(dev, file, ring, ctx_id); + if (dev_priv->lrc_enabled) + ctx = gen8_gem_validate_context(dev, file, ring, ctx_id); + else + ctx = i915_gem_validate_context(dev, file, ring, ctx_id); if (IS_ERR(ctx)) { mutex_unlock(&dev->struct_mutex); ret = PTR_ERR(ctx); diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c index 5a85496..a656b48 100644 --- a/drivers/gpu/drm/i915/intel_lrc.c +++ b/drivers/gpu/drm/i915/intel_lrc.c @@ -78,6 +78,40 @@ #define CTX_R_PWR_CLK_STATE 0x42 #define CTX_GPGPU_CSR_BASE_ADDRESS 0x44 +struct i915_hw_context * +gen8_gem_validate_context(struct drm_device *dev, struct drm_file *file, + struct intel_engine *ring, const u32 ctx_id) +{ + struct i915_hw_context *ctx = NULL; + struct i915_ctx_hang_stats *hs; + + /* There is no reason why we cannot accept non-default, non-render contexts, + * other than it changes the ABI (these kind of custom contexts have not been + * allowed before) */ + if (ring->id != RCS && ctx_id != DEFAULT_CONTEXT_ID) + return ERR_PTR(-EINVAL); + + ctx = i915_gem_context_get(file->driver_priv, ctx_id); + if (IS_ERR(ctx)) + return ctx; + + hs = &ctx->hang_stats; + if (hs->banned) { + DRM_DEBUG("Context %u tried to submit while banned\n", ctx_id); + return ERR_PTR(-EIO); + } + + if (!ctx->engine[ring->id].obj) { + int ret = gen8_create_lr_context(ctx, ring, file->driver_priv); + if (ret) { + DRM_DEBUG("Could not create LRC %u\n", ctx_id); + return ERR_PTR(ret); + } + } + + return ctx; +} + static int intel_populate_lr_context(struct i915_hw_context *ctx, struct intel_engine *ring)