[RFC PATCH] drm/xe: PM snippet
Matthew Brost
matthew.brost at intel.com
Wed Jan 10 15:20:33 UTC 2024
Code snippet for [1] as guide as to where to add PM refs.
[1] https://patchwork.freedesktop.org/series/128044/
---
drivers/gpu/drm/xe/xe_gt.c | 3 +++
drivers/gpu/drm/xe/xe_guc_ct.c | 20 ++++++++++++++++++++
drivers/gpu/drm/xe/xe_guc_submit.c | 4 ++++
drivers/gpu/drm/xe/xe_pt.c | 10 ++++++++++
4 files changed, 37 insertions(+)
diff --git a/drivers/gpu/drm/xe/xe_gt.c b/drivers/gpu/drm/xe/xe_gt.c
index 3af2adec1295..f829a1f59d42 100644
--- a/drivers/gpu/drm/xe/xe_gt.c
+++ b/drivers/gpu/drm/xe/xe_gt.c
@@ -604,6 +604,7 @@ static int gt_reset(struct xe_gt *gt)
goto err_fail;
}
+ /* PM get */
xe_gt_sanitize(gt);
xe_device_mem_access_get(gt_to_xe(gt));
@@ -630,6 +631,7 @@ static int gt_reset(struct xe_gt *gt)
goto err_out;
err = xe_force_wake_put(gt_to_fw(gt), XE_FORCEWAKE_ALL);
+ /* PM put */
xe_device_mem_access_put(gt_to_xe(gt));
XE_WARN_ON(err);
@@ -641,6 +643,7 @@ static int gt_reset(struct xe_gt *gt)
XE_WARN_ON(xe_force_wake_put(gt_to_fw(gt), XE_FORCEWAKE_ALL));
err_msg:
XE_WARN_ON(xe_uc_start(>->uc));
+ /* PM put */
xe_device_mem_access_put(gt_to_xe(gt));
err_fail:
xe_gt_err(gt, "reset failed (%pe)\n", ERR_PTR(err));
diff --git a/drivers/gpu/drm/xe/xe_guc_ct.c b/drivers/gpu/drm/xe/xe_guc_ct.c
index c29f095aa1b9..fdc25b076758 100644
--- a/drivers/gpu/drm/xe/xe_guc_ct.c
+++ b/drivers/gpu/drm/xe/xe_guc_ct.c
@@ -307,6 +307,14 @@ int xe_guc_ct_enable(struct xe_guc_ct *ct)
mutex_lock(&ct->lock);
spin_lock_irq(&ct->fast_lock);
+ /*
+ * Drop ct->g2h_outstanding PM refs here, it is expected that we will
+ * not transition to zero here. Note this changing with [1] but the
+ * idea anytime this is set zero, drop the number of PM refs by the
+ * initial value and transitioning to zero is not expected.
+ *
+ * [1] https://patchwork.freedesktop.org/series/128062/
+ */
ct->g2h_outstanding = 0;
ct->enabled = true;
spin_unlock_irq(&ct->fast_lock);
@@ -388,7 +396,13 @@ static void __g2h_reserve_space(struct xe_guc_ct *ct, u32 g2h_len, u32 num_g2h)
ct->ctbs.g2h.info.space -= g2h_len;
ct->g2h_outstanding += num_g2h;
+ /*
+ * If it is safe, ct->lock & ct->fast_lock are held, dma fencing
+ * path, take num_g2h PM refs here. It should be expected that
+ * we have at least 1.
+ */
}
+
}
static void __g2h_release_space(struct xe_guc_ct *ct, u32 g2h_len)
@@ -399,6 +413,12 @@ static void __g2h_release_space(struct xe_guc_ct *ct, u32 g2h_len)
ct->ctbs.g2h.info.space += g2h_len;
--ct->g2h_outstanding;
+
+ /*
+ * If it is safe, ct->fast_lock is held, possible IRQ context, dma
+ * fencing path, drop 1 PM ref here. The PM ref can transition to zero
+ * here.
+ */
}
static void g2h_release_space(struct xe_guc_ct *ct, u32 g2h_len)
diff --git a/drivers/gpu/drm/xe/xe_guc_submit.c b/drivers/gpu/drm/xe/xe_guc_submit.c
index 54ffcfcdd41f..a64768257d51 100644
--- a/drivers/gpu/drm/xe/xe_guc_submit.c
+++ b/drivers/gpu/drm/xe/xe_guc_submit.c
@@ -1168,6 +1168,8 @@ static void __guc_exec_queue_process_msg_resume(struct xe_sched_msg *msg)
static void guc_exec_queue_process_msg(struct xe_sched_msg *msg)
{
+ /* PM get, ref can be zero, dma-fencing path */
+
trace_xe_sched_msg_recv(msg);
switch (msg->opcode) {
@@ -1186,6 +1188,8 @@ static void guc_exec_queue_process_msg(struct xe_sched_msg *msg)
default:
XE_WARN_ON("Unknown message type");
}
+
+ /* PM put, ref can go to zero, dma-fencing path */
}
static const struct drm_sched_backend_ops drm_sched_ops = {
diff --git a/drivers/gpu/drm/xe/xe_pt.c b/drivers/gpu/drm/xe/xe_pt.c
index de1030a47588..d2ef0a5b514e 100644
--- a/drivers/gpu/drm/xe/xe_pt.c
+++ b/drivers/gpu/drm/xe/xe_pt.c
@@ -1104,8 +1104,18 @@ static void invalidation_fence_work_func(struct work_struct *w)
struct invalidation_fence *ifence =
container_of(w, struct invalidation_fence, work);
+ /*
+ * PM get, ref can be zero.
+ *
+ * Ideally make this so we have at least 1 ref, maybe if we take a
+ * reference to the job this is attached and drop the ref after calling
+ * xe_gt_tlb_invalidation_vma we can ensure the device is awake?
+ */
+
trace_xe_gt_tlb_invalidation_fence_work_func(&ifence->base);
xe_gt_tlb_invalidation_vma(ifence->gt, &ifence->base, ifence->vma);
+
+ /* PM put, ref can go to zero */
}
static int invalidation_fence_init(struct xe_gt *gt,
--
2.34.1
More information about the Intel-xe
mailing list