drm/i915: Complete kerneldoc for struct i915_gem_context
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
This commit is contained in:
@@ -60,6 +60,7 @@
|
|||||||
#include "intel_ringbuffer.h"
|
#include "intel_ringbuffer.h"
|
||||||
|
|
||||||
#include "i915_gem.h"
|
#include "i915_gem.h"
|
||||||
|
#include "i915_gem_context.h"
|
||||||
#include "i915_gem_fence_reg.h"
|
#include "i915_gem_fence_reg.h"
|
||||||
#include "i915_gem_object.h"
|
#include "i915_gem_object.h"
|
||||||
#include "i915_gem_gtt.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 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 {
|
enum fb_op_origin {
|
||||||
ORIGIN_GTT,
|
ORIGIN_GTT,
|
||||||
ORIGIN_CPU,
|
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,
|
void i915_gem_object_save_bit_17_swizzle(struct drm_i915_gem_object *obj,
|
||||||
struct sg_table *pages);
|
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 *
|
static inline struct i915_gem_context *
|
||||||
i915_gem_context_lookup(struct drm_i915_file_private *file_priv, u32 id)
|
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];
|
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,
|
int i915_perf_open_ioctl(struct drm_device *dev, void *data,
|
||||||
struct drm_file *file);
|
struct drm_file *file);
|
||||||
|
|
||||||
|
@@ -2657,34 +2657,24 @@ err_unlock:
|
|||||||
goto out_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 (i915_gem_context_is_bannable(ctx) &&
|
||||||
return true;
|
ctx->ban_score >= CONTEXT_SCORE_BAN_THRESHOLD);
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void i915_gem_context_mark_guilty(struct i915_gem_context *ctx)
|
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->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",
|
DRM_DEBUG_DRIVER("context %s marked guilty (score %d) banned? %s\n",
|
||||||
ctx->name, ctx->ban_score,
|
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;
|
return;
|
||||||
|
|
||||||
ctx->file_priv->context_bans++;
|
ctx->file_priv->context_bans++;
|
||||||
|
@@ -141,7 +141,7 @@ void i915_gem_context_free(struct kref *ctx_ref)
|
|||||||
|
|
||||||
lockdep_assert_held(&ctx->i915->drm.struct_mutex);
|
lockdep_assert_held(&ctx->i915->drm.struct_mutex);
|
||||||
trace_i915_context_free(ctx);
|
trace_i915_context_free(ctx);
|
||||||
GEM_BUG_ON(!ctx->closed);
|
GEM_BUG_ON(!i915_gem_context_is_closed(ctx));
|
||||||
|
|
||||||
i915_ppgtt_put(ctx->ppgtt);
|
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)
|
static void context_close(struct i915_gem_context *ctx)
|
||||||
{
|
{
|
||||||
GEM_BUG_ON(ctx->closed);
|
i915_gem_context_set_closed(ctx);
|
||||||
ctx->closed = true;
|
|
||||||
if (ctx->ppgtt)
|
if (ctx->ppgtt)
|
||||||
i915_ppgtt_close(&ctx->ppgtt->base);
|
i915_ppgtt_close(&ctx->ppgtt->base);
|
||||||
ctx->file_priv = ERR_PTR(-EBADF);
|
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. */
|
* is no remap info, it will be a NOP. */
|
||||||
ctx->remap_slice = ALL_L3_SLICES(dev_priv);
|
ctx->remap_slice = ALL_L3_SLICES(dev_priv);
|
||||||
|
|
||||||
ctx->bannable = true;
|
i915_gem_context_set_bannable(ctx);
|
||||||
ctx->ring_size = 4 * PAGE_SIZE;
|
ctx->ring_size = 4 * PAGE_SIZE;
|
||||||
ctx->desc_template = GEN8_CTX_ADDRESSING_MODE(dev_priv) <<
|
ctx->desc_template = GEN8_CTX_ADDRESSING_MODE(dev_priv) <<
|
||||||
GEN8_CTX_ADDRESSING_MODE_SHIFT;
|
GEN8_CTX_ADDRESSING_MODE_SHIFT;
|
||||||
@@ -418,8 +417,9 @@ i915_gem_context_create_gvt(struct drm_device *dev)
|
|||||||
if (IS_ERR(ctx))
|
if (IS_ERR(ctx))
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
ctx->closed = true; /* not user accessible */
|
i915_gem_context_set_closed(ctx); /* not user accessible */
|
||||||
ctx->execlists_force_single_submission = true;
|
i915_gem_context_clear_bannable(ctx);
|
||||||
|
i915_gem_context_set_force_single_submission(ctx);
|
||||||
ctx->ring_size = 512 * PAGE_SIZE; /* Max ring buffer size */
|
ctx->ring_size = 512 * PAGE_SIZE; /* Max ring buffer size */
|
||||||
out:
|
out:
|
||||||
mutex_unlock(&dev->struct_mutex);
|
mutex_unlock(&dev->struct_mutex);
|
||||||
@@ -468,6 +468,7 @@ int i915_gem_context_init(struct drm_i915_private *dev_priv)
|
|||||||
return PTR_ERR(ctx);
|
return PTR_ERR(ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
i915_gem_context_clear_bannable(ctx);
|
||||||
ctx->priority = I915_PRIORITY_MIN; /* lowest priority; idle task */
|
ctx->priority = I915_PRIORITY_MIN; /* lowest priority; idle task */
|
||||||
dev_priv->kernel_context = ctx;
|
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;
|
args->value = to_i915(dev)->ggtt.base.total;
|
||||||
break;
|
break;
|
||||||
case I915_CONTEXT_PARAM_NO_ERROR_CAPTURE:
|
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;
|
break;
|
||||||
case I915_CONTEXT_PARAM_BANNABLE:
|
case I915_CONTEXT_PARAM_BANNABLE:
|
||||||
args->value = ctx->bannable;
|
args->value = i915_gem_context_is_bannable(ctx);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
ret = -EINVAL;
|
ret = -EINVAL;
|
||||||
@@ -1085,22 +1086,22 @@ int i915_gem_context_setparam_ioctl(struct drm_device *dev, void *data,
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case I915_CONTEXT_PARAM_NO_ERROR_CAPTURE:
|
case I915_CONTEXT_PARAM_NO_ERROR_CAPTURE:
|
||||||
if (args->size) {
|
if (args->size)
|
||||||
ret = -EINVAL;
|
ret = -EINVAL;
|
||||||
} else {
|
else if (args->value)
|
||||||
if (args->value)
|
i915_gem_context_set_no_error_capture(ctx);
|
||||||
ctx->flags |= CONTEXT_NO_ERROR_CAPTURE;
|
else
|
||||||
else
|
i915_gem_context_clear_no_error_capture(ctx);
|
||||||
ctx->flags &= ~CONTEXT_NO_ERROR_CAPTURE;
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
case I915_CONTEXT_PARAM_BANNABLE:
|
case I915_CONTEXT_PARAM_BANNABLE:
|
||||||
if (args->size)
|
if (args->size)
|
||||||
ret = -EINVAL;
|
ret = -EINVAL;
|
||||||
else if (!capable(CAP_SYS_ADMIN) && !args->value)
|
else if (!capable(CAP_SYS_ADMIN) && !args->value)
|
||||||
ret = -EPERM;
|
ret = -EPERM;
|
||||||
|
else if (args->value)
|
||||||
|
i915_gem_context_set_bannable(ctx);
|
||||||
else
|
else
|
||||||
ctx->bannable = args->value;
|
i915_gem_context_clear_bannable(ctx);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
ret = -EINVAL;
|
ret = -EINVAL;
|
||||||
|
272
drivers/gpu/drm/i915/i915_gem_context.h
Normal file
272
drivers/gpu/drm/i915/i915_gem_context.h
Normal file
@@ -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__ */
|
@@ -1238,7 +1238,7 @@ i915_gem_validate_context(struct drm_device *dev, struct drm_file *file,
|
|||||||
if (IS_ERR(ctx))
|
if (IS_ERR(ctx))
|
||||||
return 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);
|
DRM_DEBUG("Context %u tried to submit while banned\n", ctx_id);
|
||||||
return ERR_PTR(-EIO);
|
return ERR_PTR(-EIO);
|
||||||
}
|
}
|
||||||
|
@@ -1331,7 +1331,7 @@ static void i915_gem_record_rings(struct drm_i915_private *dev_priv,
|
|||||||
}
|
}
|
||||||
|
|
||||||
error->simulated |=
|
error->simulated |=
|
||||||
request->ctx->flags & CONTEXT_NO_ERROR_CAPTURE;
|
i915_gem_context_no_error_capture(request->ctx);
|
||||||
|
|
||||||
ee->rq_head = request->head;
|
ee->rq_head = request->head;
|
||||||
ee->rq_post = request->postfix;
|
ee->rq_post = request->postfix;
|
||||||
|
@@ -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)
|
static bool ctx_single_port_submission(const struct i915_gem_context *ctx)
|
||||||
{
|
{
|
||||||
return (IS_ENABLED(CONFIG_DRM_I915_GVT) &&
|
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,
|
static bool can_merge_ctx(const struct i915_gem_context *prev,
|
||||||
|
Reference in New Issue
Block a user