Skip to content

Commit

Permalink
Merge tag 'drm-fixes-2022-07-22' of git://anongit.freedesktop.org/drm…
Browse files Browse the repository at this point in the history
…/drm

Pull drm fixes from Dave Airlie:
 "Fixes for this week.

  The main one is the i915 firmware fix for the phoronix reported issue.
  I've written some firmware guidelines as a result, should land in
  -next soon. Otherwise a few amdgpu fixes, a scheduler fix, ttm fix and
  two other minor ones.

  scheduler:
   - scheduling while atomic fix

  ttm:
   - locking fix

  edp:
   - variable typo fix

  i915:
   - add back support for v69 firmware on ADL-P

  amdgpu:
   - Drop redundant buffer cleanup that can lead to a segfault
   - Add a bo_list mutex to avoid possible list corruption in CS
   - dmub notification fix

  imx:
   - fix error path"

* tag 'drm-fixes-2022-07-22' of git://anongit.freedesktop.org/drm/drm:
  drm/amdgpu: Protect the amdgpu_bo_list list with a mutex v2
  drm/imx/dcss: Add missing of_node_put() in fail path
  drm/i915/guc: support v69 in parallel to v70
  drm/i915/guc: Support programming the EU priority in the GuC descriptor
  drm/panel-edp: Fix variable typo when saving hpd absent delay from DT
  drm/amdgpu: Remove one duplicated ef removal
  drm/ttm: fix locking in vmap/vunmap TTM GEM helpers
  drm/scheduler: Don't kill jobs in interrupt context
  drm/amd/display: Fix new dmub notification enabling in DM
  • Loading branch information
torvalds committed Jul 22, 2022
2 parents 4ba1329 + 7f5ec14 commit 8e65afb
Show file tree
Hide file tree
Showing 19 changed files with 505 additions and 98 deletions.
6 changes: 0 additions & 6 deletions drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c
Original file line number Diff line number Diff line change
Expand Up @@ -1364,16 +1364,10 @@ void amdgpu_amdkfd_gpuvm_destroy_cb(struct amdgpu_device *adev,
struct amdgpu_vm *vm)
{
struct amdkfd_process_info *process_info = vm->process_info;
struct amdgpu_bo *pd = vm->root.bo;

if (!process_info)
return;

/* Release eviction fence from PD */
amdgpu_bo_reserve(pd, false);
amdgpu_bo_fence(pd, NULL, false);
amdgpu_bo_unreserve(pd);

/* Update process info */
mutex_lock(&process_info->lock);
process_info->n_vms--;
Expand Down
3 changes: 2 additions & 1 deletion drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.c
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ static void amdgpu_bo_list_free_rcu(struct rcu_head *rcu)
{
struct amdgpu_bo_list *list = container_of(rcu, struct amdgpu_bo_list,
rhead);

mutex_destroy(&list->bo_list_mutex);
kvfree(list);
}

Expand Down Expand Up @@ -136,6 +136,7 @@ int amdgpu_bo_list_create(struct amdgpu_device *adev, struct drm_file *filp,

trace_amdgpu_cs_bo_status(list->num_entries, total_size);

mutex_init(&list->bo_list_mutex);
*result = list;
return 0;

Expand Down
4 changes: 4 additions & 0 deletions drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.h
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,10 @@ struct amdgpu_bo_list {
struct amdgpu_bo *oa_obj;
unsigned first_userptr;
unsigned num_entries;

/* Protect access during command submission.
*/
struct mutex bo_list_mutex;
};

int amdgpu_bo_list_get(struct amdgpu_fpriv *fpriv, int id,
Expand Down
16 changes: 13 additions & 3 deletions drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
Original file line number Diff line number Diff line change
Expand Up @@ -519,6 +519,8 @@ static int amdgpu_cs_parser_bos(struct amdgpu_cs_parser *p,
return r;
}

mutex_lock(&p->bo_list->bo_list_mutex);

/* One for TTM and one for the CS job */
amdgpu_bo_list_for_each_entry(e, p->bo_list)
e->tv.num_shared = 2;
Expand Down Expand Up @@ -651,6 +653,7 @@ static int amdgpu_cs_parser_bos(struct amdgpu_cs_parser *p,
kvfree(e->user_pages);
e->user_pages = NULL;
}
mutex_unlock(&p->bo_list->bo_list_mutex);
}
return r;
}
Expand Down Expand Up @@ -690,9 +693,11 @@ static void amdgpu_cs_parser_fini(struct amdgpu_cs_parser *parser, int error,
{
unsigned i;

if (error && backoff)
if (error && backoff) {
ttm_eu_backoff_reservation(&parser->ticket,
&parser->validated);
mutex_unlock(&parser->bo_list->bo_list_mutex);
}

for (i = 0; i < parser->num_post_deps; i++) {
drm_syncobj_put(parser->post_deps[i].syncobj);
Expand Down Expand Up @@ -832,12 +837,16 @@ static int amdgpu_cs_vm_handling(struct amdgpu_cs_parser *p)
continue;

r = amdgpu_vm_bo_update(adev, bo_va, false);
if (r)
if (r) {
mutex_unlock(&p->bo_list->bo_list_mutex);
return r;
}

r = amdgpu_sync_fence(&p->job->sync, bo_va->last_pt_update);
if (r)
if (r) {
mutex_unlock(&p->bo_list->bo_list_mutex);
return r;
}
}

r = amdgpu_vm_handle_moved(adev, vm);
Expand Down Expand Up @@ -1278,6 +1287,7 @@ static int amdgpu_cs_submit(struct amdgpu_cs_parser *p,

ttm_eu_fence_buffer_objects(&p->ticket, &p->validated, p->fence);
mutex_unlock(&p->adev->notifier_lock);
mutex_unlock(&p->bo_list->bo_list_mutex);

return 0;

Expand Down
27 changes: 19 additions & 8 deletions drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
Original file line number Diff line number Diff line change
Expand Up @@ -1653,7 +1653,7 @@ static int amdgpu_dm_init(struct amdgpu_device *adev)
#if defined(CONFIG_DRM_AMD_SECURE_DISPLAY)
adev->dm.crc_rd_wrk = amdgpu_dm_crtc_secure_display_create_work();
#endif
if (dc_enable_dmub_notifications(adev->dm.dc)) {
if (dc_is_dmub_outbox_supported(adev->dm.dc)) {
init_completion(&adev->dm.dmub_aux_transfer_done);
adev->dm.dmub_notify = kzalloc(sizeof(struct dmub_notification), GFP_KERNEL);
if (!adev->dm.dmub_notify) {
Expand Down Expand Up @@ -1689,6 +1689,13 @@ static int amdgpu_dm_init(struct amdgpu_device *adev)
goto error;
}

/* Enable outbox notification only after IRQ handlers are registered and DMUB is alive.
* It is expected that DMUB will resend any pending notifications at this point, for
* example HPD from DPIA.
*/
if (dc_is_dmub_outbox_supported(adev->dm.dc))
dc_enable_dmub_outbox(adev->dm.dc);

/* create fake encoders for MST */
dm_dp_create_fake_mst_encoders(adev);

Expand Down Expand Up @@ -2678,9 +2685,6 @@ static int dm_resume(void *handle)
*/
link_enc_cfg_copy(adev->dm.dc->current_state, dc_state);

if (dc_enable_dmub_notifications(adev->dm.dc))
amdgpu_dm_outbox_init(adev);

r = dm_dmub_hw_init(adev);
if (r)
DRM_ERROR("DMUB interface failed to initialize: status=%d\n", r);
Expand All @@ -2698,6 +2702,11 @@ static int dm_resume(void *handle)
}
}

if (dc_is_dmub_outbox_supported(adev->dm.dc)) {
amdgpu_dm_outbox_init(adev);
dc_enable_dmub_outbox(adev->dm.dc);
}

WARN_ON(!dc_commit_state(dm->dc, dc_state));

dm_gpureset_commit_state(dm->cached_dc_state, dm);
Expand All @@ -2719,13 +2728,15 @@ static int dm_resume(void *handle)
/* TODO: Remove dc_state->dccg, use dc->dccg directly. */
dc_resource_state_construct(dm->dc, dm_state->context);

/* Re-enable outbox interrupts for DPIA. */
if (dc_enable_dmub_notifications(adev->dm.dc))
amdgpu_dm_outbox_init(adev);

/* Before powering on DC we need to re-initialize DMUB. */
dm_dmub_hw_resume(adev);

/* Re-enable outbox interrupts for DPIA. */
if (dc_is_dmub_outbox_supported(adev->dm.dc)) {
amdgpu_dm_outbox_init(adev);
dc_enable_dmub_outbox(adev->dm.dc);
}

/* power on hardware */
dc_set_power_state(dm->dc, DC_ACPI_CM_POWER_STATE_D0);

Expand Down
9 changes: 8 additions & 1 deletion drivers/gpu/drm/drm_gem_ttm_helper.c
Original file line number Diff line number Diff line change
Expand Up @@ -64,8 +64,13 @@ int drm_gem_ttm_vmap(struct drm_gem_object *gem,
struct iosys_map *map)
{
struct ttm_buffer_object *bo = drm_gem_ttm_of_gem(gem);
int ret;

dma_resv_lock(gem->resv, NULL);
ret = ttm_bo_vmap(bo, map);
dma_resv_unlock(gem->resv);

return ttm_bo_vmap(bo, map);
return ret;
}
EXPORT_SYMBOL(drm_gem_ttm_vmap);

Expand All @@ -82,7 +87,9 @@ void drm_gem_ttm_vunmap(struct drm_gem_object *gem,
{
struct ttm_buffer_object *bo = drm_gem_ttm_of_gem(gem);

dma_resv_lock(gem->resv, NULL);
ttm_bo_vunmap(bo, map);
dma_resv_unlock(gem->resv);
}
EXPORT_SYMBOL(drm_gem_ttm_vunmap);

Expand Down
11 changes: 9 additions & 2 deletions drivers/gpu/drm/i915/gt/intel_context_types.h
Original file line number Diff line number Diff line change
Expand Up @@ -273,10 +273,17 @@ struct intel_context {
u8 child_index;
/** @guc: GuC specific members for parallel submission */
struct {
/** @wqi_head: head pointer in work queue */
/** @wqi_head: cached head pointer in work queue */
u16 wqi_head;
/** @wqi_tail: tail pointer in work queue */
/** @wqi_tail: cached tail pointer in work queue */
u16 wqi_tail;
/** @wq_head: pointer to the actual head in work queue */
u32 *wq_head;
/** @wq_tail: pointer to the actual head in work queue */
u32 *wq_tail;
/** @wq_status: pointer to the status in work queue */
u32 *wq_status;

/**
* @parent_page: page in context state (ce->state) used
* by parent for work queue, process descriptor
Expand Down
12 changes: 11 additions & 1 deletion drivers/gpu/drm/i915/gt/intel_execlists_submission.c
Original file line number Diff line number Diff line change
Expand Up @@ -661,6 +661,16 @@ static inline void execlists_schedule_out(struct i915_request *rq)
i915_request_put(rq);
}

static u32 map_i915_prio_to_lrc_desc_prio(int prio)
{
if (prio > I915_PRIORITY_NORMAL)
return GEN12_CTX_PRIORITY_HIGH;
else if (prio < I915_PRIORITY_NORMAL)
return GEN12_CTX_PRIORITY_LOW;
else
return GEN12_CTX_PRIORITY_NORMAL;
}

static u64 execlists_update_context(struct i915_request *rq)
{
struct intel_context *ce = rq->context;
Expand All @@ -669,7 +679,7 @@ static u64 execlists_update_context(struct i915_request *rq)

desc = ce->lrc.desc;
if (rq->engine->flags & I915_ENGINE_HAS_EU_PRIORITY)
desc |= lrc_desc_priority(rq_prio(rq));
desc |= map_i915_prio_to_lrc_desc_prio(rq_prio(rq));

/*
* WaIdleLiteRestore:bdw,skl
Expand Down
10 changes: 0 additions & 10 deletions drivers/gpu/drm/i915/gt/intel_lrc.h
Original file line number Diff line number Diff line change
Expand Up @@ -111,16 +111,6 @@ enum {
#define XEHP_SW_COUNTER_SHIFT 58
#define XEHP_SW_COUNTER_WIDTH 6

static inline u32 lrc_desc_priority(int prio)
{
if (prio > I915_PRIORITY_NORMAL)
return GEN12_CTX_PRIORITY_HIGH;
else if (prio < I915_PRIORITY_NORMAL)
return GEN12_CTX_PRIORITY_LOW;
else
return GEN12_CTX_PRIORITY_NORMAL;
}

static inline void lrc_runtime_start(struct intel_context *ce)
{
struct intel_context_stats *stats = &ce->stats;
Expand Down
3 changes: 3 additions & 0 deletions drivers/gpu/drm/i915/gt/uc/abi/guc_actions_abi.h
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,9 @@ enum intel_guc_action {
INTEL_GUC_ACTION_SCHED_CONTEXT_MODE_DONE = 0x1002,
INTEL_GUC_ACTION_SCHED_ENGINE_MODE_SET = 0x1003,
INTEL_GUC_ACTION_SCHED_ENGINE_MODE_DONE = 0x1004,
INTEL_GUC_ACTION_V69_SET_CONTEXT_PRIORITY = 0x1005,
INTEL_GUC_ACTION_V69_SET_CONTEXT_EXECUTION_QUANTUM = 0x1006,
INTEL_GUC_ACTION_V69_SET_CONTEXT_PREEMPTION_TIMEOUT = 0x1007,
INTEL_GUC_ACTION_CONTEXT_RESET_NOTIFICATION = 0x1008,
INTEL_GUC_ACTION_ENGINE_FAILURE_NOTIFICATION = 0x1009,
INTEL_GUC_ACTION_HOST2GUC_UPDATE_CONTEXT_POLICIES = 0x100B,
Expand Down
5 changes: 5 additions & 0 deletions drivers/gpu/drm/i915/gt/uc/intel_guc.h
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,11 @@ struct intel_guc {
/** @ads_engine_usage_size: size of engine usage in the ADS */
u32 ads_engine_usage_size;

/** @lrc_desc_pool_v69: object allocated to hold the GuC LRC descriptor pool */
struct i915_vma *lrc_desc_pool_v69;
/** @lrc_desc_pool_vaddr_v69: contents of the GuC LRC descriptor pool */
void *lrc_desc_pool_vaddr_v69;

/**
* @context_lookup: used to resolve intel_context from guc_id, if a
* context is present in this structure it is registered with the GuC
Expand Down
45 changes: 45 additions & 0 deletions drivers/gpu/drm/i915/gt/uc/intel_guc_fwif.h
Original file line number Diff line number Diff line change
Expand Up @@ -203,6 +203,20 @@ struct guc_wq_item {
u32 fence_id;
} __packed;

struct guc_process_desc_v69 {
u32 stage_id;
u64 db_base_addr;
u32 head;
u32 tail;
u32 error_offset;
u64 wq_base_addr;
u32 wq_size_bytes;
u32 wq_status;
u32 engine_presence;
u32 priority;
u32 reserved[36];
} __packed;

struct guc_sched_wq_desc {
u32 head;
u32 tail;
Expand All @@ -227,6 +241,37 @@ struct guc_ctxt_registration_info {
};
#define CONTEXT_REGISTRATION_FLAG_KMD BIT(0)

/* Preempt to idle on quantum expiry */
#define CONTEXT_POLICY_FLAG_PREEMPT_TO_IDLE_V69 BIT(0)

/*
* GuC Context registration descriptor.
* FIXME: This is only required to exist during context registration.
* The current 1:1 between guc_lrc_desc and LRCs for the lifetime of the LRC
* is not required.
*/
struct guc_lrc_desc_v69 {
u32 hw_context_desc;
u32 slpm_perf_mode_hint; /* SPLC v1 only */
u32 slpm_freq_hint;
u32 engine_submit_mask; /* In logical space */
u8 engine_class;
u8 reserved0[3];
u32 priority;
u32 process_desc;
u32 wq_addr;
u32 wq_size;
u32 context_flags; /* CONTEXT_REGISTRATION_* */
/* Time for one workload to execute. (in micro seconds) */
u32 execution_quantum;
/* Time to wait for a preemption request to complete before issuing a
* reset. (in micro seconds).
*/
u32 preemption_timeout;
u32 policy_flags; /* CONTEXT_POLICY_* */
u32 reserved1[19];
} __packed;

/* 32-bit KLV structure as used by policy updates and others */
struct guc_klv_generic_dw_t {
u32 kl;
Expand Down
Loading

0 comments on commit 8e65afb

Please sign in to comment.