Commit 8d286e2f authored by Dave Airlie's avatar Dave Airlie

Merge tag 'drm-intel-next-fixes-2020-06-04' of...

Merge tag 'drm-intel-next-fixes-2020-06-04' of git://anongit.freedesktop.org/drm/drm-intel into drm-next

- Includes gvt-next-fixes-2020-05-28
- Use after free fix for display global state.
- Whitelisting context-local timestamp on Gen9
  and two scheduler fixes with deps (Cc: stable)
- Removal of write flag from sysfs files where
  ineffective
Signed-off-by: default avatarDave Airlie <airlied@redhat.com>
From: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20200604150454.GA59322@jlahtine-desk.ger.corp.intel.com
parents fa3fa222 f8665d79
...@@ -10,6 +10,28 @@ ...@@ -10,6 +10,28 @@
#include "intel_display_types.h" #include "intel_display_types.h"
#include "intel_global_state.h" #include "intel_global_state.h"
static void __intel_atomic_global_state_free(struct kref *kref)
{
struct intel_global_state *obj_state =
container_of(kref, struct intel_global_state, ref);
struct intel_global_obj *obj = obj_state->obj;
obj->funcs->atomic_destroy_state(obj, obj_state);
}
static void intel_atomic_global_state_put(struct intel_global_state *obj_state)
{
kref_put(&obj_state->ref, __intel_atomic_global_state_free);
}
static struct intel_global_state *
intel_atomic_global_state_get(struct intel_global_state *obj_state)
{
kref_get(&obj_state->ref);
return obj_state;
}
void intel_atomic_global_obj_init(struct drm_i915_private *dev_priv, void intel_atomic_global_obj_init(struct drm_i915_private *dev_priv,
struct intel_global_obj *obj, struct intel_global_obj *obj,
struct intel_global_state *state, struct intel_global_state *state,
...@@ -17,6 +39,10 @@ void intel_atomic_global_obj_init(struct drm_i915_private *dev_priv, ...@@ -17,6 +39,10 @@ void intel_atomic_global_obj_init(struct drm_i915_private *dev_priv,
{ {
memset(obj, 0, sizeof(*obj)); memset(obj, 0, sizeof(*obj));
state->obj = obj;
kref_init(&state->ref);
obj->state = state; obj->state = state;
obj->funcs = funcs; obj->funcs = funcs;
list_add_tail(&obj->head, &dev_priv->global_obj_list); list_add_tail(&obj->head, &dev_priv->global_obj_list);
...@@ -28,7 +54,9 @@ void intel_atomic_global_obj_cleanup(struct drm_i915_private *dev_priv) ...@@ -28,7 +54,9 @@ void intel_atomic_global_obj_cleanup(struct drm_i915_private *dev_priv)
list_for_each_entry_safe(obj, next, &dev_priv->global_obj_list, head) { list_for_each_entry_safe(obj, next, &dev_priv->global_obj_list, head) {
list_del(&obj->head); list_del(&obj->head);
obj->funcs->atomic_destroy_state(obj, obj->state);
drm_WARN_ON(&dev_priv->drm, kref_read(&obj->state->ref) != 1);
intel_atomic_global_state_put(obj->state);
} }
} }
...@@ -97,10 +125,14 @@ intel_atomic_get_global_obj_state(struct intel_atomic_state *state, ...@@ -97,10 +125,14 @@ intel_atomic_get_global_obj_state(struct intel_atomic_state *state,
if (!obj_state) if (!obj_state)
return ERR_PTR(-ENOMEM); return ERR_PTR(-ENOMEM);
obj_state->obj = obj;
obj_state->changed = false; obj_state->changed = false;
kref_init(&obj_state->ref);
state->global_objs[index].state = obj_state; state->global_objs[index].state = obj_state;
state->global_objs[index].old_state = obj->state; state->global_objs[index].old_state =
intel_atomic_global_state_get(obj->state);
state->global_objs[index].new_state = obj_state; state->global_objs[index].new_state = obj_state;
state->global_objs[index].ptr = obj; state->global_objs[index].ptr = obj;
obj_state->state = state; obj_state->state = state;
...@@ -163,7 +195,9 @@ void intel_atomic_swap_global_state(struct intel_atomic_state *state) ...@@ -163,7 +195,9 @@ void intel_atomic_swap_global_state(struct intel_atomic_state *state)
new_obj_state->state = NULL; new_obj_state->state = NULL;
state->global_objs[i].state = old_obj_state; state->global_objs[i].state = old_obj_state;
obj->state = new_obj_state;
intel_atomic_global_state_put(obj->state);
obj->state = intel_atomic_global_state_get(new_obj_state);
} }
} }
...@@ -172,10 +206,9 @@ void intel_atomic_clear_global_state(struct intel_atomic_state *state) ...@@ -172,10 +206,9 @@ void intel_atomic_clear_global_state(struct intel_atomic_state *state)
int i; int i;
for (i = 0; i < state->num_global_objs; i++) { for (i = 0; i < state->num_global_objs; i++) {
struct intel_global_obj *obj = state->global_objs[i].ptr; intel_atomic_global_state_put(state->global_objs[i].old_state);
intel_atomic_global_state_put(state->global_objs[i].new_state);
obj->funcs->atomic_destroy_state(obj,
state->global_objs[i].state);
state->global_objs[i].ptr = NULL; state->global_objs[i].ptr = NULL;
state->global_objs[i].state = NULL; state->global_objs[i].state = NULL;
state->global_objs[i].old_state = NULL; state->global_objs[i].old_state = NULL;
......
...@@ -6,6 +6,7 @@ ...@@ -6,6 +6,7 @@
#ifndef __INTEL_GLOBAL_STATE_H__ #ifndef __INTEL_GLOBAL_STATE_H__
#define __INTEL_GLOBAL_STATE_H__ #define __INTEL_GLOBAL_STATE_H__
#include <linux/kref.h>
#include <linux/list.h> #include <linux/list.h>
struct drm_i915_private; struct drm_i915_private;
...@@ -54,7 +55,9 @@ struct intel_global_obj { ...@@ -54,7 +55,9 @@ struct intel_global_obj {
for_each_if(obj) for_each_if(obj)
struct intel_global_state { struct intel_global_state {
struct intel_global_obj *obj;
struct intel_atomic_state *state; struct intel_atomic_state *state;
struct kref ref;
bool changed; bool changed;
}; };
......
...@@ -230,7 +230,7 @@ static void intel_context_set_gem(struct intel_context *ce, ...@@ -230,7 +230,7 @@ static void intel_context_set_gem(struct intel_context *ce,
ce->timeline = intel_timeline_get(ctx->timeline); ce->timeline = intel_timeline_get(ctx->timeline);
if (ctx->sched.priority >= I915_PRIORITY_NORMAL && if (ctx->sched.priority >= I915_PRIORITY_NORMAL &&
intel_engine_has_semaphores(ce->engine)) intel_engine_has_timeslices(ce->engine))
__set_bit(CONTEXT_USE_SEMAPHORES, &ce->flags); __set_bit(CONTEXT_USE_SEMAPHORES, &ce->flags);
} }
...@@ -1969,7 +1969,7 @@ static int __apply_priority(struct intel_context *ce, void *arg) ...@@ -1969,7 +1969,7 @@ static int __apply_priority(struct intel_context *ce, void *arg)
{ {
struct i915_gem_context *ctx = arg; struct i915_gem_context *ctx = arg;
if (!intel_engine_has_semaphores(ce->engine)) if (!intel_engine_has_timeslices(ce->engine))
return 0; return 0;
if (ctx->sched.priority >= I915_PRIORITY_NORMAL) if (ctx->sched.priority >= I915_PRIORITY_NORMAL)
......
...@@ -39,7 +39,6 @@ static int shmem_get_pages(struct drm_i915_gem_object *obj) ...@@ -39,7 +39,6 @@ static int shmem_get_pages(struct drm_i915_gem_object *obj)
unsigned long last_pfn = 0; /* suppress gcc warning */ unsigned long last_pfn = 0; /* suppress gcc warning */
unsigned int max_segment = i915_sg_segment_size(); unsigned int max_segment = i915_sg_segment_size();
unsigned int sg_page_sizes; unsigned int sg_page_sizes;
struct pagevec pvec;
gfp_t noreclaim; gfp_t noreclaim;
int ret; int ret;
...@@ -192,13 +191,17 @@ static int shmem_get_pages(struct drm_i915_gem_object *obj) ...@@ -192,13 +191,17 @@ static int shmem_get_pages(struct drm_i915_gem_object *obj)
sg_mark_end(sg); sg_mark_end(sg);
err_pages: err_pages:
mapping_clear_unevictable(mapping); mapping_clear_unevictable(mapping);
pagevec_init(&pvec); if (sg != st->sgl) {
for_each_sgt_page(page, sgt_iter, st) { struct pagevec pvec;
if (!pagevec_add(&pvec, page))
pagevec_init(&pvec);
for_each_sgt_page(page, sgt_iter, st) {
if (!pagevec_add(&pvec, page))
check_release_pagevec(&pvec);
}
if (pagevec_count(&pvec))
check_release_pagevec(&pvec); check_release_pagevec(&pvec);
} }
if (pagevec_count(&pvec))
check_release_pagevec(&pvec);
sg_free_table(st); sg_free_table(st);
kfree(st); kfree(st);
......
...@@ -97,8 +97,6 @@ int __intel_context_do_pin(struct intel_context *ce) ...@@ -97,8 +97,6 @@ int __intel_context_do_pin(struct intel_context *ce)
{ {
int err; int err;
GEM_BUG_ON(intel_context_is_closed(ce));
if (unlikely(!test_bit(CONTEXT_ALLOC_BIT, &ce->flags))) { if (unlikely(!test_bit(CONTEXT_ALLOC_BIT, &ce->flags))) {
err = intel_context_alloc_state(ce); err = intel_context_alloc_state(ce);
if (err) if (err)
......
...@@ -124,7 +124,7 @@ int intel_gvt_init_vgpu_types(struct intel_gvt *gvt) ...@@ -124,7 +124,7 @@ int intel_gvt_init_vgpu_types(struct intel_gvt *gvt)
*/ */
low_avail = gvt_aperture_sz(gvt) - HOST_LOW_GM_SIZE; low_avail = gvt_aperture_sz(gvt) - HOST_LOW_GM_SIZE;
high_avail = gvt_hidden_sz(gvt) - HOST_HIGH_GM_SIZE; high_avail = gvt_hidden_sz(gvt) - HOST_HIGH_GM_SIZE;
num_types = sizeof(vgpu_types) / sizeof(vgpu_types[0]); num_types = ARRAY_SIZE(vgpu_types);
gvt->types = kcalloc(num_types, sizeof(struct intel_vgpu_type), gvt->types = kcalloc(num_types, sizeof(struct intel_vgpu_type),
GFP_KERNEL); GFP_KERNEL);
......
...@@ -572,6 +572,9 @@ struct drm_i915_reg_descriptor { ...@@ -572,6 +572,9 @@ struct drm_i915_reg_descriptor {
#define REG32(_reg, ...) \ #define REG32(_reg, ...) \
{ .addr = (_reg), __VA_ARGS__ } { .addr = (_reg), __VA_ARGS__ }
#define REG32_IDX(_reg, idx) \
{ .addr = _reg(idx) }
/* /*
* Convenience macro for adding 64-bit registers. * Convenience macro for adding 64-bit registers.
* *
...@@ -669,6 +672,7 @@ static const struct drm_i915_reg_descriptor gen9_blt_regs[] = { ...@@ -669,6 +672,7 @@ static const struct drm_i915_reg_descriptor gen9_blt_regs[] = {
REG64_IDX(RING_TIMESTAMP, BSD_RING_BASE), REG64_IDX(RING_TIMESTAMP, BSD_RING_BASE),
REG32(BCS_SWCTRL), REG32(BCS_SWCTRL),
REG64_IDX(RING_TIMESTAMP, BLT_RING_BASE), REG64_IDX(RING_TIMESTAMP, BLT_RING_BASE),
REG32_IDX(RING_CTX_TIMESTAMP, BLT_RING_BASE),
REG64_IDX(BCS_GPR, 0), REG64_IDX(BCS_GPR, 0),
REG64_IDX(BCS_GPR, 1), REG64_IDX(BCS_GPR, 1),
REG64_IDX(BCS_GPR, 2), REG64_IDX(BCS_GPR, 2),
......
...@@ -173,7 +173,7 @@ i915_param_named(enable_gvt, bool, 0400, ...@@ -173,7 +173,7 @@ i915_param_named(enable_gvt, bool, 0400,
#endif #endif
#if IS_ENABLED(CONFIG_DRM_I915_UNSTABLE_FAKE_LMEM) #if IS_ENABLED(CONFIG_DRM_I915_UNSTABLE_FAKE_LMEM)
i915_param_named_unsafe(fake_lmem_start, ulong, 0600, i915_param_named_unsafe(fake_lmem_start, ulong, 0400,
"Fake LMEM start offset (default: 0)"); "Fake LMEM start offset (default: 0)");
#endif #endif
......
...@@ -64,7 +64,7 @@ struct drm_printer; ...@@ -64,7 +64,7 @@ struct drm_printer;
param(int, mmio_debug, -IS_ENABLED(CONFIG_DRM_I915_DEBUG_MMIO), 0600) \ param(int, mmio_debug, -IS_ENABLED(CONFIG_DRM_I915_DEBUG_MMIO), 0600) \
param(int, edp_vswing, 0, 0400) \ param(int, edp_vswing, 0, 0400) \
param(unsigned int, reset, 3, 0600) \ param(unsigned int, reset, 3, 0600) \
param(unsigned int, inject_probe_failure, 0, 0600) \ param(unsigned int, inject_probe_failure, 0, 0) \
param(int, fastboot, -1, 0600) \ param(int, fastboot, -1, 0600) \
param(int, enable_dpcd_backlight, -1, 0600) \ param(int, enable_dpcd_backlight, -1, 0600) \
param(char *, force_probe, CONFIG_DRM_I915_FORCE_PROBE, 0400) \ param(char *, force_probe, CONFIG_DRM_I915_FORCE_PROBE, 0400) \
......
This diff is collapsed.
...@@ -209,14 +209,6 @@ static void kick_submission(struct intel_engine_cs *engine, ...@@ -209,14 +209,6 @@ static void kick_submission(struct intel_engine_cs *engine,
if (!inflight) if (!inflight)
goto unlock; goto unlock;
ENGINE_TRACE(engine,
"bumping queue-priority-hint:%d for rq:%llx:%lld, inflight:%llx:%lld prio %d\n",
prio,
rq->fence.context, rq->fence.seqno,
inflight->fence.context, inflight->fence.seqno,
inflight->sched.attr.priority);
engine->execlists.queue_priority_hint = prio;
/* /*
* If we are already the currently executing context, don't * If we are already the currently executing context, don't
* bother evaluating if we should preempt ourselves. * bother evaluating if we should preempt ourselves.
...@@ -224,6 +216,14 @@ static void kick_submission(struct intel_engine_cs *engine, ...@@ -224,6 +216,14 @@ static void kick_submission(struct intel_engine_cs *engine,
if (inflight->context == rq->context) if (inflight->context == rq->context)
goto unlock; goto unlock;
ENGINE_TRACE(engine,
"bumping queue-priority-hint:%d for rq:%llx:%lld, inflight:%llx:%lld prio %d\n",
prio,
rq->fence.context, rq->fence.seqno,
inflight->fence.context, inflight->fence.seqno,
inflight->sched.attr.priority);
engine->execlists.queue_priority_hint = prio;
if (need_preempt(prio, rq_prio(inflight))) if (need_preempt(prio, rq_prio(inflight)))
tasklet_hi_schedule(&engine->execlists.tasklet); tasklet_hi_schedule(&engine->execlists.tasklet);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment