mirror of
https://github.com/AuxXxilium/linux_dsm_epyc7002.git
synced 2024-11-26 15:50:57 +07:00
drm/i915: Make i915_gem_context_mark_guilty() safe for unlocked updates
Since we make call i915_gem_context_mark_guilty() concurrently when resetting different engines in parallel, we need to make sure that our updates are safe for the unlocked access. Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk> Cc: Michel Thierry <michel.thierry@intel.com> Cc: Mika Kuoppala <mika.kuoppala@linux.intel.com> Reviewed-by: Mika Kuoppala <mika.kuoppala@linux.intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20170721123238.16428-12-chris@chris-wilson.co.uk Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
This commit is contained in:
parent
ed454f2cd6
commit
77b25a972b
@ -602,7 +602,7 @@ struct drm_i915_file_private {
|
||||
* to limit the badly behaving clients access to gpu.
|
||||
*/
|
||||
#define I915_MAX_CLIENT_CONTEXT_BANS 3
|
||||
int context_bans;
|
||||
atomic_t context_bans;
|
||||
};
|
||||
|
||||
/* Used by dp and fdi links */
|
||||
|
@ -2740,34 +2740,38 @@ i915_gem_object_pwrite_gtt(struct drm_i915_gem_object *obj,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static bool ban_context(const struct i915_gem_context *ctx)
|
||||
static bool ban_context(const struct i915_gem_context *ctx,
|
||||
unsigned int score)
|
||||
{
|
||||
return (i915_gem_context_is_bannable(ctx) &&
|
||||
ctx->ban_score >= CONTEXT_SCORE_BAN_THRESHOLD);
|
||||
score >= CONTEXT_SCORE_BAN_THRESHOLD);
|
||||
}
|
||||
|
||||
static void i915_gem_context_mark_guilty(struct i915_gem_context *ctx)
|
||||
{
|
||||
ctx->guilty_count++;
|
||||
ctx->ban_score += CONTEXT_SCORE_GUILTY;
|
||||
if (ban_context(ctx))
|
||||
i915_gem_context_set_banned(ctx);
|
||||
unsigned int score;
|
||||
bool banned;
|
||||
|
||||
atomic_inc(&ctx->guilty_count);
|
||||
|
||||
score = atomic_add_return(CONTEXT_SCORE_GUILTY, &ctx->ban_score);
|
||||
banned = ban_context(ctx, score);
|
||||
DRM_DEBUG_DRIVER("context %s marked guilty (score %d) banned? %s\n",
|
||||
ctx->name, ctx->ban_score,
|
||||
yesno(i915_gem_context_is_banned(ctx)));
|
||||
|
||||
if (!i915_gem_context_is_banned(ctx) || IS_ERR_OR_NULL(ctx->file_priv))
|
||||
ctx->name, score, yesno(banned));
|
||||
if (!banned)
|
||||
return;
|
||||
|
||||
ctx->file_priv->context_bans++;
|
||||
DRM_DEBUG_DRIVER("client %s has had %d context banned\n",
|
||||
ctx->name, ctx->file_priv->context_bans);
|
||||
i915_gem_context_set_banned(ctx);
|
||||
if (!IS_ERR_OR_NULL(ctx->file_priv)) {
|
||||
atomic_inc(&ctx->file_priv->context_bans);
|
||||
DRM_DEBUG_DRIVER("client %s has had %d context banned\n",
|
||||
ctx->name, atomic_read(&ctx->file_priv->context_bans));
|
||||
}
|
||||
}
|
||||
|
||||
static void i915_gem_context_mark_innocent(struct i915_gem_context *ctx)
|
||||
{
|
||||
ctx->active_count++;
|
||||
atomic_inc(&ctx->active_count);
|
||||
}
|
||||
|
||||
struct drm_i915_gem_request *
|
||||
|
@ -977,7 +977,7 @@ int i915_gem_switch_to_kernel_context(struct drm_i915_private *dev_priv)
|
||||
|
||||
static bool client_is_banned(struct drm_i915_file_private *file_priv)
|
||||
{
|
||||
return file_priv->context_bans > I915_MAX_CLIENT_CONTEXT_BANS;
|
||||
return atomic_read(&file_priv->context_bans) > I915_MAX_CLIENT_CONTEXT_BANS;
|
||||
}
|
||||
|
||||
int i915_gem_context_create_ioctl(struct drm_device *dev, void *data,
|
||||
@ -1179,8 +1179,8 @@ int i915_gem_context_reset_stats_ioctl(struct drm_device *dev,
|
||||
else
|
||||
args->reset_count = 0;
|
||||
|
||||
args->batch_active = READ_ONCE(ctx->guilty_count);
|
||||
args->batch_pending = READ_ONCE(ctx->active_count);
|
||||
args->batch_active = atomic_read(&ctx->guilty_count);
|
||||
args->batch_pending = atomic_read(&ctx->active_count);
|
||||
|
||||
ret = 0;
|
||||
out:
|
||||
|
@ -191,17 +191,17 @@ struct i915_gem_context {
|
||||
u32 desc_template;
|
||||
|
||||
/** guilty_count: How many times this context has caused a GPU hang. */
|
||||
unsigned int guilty_count;
|
||||
atomic_t guilty_count;
|
||||
/**
|
||||
* @active_count: How many times this context was active during a GPU
|
||||
* hang, but did not cause it.
|
||||
*/
|
||||
unsigned int active_count;
|
||||
atomic_t 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;
|
||||
atomic_t ban_score;
|
||||
|
||||
/** remap_slice: Bitmask of cache lines that need remapping */
|
||||
u8 remap_slice;
|
||||
|
@ -374,8 +374,7 @@ static void i915_gem_request_retire(struct drm_i915_gem_request *request)
|
||||
i915_gem_request_remove_from_client(request);
|
||||
|
||||
/* Retirement decays the ban score as it is a sign of ctx progress */
|
||||
if (request->ctx->ban_score > 0)
|
||||
request->ctx->ban_score--;
|
||||
atomic_dec_if_positive(&request->ctx->ban_score);
|
||||
|
||||
/* The backing object for the context is done after switching to the
|
||||
* *next* context. Therefore we cannot retire the previous context until
|
||||
|
@ -1266,7 +1266,7 @@ static void record_request(struct drm_i915_gem_request *request,
|
||||
struct drm_i915_error_request *erq)
|
||||
{
|
||||
erq->context = request->ctx->hw_id;
|
||||
erq->ban_score = request->ctx->ban_score;
|
||||
erq->ban_score = atomic_read(&request->ctx->ban_score);
|
||||
erq->seqno = request->global_seqno;
|
||||
erq->jiffies = request->emitted_jiffies;
|
||||
erq->head = request->head;
|
||||
@ -1357,9 +1357,9 @@ static void record_context(struct drm_i915_error_context *e,
|
||||
|
||||
e->handle = ctx->user_handle;
|
||||
e->hw_id = ctx->hw_id;
|
||||
e->ban_score = ctx->ban_score;
|
||||
e->guilty = ctx->guilty_count;
|
||||
e->active = ctx->active_count;
|
||||
e->ban_score = atomic_read(&ctx->ban_score);
|
||||
e->guilty = atomic_read(&ctx->guilty_count);
|
||||
e->active = atomic_read(&ctx->active_count);
|
||||
}
|
||||
|
||||
static void request_record_user_bo(struct drm_i915_gem_request *request,
|
||||
|
Loading…
Reference in New Issue
Block a user