From patchwork Sat Feb 26 18:30:18 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ben Widawsky X-Patchwork-Id: 592751 Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) by demeter1.kernel.org (8.14.4/8.14.3) with ESMTP id p1QIgl86013010 for ; Sat, 26 Feb 2011 18:43:07 GMT Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 42B3B9E9B4 for ; Sat, 26 Feb 2011 10:42:47 -0800 (PST) X-Original-To: intel-gfx@lists.freedesktop.org Delivered-To: intel-gfx@lists.freedesktop.org Received: from mail-iy0-f177.google.com (mail-iy0-f177.google.com [209.85.210.177]) by gabe.freedesktop.org (Postfix) with ESMTP id 7DC5A9E88F for ; Sat, 26 Feb 2011 10:30:44 -0800 (PST) Received: by mail-iy0-f177.google.com with SMTP id 40so1907628iyf.36 for ; Sat, 26 Feb 2011 10:30:44 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=domainkey-signature:from:to:cc:subject:date:message-id:x-mailer :in-reply-to:references; bh=xOQ1Gtb3X4l1xLeqWvA1pV8ilDnQXP/BBey+xMTxhjw=; b=wVl/HbdtzwzAyT7adV3BRJWQl+1cN/P+zGlRV/83KBs4sUJiWDQoTov4Q+QwPqm1BP PedJxBxJ1JTtlV5f0MbOaceITzFUoB6unXbuLzX4CROw5d49RGysxDIR44SNoeQyOBVg ubEYCcNf3hBphUaEtA678xIla15NnM+NhQuZ8= DomainKey-Signature: a=rsa-sha1; c=nofws; d=gmail.com; s=gamma; h=from:to:cc:subject:date:message-id:x-mailer:in-reply-to:references; b=Err2TMHcucDE4DGhvRJiKhRgWo9saeIwarmo+rZBI45DsEx3FJM4dgm4cxJvID4M9X vzbDrGTiSk4iRRT2J7doaKoGCaObsrTajlGPIYDJacizN1W2u0FvK4r2b3zlSitbsqL/ zTmaYFsFRi/Z6x8ksA+KEWGzCaCqEx2Yyr40E= Received: by 10.42.219.137 with SMTP id hu9mr2515119icb.363.1298745044319; Sat, 26 Feb 2011 10:30:44 -0800 (PST) Received: from localhost.localdomain ([67.208.96.87]) by mx.google.com with ESMTPS id wd12sm1519339icb.17.2011.02.26.10.30.42 (version=TLSv1/SSLv3 cipher=OTHER); Sat, 26 Feb 2011 10:30:43 -0800 (PST) From: Ben Widawsky To: intel-gfx@lists.freedesktop.org Date: Sat, 26 Feb 2011 10:30:18 -0800 Message-Id: <1298745018-5937-9-git-send-email-bwidawsk@gmail.com> X-Mailer: git-send-email 1.7.3.4 In-Reply-To: <1298745018-5937-1-git-send-email-bwidawsk@gmail.com> References: <1298745018-5937-1-git-send-email-bwidawsk@gmail.com> Subject: [Intel-gfx] [RFC] [PATCH 8/8] drm/i915/context: create and destroy ioctls X-BeenThere: intel-gfx@lists.freedesktop.org X-Mailman-Version: 2.1.11 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-Greylist: IP, sender and recipient auto-whitelisted, not delayed by milter-greylist-4.2.6 (demeter1.kernel.org [140.211.167.41]); Sat, 26 Feb 2011 18:43:07 +0000 (UTC) diff --git a/drivers/gpu/drm/i915/i915_context.c b/drivers/gpu/drm/i915/i915_context.c index 3719a87..da4a0ff 100644 --- a/drivers/gpu/drm/i915/i915_context.c +++ b/drivers/gpu/drm/i915/i915_context.c @@ -33,6 +33,8 @@ #define CONTEXT_SIZE dev_priv->context_size #define CONTEXT_ALIGN 4096 +static int context_idr_cleanup(int id, void *p, void *data); + static int context_generate_id(struct drm_i915_gem_context *ctx) { struct drm_i915_file_private *file_priv = ctx->file->driver_priv; @@ -268,7 +270,50 @@ id_out: static void logical_context_fini(struct drm_i915_gem_context *ctx) { + struct drm_device *dev = ctx->dev; + struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_gem_context *last; + int i; + int ret = 0; + + if (WARN_ON(!mutex_is_locked(&dev->struct_mutex))) + return; + + if (ctx == dev_priv->default_context) + return; + + for (i = 0; i < I915_NUM_RINGS; i++) { + struct intel_ring_buffer *ring = &dev_priv->ring[i]; + if (!ring->context_switch) + continue; + + if (!(ctx->ring_enable & (1 << i))) + continue; + + if (ring->last_context != ctx) + continue; + /* + * XXX We can prevent restoring contexts, but not saving them + * so if we're going to take away our backing context object + * of the last context, we have to switch now. + */ + + DRM_DEBUG_DRIVER("Switching to default context\n"); + last = ring->context_switch(ring, dev_priv->default_context, + 0, I915_CONTEXT_NORMAL_SWITCH); + if (!last) { + DRM_ERROR("Couldn't switch back to default context\n"); + continue; + } + + BUG_ON(last != ctx); + ret = wait_for_context_switch(ring); + if (ret) + DRM_ERROR("Wait for default context switch failed " + "ring = %d (%d)", i, ret); + i915_release_context(last); + } } static int logical_context_free(struct drm_file *file, uint32_t id) @@ -304,24 +349,40 @@ static int logical_context_free(struct drm_file *file, uint32_t id) } /** - * i915_context_create_ioctl() - not yet supported + * i915_context_create_ioctl() */ int i915_context_create_ioctl(struct drm_device *dev, void *data, struct drm_file *file) { struct drm_i915_gem_context_create *args = data; - args->ctx_id = 0; - return -EIO; + struct drm_i915_gem_context *out_ctx = NULL; + int ret = 0; + + mutex_lock(&dev->struct_mutex); + ret = logical_context_alloc(dev, file, args->ring_mask, &out_ctx); + mutex_unlock(&dev->struct_mutex); + if (ret == 0) { + args->ctx_id = out_ctx->id; + if (WARN_ON(args->ctx_id == DEFAULT_CONTEXT_ID)) + return -ENXIO; + args->ring_enable = out_ctx->ring_enable; + } + + return ret; } /** - * i915_context_destroy_ioctl() - not yet supported + * i915_context_destroy_ioctl() */ int i915_context_destroy_ioctl(struct drm_device *dev, void *data, struct drm_file *file) { struct drm_i915_gem_context_destroy *args = data; - return -EINVAL; + + if (args->ctx_id == DEFAULT_CONTEXT_ID) + return -EINVAL; + + return logical_context_free(file, args->ctx_id); } /** @@ -370,18 +431,55 @@ void i915_context_unload(struct drm_device *dev) void i915_context_open(struct drm_device *dev, struct drm_file *file) { + struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_file_private *file_priv = file->driver_priv; + + if (dev_priv->contexts_disabled) + return; + idr_init(&file_priv->context_idr); + spin_lock_init(&file_priv->context_idr_lock); } void i915_context_close(struct drm_device *dev, struct drm_file *file) { + struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_file_private *file_priv = file->driver_priv; + + if (dev_priv->contexts_disabled) + return; + idr_for_each(&file_priv->context_idr, context_idr_cleanup, file); + idr_destroy(&file_priv->context_idr); +} + +static int context_idr_cleanup(int id, void *p, void *data) +{ + struct drm_file *file = (struct drm_file *) data; + logical_context_free(file, id); + return 0; } struct drm_i915_gem_context *i915_get_context(struct drm_file *file, uint32_t id) { - return NULL; + struct drm_i915_file_private *file_priv = file->driver_priv; + struct drm_i915_gem_context *ctx = NULL; + int ret; + + spin_lock(&file_priv->context_idr_lock); + ctx = idr_find(&file_priv->context_idr, id); + if (ctx) { + drm_gem_object_reference(&ctx->obj->base); + ret = i915_gem_object_pin(ctx->obj, CONTEXT_ALIGN, false); + if (ret) { + drm_gem_object_unreference(&ctx->obj->base); + ctx = NULL; + } + } + spin_unlock(&file_priv->context_idr_lock); + + return ctx; } void i915_release_context(struct drm_i915_gem_context *ctx)