drm/i915: Complete kerneldoc for struct i915_gem_context
authorChris Wilson <chris@chris-wilson.co.uk>
Sat, 31 Dec 2016 11:20:11 +0000 (11:20 +0000)
committerChris Wilson <chris@chris-wilson.co.uk>
Sat, 31 Dec 2016 11:41:47 +0000 (11:41 +0000)
The existing kerneldoc was outdated, so time for a refresh.

v2: Use single line kdoc, mention functions for manipulation

Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Link: http://patchwork.freedesktop.org/patch/msgid/20161231112012.29263-3-chris@chris-wilson.co.uk
drivers/gpu/drm/i915/i915_drv.h
drivers/gpu/drm/i915/i915_gem.c
drivers/gpu/drm/i915/i915_gem_context.c
drivers/gpu/drm/i915/i915_gem_context.h [new file with mode: 0644]
drivers/gpu/drm/i915/i915_gem_execbuffer.c
drivers/gpu/drm/i915/i915_gpu_error.c
drivers/gpu/drm/i915/intel_lrc.c

index cfa4700..1c12714 100644 (file)
@@ -60,6 +60,7 @@
 #include "intel_ringbuffer.h"
 
 #include "i915_gem.h"
+#include "i915_gem_context.h"
 #include "i915_gem_fence_reg.h"
 #include "i915_gem_object.h"
 #include "i915_gem_gtt.h"
@@ -1048,76 +1049,6 @@ enum i915_cache_level {
 
 #define I915_COLOR_UNEVICTABLE (-1) /* a non-vma sharing the address space */
 
-#define DEFAULT_CONTEXT_HANDLE 0
-
-/**
- * struct i915_gem_context - as the name implies, represents a context.
- * @ref: reference count.
- * @user_handle: userspace tracking identity for this context.
- * @remap_slice: l3 row remapping information.
- * @flags: context specific flags:
- *         CONTEXT_NO_ZEROMAP: do not allow mapping things to page 0.
- * @file_priv: filp associated with this context (NULL for global default
- *            context).
- * @hang_stats: information about the role of this context in possible GPU
- *             hangs.
- * @ppgtt: virtual memory space used by this context.
- * @legacy_hw_ctx: render context backing object and whether it is correctly
- *                initialized (legacy ring submission mechanism only).
- * @link: link in the global list of contexts.
- *
- * Contexts are memory images used by the hardware to store copies of their
- * internal state.
- */
-struct i915_gem_context {
-       struct kref ref;
-       struct drm_i915_private *i915;
-       struct drm_i915_file_private *file_priv;
-       struct i915_hw_ppgtt *ppgtt;
-       struct pid *pid;
-       const char *name;
-
-       unsigned long flags;
-#define CONTEXT_NO_ZEROMAP             BIT(0)
-#define CONTEXT_NO_ERROR_CAPTURE       BIT(1)
-
-       /* Unique identifier for this context, used by the hw for tracking */
-       unsigned int hw_id;
-       u32 user_handle;
-       int priority; /* greater priorities are serviced first */
-
-       u32 ggtt_alignment;
-       u32 ggtt_offset_bias;
-
-       struct intel_context {
-               struct i915_vma *state;
-               struct intel_ring *ring;
-               uint32_t *lrc_reg_state;
-               u64 lrc_desc;
-               int pin_count;
-               bool initialised;
-       } engine[I915_NUM_ENGINES];
-       u32 ring_size;
-       u32 desc_template;
-       struct atomic_notifier_head status_notifier;
-       bool execlists_force_single_submission;
-
-       struct list_head link;
-
-       u8 remap_slice;
-       bool closed:1;
-       bool bannable:1;
-       bool banned:1;
-
-       unsigned int guilty_count; /* guilty of a hang */
-       unsigned int active_count; /* active during hang */
-
-#define CONTEXT_SCORE_GUILTY           10
-#define CONTEXT_SCORE_BAN_THRESHOLD    40
-       /* Accumulated score of hangs caused by this context */
-       int ban_score;
-};
-
 enum fb_op_origin {
        ORIGIN_GTT,
        ORIGIN_CPU,
@@ -3494,18 +3425,6 @@ void i915_gem_object_do_bit_17_swizzle(struct drm_i915_gem_object *obj,
 void i915_gem_object_save_bit_17_swizzle(struct drm_i915_gem_object *obj,
                                         struct sg_table *pages);
 
-/* i915_gem_context.c */
-int __must_check i915_gem_context_init(struct drm_i915_private *dev_priv);
-void i915_gem_context_lost(struct drm_i915_private *dev_priv);
-void i915_gem_context_fini(struct drm_i915_private *dev_priv);
-int i915_gem_context_open(struct drm_device *dev, struct drm_file *file);
-void i915_gem_context_close(struct drm_device *dev, struct drm_file *file);
-int i915_switch_context(struct drm_i915_gem_request *req);
-int i915_gem_switch_to_kernel_context(struct drm_i915_private *dev_priv);
-void i915_gem_context_free(struct kref *ctx_ref);
-struct i915_gem_context *
-i915_gem_context_create_gvt(struct drm_device *dev);
-
 static inline struct i915_gem_context *
 i915_gem_context_lookup(struct drm_i915_file_private *file_priv, u32 id)
 {
@@ -3551,22 +3470,6 @@ i915_gem_context_lookup_timeline(struct i915_gem_context *ctx,
        return &vm->timeline.engine[engine->id];
 }
 
-static inline bool i915_gem_context_is_default(const struct i915_gem_context *c)
-{
-       return c->user_handle == DEFAULT_CONTEXT_HANDLE;
-}
-
-int i915_gem_context_create_ioctl(struct drm_device *dev, void *data,
-                                 struct drm_file *file);
-int i915_gem_context_destroy_ioctl(struct drm_device *dev, void *data,
-                                  struct drm_file *file);
-int i915_gem_context_getparam_ioctl(struct drm_device *dev, void *data,
-                                   struct drm_file *file_priv);
-int i915_gem_context_setparam_ioctl(struct drm_device *dev, void *data,
-                                   struct drm_file *file_priv);
-int i915_gem_context_reset_stats_ioctl(struct drm_device *dev, void *data,
-                                      struct drm_file *file);
-
 int i915_perf_open_ioctl(struct drm_device *dev, void *data,
                         struct drm_file *file);
 
index 71713a6..d70ea31 100644 (file)
@@ -2657,34 +2657,24 @@ err_unlock:
        goto out_unlock;
 }
 
-static bool i915_context_is_banned(const struct i915_gem_context *ctx)
+static bool ban_context(const struct i915_gem_context *ctx)
 {
-       if (ctx->banned)
-               return true;
-
-       if (!ctx->bannable)
-               return false;
-
-       if (ctx->ban_score >= CONTEXT_SCORE_BAN_THRESHOLD) {
-               DRM_DEBUG("context hanging too often, banning!\n");
-               return true;
-       }
-
-       return false;
+       return (i915_gem_context_is_bannable(ctx) &&
+               ctx->ban_score >= CONTEXT_SCORE_BAN_THRESHOLD);
 }
 
 static void i915_gem_context_mark_guilty(struct i915_gem_context *ctx)
 {
-       ctx->ban_score += CONTEXT_SCORE_GUILTY;
-
-       ctx->banned = i915_context_is_banned(ctx);
        ctx->guilty_count++;
+       ctx->ban_score += CONTEXT_SCORE_GUILTY;
+       if (ban_context(ctx))
+               i915_gem_context_set_banned(ctx);
 
        DRM_DEBUG_DRIVER("context %s marked guilty (score %d) banned? %s\n",
                         ctx->name, ctx->ban_score,
-                        yesno(ctx->banned));
+                        yesno(i915_gem_context_is_banned(ctx)));
 
-       if (!ctx->banned || IS_ERR_OR_NULL(ctx->file_priv))
+       if (!i915_gem_context_is_banned(ctx) || IS_ERR_OR_NULL(ctx->file_priv))
                return;
 
        ctx->file_priv->context_bans++;
index 48e4ed5..07ac811 100644 (file)
@@ -141,7 +141,7 @@ void i915_gem_context_free(struct kref *ctx_ref)
 
        lockdep_assert_held(&ctx->i915->drm.struct_mutex);
        trace_i915_context_free(ctx);
-       GEM_BUG_ON(!ctx->closed);
+       GEM_BUG_ON(!i915_gem_context_is_closed(ctx));
 
        i915_ppgtt_put(ctx->ppgtt);
 
@@ -228,8 +228,7 @@ static void i915_ppgtt_close(struct i915_address_space *vm)
 
 static void context_close(struct i915_gem_context *ctx)
 {
-       GEM_BUG_ON(ctx->closed);
-       ctx->closed = true;
+       i915_gem_context_set_closed(ctx);
        if (ctx->ppgtt)
                i915_ppgtt_close(&ctx->ppgtt->base);
        ctx->file_priv = ERR_PTR(-EBADF);
@@ -329,7 +328,7 @@ __create_hw_context(struct drm_i915_private *dev_priv,
         * is no remap info, it will be a NOP. */
        ctx->remap_slice = ALL_L3_SLICES(dev_priv);
 
-       ctx->bannable = true;
+       i915_gem_context_set_bannable(ctx);
        ctx->ring_size = 4 * PAGE_SIZE;
        ctx->desc_template = GEN8_CTX_ADDRESSING_MODE(dev_priv) <<
                             GEN8_CTX_ADDRESSING_MODE_SHIFT;
@@ -418,8 +417,9 @@ i915_gem_context_create_gvt(struct drm_device *dev)
        if (IS_ERR(ctx))
                goto out;
 
-       ctx->closed = true; /* not user accessible */
-       ctx->execlists_force_single_submission = true;
+       i915_gem_context_set_closed(ctx); /* not user accessible */
+       i915_gem_context_clear_bannable(ctx);
+       i915_gem_context_set_force_single_submission(ctx);
        ctx->ring_size = 512 * PAGE_SIZE; /* Max ring buffer size */
 out:
        mutex_unlock(&dev->struct_mutex);
@@ -468,6 +468,7 @@ int i915_gem_context_init(struct drm_i915_private *dev_priv)
                return PTR_ERR(ctx);
        }
 
+       i915_gem_context_clear_bannable(ctx);
        ctx->priority = I915_PRIORITY_MIN; /* lowest priority; idle task */
        dev_priv->kernel_context = ctx;
 
@@ -1040,10 +1041,10 @@ int i915_gem_context_getparam_ioctl(struct drm_device *dev, void *data,
                        args->value = to_i915(dev)->ggtt.base.total;
                break;
        case I915_CONTEXT_PARAM_NO_ERROR_CAPTURE:
-               args->value = !!(ctx->flags & CONTEXT_NO_ERROR_CAPTURE);
+               args->value = i915_gem_context_no_error_capture(ctx);
                break;
        case I915_CONTEXT_PARAM_BANNABLE:
-               args->value = ctx->bannable;
+               args->value = i915_gem_context_is_bannable(ctx);
                break;
        default:
                ret = -EINVAL;
@@ -1085,22 +1086,22 @@ int i915_gem_context_setparam_ioctl(struct drm_device *dev, void *data,
                }
                break;
        case I915_CONTEXT_PARAM_NO_ERROR_CAPTURE:
-               if (args->size) {
+               if (args->size)
                        ret = -EINVAL;
-               } else {
-                       if (args->value)
-                               ctx->flags |= CONTEXT_NO_ERROR_CAPTURE;
-                       else
-                               ctx->flags &= ~CONTEXT_NO_ERROR_CAPTURE;
-               }
+               else if (args->value)
+                       i915_gem_context_set_no_error_capture(ctx);
+               else
+                       i915_gem_context_clear_no_error_capture(ctx);
                break;
        case I915_CONTEXT_PARAM_BANNABLE:
                if (args->size)
                        ret = -EINVAL;
                else if (!capable(CAP_SYS_ADMIN) && !args->value)
                        ret = -EPERM;
+               else if (args->value)
+                       i915_gem_context_set_bannable(ctx);
                else
-                       ctx->bannable = args->value;
+                       i915_gem_context_clear_bannable(ctx);
                break;
        default:
                ret = -EINVAL;
diff --git a/drivers/gpu/drm/i915/i915_gem_context.h b/drivers/gpu/drm/i915/i915_gem_context.h
new file mode 100644 (file)
index 0000000..89f6764
--- /dev/null
@@ -0,0 +1,272 @@
+/*
+ * Copyright © 2016 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ *
+ */
+
+#ifndef __I915_GEM_CONTEXT_H__
+#define __I915_GEM_CONTEXT_H__
+
+#include <linux/bitops.h>
+#include <linux/list.h>
+
+struct pid;
+
+struct drm_device;
+struct drm_file;
+
+struct drm_i915_private;
+struct drm_i915_file_private;
+struct i915_hw_ppgtt;
+struct i915_vma;
+struct intel_ring;
+
+#define DEFAULT_CONTEXT_HANDLE 0
+
+/**
+ * struct i915_gem_context - client state
+ *
+ * The struct i915_gem_context represents the combined view of the driver and
+ * logical hardware state for a particular client.
+ */
+struct i915_gem_context {
+       /** i915: i915 device backpointer */
+       struct drm_i915_private *i915;
+
+       /** file_priv: owning file descriptor */
+       struct drm_i915_file_private *file_priv;
+
+       /**
+        * @ppgtt: unique address space (GTT)
+        *
+        * In full-ppgtt mode, each context has its own address space ensuring
+        * complete seperation of one client from all others.
+        *
+        * In other modes, this is a NULL pointer with the expectation that
+        * the caller uses the shared global GTT.
+        */
+       struct i915_hw_ppgtt *ppgtt;
+
+       /**
+        * @pid: process id of creator
+        *
+        * Note that who created the context may not be the principle user,
+        * as the context may be shared across a local socket. However,
+        * that should only affect the default context, all contexts created
+        * explicitly by the client are expected to be isolated.
+        */
+       struct pid *pid;
+
+       /**
+        * @name: arbitrary name
+        *
+        * A name is constructed for the context from the creator's process
+        * name, pid and user handle in order to uniquely identify the
+        * context in messages.
+        */
+       const char *name;
+
+       /** link: place with &drm_i915_private.context_list */
+       struct list_head link;
+
+       /**
+        * @ref: reference count
+        *
+        * A reference to a context is held by both the client who created it
+        * and on each request submitted to the hardware using the request
+        * (to ensure the hardware has access to the state until it has
+        * finished all pending writes). See i915_gem_context_get() and
+        * i915_gem_context_put() for access.
+        */
+       struct kref ref;
+
+       /**
+        * @flags: small set of booleans
+        */
+       unsigned long flags;
+#define CONTEXT_NO_ZEROMAP             BIT(0)
+#define CONTEXT_NO_ERROR_CAPTURE       1
+#define CONTEXT_CLOSED                 2
+#define CONTEXT_BANNABLE               3
+#define CONTEXT_BANNED                 4
+#define CONTEXT_FORCE_SINGLE_SUBMISSION        5
+
+       /**
+        * @hw_id: - unique identifier for the context
+        *
+        * The hardware needs to uniquely identify the context for a few
+        * functions like fault reporting, PASID, scheduling. The
+        * &drm_i915_private.context_hw_ida is used to assign a unqiue
+        * id for the lifetime of the context.
+        */
+       unsigned int hw_id;
+
+       /**
+        * @user_handle: userspace identifier
+        *
+        * A unique per-file identifier is generated from
+        * &drm_i915_file_private.contexts.
+        */
+       u32 user_handle;
+
+       /**
+        * @priority: execution and service priority
+        *
+        * All clients are equal, but some are more equal than others!
+        *
+        * Requests from a context with a greater (more positive) value of
+        * @priority will be executed before those with a lower @priority
+        * value, forming a simple QoS.
+        *
+        * The &drm_i915_private.kernel_context is assigned the lowest priority.
+        */
+       int priority;
+
+       /** ggtt_alignment: alignment restriction for context objects */
+       u32 ggtt_alignment;
+       /** ggtt_offset_bias: placement restriction for context objects */
+       u32 ggtt_offset_bias;
+
+       /** engine: per-engine logical HW state */
+       struct intel_context {
+               struct i915_vma *state;
+               struct intel_ring *ring;
+               u32 *lrc_reg_state;
+               u64 lrc_desc;
+               int pin_count;
+               bool initialised;
+       } engine[I915_NUM_ENGINES];
+
+       /** ring_size: size for allocating the per-engine ring buffer */
+       u32 ring_size;
+       /** desc_template: invariant fields for the HW context descriptor */
+       u32 desc_template;
+
+       /** status_notifier: list of callbacks for context-switch changes */
+       struct atomic_notifier_head status_notifier;
+
+       /** guilty_count: How many times this context has caused a GPU hang. */
+       unsigned int guilty_count;
+       /**
+        * @active_count: How many times this context was active during a GPU
+        * hang, but did not cause it.
+        */
+       unsigned int active_count;
+
+#define CONTEXT_SCORE_GUILTY           10
+#define CONTEXT_SCORE_BAN_THRESHOLD    40
+       /** ban_score: Accumulated score of all hangs caused by this context. */
+       int ban_score;
+
+       /** remap_slice: Bitmask of cache lines that need remapping */
+       u8 remap_slice;
+};
+
+static inline bool i915_gem_context_is_closed(const struct i915_gem_context *ctx)
+{
+       return test_bit(CONTEXT_CLOSED, &ctx->flags);
+}
+
+static inline void i915_gem_context_set_closed(struct i915_gem_context *ctx)
+{
+       GEM_BUG_ON(i915_gem_context_is_closed(ctx));
+       __set_bit(CONTEXT_CLOSED, &ctx->flags);
+}
+
+static inline bool i915_gem_context_no_error_capture(const struct i915_gem_context *ctx)
+{
+       return test_bit(CONTEXT_NO_ERROR_CAPTURE, &ctx->flags);
+}
+
+static inline void i915_gem_context_set_no_error_capture(struct i915_gem_context *ctx)
+{
+       __set_bit(CONTEXT_NO_ERROR_CAPTURE, &ctx->flags);
+}
+
+static inline void i915_gem_context_clear_no_error_capture(struct i915_gem_context *ctx)
+{
+       __clear_bit(CONTEXT_NO_ERROR_CAPTURE, &ctx->flags);
+}
+
+static inline bool i915_gem_context_is_bannable(const struct i915_gem_context *ctx)
+{
+       return test_bit(CONTEXT_BANNABLE, &ctx->flags);
+}
+
+static inline void i915_gem_context_set_bannable(struct i915_gem_context *ctx)
+{
+       __set_bit(CONTEXT_BANNABLE, &ctx->flags);
+}
+
+static inline void i915_gem_context_clear_bannable(struct i915_gem_context *ctx)
+{
+       __clear_bit(CONTEXT_BANNABLE, &ctx->flags);
+}
+
+static inline bool i915_gem_context_is_banned(const struct i915_gem_context *ctx)
+{
+       return test_bit(CONTEXT_BANNED, &ctx->flags);
+}
+
+static inline void i915_gem_context_set_banned(struct i915_gem_context *ctx)
+{
+       __set_bit(CONTEXT_BANNED, &ctx->flags);
+}
+
+static inline bool i915_gem_context_force_single_submission(const struct i915_gem_context *ctx)
+{
+       return test_bit(CONTEXT_FORCE_SINGLE_SUBMISSION, &ctx->flags);
+}
+
+static inline void i915_gem_context_set_force_single_submission(struct i915_gem_context *ctx)
+{
+       __set_bit(CONTEXT_FORCE_SINGLE_SUBMISSION, &ctx->flags);
+}
+
+static inline bool i915_gem_context_is_default(const struct i915_gem_context *c)
+{
+       return c->user_handle == DEFAULT_CONTEXT_HANDLE;
+}
+
+/* i915_gem_context.c */
+int __must_check i915_gem_context_init(struct drm_i915_private *dev_priv);
+void i915_gem_context_lost(struct drm_i915_private *dev_priv);
+void i915_gem_context_fini(struct drm_i915_private *dev_priv);
+int i915_gem_context_open(struct drm_device *dev, struct drm_file *file);
+void i915_gem_context_close(struct drm_device *dev, struct drm_file *file);
+int i915_switch_context(struct drm_i915_gem_request *req);
+int i915_gem_switch_to_kernel_context(struct drm_i915_private *dev_priv);
+void i915_gem_context_free(struct kref *ctx_ref);
+struct i915_gem_context *
+i915_gem_context_create_gvt(struct drm_device *dev);
+
+int i915_gem_context_create_ioctl(struct drm_device *dev, void *data,
+                                 struct drm_file *file);
+int i915_gem_context_destroy_ioctl(struct drm_device *dev, void *data,
+                                  struct drm_file *file);
+int i915_gem_context_getparam_ioctl(struct drm_device *dev, void *data,
+                                   struct drm_file *file_priv);
+int i915_gem_context_setparam_ioctl(struct drm_device *dev, void *data,
+                                   struct drm_file *file_priv);
+int i915_gem_context_reset_stats_ioctl(struct drm_device *dev, void *data,
+                                      struct drm_file *file);
+
+#endif /* !__I915_GEM_CONTEXT_H__ */
index c64438f..a5fe299 100644 (file)
@@ -1238,7 +1238,7 @@ i915_gem_validate_context(struct drm_device *dev, struct drm_file *file,
        if (IS_ERR(ctx))
                return ctx;
 
-       if (ctx->banned) {
+       if (i915_gem_context_is_banned(ctx)) {
                DRM_DEBUG("Context %u tried to submit while banned\n", ctx_id);
                return ERR_PTR(-EIO);
        }
index e16037d..e34532d 100644 (file)
@@ -1331,7 +1331,7 @@ static void i915_gem_record_rings(struct drm_i915_private *dev_priv,
                        }
 
                        error->simulated |=
-                               request->ctx->flags & CONTEXT_NO_ERROR_CAPTURE;
+                               i915_gem_context_no_error_capture(request->ctx);
 
                        ee->rq_head = request->head;
                        ee->rq_post = request->postfix;
index fc64be1..2279788 100644 (file)
@@ -413,7 +413,7 @@ static void execlists_submit_ports(struct intel_engine_cs *engine)
 static bool ctx_single_port_submission(const struct i915_gem_context *ctx)
 {
        return (IS_ENABLED(CONFIG_DRM_I915_GVT) &&
-               ctx->execlists_force_single_submission);
+               i915_gem_context_force_single_submission(ctx));
 }
 
 static bool can_merge_ctx(const struct i915_gem_context *prev,