* [PATCH 02/14] drm/xe: Convert mem_access assertion towards the runtime_pm state
2024-02-15 19:34 [PATCH 01/14] drm/xe: Document Xe PM component Rodrigo Vivi
@ 2024-02-15 19:34 ` Rodrigo Vivi
2024-02-15 19:34 ` [PATCH 03/14] drm/xe: Runtime PM wake on every IOCTL Rodrigo Vivi
` (16 subsequent siblings)
17 siblings, 0 replies; 26+ messages in thread
From: Rodrigo Vivi @ 2024-02-15 19:34 UTC (permalink / raw)
To: intel-xe; +Cc: Rodrigo Vivi, Matthew Auld
The mem_access helpers are going away and getting replaced by
direct calls of the xe_pm_runtime_{get,put} functions. However, an
assertion with a warning splat is desired when we hit the worst
case of a memory access with the device really in the 'suspended'
state.
Also, this needs to be the first step. Otherwise, the upcoming
conversion would be really noise with warn splats of missing mem_access
gets.
v2: Minor doc changes as suggested by Matt
Signed-off-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
Reviewed-by: Matthew Auld <matthew.auld@intel.com>
---
drivers/gpu/drm/xe/xe_device.c | 13 ++++++++++++-
drivers/gpu/drm/xe/xe_pm.c | 16 ++++++++++++++++
drivers/gpu/drm/xe/xe_pm.h | 1 +
3 files changed, 29 insertions(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/xe/xe_device.c b/drivers/gpu/drm/xe/xe_device.c
index 5b84d7305520..641af3c7fd34 100644
--- a/drivers/gpu/drm/xe/xe_device.c
+++ b/drivers/gpu/drm/xe/xe_device.c
@@ -653,9 +653,20 @@ bool xe_device_mem_access_ongoing(struct xe_device *xe)
return atomic_read(&xe->mem_access.ref);
}
+/**
+ * xe_device_assert_mem_access - Inspect the current runtime_pm state.
+ * @xe: xe device instance
+ *
+ * To be used before any kind of memory access. It will splat a debug warning
+ * if the device is currently sleeping. But it doesn't guarantee in any way
+ * that the device is going to remain awake. Xe PM runtime get and put
+ * functions might be added to the outer bound of the memory access, while
+ * this check is intended for inner usage to splat some warning if the worst
+ * case has just happened.
+ */
void xe_device_assert_mem_access(struct xe_device *xe)
{
- XE_WARN_ON(!xe_device_mem_access_ongoing(xe));
+ XE_WARN_ON(xe_pm_runtime_suspended(xe));
}
bool xe_device_mem_access_get_if_ongoing(struct xe_device *xe)
diff --git a/drivers/gpu/drm/xe/xe_pm.c b/drivers/gpu/drm/xe/xe_pm.c
index 64ffb9a35448..d1c105f0eda0 100644
--- a/drivers/gpu/drm/xe/xe_pm.c
+++ b/drivers/gpu/drm/xe/xe_pm.c
@@ -260,6 +260,22 @@ struct task_struct *xe_pm_read_callback_task(struct xe_device *xe)
return READ_ONCE(xe->pm_callback_task);
}
+/**
+ * xe_pm_runtime_suspended - Check if runtime_pm state is suspended
+ * @xe: xe device instance
+ *
+ * This does not provide any guarantee that the device is going to remain
+ * suspended as it might be racing with the runtime state transitions.
+ * It can be used only as a non-reliable assertion, to ensure that we are not in
+ * the sleep state while trying to access some memory for instance.
+ *
+ * Returns true if PCI device is suspended, false otherwise.
+ */
+bool xe_pm_runtime_suspended(struct xe_device *xe)
+{
+ return pm_runtime_suspended(xe->drm.dev);
+}
+
/**
* xe_pm_runtime_suspend - Prepare our device for D3hot/D3Cold
* @xe: xe device instance
diff --git a/drivers/gpu/drm/xe/xe_pm.h b/drivers/gpu/drm/xe/xe_pm.h
index 64a97c6726a7..75919eba1746 100644
--- a/drivers/gpu/drm/xe/xe_pm.h
+++ b/drivers/gpu/drm/xe/xe_pm.h
@@ -23,6 +23,7 @@ int xe_pm_resume(struct xe_device *xe);
void xe_pm_init_early(struct xe_device *xe);
void xe_pm_init(struct xe_device *xe);
void xe_pm_runtime_fini(struct xe_device *xe);
+bool xe_pm_runtime_suspended(struct xe_device *xe);
int xe_pm_runtime_suspend(struct xe_device *xe);
int xe_pm_runtime_resume(struct xe_device *xe);
int xe_pm_runtime_get(struct xe_device *xe);
--
2.43.0
^ permalink raw reply related [flat|nested] 26+ messages in thread* [PATCH 03/14] drm/xe: Runtime PM wake on every IOCTL
2024-02-15 19:34 [PATCH 01/14] drm/xe: Document Xe PM component Rodrigo Vivi
2024-02-15 19:34 ` [PATCH 02/14] drm/xe: Convert mem_access assertion towards the runtime_pm state Rodrigo Vivi
@ 2024-02-15 19:34 ` Rodrigo Vivi
2024-02-16 9:38 ` Francois Dugast
2024-02-15 19:34 ` [PATCH 04/14] drm/xe: Convert kunit tests from mem_access to xe_pm_runtime Rodrigo Vivi
` (15 subsequent siblings)
17 siblings, 1 reply; 26+ messages in thread
From: Rodrigo Vivi @ 2024-02-15 19:34 UTC (permalink / raw)
To: intel-xe; +Cc: Rodrigo Vivi, Matthew Auld
Let's ensure our PCI device is awaken on every IOCTL entry.
Let's increase the runtime_pm protection and start moving
that to the outer bounds.
v2: minor typo fix and renaming function to make it clear
that is intended to be used by ioctl only. (Matt)
Signed-off-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
Cc: Matthew Auld <matthew.auld@intel.com>
---
drivers/gpu/drm/xe/xe_device.c | 32 ++++++++++++++++++++++++++++++--
drivers/gpu/drm/xe/xe_pm.c | 15 +++++++++++++++
drivers/gpu/drm/xe/xe_pm.h | 1 +
3 files changed, 46 insertions(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/xe/xe_device.c b/drivers/gpu/drm/xe/xe_device.c
index 641af3c7fd34..f763385b941b 100644
--- a/drivers/gpu/drm/xe/xe_device.c
+++ b/drivers/gpu/drm/xe/xe_device.c
@@ -141,15 +141,43 @@ static const struct drm_ioctl_desc xe_ioctls[] = {
DRM_RENDER_ALLOW),
};
+static long xe_drm_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
+{
+ struct drm_file *file_priv = file->private_data;
+ struct xe_device *xe = to_xe_device(file_priv->minor->dev);
+ long ret;
+
+ ret = xe_pm_runtime_get_ioctl(xe);
+ if (ret >= 0)
+ ret = drm_ioctl(file, cmd, arg);
+ xe_pm_runtime_put(xe);
+
+ return ret;
+}
+
+static long xe_drm_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
+{
+ struct drm_file *file_priv = file->private_data;
+ struct xe_device *xe = to_xe_device(file_priv->minor->dev);
+ long ret;
+
+ ret = xe_pm_runtime_get_ioctl(xe);
+ if (ret >= 0)
+ ret = drm_compat_ioctl(file, cmd, arg);
+ xe_pm_runtime_put(xe);
+
+ return ret;
+}
+
static const struct file_operations xe_driver_fops = {
.owner = THIS_MODULE,
.open = drm_open,
.release = drm_release_noglobal,
- .unlocked_ioctl = drm_ioctl,
+ .unlocked_ioctl = xe_drm_ioctl,
.mmap = drm_gem_mmap,
.poll = drm_poll,
.read = drm_read,
- .compat_ioctl = drm_compat_ioctl,
+ .compat_ioctl = xe_drm_compat_ioctl,
.llseek = noop_llseek,
#ifdef CONFIG_PROC_FS
.show_fdinfo = drm_show_fdinfo,
diff --git a/drivers/gpu/drm/xe/xe_pm.c b/drivers/gpu/drm/xe/xe_pm.c
index d1c105f0eda0..b7a0e3cc594a 100644
--- a/drivers/gpu/drm/xe/xe_pm.c
+++ b/drivers/gpu/drm/xe/xe_pm.c
@@ -429,6 +429,21 @@ int xe_pm_runtime_put(struct xe_device *xe)
return pm_runtime_put(xe->drm.dev);
}
+/**
+ * xe_pm_runtime_get_ioctl - Get a runtime_pm reference before ioctl
+ * @xe: xe device instance
+ *
+ * Returns: Any number greater than or equal to 0 for success, negative error
+ * code otherwise.
+ */
+int xe_pm_runtime_get_ioctl(struct xe_device *xe)
+{
+ if (WARN_ON(xe_pm_read_callback_task(xe) == current))
+ return -ELOOP;
+
+ return pm_runtime_get_sync(xe->drm.dev);
+}
+
/**
* xe_pm_runtime_get_if_active - Get a runtime_pm reference if device active
* @xe: xe device instance
diff --git a/drivers/gpu/drm/xe/xe_pm.h b/drivers/gpu/drm/xe/xe_pm.h
index 75919eba1746..7f5884babb29 100644
--- a/drivers/gpu/drm/xe/xe_pm.h
+++ b/drivers/gpu/drm/xe/xe_pm.h
@@ -27,6 +27,7 @@ bool xe_pm_runtime_suspended(struct xe_device *xe);
int xe_pm_runtime_suspend(struct xe_device *xe);
int xe_pm_runtime_resume(struct xe_device *xe);
int xe_pm_runtime_get(struct xe_device *xe);
+int xe_pm_runtime_get_ioctl(struct xe_device *xe);
int xe_pm_runtime_put(struct xe_device *xe);
int xe_pm_runtime_get_if_active(struct xe_device *xe);
void xe_pm_assert_unbounded_bridge(struct xe_device *xe);
--
2.43.0
^ permalink raw reply related [flat|nested] 26+ messages in thread* Re: [PATCH 03/14] drm/xe: Runtime PM wake on every IOCTL
2024-02-15 19:34 ` [PATCH 03/14] drm/xe: Runtime PM wake on every IOCTL Rodrigo Vivi
@ 2024-02-16 9:38 ` Francois Dugast
0 siblings, 0 replies; 26+ messages in thread
From: Francois Dugast @ 2024-02-16 9:38 UTC (permalink / raw)
To: Rodrigo Vivi; +Cc: intel-xe, Matthew Auld
On Thu, Feb 15, 2024 at 02:34:19PM -0500, Rodrigo Vivi wrote:
> Let's ensure our PCI device is awaken on every IOCTL entry.
> Let's increase the runtime_pm protection and start moving
> that to the outer bounds.
>
> v2: minor typo fix and renaming function to make it clear
> that is intended to be used by ioctl only. (Matt)
>
> Signed-off-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
> Cc: Matthew Auld <matthew.auld@intel.com>
Reviewed-by: Francois Dugast <francois.dugast@intel.com>
> ---
> drivers/gpu/drm/xe/xe_device.c | 32 ++++++++++++++++++++++++++++++--
> drivers/gpu/drm/xe/xe_pm.c | 15 +++++++++++++++
> drivers/gpu/drm/xe/xe_pm.h | 1 +
> 3 files changed, 46 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/gpu/drm/xe/xe_device.c b/drivers/gpu/drm/xe/xe_device.c
> index 641af3c7fd34..f763385b941b 100644
> --- a/drivers/gpu/drm/xe/xe_device.c
> +++ b/drivers/gpu/drm/xe/xe_device.c
> @@ -141,15 +141,43 @@ static const struct drm_ioctl_desc xe_ioctls[] = {
> DRM_RENDER_ALLOW),
> };
>
> +static long xe_drm_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
> +{
> + struct drm_file *file_priv = file->private_data;
> + struct xe_device *xe = to_xe_device(file_priv->minor->dev);
> + long ret;
> +
> + ret = xe_pm_runtime_get_ioctl(xe);
> + if (ret >= 0)
> + ret = drm_ioctl(file, cmd, arg);
> + xe_pm_runtime_put(xe);
> +
> + return ret;
> +}
> +
> +static long xe_drm_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
> +{
> + struct drm_file *file_priv = file->private_data;
> + struct xe_device *xe = to_xe_device(file_priv->minor->dev);
> + long ret;
> +
> + ret = xe_pm_runtime_get_ioctl(xe);
> + if (ret >= 0)
> + ret = drm_compat_ioctl(file, cmd, arg);
> + xe_pm_runtime_put(xe);
> +
> + return ret;
> +}
> +
> static const struct file_operations xe_driver_fops = {
> .owner = THIS_MODULE,
> .open = drm_open,
> .release = drm_release_noglobal,
> - .unlocked_ioctl = drm_ioctl,
> + .unlocked_ioctl = xe_drm_ioctl,
> .mmap = drm_gem_mmap,
> .poll = drm_poll,
> .read = drm_read,
> - .compat_ioctl = drm_compat_ioctl,
> + .compat_ioctl = xe_drm_compat_ioctl,
> .llseek = noop_llseek,
> #ifdef CONFIG_PROC_FS
> .show_fdinfo = drm_show_fdinfo,
> diff --git a/drivers/gpu/drm/xe/xe_pm.c b/drivers/gpu/drm/xe/xe_pm.c
> index d1c105f0eda0..b7a0e3cc594a 100644
> --- a/drivers/gpu/drm/xe/xe_pm.c
> +++ b/drivers/gpu/drm/xe/xe_pm.c
> @@ -429,6 +429,21 @@ int xe_pm_runtime_put(struct xe_device *xe)
> return pm_runtime_put(xe->drm.dev);
> }
>
> +/**
> + * xe_pm_runtime_get_ioctl - Get a runtime_pm reference before ioctl
> + * @xe: xe device instance
> + *
> + * Returns: Any number greater than or equal to 0 for success, negative error
> + * code otherwise.
> + */
> +int xe_pm_runtime_get_ioctl(struct xe_device *xe)
> +{
> + if (WARN_ON(xe_pm_read_callback_task(xe) == current))
> + return -ELOOP;
> +
> + return pm_runtime_get_sync(xe->drm.dev);
> +}
> +
> /**
> * xe_pm_runtime_get_if_active - Get a runtime_pm reference if device active
> * @xe: xe device instance
> diff --git a/drivers/gpu/drm/xe/xe_pm.h b/drivers/gpu/drm/xe/xe_pm.h
> index 75919eba1746..7f5884babb29 100644
> --- a/drivers/gpu/drm/xe/xe_pm.h
> +++ b/drivers/gpu/drm/xe/xe_pm.h
> @@ -27,6 +27,7 @@ bool xe_pm_runtime_suspended(struct xe_device *xe);
> int xe_pm_runtime_suspend(struct xe_device *xe);
> int xe_pm_runtime_resume(struct xe_device *xe);
> int xe_pm_runtime_get(struct xe_device *xe);
> +int xe_pm_runtime_get_ioctl(struct xe_device *xe);
> int xe_pm_runtime_put(struct xe_device *xe);
> int xe_pm_runtime_get_if_active(struct xe_device *xe);
> void xe_pm_assert_unbounded_bridge(struct xe_device *xe);
> --
> 2.43.0
>
^ permalink raw reply [flat|nested] 26+ messages in thread
* [PATCH 04/14] drm/xe: Convert kunit tests from mem_access to xe_pm_runtime
2024-02-15 19:34 [PATCH 01/14] drm/xe: Document Xe PM component Rodrigo Vivi
2024-02-15 19:34 ` [PATCH 02/14] drm/xe: Convert mem_access assertion towards the runtime_pm state Rodrigo Vivi
2024-02-15 19:34 ` [PATCH 03/14] drm/xe: Runtime PM wake on every IOCTL Rodrigo Vivi
@ 2024-02-15 19:34 ` Rodrigo Vivi
2024-02-15 19:34 ` [PATCH 05/14] drm/xe: Runtime PM wake on every sysfs call Rodrigo Vivi
` (14 subsequent siblings)
17 siblings, 0 replies; 26+ messages in thread
From: Rodrigo Vivi @ 2024-02-15 19:34 UTC (permalink / raw)
To: intel-xe; +Cc: Rodrigo Vivi, Matthew Auld
Let's convert the kunit tests that are currently relying on
xe_device_mem_access_{get,put} towards the direct xe_pm_runtime_{get,put}.
While doing this we need to move the get/put calls towards the outer
bounds of the tests to ensure consistency with the other usages of
pm_runtime on the regular paths.
Signed-off-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
Reviewed-by: Matthew Auld <matthew.auld@intel.com>
---
drivers/gpu/drm/xe/tests/xe_bo.c | 8 ++++----
drivers/gpu/drm/xe/tests/xe_migrate.c | 7 +++++--
drivers/gpu/drm/xe/tests/xe_mocs.c | 14 ++++++++++----
3 files changed, 19 insertions(+), 10 deletions(-)
diff --git a/drivers/gpu/drm/xe/tests/xe_bo.c b/drivers/gpu/drm/xe/tests/xe_bo.c
index 3436fd9cf2b2..0926a1c2eb86 100644
--- a/drivers/gpu/drm/xe/tests/xe_bo.c
+++ b/drivers/gpu/drm/xe/tests/xe_bo.c
@@ -163,7 +163,7 @@ static int ccs_test_run_device(struct xe_device *xe)
return 0;
}
- xe_device_mem_access_get(xe);
+ xe_pm_runtime_get(xe);
for_each_tile(tile, xe, id) {
/* For igfx run only for primary tile */
@@ -172,7 +172,7 @@ static int ccs_test_run_device(struct xe_device *xe)
ccs_test_run_tile(xe, tile, test);
}
- xe_device_mem_access_put(xe);
+ xe_pm_runtime_put(xe);
return 0;
}
@@ -335,12 +335,12 @@ static int evict_test_run_device(struct xe_device *xe)
return 0;
}
- xe_device_mem_access_get(xe);
+ xe_pm_runtime_get(xe);
for_each_tile(tile, xe, id)
evict_test_run_tile(xe, tile, test);
- xe_device_mem_access_put(xe);
+ xe_pm_runtime_put(xe);
return 0;
}
diff --git a/drivers/gpu/drm/xe/tests/xe_migrate.c b/drivers/gpu/drm/xe/tests/xe_migrate.c
index a6523df0f1d3..ce531498f57f 100644
--- a/drivers/gpu/drm/xe/tests/xe_migrate.c
+++ b/drivers/gpu/drm/xe/tests/xe_migrate.c
@@ -10,6 +10,7 @@
#include "tests/xe_pci_test.h"
#include "xe_pci.h"
+#include "xe_pm.h"
static bool sanity_fence_failed(struct xe_device *xe, struct dma_fence *fence,
const char *str, struct kunit *test)
@@ -423,17 +424,19 @@ static int migrate_test_run_device(struct xe_device *xe)
struct xe_tile *tile;
int id;
+ xe_pm_runtime_get(xe);
+
for_each_tile(tile, xe, id) {
struct xe_migrate *m = tile->migrate;
kunit_info(test, "Testing tile id %d.\n", id);
xe_vm_lock(m->q->vm, true);
- xe_device_mem_access_get(xe);
xe_migrate_sanity_test(m, test);
- xe_device_mem_access_put(xe);
xe_vm_unlock(m->q->vm);
}
+ xe_pm_runtime_put(xe);
+
return 0;
}
diff --git a/drivers/gpu/drm/xe/tests/xe_mocs.c b/drivers/gpu/drm/xe/tests/xe_mocs.c
index df5c36b70ab4..d561582f8063 100644
--- a/drivers/gpu/drm/xe/tests/xe_mocs.c
+++ b/drivers/gpu/drm/xe/tests/xe_mocs.c
@@ -45,7 +45,6 @@ static void read_l3cc_table(struct xe_gt *gt,
struct kunit *test = xe_cur_kunit();
- xe_device_mem_access_get(gt_to_xe(gt));
ret = xe_force_wake_get(gt_to_fw(gt), XE_FW_GT);
KUNIT_ASSERT_EQ_MSG(test, ret, 0, "Forcewake Failed.\n");
mocs_dbg(>_to_xe(gt)->drm, "L3CC entries:%d\n", info->n_entries);
@@ -65,7 +64,6 @@ static void read_l3cc_table(struct xe_gt *gt,
XELP_LNCFCMOCS(i).addr);
}
xe_force_wake_put(gt_to_fw(gt), XE_FW_GT);
- xe_device_mem_access_put(gt_to_xe(gt));
}
static void read_mocs_table(struct xe_gt *gt,
@@ -80,7 +78,6 @@ static void read_mocs_table(struct xe_gt *gt,
struct kunit *test = xe_cur_kunit();
- xe_device_mem_access_get(gt_to_xe(gt));
ret = xe_force_wake_get(gt_to_fw(gt), XE_FW_GT);
KUNIT_ASSERT_EQ_MSG(test, ret, 0, "Forcewake Failed.\n");
mocs_dbg(>_to_xe(gt)->drm, "Global MOCS entries:%d\n", info->n_entries);
@@ -100,7 +97,6 @@ static void read_mocs_table(struct xe_gt *gt,
XELP_GLOBAL_MOCS(i).addr);
}
xe_force_wake_put(gt_to_fw(gt), XE_FW_GT);
- xe_device_mem_access_put(gt_to_xe(gt));
}
static int mocs_kernel_test_run_device(struct xe_device *xe)
@@ -113,6 +109,8 @@ static int mocs_kernel_test_run_device(struct xe_device *xe)
unsigned int flags;
int id;
+ xe_pm_runtime_get(xe);
+
for_each_gt(gt, xe, id) {
flags = live_mocs_init(&mocs, gt);
if (flags & HAS_GLOBAL_MOCS)
@@ -120,6 +118,9 @@ static int mocs_kernel_test_run_device(struct xe_device *xe)
if (flags & HAS_LNCF_MOCS)
read_l3cc_table(gt, &mocs.table);
}
+
+ xe_pm_runtime_put(xe);
+
return 0;
}
@@ -139,6 +140,8 @@ static int mocs_reset_test_run_device(struct xe_device *xe)
int id;
struct kunit *test = xe_cur_kunit();
+ xe_pm_runtime_get(xe);
+
for_each_gt(gt, xe, id) {
flags = live_mocs_init(&mocs, gt);
kunit_info(test, "mocs_reset_test before reset\n");
@@ -156,6 +159,9 @@ static int mocs_reset_test_run_device(struct xe_device *xe)
if (flags & HAS_LNCF_MOCS)
read_l3cc_table(gt, &mocs.table);
}
+
+ xe_pm_runtime_put(xe);
+
return 0;
}
--
2.43.0
^ permalink raw reply related [flat|nested] 26+ messages in thread* [PATCH 05/14] drm/xe: Runtime PM wake on every sysfs call
2024-02-15 19:34 [PATCH 01/14] drm/xe: Document Xe PM component Rodrigo Vivi
` (2 preceding siblings ...)
2024-02-15 19:34 ` [PATCH 04/14] drm/xe: Convert kunit tests from mem_access to xe_pm_runtime Rodrigo Vivi
@ 2024-02-15 19:34 ` Rodrigo Vivi
2024-02-15 19:34 ` [PATCH 06/14] drm/xe: Remove mem_access from guc_pc calls Rodrigo Vivi
` (13 subsequent siblings)
17 siblings, 0 replies; 26+ messages in thread
From: Rodrigo Vivi @ 2024-02-15 19:34 UTC (permalink / raw)
To: intel-xe; +Cc: Rodrigo Vivi, Matthew Auld
Let's ensure our PCI device is awaken on every sysfs call.
Let's increase the runtime_pm protection and start moving
that to the outer bounds.
For now, for the files with small number of attr functions,
let's only call the runtime pm functions directly.
For the hw_engines entries with many files, let's add
the sysfs_ops wrapper.
Signed-off-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
Reviewed-by: Matthew Auld <matthew.auld@intel.com>
---
drivers/gpu/drm/xe/xe_device_sysfs.c | 4 ++
drivers/gpu/drm/xe/xe_gt_freq.c | 38 +++++++++++-
drivers/gpu/drm/xe/xe_gt_idle.c | 23 +++++++-
drivers/gpu/drm/xe/xe_gt_throttle_sysfs.c | 3 +
drivers/gpu/drm/xe/xe_hw_engine_class_sysfs.c | 58 ++++++++++++++++++-
drivers/gpu/drm/xe/xe_hw_engine_class_sysfs.h | 7 +++
drivers/gpu/drm/xe/xe_tile_sysfs.c | 1 +
7 files changed, 129 insertions(+), 5 deletions(-)
diff --git a/drivers/gpu/drm/xe/xe_device_sysfs.c b/drivers/gpu/drm/xe/xe_device_sysfs.c
index 99113a5a2b84..e47c8ad1bb17 100644
--- a/drivers/gpu/drm/xe/xe_device_sysfs.c
+++ b/drivers/gpu/drm/xe/xe_device_sysfs.c
@@ -35,7 +35,9 @@ vram_d3cold_threshold_show(struct device *dev,
if (!xe)
return -EINVAL;
+ xe_pm_runtime_get(xe);
ret = sysfs_emit(buf, "%d\n", xe->d3cold.vram_threshold);
+ xe_pm_runtime_put(xe);
return ret;
}
@@ -58,7 +60,9 @@ vram_d3cold_threshold_store(struct device *dev, struct device_attribute *attr,
drm_dbg(&xe->drm, "vram_d3cold_threshold: %u\n", vram_d3cold_threshold);
+ xe_pm_runtime_get(xe);
ret = xe_pm_set_vram_threshold(xe, vram_d3cold_threshold);
+ xe_pm_runtime_put(xe);
return ret ?: count;
}
diff --git a/drivers/gpu/drm/xe/xe_gt_freq.c b/drivers/gpu/drm/xe/xe_gt_freq.c
index e5b0f4ecdbe8..32b9a743629c 100644
--- a/drivers/gpu/drm/xe/xe_gt_freq.c
+++ b/drivers/gpu/drm/xe/xe_gt_freq.c
@@ -15,6 +15,7 @@
#include "xe_gt_sysfs.h"
#include "xe_gt_throttle_sysfs.h"
#include "xe_guc_pc.h"
+#include "xe_pm.h"
/**
* DOC: Xe GT Frequency Management
@@ -49,12 +50,23 @@ dev_to_pc(struct device *dev)
return &kobj_to_gt(dev->kobj.parent)->uc.guc.pc;
}
+static struct xe_device *
+dev_to_xe(struct device *dev)
+{
+ return gt_to_xe(kobj_to_gt(dev->kobj.parent));
+}
+
static ssize_t act_freq_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
struct xe_guc_pc *pc = dev_to_pc(dev);
+ u32 freq;
+
+ xe_pm_runtime_get(dev_to_xe(dev));
+ freq = xe_guc_pc_get_act_freq(pc);
+ xe_pm_runtime_put(dev_to_xe(dev));
- return sysfs_emit(buf, "%d\n", xe_guc_pc_get_act_freq(pc));
+ return sysfs_emit(buf, "%d\n", freq);
}
static DEVICE_ATTR_RO(act_freq);
@@ -65,7 +77,9 @@ static ssize_t cur_freq_show(struct device *dev,
u32 freq;
ssize_t ret;
+ xe_pm_runtime_get(dev_to_xe(dev));
ret = xe_guc_pc_get_cur_freq(pc, &freq);
+ xe_pm_runtime_put(dev_to_xe(dev));
if (ret)
return ret;
@@ -77,8 +91,13 @@ static ssize_t rp0_freq_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
struct xe_guc_pc *pc = dev_to_pc(dev);
+ u32 freq;
+
+ xe_pm_runtime_get(dev_to_xe(dev));
+ freq = xe_guc_pc_get_rp0_freq(pc);
+ xe_pm_runtime_put(dev_to_xe(dev));
- return sysfs_emit(buf, "%d\n", xe_guc_pc_get_rp0_freq(pc));
+ return sysfs_emit(buf, "%d\n", freq);
}
static DEVICE_ATTR_RO(rp0_freq);
@@ -86,8 +105,13 @@ static ssize_t rpe_freq_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
struct xe_guc_pc *pc = dev_to_pc(dev);
+ u32 freq;
+
+ xe_pm_runtime_get(dev_to_xe(dev));
+ freq = xe_guc_pc_get_rpe_freq(pc);
+ xe_pm_runtime_put(dev_to_xe(dev));
- return sysfs_emit(buf, "%d\n", xe_guc_pc_get_rpe_freq(pc));
+ return sysfs_emit(buf, "%d\n", freq);
}
static DEVICE_ATTR_RO(rpe_freq);
@@ -107,7 +131,9 @@ static ssize_t min_freq_show(struct device *dev,
u32 freq;
ssize_t ret;
+ xe_pm_runtime_get(dev_to_xe(dev));
ret = xe_guc_pc_get_min_freq(pc, &freq);
+ xe_pm_runtime_put(dev_to_xe(dev));
if (ret)
return ret;
@@ -125,7 +151,9 @@ static ssize_t min_freq_store(struct device *dev, struct device_attribute *attr,
if (ret)
return ret;
+ xe_pm_runtime_get(dev_to_xe(dev));
ret = xe_guc_pc_set_min_freq(pc, freq);
+ xe_pm_runtime_put(dev_to_xe(dev));
if (ret)
return ret;
@@ -140,7 +168,9 @@ static ssize_t max_freq_show(struct device *dev,
u32 freq;
ssize_t ret;
+ xe_pm_runtime_get(dev_to_xe(dev));
ret = xe_guc_pc_get_max_freq(pc, &freq);
+ xe_pm_runtime_put(dev_to_xe(dev));
if (ret)
return ret;
@@ -158,7 +188,9 @@ static ssize_t max_freq_store(struct device *dev, struct device_attribute *attr,
if (ret)
return ret;
+ xe_pm_runtime_get(dev_to_xe(dev));
ret = xe_guc_pc_set_max_freq(pc, freq);
+ xe_pm_runtime_put(dev_to_xe(dev));
if (ret)
return ret;
diff --git a/drivers/gpu/drm/xe/xe_gt_idle.c b/drivers/gpu/drm/xe/xe_gt_idle.c
index 9358f7336889..824ff458011f 100644
--- a/drivers/gpu/drm/xe/xe_gt_idle.c
+++ b/drivers/gpu/drm/xe/xe_gt_idle.c
@@ -12,6 +12,7 @@
#include "xe_guc_pc.h"
#include "regs/xe_gt_regs.h"
#include "xe_mmio.h"
+#include "xe_pm.h"
/**
* DOC: Xe GT Idle
@@ -40,6 +41,15 @@ static struct xe_guc_pc *gtidle_to_pc(struct xe_gt_idle *gtidle)
return >idle_to_gt(gtidle)->uc.guc.pc;
}
+static struct xe_device *
+pc_to_xe(struct xe_guc_pc *pc)
+{
+ struct xe_guc *guc = container_of(pc, struct xe_guc, pc);
+ struct xe_gt *gt = container_of(guc, struct xe_gt, uc.guc);
+
+ return gt_to_xe(gt);
+}
+
static const char *gt_idle_state_to_string(enum xe_gt_idle_state state)
{
switch (state) {
@@ -86,8 +96,14 @@ static ssize_t name_show(struct device *dev,
struct device_attribute *attr, char *buff)
{
struct xe_gt_idle *gtidle = dev_to_gtidle(dev);
+ struct xe_guc_pc *pc = gtidle_to_pc(gtidle);
+ ssize_t ret;
+
+ xe_pm_runtime_get(pc_to_xe(pc));
+ ret = sysfs_emit(buff, "%s\n", gtidle->name);
+ xe_pm_runtime_put(pc_to_xe(pc));
- return sysfs_emit(buff, "%s\n", gtidle->name);
+ return ret;
}
static DEVICE_ATTR_RO(name);
@@ -98,7 +114,9 @@ static ssize_t idle_status_show(struct device *dev,
struct xe_guc_pc *pc = gtidle_to_pc(gtidle);
enum xe_gt_idle_state state;
+ xe_pm_runtime_get(pc_to_xe(pc));
state = gtidle->idle_status(pc);
+ xe_pm_runtime_put(pc_to_xe(pc));
return sysfs_emit(buff, "%s\n", gt_idle_state_to_string(state));
}
@@ -111,7 +129,10 @@ static ssize_t idle_residency_ms_show(struct device *dev,
struct xe_guc_pc *pc = gtidle_to_pc(gtidle);
u64 residency;
+ xe_pm_runtime_get(pc_to_xe(pc));
residency = gtidle->idle_residency(pc);
+ xe_pm_runtime_put(pc_to_xe(pc));
+
return sysfs_emit(buff, "%llu\n", get_residency_ms(gtidle, residency));
}
static DEVICE_ATTR_RO(idle_residency_ms);
diff --git a/drivers/gpu/drm/xe/xe_gt_throttle_sysfs.c b/drivers/gpu/drm/xe/xe_gt_throttle_sysfs.c
index 63d640591a52..9c33045ff1ef 100644
--- a/drivers/gpu/drm/xe/xe_gt_throttle_sysfs.c
+++ b/drivers/gpu/drm/xe/xe_gt_throttle_sysfs.c
@@ -11,6 +11,7 @@
#include "xe_gt_sysfs.h"
#include "xe_gt_throttle_sysfs.h"
#include "xe_mmio.h"
+#include "xe_pm.h"
/**
* DOC: Xe GT Throttle
@@ -38,10 +39,12 @@ static u32 read_perf_limit_reasons(struct xe_gt *gt)
{
u32 reg;
+ xe_pm_runtime_get(gt_to_xe(gt));
if (xe_gt_is_media_type(gt))
reg = xe_mmio_read32(gt, MTL_MEDIA_PERF_LIMIT_REASONS);
else
reg = xe_mmio_read32(gt, GT0_PERF_LIMIT_REASONS);
+ xe_pm_runtime_put(gt_to_xe(gt));
return reg;
}
diff --git a/drivers/gpu/drm/xe/xe_hw_engine_class_sysfs.c b/drivers/gpu/drm/xe/xe_hw_engine_class_sysfs.c
index 2345fb42fa39..9e23ca7f45ad 100644
--- a/drivers/gpu/drm/xe/xe_hw_engine_class_sysfs.c
+++ b/drivers/gpu/drm/xe/xe_hw_engine_class_sysfs.c
@@ -9,6 +9,7 @@
#include "xe_gt.h"
#include "xe_hw_engine_class_sysfs.h"
+#include "xe_pm.h"
#define MAX_ENGINE_CLASS_NAME_LEN 16
static int xe_add_hw_engine_class_defaults(struct xe_device *xe,
@@ -513,6 +514,7 @@ kobj_xe_hw_engine_class(struct xe_device *xe, struct kobject *parent, char *name
kobject_put(&keclass->base);
return NULL;
}
+ keclass->xe = xe;
err = drmm_add_action_or_reset(&xe->drm, kobj_xe_hw_engine_class_fini,
&keclass->base);
@@ -567,9 +569,63 @@ static void xe_hw_engine_sysfs_kobj_release(struct kobject *kobj)
kfree(kobj);
}
+#include "xe_pm.h"
+
+static inline struct xe_device *pdev_to_xe_device(struct pci_dev *pdev)
+{
+ return pci_get_drvdata(pdev);
+}
+
+static inline struct xe_device *to_xe_device(const struct drm_device *dev)
+{
+ return container_of(dev, struct xe_device, drm);
+}
+
+static ssize_t xe_hw_engine_class_sysfs_attr_show(struct kobject *kobj,
+ struct attribute *attr,
+ char *buf)
+{
+ struct xe_device *xe = kobj_to_xe(kobj);
+ struct kobj_attribute *kattr;
+ ssize_t ret = -EIO;
+
+ kattr = container_of(attr, struct kobj_attribute, attr);
+ if (kattr->show) {
+ xe_pm_runtime_get(xe);
+ ret = kattr->show(kobj, kattr, buf);
+ xe_pm_runtime_put(xe);
+ }
+
+ return ret;
+}
+
+static ssize_t xe_hw_engine_class_sysfs_attr_store(struct kobject *kobj,
+ struct attribute *attr,
+ const char *buf,
+ size_t count)
+{
+ struct xe_device *xe = kobj_to_xe(kobj);
+ struct kobj_attribute *kattr;
+ ssize_t ret = -EIO;
+
+ kattr = container_of(attr, struct kobj_attribute, attr);
+ if (kattr->store) {
+ xe_pm_runtime_get(xe);
+ ret = kattr->store(kobj, kattr, buf, count);
+ xe_pm_runtime_put(xe);
+ }
+
+ return ret;
+}
+
+static const struct sysfs_ops xe_hw_engine_class_sysfs_ops = {
+ .show = xe_hw_engine_class_sysfs_attr_show,
+ .store = xe_hw_engine_class_sysfs_attr_store,
+};
+
static const struct kobj_type xe_hw_engine_sysfs_kobj_type = {
.release = xe_hw_engine_sysfs_kobj_release,
- .sysfs_ops = &kobj_sysfs_ops,
+ .sysfs_ops = &xe_hw_engine_class_sysfs_ops,
};
static void hw_engine_class_sysfs_fini(struct drm_device *drm, void *arg)
diff --git a/drivers/gpu/drm/xe/xe_hw_engine_class_sysfs.h b/drivers/gpu/drm/xe/xe_hw_engine_class_sysfs.h
index ec5ba673b314..28a0d7c909c0 100644
--- a/drivers/gpu/drm/xe/xe_hw_engine_class_sysfs.h
+++ b/drivers/gpu/drm/xe/xe_hw_engine_class_sysfs.h
@@ -26,6 +26,8 @@ struct kobj_eclass {
struct kobject base;
/** @eclass: A pointer to the hw engine class interface */
struct xe_hw_engine_class_intf *eclass;
+ /** @xe: A pointer to the xe device */
+ struct xe_device *xe;
};
static inline struct xe_hw_engine_class_intf *kobj_to_eclass(struct kobject *kobj)
@@ -33,4 +35,9 @@ static inline struct xe_hw_engine_class_intf *kobj_to_eclass(struct kobject *kob
return container_of(kobj, struct kobj_eclass, base)->eclass;
}
+static inline struct xe_device *kobj_to_xe(struct kobject *kobj)
+{
+ return container_of(kobj, struct kobj_eclass, base)->xe;
+}
+
#endif
diff --git a/drivers/gpu/drm/xe/xe_tile_sysfs.c b/drivers/gpu/drm/xe/xe_tile_sysfs.c
index 0662968d7bcb..237a0761d3ad 100644
--- a/drivers/gpu/drm/xe/xe_tile_sysfs.c
+++ b/drivers/gpu/drm/xe/xe_tile_sysfs.c
@@ -7,6 +7,7 @@
#include <linux/sysfs.h>
#include <drm/drm_managed.h>
+#include "xe_pm.h"
#include "xe_tile.h"
#include "xe_tile_sysfs.h"
#include "xe_vram_freq.h"
--
2.43.0
^ permalink raw reply related [flat|nested] 26+ messages in thread* [PATCH 06/14] drm/xe: Remove mem_access from guc_pc calls
2024-02-15 19:34 [PATCH 01/14] drm/xe: Document Xe PM component Rodrigo Vivi
` (3 preceding siblings ...)
2024-02-15 19:34 ` [PATCH 05/14] drm/xe: Runtime PM wake on every sysfs call Rodrigo Vivi
@ 2024-02-15 19:34 ` Rodrigo Vivi
2024-02-15 19:34 ` [PATCH 07/14] drm/xe: Runtime PM wake on every debugfs call Rodrigo Vivi
` (12 subsequent siblings)
17 siblings, 0 replies; 26+ messages in thread
From: Rodrigo Vivi @ 2024-02-15 19:34 UTC (permalink / raw)
To: intel-xe; +Cc: Rodrigo Vivi, Matthew Auld
We are now protected by init, sysfs, or removal and don't
need these mem_access protections around GuC_PC anymore.
Signed-off-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
Reviewed-by: Matthew Auld <matthew.auld@intel.com>
---
drivers/gpu/drm/xe/xe_guc_pc.c | 64 ++++++----------------------------
1 file changed, 10 insertions(+), 54 deletions(-)
diff --git a/drivers/gpu/drm/xe/xe_guc_pc.c b/drivers/gpu/drm/xe/xe_guc_pc.c
index d91702592520..ce39eac7c8f5 100644
--- a/drivers/gpu/drm/xe/xe_guc_pc.c
+++ b/drivers/gpu/drm/xe/xe_guc_pc.c
@@ -381,8 +381,6 @@ u32 xe_guc_pc_get_act_freq(struct xe_guc_pc *pc)
struct xe_device *xe = gt_to_xe(gt);
u32 freq;
- xe_device_mem_access_get(gt_to_xe(gt));
-
/* When in RC6, actual frequency reported will be 0. */
if (GRAPHICS_VERx100(xe) >= 1270) {
freq = xe_mmio_read32(gt, MTL_MIRROR_TARGET_WP1);
@@ -394,8 +392,6 @@ u32 xe_guc_pc_get_act_freq(struct xe_guc_pc *pc)
freq = decode_freq(freq);
- xe_device_mem_access_put(gt_to_xe(gt));
-
return freq;
}
@@ -412,14 +408,13 @@ int xe_guc_pc_get_cur_freq(struct xe_guc_pc *pc, u32 *freq)
struct xe_gt *gt = pc_to_gt(pc);
int ret;
- xe_device_mem_access_get(gt_to_xe(gt));
/*
* GuC SLPC plays with cur freq request when GuCRC is enabled
* Block RC6 for a more reliable read.
*/
ret = xe_force_wake_get(gt_to_fw(gt), XE_FORCEWAKE_ALL);
if (ret)
- goto out;
+ return ret;
*freq = xe_mmio_read32(gt, RPNSWREQ);
@@ -427,9 +422,7 @@ int xe_guc_pc_get_cur_freq(struct xe_guc_pc *pc, u32 *freq)
*freq = decode_freq(*freq);
XE_WARN_ON(xe_force_wake_put(gt_to_fw(gt), XE_FORCEWAKE_ALL));
-out:
- xe_device_mem_access_put(gt_to_xe(gt));
- return ret;
+ return 0;
}
/**
@@ -451,12 +444,7 @@ u32 xe_guc_pc_get_rp0_freq(struct xe_guc_pc *pc)
*/
u32 xe_guc_pc_get_rpe_freq(struct xe_guc_pc *pc)
{
- struct xe_gt *gt = pc_to_gt(pc);
- struct xe_device *xe = gt_to_xe(gt);
-
- xe_device_mem_access_get(xe);
pc_update_rp_values(pc);
- xe_device_mem_access_put(xe);
return pc->rpe_freq;
}
@@ -485,7 +473,6 @@ int xe_guc_pc_get_min_freq(struct xe_guc_pc *pc, u32 *freq)
struct xe_gt *gt = pc_to_gt(pc);
int ret;
- xe_device_mem_access_get(pc_to_xe(pc));
mutex_lock(&pc->freq_lock);
if (!pc->freq_ready) {
/* Might be in the middle of a gt reset */
@@ -511,7 +498,6 @@ int xe_guc_pc_get_min_freq(struct xe_guc_pc *pc, u32 *freq)
XE_WARN_ON(xe_force_wake_put(gt_to_fw(gt), XE_FORCEWAKE_ALL));
out:
mutex_unlock(&pc->freq_lock);
- xe_device_mem_access_put(pc_to_xe(pc));
return ret;
}
@@ -528,7 +514,6 @@ int xe_guc_pc_set_min_freq(struct xe_guc_pc *pc, u32 freq)
{
int ret;
- xe_device_mem_access_get(pc_to_xe(pc));
mutex_lock(&pc->freq_lock);
if (!pc->freq_ready) {
/* Might be in the middle of a gt reset */
@@ -544,8 +529,6 @@ int xe_guc_pc_set_min_freq(struct xe_guc_pc *pc, u32 freq)
out:
mutex_unlock(&pc->freq_lock);
- xe_device_mem_access_put(pc_to_xe(pc));
-
return ret;
}
@@ -561,7 +544,6 @@ int xe_guc_pc_get_max_freq(struct xe_guc_pc *pc, u32 *freq)
{
int ret;
- xe_device_mem_access_get(pc_to_xe(pc));
mutex_lock(&pc->freq_lock);
if (!pc->freq_ready) {
/* Might be in the middle of a gt reset */
@@ -577,7 +559,6 @@ int xe_guc_pc_get_max_freq(struct xe_guc_pc *pc, u32 *freq)
out:
mutex_unlock(&pc->freq_lock);
- xe_device_mem_access_put(pc_to_xe(pc));
return ret;
}
@@ -594,7 +575,6 @@ int xe_guc_pc_set_max_freq(struct xe_guc_pc *pc, u32 freq)
{
int ret;
- xe_device_mem_access_get(pc_to_xe(pc));
mutex_lock(&pc->freq_lock);
if (!pc->freq_ready) {
/* Might be in the middle of a gt reset */
@@ -610,7 +590,6 @@ int xe_guc_pc_set_max_freq(struct xe_guc_pc *pc, u32 freq)
out:
mutex_unlock(&pc->freq_lock);
- xe_device_mem_access_put(pc_to_xe(pc));
return ret;
}
@@ -623,8 +602,6 @@ enum xe_gt_idle_state xe_guc_pc_c_status(struct xe_guc_pc *pc)
struct xe_gt *gt = pc_to_gt(pc);
u32 reg, gt_c_state;
- xe_device_mem_access_get(gt_to_xe(gt));
-
if (GRAPHICS_VERx100(gt_to_xe(gt)) >= 1270) {
reg = xe_mmio_read32(gt, MTL_MIRROR_TARGET_WP1);
gt_c_state = REG_FIELD_GET(MTL_CC_MASK, reg);
@@ -633,8 +610,6 @@ enum xe_gt_idle_state xe_guc_pc_c_status(struct xe_guc_pc *pc)
gt_c_state = REG_FIELD_GET(RCN_MASK, reg);
}
- xe_device_mem_access_put(gt_to_xe(gt));
-
switch (gt_c_state) {
case GT_C6:
return GT_IDLE_C6;
@@ -654,9 +629,7 @@ u64 xe_guc_pc_rc6_residency(struct xe_guc_pc *pc)
struct xe_gt *gt = pc_to_gt(pc);
u32 reg;
- xe_device_mem_access_get(gt_to_xe(gt));
reg = xe_mmio_read32(gt, GT_GFX_RC6);
- xe_device_mem_access_put(gt_to_xe(gt));
return reg;
}
@@ -670,9 +643,7 @@ u64 xe_guc_pc_mc6_residency(struct xe_guc_pc *pc)
struct xe_gt *gt = pc_to_gt(pc);
u64 reg;
- xe_device_mem_access_get(gt_to_xe(gt));
reg = xe_mmio_read32(gt, MTL_MEDIA_MC6);
- xe_device_mem_access_put(gt_to_xe(gt));
return reg;
}
@@ -801,23 +772,19 @@ int xe_guc_pc_gucrc_disable(struct xe_guc_pc *pc)
if (xe->info.skip_guc_pc)
return 0;
- xe_device_mem_access_get(pc_to_xe(pc));
-
ret = pc_action_setup_gucrc(pc, XE_GUCRC_HOST_CONTROL);
if (ret)
- goto out;
+ return ret;
ret = xe_force_wake_get(gt_to_fw(gt), XE_FORCEWAKE_ALL);
if (ret)
- goto out;
+ return ret;
xe_gt_idle_disable_c6(gt);
XE_WARN_ON(xe_force_wake_put(gt_to_fw(gt), XE_FORCEWAKE_ALL));
-out:
- xe_device_mem_access_put(pc_to_xe(pc));
- return ret;
+ return 0;
}
static void pc_init_pcode_freq(struct xe_guc_pc *pc)
@@ -870,11 +837,9 @@ int xe_guc_pc_start(struct xe_guc_pc *pc)
xe_gt_assert(gt, xe_device_uc_enabled(xe));
- xe_device_mem_access_get(pc_to_xe(pc));
-
ret = xe_force_wake_get(gt_to_fw(gt), XE_FORCEWAKE_ALL);
if (ret)
- goto out_fail_force_wake;
+ return ret;
if (xe->info.skip_guc_pc) {
if (xe->info.platform != XE_PVC)
@@ -914,8 +879,6 @@ int xe_guc_pc_start(struct xe_guc_pc *pc)
out:
XE_WARN_ON(xe_force_wake_put(gt_to_fw(gt), XE_FORCEWAKE_ALL));
-out_fail_force_wake:
- xe_device_mem_access_put(pc_to_xe(pc));
return ret;
}
@@ -928,12 +891,9 @@ int xe_guc_pc_stop(struct xe_guc_pc *pc)
struct xe_device *xe = pc_to_xe(pc);
int ret;
- xe_device_mem_access_get(pc_to_xe(pc));
-
if (xe->info.skip_guc_pc) {
xe_gt_idle_disable_c6(pc_to_gt(pc));
- ret = 0;
- goto out;
+ return 0;
}
mutex_lock(&pc->freq_lock);
@@ -942,16 +902,14 @@ int xe_guc_pc_stop(struct xe_guc_pc *pc)
ret = pc_action_shutdown(pc);
if (ret)
- goto out;
+ return ret;
if (wait_for_pc_state(pc, SLPC_GLOBAL_STATE_NOT_RUNNING)) {
drm_err(&pc_to_xe(pc)->drm, "GuC PC Shutdown failed\n");
- ret = -EIO;
+ return -EIO;
}
-out:
- xe_device_mem_access_put(pc_to_xe(pc));
- return ret;
+ return 0;
}
/**
@@ -963,9 +921,7 @@ void xe_guc_pc_fini(struct xe_guc_pc *pc)
struct xe_device *xe = pc_to_xe(pc);
if (xe->info.skip_guc_pc) {
- xe_device_mem_access_get(xe);
xe_gt_idle_disable_c6(pc_to_gt(pc));
- xe_device_mem_access_put(xe);
return;
}
--
2.43.0
^ permalink raw reply related [flat|nested] 26+ messages in thread* [PATCH 07/14] drm/xe: Runtime PM wake on every debugfs call
2024-02-15 19:34 [PATCH 01/14] drm/xe: Document Xe PM component Rodrigo Vivi
` (4 preceding siblings ...)
2024-02-15 19:34 ` [PATCH 06/14] drm/xe: Remove mem_access from guc_pc calls Rodrigo Vivi
@ 2024-02-15 19:34 ` Rodrigo Vivi
2024-02-15 19:34 ` [PATCH 08/14] drm/xe: Replace dma_buf mem_access per direct xe_pm_runtime calls Rodrigo Vivi
` (11 subsequent siblings)
17 siblings, 0 replies; 26+ messages in thread
From: Rodrigo Vivi @ 2024-02-15 19:34 UTC (permalink / raw)
To: intel-xe; +Cc: Rodrigo Vivi, Matthew Auld
Let's ensure our PCI device is awaken on every debugfs call.
Let's increase the runtime_pm protection and start moving
that to the outer bounds.
Also let's remove the mem_access_{get,put} from where they are
not needed anymore.
Signed-off-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
Reviewed-by: Matthew Auld <matthew.auld@intel.com>
---
drivers/gpu/drm/xe/xe_debugfs.c | 10 +++---
drivers/gpu/drm/xe/xe_gt_debugfs.c | 53 ++++++++++++++++++++++++++---
drivers/gpu/drm/xe/xe_guc_debugfs.c | 9 ++---
drivers/gpu/drm/xe/xe_huc_debugfs.c | 5 +--
drivers/gpu/drm/xe/xe_ttm_sys_mgr.c | 5 ++-
5 files changed, 66 insertions(+), 16 deletions(-)
diff --git a/drivers/gpu/drm/xe/xe_debugfs.c b/drivers/gpu/drm/xe/xe_debugfs.c
index 01db5b27bec5..8abdf3c17e1d 100644
--- a/drivers/gpu/drm/xe/xe_debugfs.c
+++ b/drivers/gpu/drm/xe/xe_debugfs.c
@@ -12,6 +12,7 @@
#include "xe_bo.h"
#include "xe_device.h"
#include "xe_gt_debugfs.h"
+#include "xe_pm.h"
#include "xe_step.h"
#ifdef CONFIG_DRM_XE_DEBUG
@@ -37,6 +38,8 @@ static int info(struct seq_file *m, void *data)
struct xe_gt *gt;
u8 id;
+ xe_pm_runtime_get(xe);
+
drm_printf(&p, "graphics_verx100 %d\n", xe->info.graphics_verx100);
drm_printf(&p, "media_verx100 %d\n", xe->info.media_verx100);
drm_printf(&p, "stepping G:%s M:%s D:%s B:%s\n",
@@ -63,6 +66,7 @@ static int info(struct seq_file *m, void *data)
gt->info.engine_mask);
}
+ xe_pm_runtime_put(xe);
return 0;
}
@@ -76,8 +80,7 @@ static int forcewake_open(struct inode *inode, struct file *file)
struct xe_gt *gt;
u8 id;
- xe_device_mem_access_get(xe);
-
+ xe_pm_runtime_get(xe);
for_each_gt(gt, xe, id)
XE_WARN_ON(xe_force_wake_get(gt_to_fw(gt), XE_FORCEWAKE_ALL));
@@ -92,8 +95,7 @@ static int forcewake_release(struct inode *inode, struct file *file)
for_each_gt(gt, xe, id)
XE_WARN_ON(xe_force_wake_put(gt_to_fw(gt), XE_FORCEWAKE_ALL));
-
- xe_device_mem_access_put(xe);
+ xe_pm_runtime_put(xe);
return 0;
}
diff --git a/drivers/gpu/drm/xe/xe_gt_debugfs.c b/drivers/gpu/drm/xe/xe_gt_debugfs.c
index c4b67cf09f8f..6b4dc2927727 100644
--- a/drivers/gpu/drm/xe/xe_gt_debugfs.c
+++ b/drivers/gpu/drm/xe/xe_gt_debugfs.c
@@ -18,6 +18,7 @@
#include "xe_lrc.h"
#include "xe_macros.h"
#include "xe_pat.h"
+#include "xe_pm.h"
#include "xe_reg_sr.h"
#include "xe_reg_whitelist.h"
#include "xe_uc_debugfs.h"
@@ -37,10 +38,10 @@ static int hw_engines(struct seq_file *m, void *data)
enum xe_hw_engine_id id;
int err;
- xe_device_mem_access_get(xe);
+ xe_pm_runtime_get(xe);
err = xe_force_wake_get(gt_to_fw(gt), XE_FORCEWAKE_ALL);
if (err) {
- xe_device_mem_access_put(xe);
+ xe_pm_runtime_put(xe);
return err;
}
@@ -48,7 +49,7 @@ static int hw_engines(struct seq_file *m, void *data)
xe_hw_engine_print(hwe, &p);
err = xe_force_wake_put(gt_to_fw(gt), XE_FORCEWAKE_ALL);
- xe_device_mem_access_put(xe);
+ xe_pm_runtime_put(xe);
if (err)
return err;
@@ -59,18 +60,23 @@ static int force_reset(struct seq_file *m, void *data)
{
struct xe_gt *gt = node_to_gt(m->private);
+ xe_pm_runtime_get(gt_to_xe(gt));
xe_gt_reset_async(gt);
+ xe_pm_runtime_put(gt_to_xe(gt));
return 0;
}
static int sa_info(struct seq_file *m, void *data)
{
- struct xe_tile *tile = gt_to_tile(node_to_gt(m->private));
+ struct xe_gt *gt = node_to_gt(m->private);
+ struct xe_tile *tile = gt_to_tile(gt);
struct drm_printer p = drm_seq_file_printer(m);
+ xe_pm_runtime_get(gt_to_xe(gt));
drm_suballoc_dump_debug_info(&tile->mem.kernel_bb_pool->base, &p,
tile->mem.kernel_bb_pool->gpu_addr);
+ xe_pm_runtime_put(gt_to_xe(gt));
return 0;
}
@@ -80,7 +86,9 @@ static int topology(struct seq_file *m, void *data)
struct xe_gt *gt = node_to_gt(m->private);
struct drm_printer p = drm_seq_file_printer(m);
+ xe_pm_runtime_get(gt_to_xe(gt));
xe_gt_topology_dump(gt, &p);
+ xe_pm_runtime_put(gt_to_xe(gt));
return 0;
}
@@ -90,7 +98,9 @@ static int steering(struct seq_file *m, void *data)
struct xe_gt *gt = node_to_gt(m->private);
struct drm_printer p = drm_seq_file_printer(m);
+ xe_pm_runtime_get(gt_to_xe(gt));
xe_gt_mcr_steering_dump(gt, &p);
+ xe_pm_runtime_put(gt_to_xe(gt));
return 0;
}
@@ -99,8 +109,13 @@ static int ggtt(struct seq_file *m, void *data)
{
struct xe_gt *gt = node_to_gt(m->private);
struct drm_printer p = drm_seq_file_printer(m);
+ int ret;
+
+ xe_pm_runtime_get(gt_to_xe(gt));
+ ret = xe_ggtt_dump(gt_to_tile(gt)->mem.ggtt, &p);
+ xe_pm_runtime_put(gt_to_xe(gt));
- return xe_ggtt_dump(gt_to_tile(gt)->mem.ggtt, &p);
+ return ret;
}
static int register_save_restore(struct seq_file *m, void *data)
@@ -110,6 +125,8 @@ static int register_save_restore(struct seq_file *m, void *data)
struct xe_hw_engine *hwe;
enum xe_hw_engine_id id;
+ xe_pm_runtime_get(gt_to_xe(gt));
+
xe_reg_sr_dump(>->reg_sr, &p);
drm_printf(&p, "\n");
@@ -127,6 +144,8 @@ static int register_save_restore(struct seq_file *m, void *data)
for_each_hw_engine(hwe, gt, id)
xe_reg_whitelist_dump(&hwe->reg_whitelist, &p);
+ xe_pm_runtime_put(gt_to_xe(gt));
+
return 0;
}
@@ -135,7 +154,9 @@ static int workarounds(struct seq_file *m, void *data)
struct xe_gt *gt = node_to_gt(m->private);
struct drm_printer p = drm_seq_file_printer(m);
+ xe_pm_runtime_get(gt_to_xe(gt));
xe_wa_dump(gt, &p);
+ xe_pm_runtime_put(gt_to_xe(gt));
return 0;
}
@@ -145,48 +166,70 @@ static int pat(struct seq_file *m, void *data)
struct xe_gt *gt = node_to_gt(m->private);
struct drm_printer p = drm_seq_file_printer(m);
+ xe_pm_runtime_get(gt_to_xe(gt));
xe_pat_dump(gt, &p);
+ xe_pm_runtime_put(gt_to_xe(gt));
return 0;
}
static int rcs_default_lrc(struct seq_file *m, void *data)
{
+ struct xe_gt *gt = node_to_gt(m->private);
struct drm_printer p = drm_seq_file_printer(m);
+ xe_pm_runtime_get(gt_to_xe(gt));
xe_lrc_dump_default(&p, node_to_gt(m->private), XE_ENGINE_CLASS_RENDER);
+ xe_pm_runtime_put(gt_to_xe(gt));
+
return 0;
}
static int ccs_default_lrc(struct seq_file *m, void *data)
{
+ struct xe_gt *gt = node_to_gt(m->private);
struct drm_printer p = drm_seq_file_printer(m);
+ xe_pm_runtime_get(gt_to_xe(gt));
xe_lrc_dump_default(&p, node_to_gt(m->private), XE_ENGINE_CLASS_COMPUTE);
+ xe_pm_runtime_put(gt_to_xe(gt));
+
return 0;
}
static int bcs_default_lrc(struct seq_file *m, void *data)
{
+ struct xe_gt *gt = node_to_gt(m->private);
struct drm_printer p = drm_seq_file_printer(m);
+ xe_pm_runtime_get(gt_to_xe(gt));
xe_lrc_dump_default(&p, node_to_gt(m->private), XE_ENGINE_CLASS_COPY);
+ xe_pm_runtime_put(gt_to_xe(gt));
+
return 0;
}
static int vcs_default_lrc(struct seq_file *m, void *data)
{
+ struct xe_gt *gt = node_to_gt(m->private);
struct drm_printer p = drm_seq_file_printer(m);
+ xe_pm_runtime_get(gt_to_xe(gt));
xe_lrc_dump_default(&p, node_to_gt(m->private), XE_ENGINE_CLASS_VIDEO_DECODE);
+ xe_pm_runtime_put(gt_to_xe(gt));
+
return 0;
}
static int vecs_default_lrc(struct seq_file *m, void *data)
{
+ struct xe_gt *gt = node_to_gt(m->private);
struct drm_printer p = drm_seq_file_printer(m);
+ xe_pm_runtime_get(gt_to_xe(gt));
xe_lrc_dump_default(&p, node_to_gt(m->private), XE_ENGINE_CLASS_VIDEO_ENHANCE);
+ xe_pm_runtime_put(gt_to_xe(gt));
+
return 0;
}
diff --git a/drivers/gpu/drm/xe/xe_guc_debugfs.c b/drivers/gpu/drm/xe/xe_guc_debugfs.c
index ffd7d53bcc42..d3822cbea273 100644
--- a/drivers/gpu/drm/xe/xe_guc_debugfs.c
+++ b/drivers/gpu/drm/xe/xe_guc_debugfs.c
@@ -14,6 +14,7 @@
#include "xe_guc_ct.h"
#include "xe_guc_log.h"
#include "xe_macros.h"
+#include "xe_pm.h"
static struct xe_guc *node_to_guc(struct drm_info_node *node)
{
@@ -26,9 +27,9 @@ static int guc_info(struct seq_file *m, void *data)
struct xe_device *xe = guc_to_xe(guc);
struct drm_printer p = drm_seq_file_printer(m);
- xe_device_mem_access_get(xe);
+ xe_pm_runtime_get(xe);
xe_guc_print_info(guc, &p);
- xe_device_mem_access_put(xe);
+ xe_pm_runtime_put(xe);
return 0;
}
@@ -39,9 +40,9 @@ static int guc_log(struct seq_file *m, void *data)
struct xe_device *xe = guc_to_xe(guc);
struct drm_printer p = drm_seq_file_printer(m);
- xe_device_mem_access_get(xe);
+ xe_pm_runtime_get(xe);
xe_guc_log_print(&guc->log, &p);
- xe_device_mem_access_put(xe);
+ xe_pm_runtime_put(xe);
return 0;
}
diff --git a/drivers/gpu/drm/xe/xe_huc_debugfs.c b/drivers/gpu/drm/xe/xe_huc_debugfs.c
index 18585a7eeb9d..3a888a40188b 100644
--- a/drivers/gpu/drm/xe/xe_huc_debugfs.c
+++ b/drivers/gpu/drm/xe/xe_huc_debugfs.c
@@ -12,6 +12,7 @@
#include "xe_gt.h"
#include "xe_huc.h"
#include "xe_macros.h"
+#include "xe_pm.h"
static struct xe_gt *
huc_to_gt(struct xe_huc *huc)
@@ -36,9 +37,9 @@ static int huc_info(struct seq_file *m, void *data)
struct xe_device *xe = huc_to_xe(huc);
struct drm_printer p = drm_seq_file_printer(m);
- xe_device_mem_access_get(xe);
+ xe_pm_runtime_get(xe);
xe_huc_print_info(huc, &p);
- xe_device_mem_access_put(xe);
+ xe_pm_runtime_put(xe);
return 0;
}
diff --git a/drivers/gpu/drm/xe/xe_ttm_sys_mgr.c b/drivers/gpu/drm/xe/xe_ttm_sys_mgr.c
index 3e1fa0c832ca..9844a8edbfe1 100644
--- a/drivers/gpu/drm/xe/xe_ttm_sys_mgr.c
+++ b/drivers/gpu/drm/xe/xe_ttm_sys_mgr.c
@@ -73,7 +73,10 @@ static void xe_ttm_sys_mgr_del(struct ttm_resource_manager *man,
static void xe_ttm_sys_mgr_debug(struct ttm_resource_manager *man,
struct drm_printer *printer)
{
-
+ /*
+ * This function is called by debugfs entry and would require
+ * pm_runtime_{get,put} wrappers around any operation.
+ */
}
static const struct ttm_resource_manager_func xe_ttm_sys_mgr_func = {
--
2.43.0
^ permalink raw reply related [flat|nested] 26+ messages in thread* [PATCH 08/14] drm/xe: Replace dma_buf mem_access per direct xe_pm_runtime calls
2024-02-15 19:34 [PATCH 01/14] drm/xe: Document Xe PM component Rodrigo Vivi
` (5 preceding siblings ...)
2024-02-15 19:34 ` [PATCH 07/14] drm/xe: Runtime PM wake on every debugfs call Rodrigo Vivi
@ 2024-02-15 19:34 ` Rodrigo Vivi
2024-02-15 19:34 ` [PATCH 09/14] drm/xe: Convert hwmon from mem_access to " Rodrigo Vivi
` (10 subsequent siblings)
17 siblings, 0 replies; 26+ messages in thread
From: Rodrigo Vivi @ 2024-02-15 19:34 UTC (permalink / raw)
To: intel-xe; +Cc: Rodrigo Vivi, Matthew Auld
Continue on the path to entirely remove mem_access helpers in
favour of the direct xe_pm_runtime calls. This item is one of
the direct outer bounds of the protection.
Signed-off-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
Reviewed-by: Matthew Auld <matthew.auld@intel.com>
---
drivers/gpu/drm/xe/xe_dma_buf.c | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/xe/xe_dma_buf.c b/drivers/gpu/drm/xe/xe_dma_buf.c
index da2627ed6ae7..5b26af21e029 100644
--- a/drivers/gpu/drm/xe/xe_dma_buf.c
+++ b/drivers/gpu/drm/xe/xe_dma_buf.c
@@ -16,6 +16,7 @@
#include "tests/xe_test.h"
#include "xe_bo.h"
#include "xe_device.h"
+#include "xe_pm.h"
#include "xe_ttm_vram_mgr.h"
#include "xe_vm.h"
@@ -33,7 +34,7 @@ static int xe_dma_buf_attach(struct dma_buf *dmabuf,
if (!attach->peer2peer && !xe_bo_can_migrate(gem_to_xe_bo(obj), XE_PL_TT))
return -EOPNOTSUPP;
- xe_device_mem_access_get(to_xe_device(obj->dev));
+ xe_pm_runtime_get(to_xe_device(obj->dev));
return 0;
}
@@ -42,7 +43,7 @@ static void xe_dma_buf_detach(struct dma_buf *dmabuf,
{
struct drm_gem_object *obj = attach->dmabuf->priv;
- xe_device_mem_access_put(to_xe_device(obj->dev));
+ xe_pm_runtime_put(to_xe_device(obj->dev));
}
static int xe_dma_buf_pin(struct dma_buf_attachment *attach)
--
2.43.0
^ permalink raw reply related [flat|nested] 26+ messages in thread* [PATCH 09/14] drm/xe: Convert hwmon from mem_access to xe_pm_runtime calls
2024-02-15 19:34 [PATCH 01/14] drm/xe: Document Xe PM component Rodrigo Vivi
` (6 preceding siblings ...)
2024-02-15 19:34 ` [PATCH 08/14] drm/xe: Replace dma_buf mem_access per direct xe_pm_runtime calls Rodrigo Vivi
@ 2024-02-15 19:34 ` Rodrigo Vivi
2024-02-15 19:34 ` [PATCH 10/14] drm/xe: Remove useless mem_access protection for query ioctls Rodrigo Vivi
` (9 subsequent siblings)
17 siblings, 0 replies; 26+ messages in thread
From: Rodrigo Vivi @ 2024-02-15 19:34 UTC (permalink / raw)
To: intel-xe; +Cc: Rodrigo Vivi, Matthew Auld
Continue the work to kill the mem_access in favor of a pure runtime pm.
Signed-off-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
Reviewed-by: Matthew Auld <matthew.auld@intel.com>
---
drivers/gpu/drm/xe/xe_hwmon.c | 25 +++++++++++++------------
1 file changed, 13 insertions(+), 12 deletions(-)
diff --git a/drivers/gpu/drm/xe/xe_hwmon.c b/drivers/gpu/drm/xe/xe_hwmon.c
index b82233a41606..a256af8c2012 100644
--- a/drivers/gpu/drm/xe/xe_hwmon.c
+++ b/drivers/gpu/drm/xe/xe_hwmon.c
@@ -18,6 +18,7 @@
#include "xe_pcode.h"
#include "xe_pcode_api.h"
#include "xe_sriov.h"
+#include "xe_pm.h"
enum xe_hwmon_reg {
REG_PKG_RAPL_LIMIT,
@@ -266,7 +267,7 @@ xe_hwmon_power1_max_interval_show(struct device *dev, struct device_attribute *a
u32 x, y, x_w = 2; /* 2 bits */
u64 r, tau4, out;
- xe_device_mem_access_get(gt_to_xe(hwmon->gt));
+ xe_pm_runtime_get(gt_to_xe(hwmon->gt));
mutex_lock(&hwmon->hwmon_lock);
@@ -275,7 +276,7 @@ xe_hwmon_power1_max_interval_show(struct device *dev, struct device_attribute *a
mutex_unlock(&hwmon->hwmon_lock);
- xe_device_mem_access_put(gt_to_xe(hwmon->gt));
+ xe_pm_runtime_put(gt_to_xe(hwmon->gt));
x = REG_FIELD_GET(PKG_PWR_LIM_1_TIME_X, r);
y = REG_FIELD_GET(PKG_PWR_LIM_1_TIME_Y, r);
@@ -354,7 +355,7 @@ xe_hwmon_power1_max_interval_store(struct device *dev, struct device_attribute *
rxy = REG_FIELD_PREP(PKG_PWR_LIM_1_TIME_X, x) | REG_FIELD_PREP(PKG_PWR_LIM_1_TIME_Y, y);
- xe_device_mem_access_get(gt_to_xe(hwmon->gt));
+ xe_pm_runtime_get(gt_to_xe(hwmon->gt));
mutex_lock(&hwmon->hwmon_lock);
@@ -363,7 +364,7 @@ xe_hwmon_power1_max_interval_store(struct device *dev, struct device_attribute *
mutex_unlock(&hwmon->hwmon_lock);
- xe_device_mem_access_put(gt_to_xe(hwmon->gt));
+ xe_pm_runtime_put(gt_to_xe(hwmon->gt));
return count;
}
@@ -384,12 +385,12 @@ static umode_t xe_hwmon_attributes_visible(struct kobject *kobj,
struct xe_hwmon *hwmon = dev_get_drvdata(dev);
int ret = 0;
- xe_device_mem_access_get(gt_to_xe(hwmon->gt));
+ xe_pm_runtime_get(gt_to_xe(hwmon->gt));
if (attr == &sensor_dev_attr_power1_max_interval.dev_attr.attr)
ret = xe_hwmon_get_reg(hwmon, REG_PKG_RAPL_LIMIT) ? attr->mode : 0;
- xe_device_mem_access_put(gt_to_xe(hwmon->gt));
+ xe_pm_runtime_put(gt_to_xe(hwmon->gt));
return ret;
}
@@ -610,7 +611,7 @@ xe_hwmon_is_visible(const void *drvdata, enum hwmon_sensor_types type,
struct xe_hwmon *hwmon = (struct xe_hwmon *)drvdata;
int ret;
- xe_device_mem_access_get(gt_to_xe(hwmon->gt));
+ xe_pm_runtime_get(gt_to_xe(hwmon->gt));
switch (type) {
case hwmon_power:
@@ -630,7 +631,7 @@ xe_hwmon_is_visible(const void *drvdata, enum hwmon_sensor_types type,
break;
}
- xe_device_mem_access_put(gt_to_xe(hwmon->gt));
+ xe_pm_runtime_put(gt_to_xe(hwmon->gt));
return ret;
}
@@ -642,7 +643,7 @@ xe_hwmon_read(struct device *dev, enum hwmon_sensor_types type, u32 attr,
struct xe_hwmon *hwmon = dev_get_drvdata(dev);
int ret;
- xe_device_mem_access_get(gt_to_xe(hwmon->gt));
+ xe_pm_runtime_get(gt_to_xe(hwmon->gt));
switch (type) {
case hwmon_power:
@@ -662,7 +663,7 @@ xe_hwmon_read(struct device *dev, enum hwmon_sensor_types type, u32 attr,
break;
}
- xe_device_mem_access_put(gt_to_xe(hwmon->gt));
+ xe_pm_runtime_put(gt_to_xe(hwmon->gt));
return ret;
}
@@ -674,7 +675,7 @@ xe_hwmon_write(struct device *dev, enum hwmon_sensor_types type, u32 attr,
struct xe_hwmon *hwmon = dev_get_drvdata(dev);
int ret;
- xe_device_mem_access_get(gt_to_xe(hwmon->gt));
+ xe_pm_runtime_get(gt_to_xe(hwmon->gt));
switch (type) {
case hwmon_power:
@@ -688,7 +689,7 @@ xe_hwmon_write(struct device *dev, enum hwmon_sensor_types type, u32 attr,
break;
}
- xe_device_mem_access_put(gt_to_xe(hwmon->gt));
+ xe_pm_runtime_put(gt_to_xe(hwmon->gt));
return ret;
}
--
2.43.0
^ permalink raw reply related [flat|nested] 26+ messages in thread* [PATCH 10/14] drm/xe: Remove useless mem_access protection for query ioctls
2024-02-15 19:34 [PATCH 01/14] drm/xe: Document Xe PM component Rodrigo Vivi
` (7 preceding siblings ...)
2024-02-15 19:34 ` [PATCH 09/14] drm/xe: Convert hwmon from mem_access to " Rodrigo Vivi
@ 2024-02-15 19:34 ` Rodrigo Vivi
2024-02-15 19:34 ` [PATCH 11/14] drm/xe: Convert gsc_work from mem_access to xe_pm_runtime Rodrigo Vivi
` (8 subsequent siblings)
17 siblings, 0 replies; 26+ messages in thread
From: Rodrigo Vivi @ 2024-02-15 19:34 UTC (permalink / raw)
To: intel-xe; +Cc: Rodrigo Vivi, Matthew Auld
Every IOCTL is already protected on its outer bounds by
xe_pm_runtime_{get,put} calls, so we can now remove
these.
Signed-off-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
Reviewed-by: Matthew Auld <matthew.auld@intel.com>
---
drivers/gpu/drm/xe/xe_query.c | 4 ----
1 file changed, 4 deletions(-)
diff --git a/drivers/gpu/drm/xe/xe_query.c b/drivers/gpu/drm/xe/xe_query.c
index 92bb06c0586e..f1876b556ab4 100644
--- a/drivers/gpu/drm/xe/xe_query.c
+++ b/drivers/gpu/drm/xe/xe_query.c
@@ -147,7 +147,6 @@ query_engine_cycles(struct xe_device *xe,
if (!hwe)
return -EINVAL;
- xe_device_mem_access_get(xe);
xe_force_wake_get(gt_to_fw(gt), XE_FORCEWAKE_ALL);
__read_timestamps(gt,
@@ -159,7 +158,6 @@ query_engine_cycles(struct xe_device *xe,
cpu_clock);
xe_force_wake_put(gt_to_fw(gt), XE_FORCEWAKE_ALL);
- xe_device_mem_access_put(xe);
resp.width = 36;
/* Only write to the output fields of user query */
@@ -433,9 +431,7 @@ static int query_hwconfig(struct xe_device *xe,
if (!hwconfig)
return -ENOMEM;
- xe_device_mem_access_get(xe);
xe_guc_hwconfig_copy(>->uc.guc, hwconfig);
- xe_device_mem_access_put(xe);
if (copy_to_user(query_ptr, hwconfig, size)) {
kfree(hwconfig);
--
2.43.0
^ permalink raw reply related [flat|nested] 26+ messages in thread* [PATCH 11/14] drm/xe: Convert gsc_work from mem_access to xe_pm_runtime
2024-02-15 19:34 [PATCH 01/14] drm/xe: Document Xe PM component Rodrigo Vivi
` (8 preceding siblings ...)
2024-02-15 19:34 ` [PATCH 10/14] drm/xe: Remove useless mem_access protection for query ioctls Rodrigo Vivi
@ 2024-02-15 19:34 ` Rodrigo Vivi
2024-02-15 19:34 ` [PATCH 12/14] drm/xe: Remove mem_access from suspend and resume functions Rodrigo Vivi
` (7 subsequent siblings)
17 siblings, 0 replies; 26+ messages in thread
From: Rodrigo Vivi @ 2024-02-15 19:34 UTC (permalink / raw)
To: intel-xe; +Cc: Rodrigo Vivi, Matthew Auld
Let's directly use xe_pm_runtime_{get,put} instead of the
mem_access helpers that are going away soon.
Signed-off-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
Reviewed-by: Matthew Auld <matthew.auld@intel.com>
---
drivers/gpu/drm/xe/xe_gsc.c | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/xe/xe_gsc.c b/drivers/gpu/drm/xe/xe_gsc.c
index 0b90fd9ef63a..904026634991 100644
--- a/drivers/gpu/drm/xe/xe_gsc.c
+++ b/drivers/gpu/drm/xe/xe_gsc.c
@@ -20,6 +20,7 @@
#include "xe_huc.h"
#include "xe_map.h"
#include "xe_mmio.h"
+#include "xe_pm.h"
#include "xe_sched_job.h"
#include "xe_uc_fw.h"
#include "xe_wa.h"
@@ -284,7 +285,7 @@ static void gsc_work(struct work_struct *work)
gsc->work_actions = 0;
spin_unlock_irq(&gsc->lock);
- xe_device_mem_access_get(xe);
+ xe_pm_runtime_get(xe);
xe_force_wake_get(gt_to_fw(gt), XE_FW_GSC);
if (actions & GSC_ACTION_FW_LOAD) {
@@ -299,7 +300,7 @@ static void gsc_work(struct work_struct *work)
xe_gsc_proxy_request_handler(gsc);
xe_force_wake_put(gt_to_fw(gt), XE_FW_GSC);
- xe_device_mem_access_put(xe);
+ xe_pm_runtime_put(xe);
}
int xe_gsc_init(struct xe_gsc *gsc)
--
2.43.0
^ permalink raw reply related [flat|nested] 26+ messages in thread* [PATCH 12/14] drm/xe: Remove mem_access from suspend and resume functions
2024-02-15 19:34 [PATCH 01/14] drm/xe: Document Xe PM component Rodrigo Vivi
` (9 preceding siblings ...)
2024-02-15 19:34 ` [PATCH 11/14] drm/xe: Convert gsc_work from mem_access to xe_pm_runtime Rodrigo Vivi
@ 2024-02-15 19:34 ` Rodrigo Vivi
2024-02-15 19:34 ` [PATCH 13/14] drm/xe: Convert gt_reset from mem_access to xe_pm_runtime Rodrigo Vivi
` (6 subsequent siblings)
17 siblings, 0 replies; 26+ messages in thread
From: Rodrigo Vivi @ 2024-02-15 19:34 UTC (permalink / raw)
To: intel-xe; +Cc: Rodrigo Vivi, Matthew Auld
At these points, we are sure that device is awake in D0.
Likely in the middle of the transition, but awake. So,
these extra protections are useless. Let's remove it and
continue with the killing of xe_device_mem_access.
Signed-off-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
Reviewed-by: Matthew Auld <matthew.auld@intel.com>
---
drivers/gpu/drm/xe/xe_gt.c | 8 --------
1 file changed, 8 deletions(-)
diff --git a/drivers/gpu/drm/xe/xe_gt.c b/drivers/gpu/drm/xe/xe_gt.c
index c79edfd5a34f..afc62eb26071 100644
--- a/drivers/gpu/drm/xe/xe_gt.c
+++ b/drivers/gpu/drm/xe/xe_gt.c
@@ -693,13 +693,11 @@ void xe_gt_reset_async(struct xe_gt *gt)
void xe_gt_suspend_prepare(struct xe_gt *gt)
{
- xe_device_mem_access_get(gt_to_xe(gt));
XE_WARN_ON(xe_force_wake_get(gt_to_fw(gt), XE_FORCEWAKE_ALL));
xe_uc_stop_prepare(>->uc);
XE_WARN_ON(xe_force_wake_put(gt_to_fw(gt), XE_FORCEWAKE_ALL));
- xe_device_mem_access_put(gt_to_xe(gt));
}
int xe_gt_suspend(struct xe_gt *gt)
@@ -708,7 +706,6 @@ int xe_gt_suspend(struct xe_gt *gt)
xe_gt_sanitize(gt);
- xe_device_mem_access_get(gt_to_xe(gt));
err = xe_force_wake_get(gt_to_fw(gt), XE_FORCEWAKE_ALL);
if (err)
goto err_msg;
@@ -718,7 +715,6 @@ int xe_gt_suspend(struct xe_gt *gt)
goto err_force_wake;
XE_WARN_ON(xe_force_wake_put(gt_to_fw(gt), XE_FORCEWAKE_ALL));
- xe_device_mem_access_put(gt_to_xe(gt));
xe_gt_info(gt, "suspended\n");
return 0;
@@ -726,7 +722,6 @@ int xe_gt_suspend(struct xe_gt *gt)
err_force_wake:
XE_WARN_ON(xe_force_wake_put(gt_to_fw(gt), XE_FORCEWAKE_ALL));
err_msg:
- xe_device_mem_access_put(gt_to_xe(gt));
xe_gt_err(gt, "suspend failed (%pe)\n", ERR_PTR(err));
return err;
@@ -736,7 +731,6 @@ int xe_gt_resume(struct xe_gt *gt)
{
int err;
- xe_device_mem_access_get(gt_to_xe(gt));
err = xe_force_wake_get(gt_to_fw(gt), XE_FORCEWAKE_ALL);
if (err)
goto err_msg;
@@ -746,7 +740,6 @@ int xe_gt_resume(struct xe_gt *gt)
goto err_force_wake;
XE_WARN_ON(xe_force_wake_put(gt_to_fw(gt), XE_FORCEWAKE_ALL));
- xe_device_mem_access_put(gt_to_xe(gt));
xe_gt_info(gt, "resumed\n");
return 0;
@@ -754,7 +747,6 @@ int xe_gt_resume(struct xe_gt *gt)
err_force_wake:
XE_WARN_ON(xe_force_wake_put(gt_to_fw(gt), XE_FORCEWAKE_ALL));
err_msg:
- xe_device_mem_access_put(gt_to_xe(gt));
xe_gt_err(gt, "resume failed (%pe)\n", ERR_PTR(err));
return err;
--
2.43.0
^ permalink raw reply related [flat|nested] 26+ messages in thread* [PATCH 13/14] drm/xe: Convert gt_reset from mem_access to xe_pm_runtime
2024-02-15 19:34 [PATCH 01/14] drm/xe: Document Xe PM component Rodrigo Vivi
` (10 preceding siblings ...)
2024-02-15 19:34 ` [PATCH 12/14] drm/xe: Remove mem_access from suspend and resume functions Rodrigo Vivi
@ 2024-02-15 19:34 ` Rodrigo Vivi
2024-02-15 19:34 ` [PATCH 14/14] drm/xe: Remove useless mem_access on PAT dumps Rodrigo Vivi
` (5 subsequent siblings)
17 siblings, 0 replies; 26+ messages in thread
From: Rodrigo Vivi @ 2024-02-15 19:34 UTC (permalink / raw)
To: intel-xe; +Cc: Rodrigo Vivi, Matthew Brost, Matthew Auld
We need to ensure that device is in D0 on any kind of GT reset.
We are likely already protected by outer bounds like exec,
but if exec/sched ref gets dropped on a hang, we might transition
to D3 before we are able to perform the gt_reset and recover.
Suggested-by: Matthew Brost <matthew.brost@intel.com>
Signed-off-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
Reviewed-by: Matthew Auld <matthew.auld@intel.com>
---
drivers/gpu/drm/xe/xe_gt.c | 7 ++++---
1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/drivers/gpu/drm/xe/xe_gt.c b/drivers/gpu/drm/xe/xe_gt.c
index afc62eb26071..88f9f45bf92f 100644
--- a/drivers/gpu/drm/xe/xe_gt.c
+++ b/drivers/gpu/drm/xe/xe_gt.c
@@ -43,6 +43,7 @@
#include "xe_migrate.h"
#include "xe_mmio.h"
#include "xe_pat.h"
+#include "xe_pm.h"
#include "xe_mocs.h"
#include "xe_reg_sr.h"
#include "xe_ring_ops.h"
@@ -626,9 +627,9 @@ static int gt_reset(struct xe_gt *gt)
goto err_fail;
}
+ xe_pm_runtime_get(gt_to_xe(gt));
xe_gt_sanitize(gt);
- xe_device_mem_access_get(gt_to_xe(gt));
err = xe_force_wake_get(gt_to_fw(gt), XE_FORCEWAKE_ALL);
if (err)
goto err_msg;
@@ -652,8 +653,8 @@ static int gt_reset(struct xe_gt *gt)
goto err_out;
err = xe_force_wake_put(gt_to_fw(gt), XE_FORCEWAKE_ALL);
- xe_device_mem_access_put(gt_to_xe(gt));
XE_WARN_ON(err);
+ xe_pm_runtime_put(gt_to_xe(gt));
xe_gt_info(gt, "reset done\n");
@@ -663,7 +664,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));
- xe_device_mem_access_put(gt_to_xe(gt));
+ xe_pm_runtime_put(gt_to_xe(gt));
err_fail:
xe_gt_err(gt, "reset failed (%pe)\n", ERR_PTR(err));
--
2.43.0
^ permalink raw reply related [flat|nested] 26+ messages in thread* [PATCH 14/14] drm/xe: Remove useless mem_access on PAT dumps
2024-02-15 19:34 [PATCH 01/14] drm/xe: Document Xe PM component Rodrigo Vivi
` (11 preceding siblings ...)
2024-02-15 19:34 ` [PATCH 13/14] drm/xe: Convert gt_reset from mem_access to xe_pm_runtime Rodrigo Vivi
@ 2024-02-15 19:34 ` Rodrigo Vivi
2024-02-15 20:04 ` ✓ CI.Patch_applied: success for series starting with [01/14] drm/xe: Document Xe PM component Patchwork
` (4 subsequent siblings)
17 siblings, 0 replies; 26+ messages in thread
From: Rodrigo Vivi @ 2024-02-15 19:34 UTC (permalink / raw)
To: intel-xe; +Cc: Rodrigo Vivi, Matthew Auld
PAT dumps are already protected by the xe_pm_runtime_{get,put}
around the debugfs call. So, these can be removed.
Signed-off-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
Reviewed-by: Matthew Auld <matthew.auld@intel.com>
---
drivers/gpu/drm/xe/xe_pat.c | 10 ----------
1 file changed, 10 deletions(-)
diff --git a/drivers/gpu/drm/xe/xe_pat.c b/drivers/gpu/drm/xe/xe_pat.c
index e148934d554b..66d8e3dd8237 100644
--- a/drivers/gpu/drm/xe/xe_pat.c
+++ b/drivers/gpu/drm/xe/xe_pat.c
@@ -174,7 +174,6 @@ static void xelp_dump(struct xe_gt *gt, struct drm_printer *p)
struct xe_device *xe = gt_to_xe(gt);
int i, err;
- xe_device_mem_access_get(xe);
err = xe_force_wake_get(gt_to_fw(gt), XE_FW_GT);
if (err)
goto err_fw;
@@ -192,7 +191,6 @@ static void xelp_dump(struct xe_gt *gt, struct drm_printer *p)
err = xe_force_wake_put(gt_to_fw(gt), XE_FW_GT);
err_fw:
xe_assert(xe, !err);
- xe_device_mem_access_put(xe);
}
static const struct xe_pat_ops xelp_pat_ops = {
@@ -205,7 +203,6 @@ static void xehp_dump(struct xe_gt *gt, struct drm_printer *p)
struct xe_device *xe = gt_to_xe(gt);
int i, err;
- xe_device_mem_access_get(xe);
err = xe_force_wake_get(gt_to_fw(gt), XE_FW_GT);
if (err)
goto err_fw;
@@ -225,7 +222,6 @@ static void xehp_dump(struct xe_gt *gt, struct drm_printer *p)
err = xe_force_wake_put(gt_to_fw(gt), XE_FW_GT);
err_fw:
xe_assert(xe, !err);
- xe_device_mem_access_put(xe);
}
static const struct xe_pat_ops xehp_pat_ops = {
@@ -238,7 +234,6 @@ static void xehpc_dump(struct xe_gt *gt, struct drm_printer *p)
struct xe_device *xe = gt_to_xe(gt);
int i, err;
- xe_device_mem_access_get(xe);
err = xe_force_wake_get(gt_to_fw(gt), XE_FW_GT);
if (err)
goto err_fw;
@@ -256,7 +251,6 @@ static void xehpc_dump(struct xe_gt *gt, struct drm_printer *p)
err = xe_force_wake_put(gt_to_fw(gt), XE_FW_GT);
err_fw:
xe_assert(xe, !err);
- xe_device_mem_access_put(xe);
}
static const struct xe_pat_ops xehpc_pat_ops = {
@@ -269,7 +263,6 @@ static void xelpg_dump(struct xe_gt *gt, struct drm_printer *p)
struct xe_device *xe = gt_to_xe(gt);
int i, err;
- xe_device_mem_access_get(xe);
err = xe_force_wake_get(gt_to_fw(gt), XE_FW_GT);
if (err)
goto err_fw;
@@ -292,7 +285,6 @@ static void xelpg_dump(struct xe_gt *gt, struct drm_printer *p)
err = xe_force_wake_put(gt_to_fw(gt), XE_FW_GT);
err_fw:
xe_assert(xe, !err);
- xe_device_mem_access_put(xe);
}
/*
@@ -325,7 +317,6 @@ static void xe2_dump(struct xe_gt *gt, struct drm_printer *p)
int i, err;
u32 pat;
- xe_device_mem_access_get(xe);
err = xe_force_wake_get(gt_to_fw(gt), XE_FW_GT);
if (err)
goto err_fw;
@@ -370,7 +361,6 @@ static void xe2_dump(struct xe_gt *gt, struct drm_printer *p)
err = xe_force_wake_put(gt_to_fw(gt), XE_FW_GT);
err_fw:
xe_assert(xe, !err);
- xe_device_mem_access_put(xe);
}
static const struct xe_pat_ops xe2_pat_ops = {
--
2.43.0
^ permalink raw reply related [flat|nested] 26+ messages in thread* ✓ CI.Patch_applied: success for series starting with [01/14] drm/xe: Document Xe PM component
2024-02-15 19:34 [PATCH 01/14] drm/xe: Document Xe PM component Rodrigo Vivi
` (12 preceding siblings ...)
2024-02-15 19:34 ` [PATCH 14/14] drm/xe: Remove useless mem_access on PAT dumps Rodrigo Vivi
@ 2024-02-15 20:04 ` Patchwork
2024-02-15 20:05 ` ✓ CI.checkpatch: " Patchwork
` (3 subsequent siblings)
17 siblings, 0 replies; 26+ messages in thread
From: Patchwork @ 2024-02-15 20:04 UTC (permalink / raw)
To: Rodrigo Vivi; +Cc: intel-xe
== Series Details ==
Series: series starting with [01/14] drm/xe: Document Xe PM component
URL : https://patchwork.freedesktop.org/series/129970/
State : success
== Summary ==
=== Applying kernel patches on branch 'drm-tip' with base: ===
Base commit: 6d3abf8f7 drm-tip: 2024y-02m-15d-16h-35m-05s UTC integration manifest
=== git am output follows ===
Applying: drm/xe: Document Xe PM component
Applying: drm/xe: Convert mem_access assertion towards the runtime_pm state
Applying: drm/xe: Runtime PM wake on every IOCTL
Applying: drm/xe: Convert kunit tests from mem_access to xe_pm_runtime
Applying: drm/xe: Runtime PM wake on every sysfs call
Applying: drm/xe: Remove mem_access from guc_pc calls
Applying: drm/xe: Runtime PM wake on every debugfs call
Applying: drm/xe: Replace dma_buf mem_access per direct xe_pm_runtime calls
Applying: drm/xe: Convert hwmon from mem_access to xe_pm_runtime calls
Applying: drm/xe: Remove useless mem_access protection for query ioctls
Applying: drm/xe: Convert gsc_work from mem_access to xe_pm_runtime
Applying: drm/xe: Remove mem_access from suspend and resume functions
Applying: drm/xe: Convert gt_reset from mem_access to xe_pm_runtime
Applying: drm/xe: Remove useless mem_access on PAT dumps
^ permalink raw reply [flat|nested] 26+ messages in thread* ✓ CI.checkpatch: success for series starting with [01/14] drm/xe: Document Xe PM component
2024-02-15 19:34 [PATCH 01/14] drm/xe: Document Xe PM component Rodrigo Vivi
` (13 preceding siblings ...)
2024-02-15 20:04 ` ✓ CI.Patch_applied: success for series starting with [01/14] drm/xe: Document Xe PM component Patchwork
@ 2024-02-15 20:05 ` Patchwork
2024-02-15 20:05 ` ✗ CI.KUnit: failure " Patchwork
` (2 subsequent siblings)
17 siblings, 0 replies; 26+ messages in thread
From: Patchwork @ 2024-02-15 20:05 UTC (permalink / raw)
To: Rodrigo Vivi; +Cc: intel-xe
== Series Details ==
Series: series starting with [01/14] drm/xe: Document Xe PM component
URL : https://patchwork.freedesktop.org/series/129970/
State : success
== Summary ==
+ KERNEL=/kernel
+ git clone https://gitlab.freedesktop.org/drm/maintainer-tools mt
Cloning into 'mt'...
warning: redirecting to https://gitlab.freedesktop.org/drm/maintainer-tools.git/
+ git -C mt rev-list -n1 origin/master
35591fb8b4d5305b37ce31483f85ac0956eaa536
+ cd /kernel
+ git config --global --add safe.directory /kernel
+ git log -n1
commit aaee5ca327b76110bf1c46a053177c4287f368cb
Author: Rodrigo Vivi <rodrigo.vivi@intel.com>
Date: Thu Feb 15 14:34:30 2024 -0500
drm/xe: Remove useless mem_access on PAT dumps
PAT dumps are already protected by the xe_pm_runtime_{get,put}
around the debugfs call. So, these can be removed.
Signed-off-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
Reviewed-by: Matthew Auld <matthew.auld@intel.com>
+ /mt/dim checkpatch 6d3abf8f7f55420cf53e9ed344872c459ecfd0ed drm-intel
b58c30d39 drm/xe: Document Xe PM component
85900407f drm/xe: Convert mem_access assertion towards the runtime_pm state
a65d23c1a drm/xe: Runtime PM wake on every IOCTL
bb2209c14 drm/xe: Convert kunit tests from mem_access to xe_pm_runtime
8adfa4bf2 drm/xe: Runtime PM wake on every sysfs call
58747853e drm/xe: Remove mem_access from guc_pc calls
c9fb1a10c drm/xe: Runtime PM wake on every debugfs call
e5ae8b381 drm/xe: Replace dma_buf mem_access per direct xe_pm_runtime calls
526c07039 drm/xe: Convert hwmon from mem_access to xe_pm_runtime calls
6e1ee37ec drm/xe: Remove useless mem_access protection for query ioctls
285e7835b drm/xe: Convert gsc_work from mem_access to xe_pm_runtime
ca6090351 drm/xe: Remove mem_access from suspend and resume functions
8b7624f0a drm/xe: Convert gt_reset from mem_access to xe_pm_runtime
aaee5ca32 drm/xe: Remove useless mem_access on PAT dumps
^ permalink raw reply [flat|nested] 26+ messages in thread* ✗ CI.KUnit: failure for series starting with [01/14] drm/xe: Document Xe PM component
2024-02-15 19:34 [PATCH 01/14] drm/xe: Document Xe PM component Rodrigo Vivi
` (14 preceding siblings ...)
2024-02-15 20:05 ` ✓ CI.checkpatch: " Patchwork
@ 2024-02-15 20:05 ` Patchwork
2024-02-21 12:07 ` [PATCH 01/14] " Francois Dugast
2024-02-21 19:05 ` ✗ CI.Patch_applied: failure for series starting with [01/14] drm/xe: Document Xe PM component (rev2) Patchwork
17 siblings, 0 replies; 26+ messages in thread
From: Patchwork @ 2024-02-15 20:05 UTC (permalink / raw)
To: Rodrigo Vivi; +Cc: intel-xe
== Series Details ==
Series: series starting with [01/14] drm/xe: Document Xe PM component
URL : https://patchwork.freedesktop.org/series/129970/
State : failure
== Summary ==
+ trap cleanup EXIT
+ /kernel/tools/testing/kunit/kunit.py run --kunitconfig /kernel/drivers/gpu/drm/xe/.kunitconfig
ERROR:root:../arch/x86/um/user-offsets.c:17:6: warning: no previous prototype for ‘foo’ [-Wmissing-prototypes]
17 | void foo(void)
| ^~~
In file included from ../arch/um/kernel/asm-offsets.c:1:
../arch/x86/um/shared/sysdep/kernel-offsets.h:9:6: warning: no previous prototype for ‘foo’ [-Wmissing-prototypes]
9 | void foo(void)
| ^~~
../arch/x86/um/bugs_64.c:9:6: warning: no previous prototype for ‘arch_check_bugs’ [-Wmissing-prototypes]
9 | void arch_check_bugs(void)
| ^~~~~~~~~~~~~~~
../arch/x86/um/bugs_64.c:13:6: warning: no previous prototype for ‘arch_examine_signal’ [-Wmissing-prototypes]
13 | void arch_examine_signal(int sig, struct uml_pt_regs *regs)
| ^~~~~~~~~~~~~~~~~~~
../arch/x86/um/fault.c:18:5: warning: no previous prototype for ‘arch_fixup’ [-Wmissing-prototypes]
18 | int arch_fixup(unsigned long address, struct uml_pt_regs *regs)
| ^~~~~~~~~~
../arch/x86/um/os-Linux/mcontext.c:7:6: warning: no previous prototype for ‘get_regs_from_mc’ [-Wmissing-prototypes]
7 | void get_regs_from_mc(struct uml_pt_regs *regs, mcontext_t *mc)
| ^~~~~~~~~~~~~~~~
../arch/x86/um/vdso/um_vdso.c:16:5: warning: no previous prototype for ‘__vdso_clock_gettime’ [-Wmissing-prototypes]
16 | int __vdso_clock_gettime(clockid_t clock, struct __kernel_old_timespec *ts)
| ^~~~~~~~~~~~~~~~~~~~
../arch/x86/um/vdso/um_vdso.c:30:5: warning: no previous prototype for ‘__vdso_gettimeofday’ [-Wmissing-prototypes]
30 | int __vdso_gettimeofday(struct __kernel_old_timeval *tv, struct timezone *tz)
| ^~~~~~~~~~~~~~~~~~~
../arch/x86/um/vdso/um_vdso.c:44:21: warning: no previous prototype for ‘__vdso_time’ [-Wmissing-prototypes]
44 | __kernel_old_time_t __vdso_time(__kernel_old_time_t *t)
| ^~~~~~~~~~~
../arch/x86/um/vdso/um_vdso.c:57:1: warning: no previous prototype for ‘__vdso_getcpu’ [-Wmissing-prototypes]
57 | __vdso_getcpu(unsigned *cpu, unsigned *node, struct getcpu_cache *unused)
| ^~~~~~~~~~~~~
../arch/x86/um/os-Linux/registers.c:146:15: warning: no previous prototype for ‘get_thread_reg’ [-Wmissing-prototypes]
146 | unsigned long get_thread_reg(int reg, jmp_buf *buf)
| ^~~~~~~~~~~~~~
../arch/um/os-Linux/skas/process.c:107:6: warning: no previous prototype for ‘wait_stub_done’ [-Wmissing-prototypes]
107 | void wait_stub_done(int pid)
| ^~~~~~~~~~~~~~
../arch/um/os-Linux/skas/process.c:683:6: warning: no previous prototype for ‘__switch_mm’ [-Wmissing-prototypes]
683 | void __switch_mm(struct mm_id *mm_idp)
| ^~~~~~~~~~~
../arch/x86/um/ptrace_64.c:111:5: warning: no previous prototype for ‘poke_user’ [-Wmissing-prototypes]
111 | int poke_user(struct task_struct *child, long addr, long data)
| ^~~~~~~~~
../arch/x86/um/ptrace_64.c:171:5: warning: no previous prototype for ‘peek_user’ [-Wmissing-prototypes]
171 | int peek_user(struct task_struct *child, long addr, long data)
| ^~~~~~~~~
../arch/um/kernel/skas/mmu.c:17:5: warning: no previous prototype for ‘init_new_context’ [-Wmissing-prototypes]
17 | int init_new_context(struct task_struct *task, struct mm_struct *mm)
| ^~~~~~~~~~~~~~~~
../arch/um/kernel/skas/mmu.c:60:6: warning: no previous prototype for ‘destroy_context’ [-Wmissing-prototypes]
60 | void destroy_context(struct mm_struct *mm)
| ^~~~~~~~~~~~~~~
../arch/um/os-Linux/main.c:187:7: warning: no previous prototype for ‘__wrap_malloc’ [-Wmissing-prototypes]
187 | void *__wrap_malloc(int size)
| ^~~~~~~~~~~~~
../arch/um/os-Linux/main.c:208:7: warning: no previous prototype for ‘__wrap_calloc’ [-Wmissing-prototypes]
208 | void *__wrap_calloc(int n, int size)
| ^~~~~~~~~~~~~
../arch/um/os-Linux/main.c:222:6: warning: no previous prototype for ‘__wrap_free’ [-Wmissing-prototypes]
222 | void __wrap_free(void *ptr)
| ^~~~~~~~~~~
../arch/um/kernel/skas/process.c:36:12: warning: no previous prototype for ‘start_uml’ [-Wmissing-prototypes]
36 | int __init start_uml(void)
| ^~~~~~~~~
../arch/um/os-Linux/mem.c:28:6: warning: no previous prototype for ‘kasan_map_memory’ [-Wmissing-prototypes]
28 | void kasan_map_memory(void *start, size_t len)
| ^~~~~~~~~~~~~~~~
../arch/um/os-Linux/mem.c:212:13: warning: no previous prototype for ‘check_tmpexec’ [-Wmissing-prototypes]
212 | void __init check_tmpexec(void)
| ^~~~~~~~~~~~~
../arch/x86/um/signal.c:560:6: warning: no previous prototype for ‘sys_rt_sigreturn’ [-Wmissing-prototypes]
560 | long sys_rt_sigreturn(void)
| ^~~~~~~~~~~~~~~~
../arch/um/os-Linux/signal.c:75:6: warning: no previous prototype for ‘sig_handler’ [-Wmissing-prototypes]
75 | void sig_handler(int sig, struct siginfo *si, mcontext_t *mc)
| ^~~~~~~~~~~
../arch/um/os-Linux/signal.c:111:6: warning: no previous prototype for ‘timer_alarm_handler’ [-Wmissing-prototypes]
111 | void timer_alarm_handler(int sig, struct siginfo *unused_si, mcontext_t *mc)
| ^~~~~~~~~~~~~~~~~~~
../arch/um/os-Linux/start_up.c:301:12: warning: no previous prototype for ‘parse_iomem’ [-Wmissing-prototypes]
301 | int __init parse_iomem(char *str, int *add)
| ^~~~~~~~~~~
../arch/x86/um/syscalls_64.c:48:6: warning: no previous prototype for ‘arch_switch_to’ [-Wmissing-prototypes]
48 | void arch_switch_to(struct task_struct *to)
| ^~~~~~~~~~~~~~
../arch/um/kernel/reboot.c:45:6: warning: no previous prototype for ‘machine_restart’ [-Wmissing-prototypes]
45 | void machine_restart(char * __unused)
| ^~~~~~~~~~~~~~~
../arch/um/kernel/reboot.c:51:6: warning: no previous prototype for ‘machine_power_off’ [-Wmissing-prototypes]
51 | void machine_power_off(void)
| ^~~~~~~~~~~~~~~~~
../arch/um/kernel/reboot.c:57:6: warning: no previous prototype for ‘machine_halt’ [-Wmissing-prototypes]
57 | void machine_halt(void)
| ^~~~~~~~~~~~
../arch/um/kernel/mem.c:202:8: warning: no previous prototype for ‘pgd_alloc’ [-Wmissing-prototypes]
202 | pgd_t *pgd_alloc(struct mm_struct *mm)
| ^~~~~~~~~
../arch/um/kernel/mem.c:215:7: warning: no previous prototype for ‘uml_kmalloc’ [-Wmissing-prototypes]
215 | void *uml_kmalloc(int size, int flags)
| ^~~~~~~~~~~
../arch/um/kernel/process.c:51:5: warning: no previous prototype for ‘pid_to_processor_id’ [-Wmissing-prototypes]
51 | int pid_to_processor_id(int pid)
| ^~~~~~~~~~~~~~~~~~~
../arch/um/kernel/process.c:87:7: warning: no previous prototype for ‘__switch_to’ [-Wmissing-prototypes]
87 | void *__switch_to(struct task_struct *from, struct task_struct *to)
| ^~~~~~~~~~~
../arch/um/kernel/process.c:140:6: warning: no previous prototype for ‘fork_handler’ [-Wmissing-prototypes]
140 | void fork_handler(void)
| ^~~~~~~~~~~~
../arch/um/kernel/process.c:217:6: warning: no previous prototype for ‘arch_cpu_idle’ [-Wmissing-prototypes]
217 | void arch_cpu_idle(void)
| ^~~~~~~~~~~~~
../arch/um/kernel/process.c:253:5: warning: no previous prototype for ‘copy_to_user_proc’ [-Wmissing-prototypes]
253 | int copy_to_user_proc(void __user *to, void *from, int size)
| ^~~~~~~~~~~~~~~~~
../arch/um/kernel/process.c:263:5: warning: no previous prototype for ‘clear_user_proc’ [-Wmissing-prototypes]
263 | int clear_user_proc(void __user *buf, int size)
| ^~~~~~~~~~~~~~~
../arch/um/kernel/process.c:271:6: warning: no previous prototype for ‘set_using_sysemu’ [-Wmissing-prototypes]
271 | void set_using_sysemu(int value)
| ^~~~~~~~~~~~~~~~
../arch/um/kernel/process.c:278:5: warning: no previous prototype for ‘get_using_sysemu’ [-Wmissing-prototypes]
278 | int get_using_sysemu(void)
| ^~~~~~~~~~~~~~~~
../arch/um/kernel/process.c:316:12: warning: no previous prototype for ‘make_proc_sysemu’ [-Wmissing-prototypes]
316 | int __init make_proc_sysemu(void)
| ^~~~~~~~~~~~~~~~
../arch/um/kernel/process.c:348:15: warning: no previous prototype for ‘arch_align_stack’ [-Wmissing-prototypes]
348 | unsigned long arch_align_stack(unsigned long sp)
| ^~~~~~~~~~~~~~~~
../arch/um/kernel/tlb.c:579:6: warning: no previous prototype for ‘flush_tlb_mm_range’ [-Wmissing-prototypes]
579 | void flush_tlb_mm_range(struct mm_struct *mm, unsigned long start,
| ^~~~~~~~~~~~~~~~~~
../arch/um/kernel/tlb.c:594:6: warning: no previous prototype for ‘force_flush_all’ [-Wmissing-prototypes]
594 | void force_flush_all(void)
| ^~~~~~~~~~~~~~~
../arch/um/kernel/kmsg_dump.c:60:12: warning: no previous prototype for ‘kmsg_dumper_stdout_init’ [-Wmissing-prototypes]
60 | int __init kmsg_dumper_stdout_init(void)
| ^~~~~~~~~~~~~~~~~~~~~~~
../arch/um/kernel/um_arch.c:408:19: warning: no previous prototype for ‘read_initrd’ [-Wmissing-prototypes]
408 | int __init __weak read_initrd(void)
| ^~~~~~~~~~~
../arch/um/kernel/um_arch.c:461:7: warning: no previous prototype for ‘text_poke’ [-Wmissing-prototypes]
461 | void *text_poke(void *addr, const void *opcode, size_t len)
| ^~~~~~~~~
../arch/um/kernel/um_arch.c:473:6: warning: no previous prototype for ‘text_poke_sync’ [-Wmissing-prototypes]
473 | void text_poke_sync(void)
| ^~~~~~~~~~~~~~
In file included from ../include/uapi/linux/posix_types.h:5,
from ../include/uapi/linux/types.h:14,
from ../include/linux/types.h:6,
from ../include/linux/kasan-checks.h:5,
from ../include/asm-generic/rwonce.h:26,
from ./arch/x86/include/generated/asm/rwonce.h:1,
from ../include/linux/compiler.h:251,
from ../include/linux/array_size.h:5,
from ../include/linux/kernel.h:16,
from ../include/linux/interrupt.h:6,
from ../include/drm/drm_util.h:35,
from ../drivers/gpu/drm/xe/xe_device.h:12,
from ../drivers/gpu/drm/xe/xe_device.c:6:
../drivers/gpu/drm/xe/xe_device.c: In function ‘xe_drm_compat_ioctl’:
../include/linux/stddef.h:8:14: error: called object is not a function or function pointer
8 | #define NULL ((void *)0)
| ^
../include/drm/drm_ioctl.h:165:26: note: in expansion of macro ‘NULL’
165 | #define drm_compat_ioctl NULL
| ^~~~
../drivers/gpu/drm/xe/xe_device.c:166:9: note: in expansion of macro ‘drm_compat_ioctl’
166 | ret = drm_compat_ioctl(file, cmd, arg);
| ^~~~~~~~~~~~~~~~
make[7]: *** [../scripts/Makefile.build:243: drivers/gpu/drm/xe/xe_device.o] Error 1
make[7]: *** Waiting for unfinished jobs....
make[6]: *** [../scripts/Makefile.build:481: drivers/gpu/drm/xe] Error 2
make[6]: *** Waiting for unfinished jobs....
make[5]: *** [../scripts/Makefile.build:481: drivers/gpu/drm] Error 2
make[4]: *** [../scripts/Makefile.build:481: drivers/gpu] Error 2
make[4]: *** Waiting for unfinished jobs....
make[3]: *** [../scripts/Makefile.build:481: drivers] Error 2
make[3]: *** Waiting for unfinished jobs....
../lib/iomap.c:156:5: warning: no previous prototype for ‘ioread64_lo_hi’ [-Wmissing-prototypes]
156 | u64 ioread64_lo_hi(const void __iomem *addr)
| ^~~~~~~~~~~~~~
../lib/iomap.c:163:5: warning: no previous prototype for ‘ioread64_hi_lo’ [-Wmissing-prototypes]
163 | u64 ioread64_hi_lo(const void __iomem *addr)
| ^~~~~~~~~~~~~~
../lib/iomap.c:170:5: warning: no previous prototype for ‘ioread64be_lo_hi’ [-Wmissing-prototypes]
170 | u64 ioread64be_lo_hi(const void __iomem *addr)
| ^~~~~~~~~~~~~~~~
../lib/iomap.c:178:5: warning: no previous prototype for ‘ioread64be_hi_lo’ [-Wmissing-prototypes]
178 | u64 ioread64be_hi_lo(const void __iomem *addr)
| ^~~~~~~~~~~~~~~~
../lib/iomap.c:264:6: warning: no previous prototype for ‘iowrite64_lo_hi’ [-Wmissing-prototypes]
264 | void iowrite64_lo_hi(u64 val, void __iomem *addr)
| ^~~~~~~~~~~~~~~
../lib/iomap.c:272:6: warning: no previous prototype for ‘iowrite64_hi_lo’ [-Wmissing-prototypes]
272 | void iowrite64_hi_lo(u64 val, void __iomem *addr)
| ^~~~~~~~~~~~~~~
../lib/iomap.c:280:6: warning: no previous prototype for ‘iowrite64be_lo_hi’ [-Wmissing-prototypes]
280 | void iowrite64be_lo_hi(u64 val, void __iomem *addr)
| ^~~~~~~~~~~~~~~~~
../lib/iomap.c:288:6: warning: no previous prototype for ‘iowrite64be_hi_lo’ [-Wmissing-prototypes]
288 | void iowrite64be_hi_lo(u64 val, void __iomem *addr)
| ^~~~~~~~~~~~~~~~~
make[2]: *** [/kernel/Makefile:1921: .] Error 2
make[1]: *** [/kernel/Makefile:240: __sub-make] Error 2
make: *** [Makefile:240: __sub-make] Error 2
[20:05:04] Configuring KUnit Kernel ...
Generating .config ...
Populating config with:
$ make ARCH=um O=.kunit olddefconfig
[20:05:08] Building KUnit Kernel ...
Populating config with:
$ make ARCH=um O=.kunit olddefconfig
Building with:
$ make ARCH=um O=.kunit --jobs=48
+ cleanup
++ stat -c %u:%g /kernel
+ chown -R 1003:1003 /kernel
^ permalink raw reply [flat|nested] 26+ messages in thread* Re: [PATCH 01/14] drm/xe: Document Xe PM component
2024-02-15 19:34 [PATCH 01/14] drm/xe: Document Xe PM component Rodrigo Vivi
` (15 preceding siblings ...)
2024-02-15 20:05 ` ✗ CI.KUnit: failure " Patchwork
@ 2024-02-21 12:07 ` Francois Dugast
2024-02-21 14:41 ` Gupta, Anshuman
2024-02-21 19:05 ` ✗ CI.Patch_applied: failure for series starting with [01/14] drm/xe: Document Xe PM component (rev2) Patchwork
17 siblings, 1 reply; 26+ messages in thread
From: Francois Dugast @ 2024-02-21 12:07 UTC (permalink / raw)
To: Rodrigo Vivi; +Cc: intel-xe, Matthew Auld, Anshuman Gupta
On Thu, Feb 15, 2024 at 02:34:17PM -0500, Rodrigo Vivi wrote:
> Replace outdated information with a proper PM documentation.
> Already establish the rules for the runtime PM get and put that
> Xe needs to follow.
>
> Also add missing function documentation to all the "exported" functions.
>
> v2: updated after Francois' feedback.
> s/grater/greater (Matt)
>
> Cc: Matthew Auld <matthew.auld@intel.com>
> Cc: Anshuman Gupta <anshuman.gupta@intel.com>
> Signed-off-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
> Acked-by: Francois Dugast <francois.dugast@intel.com>
> ---
> drivers/gpu/drm/xe/xe_pm.c | 108 +++++++++++++++++++++++++++++++++----
> 1 file changed, 97 insertions(+), 11 deletions(-)
>
> diff --git a/drivers/gpu/drm/xe/xe_pm.c b/drivers/gpu/drm/xe/xe_pm.c
> index ab283e9a8b4e..64ffb9a35448 100644
> --- a/drivers/gpu/drm/xe/xe_pm.c
> +++ b/drivers/gpu/drm/xe/xe_pm.c
> @@ -25,21 +25,46 @@
> /**
> * DOC: Xe Power Management
> *
> - * Xe PM shall be guided by the simplicity.
> - * Use the simplest hook options whenever possible.
> - * Let's not reinvent the runtime_pm references and hooks.
> - * Shall have a clear separation of display and gt underneath this component.
> + * Xe PM implements the main routines for both system level suspend states and
> + * for the opportunistic runtime suspend states.
> *
> - * What's next:
> + * System Level Suspend (S-States) - In general this is OS initiated suspend
> + * driven by ACPI for achieving S0ix (a.k.a. S2idle, freeze), S3 (suspend to ram),
> + * S4 (disk). The main functions here are `xe_pm_suspend` and `xe_pm_resume`. They
> + * are the main point for the suspend to and resume from these states.
> *
> - * For now s2idle and s3 are only working in integrated devices. The next step
> - * is to iterate through all VRAM's BO backing them up into the system memory
> - * before allowing the system suspend.
> + * Runtime Suspend (D-States) - This is the opportunistic PCIe device low power
> + * state D3. Xe PM component provides `xe_pm_runtime_suspend` and
> + * `xe_pm_runtime_resume` systems that PCI subsystem will call before transition
> + * to D3. Also, Xe PM provides get and put functions that Xe driver will use to
> + * indicate activity. In order to avoid locking complications with the memory
> + * management, whenever possible, these get and put functions needs to be called
> + * from the higher/outer levels.
> *
> - * Also runtime_pm needs to be here from the beginning.
> + * The main cases that need to be protected from the outer levels are: IOCTL,
> + * sysfs, debugfs, dma-buf sharing, GPU execution.
> *
> - * RC6/RPS are also critical PM features. Let's start with GuCRC and GuC SLPC
> - * and no wait boost. Frequency optimizations should come on a next stage.
> + * PCI D3 is special and can mean D3hot, where Vcc power is on for keeping memory
> + * alive and quicker low latency resume or D3Cold where Vcc power is off for
> + * better power savings.
> + * The Vcc control of PCI hierarchy can only be controlled at the PCI root port
> + * level, while the device driver can be behind multiple bridges/switches and
> + * paired with other devices. For this reason, the PCI subsystem cannot perform
> + * the transition towards D3Cold. The lowest runtime PM possible from the PCI
> + * subsystem is D3hot. Then, if all these paired devices in the same root port
> + * are in D3hot, ACPI will assist here and run its own methods (_PR3 and _OFF)
> + * to perform the transition from D3hot to D3cold. Xe may disallow this
> + * transition by calling pci_d3cold_disable(root_pdev) before going to runtime
> + * suspend. It will be based on runtime conditions such as VRAM usage for a
> + * quick and low latency resume for instance.
> + *
> + * Intel systems are capable of taking the system to S0ix when devices are on
> + * D3hot through the runtime PM. This is also called as 'opportunistic-S0iX'.
> + * But in this case, the `xe_pm_suspend` and `xe_pm_resume` won't be called for
> + * S0ix.
> + *
> + * This component is no responsible for GT idleness (RC6) nor GT frequency
Isn't it s/no/not/? Or s/no/neither/ + s/nor/nor for/? In any case:
Reviewed-by: Francois Dugast <francois.dugast@intel.com>
Francois
> + * management (RPS).
> */
>
> /**
> @@ -178,6 +203,12 @@ void xe_pm_init_early(struct xe_device *xe)
> drmm_mutex_init(&xe->drm, &xe->mem_access.vram_userfault.lock);
> }
>
> +/**
> + * xe_pm_init - Initialize Xe Power Management
> + * @xe: xe device instance
> + *
> + * This component is responsible for System and Device sleep states.
> + */
> void xe_pm_init(struct xe_device *xe)
> {
> /* For now suspend/resume is only allowed with GuC */
> @@ -196,6 +227,10 @@ void xe_pm_init(struct xe_device *xe)
> xe_pm_runtime_init(xe);
> }
>
> +/**
> + * xe_pm_runtime_fini - Finalize Runtime PM
> + * @xe: xe device instance
> + */
> void xe_pm_runtime_fini(struct xe_device *xe)
> {
> struct device *dev = xe->drm.dev;
> @@ -225,6 +260,12 @@ struct task_struct *xe_pm_read_callback_task(struct xe_device *xe)
> return READ_ONCE(xe->pm_callback_task);
> }
>
> +/**
> + * xe_pm_runtime_suspend - Prepare our device for D3hot/D3Cold
> + * @xe: xe device instance
> + *
> + * Returns 0 for success, negative error code otherwise.
> + */
> int xe_pm_runtime_suspend(struct xe_device *xe)
> {
> struct xe_bo *bo, *on;
> @@ -290,6 +331,12 @@ int xe_pm_runtime_suspend(struct xe_device *xe)
> return err;
> }
>
> +/**
> + * xe_pm_runtime_resume - Waking up from D3hot/D3Cold
> + * @xe: xe device instance
> + *
> + * Returns 0 for success, negative error code otherwise.
> + */
> int xe_pm_runtime_resume(struct xe_device *xe)
> {
> struct xe_gt *gt;
> @@ -341,22 +388,47 @@ int xe_pm_runtime_resume(struct xe_device *xe)
> return err;
> }
>
> +/**
> + * xe_pm_runtime_get - Get a runtime_pm reference and resume synchronously
> + * @xe: xe device instance
> + *
> + * Returns: Any number greater than or equal to 0 for success, negative error
> + * code otherwise.
> + */
> int xe_pm_runtime_get(struct xe_device *xe)
> {
> return pm_runtime_get_sync(xe->drm.dev);
> }
>
> +/**
> + * xe_pm_runtime_put - Put the runtime_pm reference back and mark as idle
> + * @xe: xe device instance
> + *
> + * Returns: Any number greater than or equal to 0 for success, negative error
> + * code otherwise.
> + */
> int xe_pm_runtime_put(struct xe_device *xe)
> {
> pm_runtime_mark_last_busy(xe->drm.dev);
> return pm_runtime_put(xe->drm.dev);
> }
>
> +/**
> + * xe_pm_runtime_get_if_active - Get a runtime_pm reference if device active
> + * @xe: xe device instance
> + *
> + * Returns: Any number greater than or equal to 0 for success, negative error
> + * code otherwise.
> + */
> int xe_pm_runtime_get_if_active(struct xe_device *xe)
> {
> return pm_runtime_get_if_active(xe->drm.dev, true);
> }
>
> +/**
> + * xe_pm_assert_unbounded_bridge - Disable PM on unbounded pcie parent bridge
> + * @xe: xe device instance
> + */
> void xe_pm_assert_unbounded_bridge(struct xe_device *xe)
> {
> struct pci_dev *pdev = to_pci_dev(xe->drm.dev);
> @@ -371,6 +443,13 @@ void xe_pm_assert_unbounded_bridge(struct xe_device *xe)
> }
> }
>
> +/**
> + * xe_pm_set_vram_threshold - Set a vram threshold for allowing/blocking D3Cold
> + * @xe: xe device instance
> + * @threshold: VRAM size in bites for the D3cold threshold
> + *
> + * Returns 0 for success, negative error code otherwise.
> + */
> int xe_pm_set_vram_threshold(struct xe_device *xe, u32 threshold)
> {
> struct ttm_resource_manager *man;
> @@ -395,6 +474,13 @@ int xe_pm_set_vram_threshold(struct xe_device *xe, u32 threshold)
> return 0;
> }
>
> +/**
> + * xe_pm_d3cold_allowed_toggle - Check conditions to toggle d3cold.allowed
> + * @xe: xe device instance
> + *
> + * To be called during runtime_pm idle callback.
> + * Check for all the D3Cold conditions ahead of runtime suspend.
> + */
> void xe_pm_d3cold_allowed_toggle(struct xe_device *xe)
> {
> struct ttm_resource_manager *man;
> --
> 2.43.0
>
^ permalink raw reply [flat|nested] 26+ messages in thread* RE: [PATCH 01/14] drm/xe: Document Xe PM component
2024-02-21 12:07 ` [PATCH 01/14] " Francois Dugast
@ 2024-02-21 14:41 ` Gupta, Anshuman
2024-02-21 19:00 ` Rodrigo Vivi
0 siblings, 1 reply; 26+ messages in thread
From: Gupta, Anshuman @ 2024-02-21 14:41 UTC (permalink / raw)
To: Dugast, Francois, Vivi, Rodrigo
Cc: intel-xe@lists.freedesktop.org, Auld, Matthew
> -----Original Message-----
> From: Dugast, Francois <francois.dugast@intel.com>
> Sent: Wednesday, February 21, 2024 5:38 PM
> To: Vivi, Rodrigo <rodrigo.vivi@intel.com>
> Cc: intel-xe@lists.freedesktop.org; Auld, Matthew <matthew.auld@intel.com>;
> Gupta, Anshuman <anshuman.gupta@intel.com>
> Subject: Re: [PATCH 01/14] drm/xe: Document Xe PM component
>
> On Thu, Feb 15, 2024 at 02:34:17PM -0500, Rodrigo Vivi wrote:
> > Replace outdated information with a proper PM documentation.
> > Already establish the rules for the runtime PM get and put that Xe
> > needs to follow.
> >
> > Also add missing function documentation to all the "exported" functions.
> >
> > v2: updated after Francois' feedback.
> > s/grater/greater (Matt)
> >
> > Cc: Matthew Auld <matthew.auld@intel.com>
> > Cc: Anshuman Gupta <anshuman.gupta@intel.com>
> > Signed-off-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
> > Acked-by: Francois Dugast <francois.dugast@intel.com>
> > ---
> > drivers/gpu/drm/xe/xe_pm.c | 108
> > +++++++++++++++++++++++++++++++++----
> > 1 file changed, 97 insertions(+), 11 deletions(-)
> >
> > diff --git a/drivers/gpu/drm/xe/xe_pm.c b/drivers/gpu/drm/xe/xe_pm.c
> > index ab283e9a8b4e..64ffb9a35448 100644
> > --- a/drivers/gpu/drm/xe/xe_pm.c
> > +++ b/drivers/gpu/drm/xe/xe_pm.c
> > @@ -25,21 +25,46 @@
> > /**
> > * DOC: Xe Power Management
> > *
> > - * Xe PM shall be guided by the simplicity.
> > - * Use the simplest hook options whenever possible.
> > - * Let's not reinvent the runtime_pm references and hooks.
> > - * Shall have a clear separation of display and gt underneath this component.
> > + * Xe PM implements the main routines for both system level suspend
> > + states and
> > + * for the opportunistic runtime suspend states.
> > *
> > - * What's next:
> > + * System Level Suspend (S-States) - In general this is OS initiated
> > + suspend
> > + * driven by ACPI for achieving S0ix (a.k.a. S2idle, freeze), S3
> > + (suspend to ram),
> > + * S4 (disk). The main functions here are `xe_pm_suspend` and
> > + `xe_pm_resume`. They
> > + * are the main point for the suspend to and resume from these states.
> > *
> > - * For now s2idle and s3 are only working in integrated devices. The
> > next step
> > - * is to iterate through all VRAM's BO backing them up into the
> > system memory
> > - * before allowing the system suspend.
> > + * Runtime Suspend (D-States) - This is the opportunistic PCIe device
> > + low power
> > + * state D3. Xe PM component provides `xe_pm_runtime_suspend` and
> > + * `xe_pm_runtime_resume` systems that PCI subsystem will call before
> > + transition
> > + * to D3. Also, Xe PM provides get and put functions that Xe driver
> > + will use to
> > + * indicate activity. In order to avoid locking complications with
> > + the memory
> > + * management, whenever possible, these get and put functions needs
> > + to be called
> > + * from the higher/outer levels.
> > *
> > - * Also runtime_pm needs to be here from the beginning.
> > + * The main cases that need to be protected from the outer levels
> > + are: IOCTL,
> > + * sysfs, debugfs, dma-buf sharing, GPU execution.
> > *
> > - * RC6/RPS are also critical PM features. Let's start with GuCRC and
> > GuC SLPC
> > - * and no wait boost. Frequency optimizations should come on a next stage.
> > + * PCI D3 is special and can mean D3hot, where Vcc power is on for
> > + keeping memory
> > + * alive and quicker low latency resume or D3Cold where Vcc power is
> > + off for
> > + * better power savings.
> > + * The Vcc control of PCI hierarchy can only be controlled at the PCI
> > + root port
> > + * level, while the device driver can be behind multiple
> > + bridges/switches and
> > + * paired with other devices. For this reason, the PCI subsystem
> > + cannot perform
> > + * the transition towards D3Cold. The lowest runtime PM possible from
> > + the PCI
> > + * subsystem is D3hot. Then, if all these paired devices in the same
> > + root port
> > + * are in D3hot, ACPI will assist here and run its own methods (_PR3
> > + and _OFF)
> > + * to perform the transition from D3hot to D3cold. Xe may disallow
> > + this
> > + * transition by calling pci_d3cold_disable(root_pdev) before going
> > + to runtime
> > + * suspend. It will be based on runtime conditions such as VRAM usage
> > + for a
> > + * quick and low latency resume for instance.
> > + *
> > + * Intel systems are capable of taking the system to S0ix when
> > + devices are on
> > + * D3hot through the runtime PM. This is also called as 'opportunistic-S0iX'.
> > + * But in this case, the `xe_pm_suspend` and `xe_pm_resume` won't be
> > + called for
> > + * S0ix.
Hi Rodrigo,
Sorry of late review comment, was busy with other stuff.
we do need modify the doc slightly.
For integrated graphics D3hot is not necessary to achieve for the host s0ix, like with PSR panel
PCI device will be in D0 state as KMS CRTC will be active and will held a device wakeref.
AFAIK for discrete card perspective, host s0ix requires PCIe link to be in low power state.
Thanks,
Anshuman Gupta.
> > + *
> > + * This component is no responsible for GT idleness (RC6) nor GT
> > + frequency
>
> Isn't it s/no/not/? Or s/no/neither/ + s/nor/nor for/? In any case:
>
> Reviewed-by: Francois Dugast <francois.dugast@intel.com>
>
> Francois
>
> > + * management (RPS).
> > */
> >
> > /**
> > @@ -178,6 +203,12 @@ void xe_pm_init_early(struct xe_device *xe)
> > drmm_mutex_init(&xe->drm, &xe->mem_access.vram_userfault.lock);
> > }
> >
> > +/**
> > + * xe_pm_init - Initialize Xe Power Management
> > + * @xe: xe device instance
> > + *
> > + * This component is responsible for System and Device sleep states.
> > + */
> > void xe_pm_init(struct xe_device *xe) {
> > /* For now suspend/resume is only allowed with GuC */ @@ -196,6
> > +227,10 @@ void xe_pm_init(struct xe_device *xe)
> > xe_pm_runtime_init(xe);
> > }
> >
> > +/**
> > + * xe_pm_runtime_fini - Finalize Runtime PM
> > + * @xe: xe device instance
> > + */
> > void xe_pm_runtime_fini(struct xe_device *xe) {
> > struct device *dev = xe->drm.dev;
> > @@ -225,6 +260,12 @@ struct task_struct *xe_pm_read_callback_task(struct
> xe_device *xe)
> > return READ_ONCE(xe->pm_callback_task); }
> >
> > +/**
> > + * xe_pm_runtime_suspend - Prepare our device for D3hot/D3Cold
> > + * @xe: xe device instance
> > + *
> > + * Returns 0 for success, negative error code otherwise.
> > + */
> > int xe_pm_runtime_suspend(struct xe_device *xe) {
> > struct xe_bo *bo, *on;
> > @@ -290,6 +331,12 @@ int xe_pm_runtime_suspend(struct xe_device *xe)
> > return err;
> > }
> >
> > +/**
> > + * xe_pm_runtime_resume - Waking up from D3hot/D3Cold
> > + * @xe: xe device instance
> > + *
> > + * Returns 0 for success, negative error code otherwise.
> > + */
> > int xe_pm_runtime_resume(struct xe_device *xe) {
> > struct xe_gt *gt;
> > @@ -341,22 +388,47 @@ int xe_pm_runtime_resume(struct xe_device *xe)
> > return err;
> > }
> >
> > +/**
> > + * xe_pm_runtime_get - Get a runtime_pm reference and resume
> > +synchronously
> > + * @xe: xe device instance
> > + *
> > + * Returns: Any number greater than or equal to 0 for success,
> > +negative error
> > + * code otherwise.
> > + */
> > int xe_pm_runtime_get(struct xe_device *xe) {
> > return pm_runtime_get_sync(xe->drm.dev); }
> >
> > +/**
> > + * xe_pm_runtime_put - Put the runtime_pm reference back and mark as
> > +idle
> > + * @xe: xe device instance
> > + *
> > + * Returns: Any number greater than or equal to 0 for success,
> > +negative error
> > + * code otherwise.
> > + */
> > int xe_pm_runtime_put(struct xe_device *xe) {
> > pm_runtime_mark_last_busy(xe->drm.dev);
> > return pm_runtime_put(xe->drm.dev);
> > }
> >
> > +/**
> > + * xe_pm_runtime_get_if_active - Get a runtime_pm reference if device
> > +active
> > + * @xe: xe device instance
> > + *
> > + * Returns: Any number greater than or equal to 0 for success,
> > +negative error
> > + * code otherwise.
> > + */
> > int xe_pm_runtime_get_if_active(struct xe_device *xe) {
> > return pm_runtime_get_if_active(xe->drm.dev, true); }
> >
> > +/**
> > + * xe_pm_assert_unbounded_bridge - Disable PM on unbounded pcie
> > +parent bridge
> > + * @xe: xe device instance
> > + */
> > void xe_pm_assert_unbounded_bridge(struct xe_device *xe) {
> > struct pci_dev *pdev = to_pci_dev(xe->drm.dev); @@ -371,6 +443,13
> @@
> > void xe_pm_assert_unbounded_bridge(struct xe_device *xe)
> > }
> > }
> >
> > +/**
> > + * xe_pm_set_vram_threshold - Set a vram threshold for
> > +allowing/blocking D3Cold
> > + * @xe: xe device instance
> > + * @threshold: VRAM size in bites for the D3cold threshold
> > + *
> > + * Returns 0 for success, negative error code otherwise.
> > + */
> > int xe_pm_set_vram_threshold(struct xe_device *xe, u32 threshold) {
> > struct ttm_resource_manager *man;
> > @@ -395,6 +474,13 @@ int xe_pm_set_vram_threshold(struct xe_device *xe,
> u32 threshold)
> > return 0;
> > }
> >
> > +/**
> > + * xe_pm_d3cold_allowed_toggle - Check conditions to toggle
> > +d3cold.allowed
> > + * @xe: xe device instance
> > + *
> > + * To be called during runtime_pm idle callback.
> > + * Check for all the D3Cold conditions ahead of runtime suspend.
> > + */
> > void xe_pm_d3cold_allowed_toggle(struct xe_device *xe) {
> > struct ttm_resource_manager *man;
> > --
> > 2.43.0
> >
^ permalink raw reply [flat|nested] 26+ messages in thread* Re: [PATCH 01/14] drm/xe: Document Xe PM component
2024-02-21 14:41 ` Gupta, Anshuman
@ 2024-02-21 19:00 ` Rodrigo Vivi
2024-02-22 15:06 ` Gupta, Anshuman
0 siblings, 1 reply; 26+ messages in thread
From: Rodrigo Vivi @ 2024-02-21 19:00 UTC (permalink / raw)
To: Gupta, Anshuman
Cc: Dugast, Francois, intel-xe@lists.freedesktop.org, Auld, Matthew
On Wed, Feb 21, 2024 at 09:41:44AM -0500, Gupta, Anshuman wrote:
>
>
> > -----Original Message-----
> > From: Dugast, Francois <francois.dugast@intel.com>
> > Sent: Wednesday, February 21, 2024 5:38 PM
> > To: Vivi, Rodrigo <rodrigo.vivi@intel.com>
> > Cc: intel-xe@lists.freedesktop.org; Auld, Matthew <matthew.auld@intel.com>;
> > Gupta, Anshuman <anshuman.gupta@intel.com>
> > Subject: Re: [PATCH 01/14] drm/xe: Document Xe PM component
> >
> > On Thu, Feb 15, 2024 at 02:34:17PM -0500, Rodrigo Vivi wrote:
> > > Replace outdated information with a proper PM documentation.
> > > Already establish the rules for the runtime PM get and put that Xe
> > > needs to follow.
> > >
> > > Also add missing function documentation to all the "exported" functions.
> > >
> > > v2: updated after Francois' feedback.
> > > s/grater/greater (Matt)
> > >
> > > Cc: Matthew Auld <matthew.auld@intel.com>
> > > Cc: Anshuman Gupta <anshuman.gupta@intel.com>
> > > Signed-off-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
> > > Acked-by: Francois Dugast <francois.dugast@intel.com>
> > > ---
> > > drivers/gpu/drm/xe/xe_pm.c | 108
> > > +++++++++++++++++++++++++++++++++----
> > > 1 file changed, 97 insertions(+), 11 deletions(-)
> > >
> > > diff --git a/drivers/gpu/drm/xe/xe_pm.c b/drivers/gpu/drm/xe/xe_pm.c
> > > index ab283e9a8b4e..64ffb9a35448 100644
> > > --- a/drivers/gpu/drm/xe/xe_pm.c
> > > +++ b/drivers/gpu/drm/xe/xe_pm.c
> > > @@ -25,21 +25,46 @@
> > > /**
> > > * DOC: Xe Power Management
> > > *
> > > - * Xe PM shall be guided by the simplicity.
> > > - * Use the simplest hook options whenever possible.
> > > - * Let's not reinvent the runtime_pm references and hooks.
> > > - * Shall have a clear separation of display and gt underneath this component.
> > > + * Xe PM implements the main routines for both system level suspend
> > > + states and
> > > + * for the opportunistic runtime suspend states.
> > > *
> > > - * What's next:
> > > + * System Level Suspend (S-States) - In general this is OS initiated
> > > + suspend
> > > + * driven by ACPI for achieving S0ix (a.k.a. S2idle, freeze), S3
> > > + (suspend to ram),
> > > + * S4 (disk). The main functions here are `xe_pm_suspend` and
> > > + `xe_pm_resume`. They
> > > + * are the main point for the suspend to and resume from these states.
> > > *
> > > - * For now s2idle and s3 are only working in integrated devices. The
> > > next step
> > > - * is to iterate through all VRAM's BO backing them up into the
> > > system memory
> > > - * before allowing the system suspend.
> > > + * Runtime Suspend (D-States) - This is the opportunistic PCIe device
> > > + low power
> > > + * state D3. Xe PM component provides `xe_pm_runtime_suspend` and
> > > + * `xe_pm_runtime_resume` systems that PCI subsystem will call before
> > > + transition
> > > + * to D3. Also, Xe PM provides get and put functions that Xe driver
> > > + will use to
> > > + * indicate activity. In order to avoid locking complications with
> > > + the memory
> > > + * management, whenever possible, these get and put functions needs
> > > + to be called
> > > + * from the higher/outer levels.
> > > *
> > > - * Also runtime_pm needs to be here from the beginning.
> > > + * The main cases that need to be protected from the outer levels
> > > + are: IOCTL,
> > > + * sysfs, debugfs, dma-buf sharing, GPU execution.
> > > *
> > > - * RC6/RPS are also critical PM features. Let's start with GuCRC and
> > > GuC SLPC
> > > - * and no wait boost. Frequency optimizations should come on a next stage.
> > > + * PCI D3 is special and can mean D3hot, where Vcc power is on for
> > > + keeping memory
> > > + * alive and quicker low latency resume or D3Cold where Vcc power is
> > > + off for
> > > + * better power savings.
> > > + * The Vcc control of PCI hierarchy can only be controlled at the PCI
> > > + root port
> > > + * level, while the device driver can be behind multiple
> > > + bridges/switches and
> > > + * paired with other devices. For this reason, the PCI subsystem
> > > + cannot perform
> > > + * the transition towards D3Cold. The lowest runtime PM possible from
> > > + the PCI
> > > + * subsystem is D3hot. Then, if all these paired devices in the same
> > > + root port
> > > + * are in D3hot, ACPI will assist here and run its own methods (_PR3
> > > + and _OFF)
> > > + * to perform the transition from D3hot to D3cold. Xe may disallow
> > > + this
> > > + * transition by calling pci_d3cold_disable(root_pdev) before going
> > > + to runtime
> > > + * suspend. It will be based on runtime conditions such as VRAM usage
> > > + for a
> > > + * quick and low latency resume for instance.
> > > + *
> > > + * Intel systems are capable of taking the system to S0ix when
> > > + devices are on
> > > + * D3hot through the runtime PM. This is also called as 'opportunistic-S0iX'.
> > > + * But in this case, the `xe_pm_suspend` and `xe_pm_resume` won't be
> > > + called for
> > > + * S0ix.
> Hi Rodrigo,
> Sorry of late review comment, was busy with other stuff.
no worries. Thank you so much for jumping in. Really appreciated.
> we do need modify the doc slightly.
indeed... I also realized that to avoid confusion we need to detach the D3.
In our integrated devices it is power important for the package-C states then
for 'D3' itself. One might look at our PCI config for integrated and see D3hot- and
get confused.
> For integrated graphics D3hot is not necessary to achieve for the host s0ix, like with PSR panel
> PCI device will be in D0 state as KMS CRTC will be active and will held a device wakeref.
Then let's also detach the opportunistic s0ix from the runtime_pm with this PSR
case in mind.
>
> AFAIK for discrete card perspective, host s0ix requires PCIe link to be in low power state.
yeap, but that's outside of our scope so let's minimize the doc to the calls
around the functions that we are implementing here.
So, what do you think of this diff between what I had here in this patch and
what I'm seending soon on a v2:
--- a/drivers/gpu/drm/xe/xe_pm.c
+++ b/drivers/gpu/drm/xe/xe_pm.c
@@ -33,17 +33,9 @@
* S4 (disk). The main functions here are `xe_pm_suspend` and `xe_pm_resume`. They
* are the main point for the suspend to and resume from these states.
*
- * Runtime Suspend (D-States) - This is the opportunistic PCIe device low power
- * state D3. Xe PM component provides `xe_pm_runtime_suspend` and
- * `xe_pm_runtime_resume` systems that PCI subsystem will call before transition
- * to D3. Also, Xe PM provides get and put functions that Xe driver will use to
- * indicate activity. In order to avoid locking complications with the memory
- * management, whenever possible, these get and put functions needs to be called
- * from the higher/outer levels.
- *
- * The main cases that need to be protected from the outer levels are: IOCTL,
- * sysfs, debugfs, dma-buf sharing, GPU execution.
- *
+ * PCI Device Suspend (D-States) - This is the opportunistic PCIe device low power
+ * state D3, controlled by the PCI subsystem and ACPI with the help from the
+ * runtime_pm infrastructure.
* PCI D3 is special and can mean D3hot, where Vcc power is on for keeping memory
* alive and quicker low latency resume or D3Cold where Vcc power is off for
* better power savings.
@@ -58,12 +50,28 @@
* suspend. It will be based on runtime conditions such as VRAM usage for a
* quick and low latency resume for instance.
*
- * Intel systems are capable of taking the system to S0ix when devices are on
- * D3hot through the runtime PM. This is also called as 'opportunistic-S0iX'.
- * But in this case, the `xe_pm_suspend` and `xe_pm_resume` won't be called for
- * S0ix.
+ * Runtime PM - This infrastructure provided by the Linux kernel allows the
+ * device drivers to indicate when the can be runtime suspended, so the device
+ * could be put at D3 (if supported), or allow deeper package sleep states
+ * (PC-states), and/or other low level power states. Xe PM component provides
+ * `xe_pm_runtime_suspend` and `xe_pm_runtime_resume` functions that PCI
+ * subsystem will call before transition to/from runtime suspend.
+ *
+ * Also, Xe PM provides get and put functions that Xe driver will use to
+ * indicate activity. In order to avoid locking complications with the memory
+ * management, whenever possible, these get and put functions needs to be called
+ * from the higher/outer levels.
+ * The main cases that need to be protected from the outer levels are: IOCTL,
+ * sysfs, debugfs, dma-buf sharing, GPU execution.
+ *
+ * Intel systems are capable of taking the system to S0ix when all certain
+ * conditions are met. This is also called as 'opportunistic-S0iX'.
+ * But in this case, the `xe_pm_suspend` and `xe_pm_resume` won't be called
+ * for S0ix. In certain cases, like when Display Panel Self-Refresh (eDP PSR) is
+ * active, not even `xe_pm_runtime_suspend` and `xe_pm_runtime_resume` will be
+ * called.
*
- * This component is no responsible for GT idleness (RC6) nor GT frequency
+ * This component is not responsible for GT idleness (RC6) nor GT frequency
* management (RPS).
*/
> Thanks,
> Anshuman Gupta.
> > > + *
> > > + * This component is no responsible for GT idleness (RC6) nor GT
> > > + frequency
> >
> > Isn't it s/no/not/? Or s/no/neither/ + s/nor/nor for/? In any case:
> >
> > Reviewed-by: Francois Dugast <francois.dugast@intel.com>
> >
> > Francois
> >
> > > + * management (RPS).
> > > */
> > >
> > > /**
> > > @@ -178,6 +203,12 @@ void xe_pm_init_early(struct xe_device *xe)
> > > drmm_mutex_init(&xe->drm, &xe->mem_access.vram_userfault.lock);
> > > }
> > >
> > > +/**
> > > + * xe_pm_init - Initialize Xe Power Management
> > > + * @xe: xe device instance
> > > + *
> > > + * This component is responsible for System and Device sleep states.
> > > + */
> > > void xe_pm_init(struct xe_device *xe) {
> > > /* For now suspend/resume is only allowed with GuC */ @@ -196,6
> > > +227,10 @@ void xe_pm_init(struct xe_device *xe)
> > > xe_pm_runtime_init(xe);
> > > }
> > >
> > > +/**
> > > + * xe_pm_runtime_fini - Finalize Runtime PM
> > > + * @xe: xe device instance
> > > + */
> > > void xe_pm_runtime_fini(struct xe_device *xe) {
> > > struct device *dev = xe->drm.dev;
> > > @@ -225,6 +260,12 @@ struct task_struct *xe_pm_read_callback_task(struct
> > xe_device *xe)
> > > return READ_ONCE(xe->pm_callback_task); }
> > >
> > > +/**
> > > + * xe_pm_runtime_suspend - Prepare our device for D3hot/D3Cold
> > > + * @xe: xe device instance
> > > + *
> > > + * Returns 0 for success, negative error code otherwise.
> > > + */
> > > int xe_pm_runtime_suspend(struct xe_device *xe) {
> > > struct xe_bo *bo, *on;
> > > @@ -290,6 +331,12 @@ int xe_pm_runtime_suspend(struct xe_device *xe)
> > > return err;
> > > }
> > >
> > > +/**
> > > + * xe_pm_runtime_resume - Waking up from D3hot/D3Cold
> > > + * @xe: xe device instance
> > > + *
> > > + * Returns 0 for success, negative error code otherwise.
> > > + */
> > > int xe_pm_runtime_resume(struct xe_device *xe) {
> > > struct xe_gt *gt;
> > > @@ -341,22 +388,47 @@ int xe_pm_runtime_resume(struct xe_device *xe)
> > > return err;
> > > }
> > >
> > > +/**
> > > + * xe_pm_runtime_get - Get a runtime_pm reference and resume
> > > +synchronously
> > > + * @xe: xe device instance
> > > + *
> > > + * Returns: Any number greater than or equal to 0 for success,
> > > +negative error
> > > + * code otherwise.
> > > + */
> > > int xe_pm_runtime_get(struct xe_device *xe) {
> > > return pm_runtime_get_sync(xe->drm.dev); }
> > >
> > > +/**
> > > + * xe_pm_runtime_put - Put the runtime_pm reference back and mark as
> > > +idle
> > > + * @xe: xe device instance
> > > + *
> > > + * Returns: Any number greater than or equal to 0 for success,
> > > +negative error
> > > + * code otherwise.
> > > + */
> > > int xe_pm_runtime_put(struct xe_device *xe) {
> > > pm_runtime_mark_last_busy(xe->drm.dev);
> > > return pm_runtime_put(xe->drm.dev);
> > > }
> > >
> > > +/**
> > > + * xe_pm_runtime_get_if_active - Get a runtime_pm reference if device
> > > +active
> > > + * @xe: xe device instance
> > > + *
> > > + * Returns: Any number greater than or equal to 0 for success,
> > > +negative error
> > > + * code otherwise.
> > > + */
> > > int xe_pm_runtime_get_if_active(struct xe_device *xe) {
> > > return pm_runtime_get_if_active(xe->drm.dev, true); }
> > >
> > > +/**
> > > + * xe_pm_assert_unbounded_bridge - Disable PM on unbounded pcie
> > > +parent bridge
> > > + * @xe: xe device instance
> > > + */
> > > void xe_pm_assert_unbounded_bridge(struct xe_device *xe) {
> > > struct pci_dev *pdev = to_pci_dev(xe->drm.dev); @@ -371,6 +443,13
> > @@
> > > void xe_pm_assert_unbounded_bridge(struct xe_device *xe)
> > > }
> > > }
> > >
> > > +/**
> > > + * xe_pm_set_vram_threshold - Set a vram threshold for
> > > +allowing/blocking D3Cold
> > > + * @xe: xe device instance
> > > + * @threshold: VRAM size in bites for the D3cold threshold
> > > + *
> > > + * Returns 0 for success, negative error code otherwise.
> > > + */
> > > int xe_pm_set_vram_threshold(struct xe_device *xe, u32 threshold) {
> > > struct ttm_resource_manager *man;
> > > @@ -395,6 +474,13 @@ int xe_pm_set_vram_threshold(struct xe_device *xe,
> > u32 threshold)
> > > return 0;
> > > }
> > >
> > > +/**
> > > + * xe_pm_d3cold_allowed_toggle - Check conditions to toggle
> > > +d3cold.allowed
> > > + * @xe: xe device instance
> > > + *
> > > + * To be called during runtime_pm idle callback.
> > > + * Check for all the D3Cold conditions ahead of runtime suspend.
> > > + */
> > > void xe_pm_d3cold_allowed_toggle(struct xe_device *xe) {
> > > struct ttm_resource_manager *man;
> > > --
> > > 2.43.0
> > >
^ permalink raw reply [flat|nested] 26+ messages in thread* RE: [PATCH 01/14] drm/xe: Document Xe PM component
2024-02-21 19:00 ` Rodrigo Vivi
@ 2024-02-22 15:06 ` Gupta, Anshuman
2024-02-22 16:29 ` Vivi, Rodrigo
0 siblings, 1 reply; 26+ messages in thread
From: Gupta, Anshuman @ 2024-02-22 15:06 UTC (permalink / raw)
To: Vivi, Rodrigo
Cc: Dugast, Francois, intel-xe@lists.freedesktop.org, Auld, Matthew
> -----Original Message-----
> From: Vivi, Rodrigo <rodrigo.vivi@intel.com>
> Sent: Thursday, February 22, 2024 12:30 AM
> To: Gupta, Anshuman <anshuman.gupta@intel.com>
> Cc: Dugast, Francois <francois.dugast@intel.com>; intel-
> xe@lists.freedesktop.org; Auld, Matthew <matthew.auld@intel.com>
> Subject: Re: [PATCH 01/14] drm/xe: Document Xe PM component
>
> On Wed, Feb 21, 2024 at 09:41:44AM -0500, Gupta, Anshuman wrote:
> >
> >
> > > -----Original Message-----
> > > From: Dugast, Francois <francois.dugast@intel.com>
> > > Sent: Wednesday, February 21, 2024 5:38 PM
> > > To: Vivi, Rodrigo <rodrigo.vivi@intel.com>
> > > Cc: intel-xe@lists.freedesktop.org; Auld, Matthew
> > > <matthew.auld@intel.com>; Gupta, Anshuman
> <anshuman.gupta@intel.com>
> > > Subject: Re: [PATCH 01/14] drm/xe: Document Xe PM component
> > >
> > > On Thu, Feb 15, 2024 at 02:34:17PM -0500, Rodrigo Vivi wrote:
> > > > Replace outdated information with a proper PM documentation.
> > > > Already establish the rules for the runtime PM get and put that Xe
> > > > needs to follow.
> > > >
> > > > Also add missing function documentation to all the "exported"
> functions.
> > > >
> > > > v2: updated after Francois' feedback.
> > > > s/grater/greater (Matt)
> > > >
> > > > Cc: Matthew Auld <matthew.auld@intel.com>
> > > > Cc: Anshuman Gupta <anshuman.gupta@intel.com>
> > > > Signed-off-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
> > > > Acked-by: Francois Dugast <francois.dugast@intel.com>
> > > > ---
> > > > drivers/gpu/drm/xe/xe_pm.c | 108
> > > > +++++++++++++++++++++++++++++++++----
> > > > 1 file changed, 97 insertions(+), 11 deletions(-)
> > > >
> > > > diff --git a/drivers/gpu/drm/xe/xe_pm.c
> > > > b/drivers/gpu/drm/xe/xe_pm.c index ab283e9a8b4e..64ffb9a35448
> > > > 100644
> > > > --- a/drivers/gpu/drm/xe/xe_pm.c
> > > > +++ b/drivers/gpu/drm/xe/xe_pm.c
> > > > @@ -25,21 +25,46 @@
> > > > /**
> > > > * DOC: Xe Power Management
> > > > *
> > > > - * Xe PM shall be guided by the simplicity.
> > > > - * Use the simplest hook options whenever possible.
> > > > - * Let's not reinvent the runtime_pm references and hooks.
> > > > - * Shall have a clear separation of display and gt underneath this
> component.
> > > > + * Xe PM implements the main routines for both system level
> > > > + suspend states and
> > > > + * for the opportunistic runtime suspend states.
> > > > *
> > > > - * What's next:
> > > > + * System Level Suspend (S-States) - In general this is OS
> > > > + initiated suspend
> > > > + * driven by ACPI for achieving S0ix (a.k.a. S2idle, freeze), S3
> > > > + (suspend to ram),
> > > > + * S4 (disk). The main functions here are `xe_pm_suspend` and
> > > > + `xe_pm_resume`. They
> > > > + * are the main point for the suspend to and resume from these
> states.
> > > > *
> > > > - * For now s2idle and s3 are only working in integrated devices.
> > > > The next step
> > > > - * is to iterate through all VRAM's BO backing them up into the
> > > > system memory
> > > > - * before allowing the system suspend.
> > > > + * Runtime Suspend (D-States) - This is the opportunistic PCIe
> > > > + device low power
> > > > + * state D3. Xe PM component provides `xe_pm_runtime_suspend` and
> > > > + * `xe_pm_runtime_resume` systems that PCI subsystem will call
> > > > + before transition
> > > > + * to D3. Also, Xe PM provides get and put functions that Xe
> > > > + driver will use to
> > > > + * indicate activity. In order to avoid locking complications
> > > > + with the memory
> > > > + * management, whenever possible, these get and put functions
> > > > + needs to be called
> > > > + * from the higher/outer levels.
> > > > *
> > > > - * Also runtime_pm needs to be here from the beginning.
> > > > + * The main cases that need to be protected from the outer levels
> > > > + are: IOCTL,
> > > > + * sysfs, debugfs, dma-buf sharing, GPU execution.
> > > > *
> > > > - * RC6/RPS are also critical PM features. Let's start with GuCRC
> > > > and GuC SLPC
> > > > - * and no wait boost. Frequency optimizations should come on a next
> stage.
> > > > + * PCI D3 is special and can mean D3hot, where Vcc power is on
> > > > + for keeping memory
> > > > + * alive and quicker low latency resume or D3Cold where Vcc power
> > > > + is off for
> > > > + * better power savings.
> > > > + * The Vcc control of PCI hierarchy can only be controlled at the
> > > > + PCI root port
> > > > + * level, while the device driver can be behind multiple
> > > > + bridges/switches and
> > > > + * paired with other devices. For this reason, the PCI subsystem
> > > > + cannot perform
> > > > + * the transition towards D3Cold. The lowest runtime PM possible
> > > > + from the PCI
> > > > + * subsystem is D3hot. Then, if all these paired devices in the
> > > > + same root port
> > > > + * are in D3hot, ACPI will assist here and run its own methods
> > > > + (_PR3 and _OFF)
> > > > + * to perform the transition from D3hot to D3cold. Xe may
> > > > + disallow this
> > > > + * transition by calling pci_d3cold_disable(root_pdev) before
> > > > + going to runtime
> > > > + * suspend. It will be based on runtime conditions such as VRAM
> > > > + usage for a
> > > > + * quick and low latency resume for instance.
> > > > + *
> > > > + * Intel systems are capable of taking the system to S0ix when
> > > > + devices are on
> > > > + * D3hot through the runtime PM. This is also called as 'opportunistic-
> S0iX'.
> > > > + * But in this case, the `xe_pm_suspend` and `xe_pm_resume` won't
> > > > + be called for
> > > > + * S0ix.
> > Hi Rodrigo,
> > Sorry of late review comment, was busy with other stuff.
>
> no worries. Thank you so much for jumping in. Really appreciated.
>
> > we do need modify the doc slightly.
>
> indeed... I also realized that to avoid confusion we need to detach the D3.
> In our integrated devices it is power important for the package-C states then
> for 'D3' itself. One might look at our PCI config for integrated and see D3hot-
> and get confused.
>
> > For integrated graphics D3hot is not necessary to achieve for the host
> > s0ix, like with PSR panel PCI device will be in D0 state as KMS CRTC will be
> active and will held a device wakeref.
>
> Then let's also detach the opportunistic s0ix from the runtime_pm with this
> PSR case in mind.
>
> >
> > AFAIK for discrete card perspective, host s0ix requires PCIe link to be in low
> power state.
>
> yeap, but that's outside of our scope so let's minimize the doc to the calls
> around the functions that we are implementing here.
>
> So, what do you think of this diff between what I had here in this patch and
> what I'm seending soon on a v2:
IMO let's keep the documentation limited to PCI PM D3 state, s0ix does not belongs here,
gtidle component should document the s0ix dependency and display C states doc should
document the runtime opportunistic s0ix with PSR. Xe_pm is not correct component.
Thanks,
Anshuman Gupta.
>
> --- a/drivers/gpu/drm/xe/xe_pm.c
> +++ b/drivers/gpu/drm/xe/xe_pm.c
> @@ -33,17 +33,9 @@
> * S4 (disk). The main functions here are `xe_pm_suspend` and
> `xe_pm_resume`. They
> * are the main point for the suspend to and resume from these states.
> *
> - * Runtime Suspend (D-States) - This is the opportunistic PCIe device low
> power
> - * state D3. Xe PM component provides `xe_pm_runtime_suspend` and
> - * `xe_pm_runtime_resume` systems that PCI subsystem will call before
> transition
> - * to D3. Also, Xe PM provides get and put functions that Xe driver will use
> to
> - * indicate activity. In order to avoid locking complications with the memory
> - * management, whenever possible, these get and put functions needs to be
> called
> - * from the higher/outer levels.
> - *
> - * The main cases that need to be protected from the outer levels are:
> IOCTL,
> - * sysfs, debugfs, dma-buf sharing, GPU execution.
> - *
> + * PCI Device Suspend (D-States) - This is the opportunistic PCIe
> + device low power
> + * state D3, controlled by the PCI subsystem and ACPI with the help
> + from the
> + * runtime_pm infrastructure.
> * PCI D3 is special and can mean D3hot, where Vcc power is on for keeping
> memory
> * alive and quicker low latency resume or D3Cold where Vcc power is off for
> * better power savings.
> @@ -58,12 +50,28 @@
> * suspend. It will be based on runtime conditions such as VRAM usage for a
> * quick and low latency resume for instance.
> *
> - * Intel systems are capable of taking the system to S0ix when devices are on
> - * D3hot through the runtime PM. This is also called as 'opportunistic-S0iX'.
> - * But in this case, the `xe_pm_suspend` and `xe_pm_resume` won't be
> called for
> - * S0ix.
> + * Runtime PM - This infrastructure provided by the Linux kernel allows
> + the
> + * device drivers to indicate when the can be runtime suspended, so the
> + device
> + * could be put at D3 (if supported), or allow deeper package sleep
> + states
> + * (PC-states), and/or other low level power states. Xe PM component
> + provides
> + * `xe_pm_runtime_suspend` and `xe_pm_runtime_resume` functions that
> + PCI
> + * subsystem will call before transition to/from runtime suspend.
> + *
> + * Also, Xe PM provides get and put functions that Xe driver will use
> + to
> + * indicate activity. In order to avoid locking complications with the
> + memory
> + * management, whenever possible, these get and put functions needs to
> + be called
> + * from the higher/outer levels.
> + * The main cases that need to be protected from the outer levels are:
> + IOCTL,
> + * sysfs, debugfs, dma-buf sharing, GPU execution.
> + *
> + * Intel systems are capable of taking the system to S0ix when all
> + certain
> + * conditions are met. This is also called as 'opportunistic-S0iX'.
> + * But in this case, the `xe_pm_suspend` and `xe_pm_resume` won't be
> + called
> + * for S0ix. In certain cases, like when Display Panel Self-Refresh
> + (eDP PSR) is
> + * active, not even `xe_pm_runtime_suspend` and `xe_pm_runtime_resume`
> + will be
> + * called.
> *
> - * This component is no responsible for GT idleness (RC6) nor GT frequency
> + * This component is not responsible for GT idleness (RC6) nor GT
> + frequency
> * management (RPS).
> */
>
> > Thanks,
> > Anshuman Gupta.
> > > > + *
> > > > + * This component is no responsible for GT idleness (RC6) nor GT
> > > > + frequency
> > >
> > > Isn't it s/no/not/? Or s/no/neither/ + s/nor/nor for/? In any case:
> > >
> > > Reviewed-by: Francois Dugast <francois.dugast@intel.com>
> > >
> > > Francois
> > >
> > > > + * management (RPS).
> > > > */
> > > >
> > > > /**
> > > > @@ -178,6 +203,12 @@ void xe_pm_init_early(struct xe_device *xe)
> > > > drmm_mutex_init(&xe->drm, &xe->mem_access.vram_userfault.lock);
> > > > }
> > > >
> > > > +/**
> > > > + * xe_pm_init - Initialize Xe Power Management
> > > > + * @xe: xe device instance
> > > > + *
> > > > + * This component is responsible for System and Device sleep states.
> > > > + */
> > > > void xe_pm_init(struct xe_device *xe) {
> > > > /* For now suspend/resume is only allowed with GuC */ @@ -196,6
> > > > +227,10 @@ void xe_pm_init(struct xe_device *xe)
> > > > xe_pm_runtime_init(xe);
> > > > }
> > > >
> > > > +/**
> > > > + * xe_pm_runtime_fini - Finalize Runtime PM
> > > > + * @xe: xe device instance
> > > > + */
> > > > void xe_pm_runtime_fini(struct xe_device *xe) {
> > > > struct device *dev = xe->drm.dev; @@ -225,6 +260,12 @@ struct
> > > > task_struct *xe_pm_read_callback_task(struct
> > > xe_device *xe)
> > > > return READ_ONCE(xe->pm_callback_task); }
> > > >
> > > > +/**
> > > > + * xe_pm_runtime_suspend - Prepare our device for D3hot/D3Cold
> > > > + * @xe: xe device instance
> > > > + *
> > > > + * Returns 0 for success, negative error code otherwise.
> > > > + */
> > > > int xe_pm_runtime_suspend(struct xe_device *xe) {
> > > > struct xe_bo *bo, *on;
> > > > @@ -290,6 +331,12 @@ int xe_pm_runtime_suspend(struct xe_device
> *xe)
> > > > return err;
> > > > }
> > > >
> > > > +/**
> > > > + * xe_pm_runtime_resume - Waking up from D3hot/D3Cold
> > > > + * @xe: xe device instance
> > > > + *
> > > > + * Returns 0 for success, negative error code otherwise.
> > > > + */
> > > > int xe_pm_runtime_resume(struct xe_device *xe) {
> > > > struct xe_gt *gt;
> > > > @@ -341,22 +388,47 @@ int xe_pm_runtime_resume(struct xe_device
> *xe)
> > > > return err;
> > > > }
> > > >
> > > > +/**
> > > > + * xe_pm_runtime_get - Get a runtime_pm reference and resume
> > > > +synchronously
> > > > + * @xe: xe device instance
> > > > + *
> > > > + * Returns: Any number greater than or equal to 0 for success,
> > > > +negative error
> > > > + * code otherwise.
> > > > + */
> > > > int xe_pm_runtime_get(struct xe_device *xe) {
> > > > return pm_runtime_get_sync(xe->drm.dev); }
> > > >
> > > > +/**
> > > > + * xe_pm_runtime_put - Put the runtime_pm reference back and mark
> > > > +as idle
> > > > + * @xe: xe device instance
> > > > + *
> > > > + * Returns: Any number greater than or equal to 0 for success,
> > > > +negative error
> > > > + * code otherwise.
> > > > + */
> > > > int xe_pm_runtime_put(struct xe_device *xe) {
> > > > pm_runtime_mark_last_busy(xe->drm.dev);
> > > > return pm_runtime_put(xe->drm.dev); }
> > > >
> > > > +/**
> > > > + * xe_pm_runtime_get_if_active - Get a runtime_pm reference if
> > > > +device active
> > > > + * @xe: xe device instance
> > > > + *
> > > > + * Returns: Any number greater than or equal to 0 for success,
> > > > +negative error
> > > > + * code otherwise.
> > > > + */
> > > > int xe_pm_runtime_get_if_active(struct xe_device *xe) {
> > > > return pm_runtime_get_if_active(xe->drm.dev, true); }
> > > >
> > > > +/**
> > > > + * xe_pm_assert_unbounded_bridge - Disable PM on unbounded pcie
> > > > +parent bridge
> > > > + * @xe: xe device instance
> > > > + */
> > > > void xe_pm_assert_unbounded_bridge(struct xe_device *xe) {
> > > > struct pci_dev *pdev = to_pci_dev(xe->drm.dev); @@ -371,6
> > > > +443,13
> > > @@
> > > > void xe_pm_assert_unbounded_bridge(struct xe_device *xe)
> > > > }
> > > > }
> > > >
> > > > +/**
> > > > + * xe_pm_set_vram_threshold - Set a vram threshold for
> > > > +allowing/blocking D3Cold
> > > > + * @xe: xe device instance
> > > > + * @threshold: VRAM size in bites for the D3cold threshold
> > > > + *
> > > > + * Returns 0 for success, negative error code otherwise.
> > > > + */
> > > > int xe_pm_set_vram_threshold(struct xe_device *xe, u32 threshold) {
> > > > struct ttm_resource_manager *man; @@ -395,6 +474,13 @@ int
> > > > xe_pm_set_vram_threshold(struct xe_device *xe,
> > > u32 threshold)
> > > > return 0;
> > > > }
> > > >
> > > > +/**
> > > > + * xe_pm_d3cold_allowed_toggle - Check conditions to toggle
> > > > +d3cold.allowed
> > > > + * @xe: xe device instance
> > > > + *
> > > > + * To be called during runtime_pm idle callback.
> > > > + * Check for all the D3Cold conditions ahead of runtime suspend.
> > > > + */
> > > > void xe_pm_d3cold_allowed_toggle(struct xe_device *xe) {
> > > > struct ttm_resource_manager *man;
> > > > --
> > > > 2.43.0
> > > >
^ permalink raw reply [flat|nested] 26+ messages in thread* Re: [PATCH 01/14] drm/xe: Document Xe PM component
2024-02-22 15:06 ` Gupta, Anshuman
@ 2024-02-22 16:29 ` Vivi, Rodrigo
0 siblings, 0 replies; 26+ messages in thread
From: Vivi, Rodrigo @ 2024-02-22 16:29 UTC (permalink / raw)
To: Gupta, Anshuman
Cc: intel-xe@lists.freedesktop.org, Auld, Matthew, Dugast, Francois
On Thu, 2024-02-22 at 15:06 +0000, Gupta, Anshuman wrote:
>
>
> > -----Original Message-----
> > From: Vivi, Rodrigo <rodrigo.vivi@intel.com>
> > Sent: Thursday, February 22, 2024 12:30 AM
> > To: Gupta, Anshuman <anshuman.gupta@intel.com>
> > Cc: Dugast, Francois <francois.dugast@intel.com>; intel-
> > xe@lists.freedesktop.org; Auld, Matthew <matthew.auld@intel.com>
> > Subject: Re: [PATCH 01/14] drm/xe: Document Xe PM component
> >
> > On Wed, Feb 21, 2024 at 09:41:44AM -0500, Gupta, Anshuman wrote:
> > >
> > >
> > > > -----Original Message-----
> > > > From: Dugast, Francois <francois.dugast@intel.com>
> > > > Sent: Wednesday, February 21, 2024 5:38 PM
> > > > To: Vivi, Rodrigo <rodrigo.vivi@intel.com>
> > > > Cc: intel-xe@lists.freedesktop.org; Auld, Matthew
> > > > <matthew.auld@intel.com>; Gupta, Anshuman
> > <anshuman.gupta@intel.com>
> > > > Subject: Re: [PATCH 01/14] drm/xe: Document Xe PM component
> > > >
> > > > On Thu, Feb 15, 2024 at 02:34:17PM -0500, Rodrigo Vivi wrote:
> > > > > Replace outdated information with a proper PM documentation.
> > > > > Already establish the rules for the runtime PM get and put
> > > > > that Xe
> > > > > needs to follow.
> > > > >
> > > > > Also add missing function documentation to all the "exported"
> > functions.
> > > > >
> > > > > v2: updated after Francois' feedback.
> > > > > s/grater/greater (Matt)
> > > > >
> > > > > Cc: Matthew Auld <matthew.auld@intel.com>
> > > > > Cc: Anshuman Gupta <anshuman.gupta@intel.com>
> > > > > Signed-off-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
> > > > > Acked-by: Francois Dugast <francois.dugast@intel.com>
> > > > > ---
> > > > > drivers/gpu/drm/xe/xe_pm.c | 108
> > > > > +++++++++++++++++++++++++++++++++----
> > > > > 1 file changed, 97 insertions(+), 11 deletions(-)
> > > > >
> > > > > diff --git a/drivers/gpu/drm/xe/xe_pm.c
> > > > > b/drivers/gpu/drm/xe/xe_pm.c index ab283e9a8b4e..64ffb9a35448
> > > > > 100644
> > > > > --- a/drivers/gpu/drm/xe/xe_pm.c
> > > > > +++ b/drivers/gpu/drm/xe/xe_pm.c
> > > > > @@ -25,21 +25,46 @@
> > > > > /**
> > > > > * DOC: Xe Power Management
> > > > > *
> > > > > - * Xe PM shall be guided by the simplicity.
> > > > > - * Use the simplest hook options whenever possible.
> > > > > - * Let's not reinvent the runtime_pm references and hooks.
> > > > > - * Shall have a clear separation of display and gt
> > > > > underneath this
> > component.
> > > > > + * Xe PM implements the main routines for both system level
> > > > > + suspend states and
> > > > > + * for the opportunistic runtime suspend states.
> > > > > *
> > > > > - * What's next:
> > > > > + * System Level Suspend (S-States) - In general this is OS
> > > > > + initiated suspend
> > > > > + * driven by ACPI for achieving S0ix (a.k.a. S2idle,
> > > > > freeze), S3
> > > > > + (suspend to ram),
> > > > > + * S4 (disk). The main functions here are `xe_pm_suspend`
> > > > > and
> > > > > + `xe_pm_resume`. They
> > > > > + * are the main point for the suspend to and resume from
> > > > > these
> > states.
> > > > > *
> > > > > - * For now s2idle and s3 are only working in integrated
> > > > > devices.
> > > > > The next step
> > > > > - * is to iterate through all VRAM's BO backing them up into
> > > > > the
> > > > > system memory
> > > > > - * before allowing the system suspend.
> > > > > + * Runtime Suspend (D-States) - This is the opportunistic
> > > > > PCIe
> > > > > + device low power
> > > > > + * state D3. Xe PM component provides
> > > > > `xe_pm_runtime_suspend` and
> > > > > + * `xe_pm_runtime_resume` systems that PCI subsystem will
> > > > > call
> > > > > + before transition
> > > > > + * to D3. Also, Xe PM provides get and put functions that Xe
> > > > > + driver will use to
> > > > > + * indicate activity. In order to avoid locking
> > > > > complications
> > > > > + with the memory
> > > > > + * management, whenever possible, these get and put
> > > > > functions
> > > > > + needs to be called
> > > > > + * from the higher/outer levels.
> > > > > *
> > > > > - * Also runtime_pm needs to be here from the beginning.
> > > > > + * The main cases that need to be protected from the outer
> > > > > levels
> > > > > + are: IOCTL,
> > > > > + * sysfs, debugfs, dma-buf sharing, GPU execution.
> > > > > *
> > > > > - * RC6/RPS are also critical PM features. Let's start with
> > > > > GuCRC
> > > > > and GuC SLPC
> > > > > - * and no wait boost. Frequency optimizations should come on
> > > > > a next
> > stage.
> > > > > + * PCI D3 is special and can mean D3hot, where Vcc power is
> > > > > on
> > > > > + for keeping memory
> > > > > + * alive and quicker low latency resume or D3Cold where Vcc
> > > > > power
> > > > > + is off for
> > > > > + * better power savings.
> > > > > + * The Vcc control of PCI hierarchy can only be controlled
> > > > > at the
> > > > > + PCI root port
> > > > > + * level, while the device driver can be behind multiple
> > > > > + bridges/switches and
> > > > > + * paired with other devices. For this reason, the PCI
> > > > > subsystem
> > > > > + cannot perform
> > > > > + * the transition towards D3Cold. The lowest runtime PM
> > > > > possible
> > > > > + from the PCI
> > > > > + * subsystem is D3hot. Then, if all these paired devices in
> > > > > the
> > > > > + same root port
> > > > > + * are in D3hot, ACPI will assist here and run its own
> > > > > methods
> > > > > + (_PR3 and _OFF)
> > > > > + * to perform the transition from D3hot to D3cold. Xe may
> > > > > + disallow this
> > > > > + * transition by calling pci_d3cold_disable(root_pdev)
> > > > > before
> > > > > + going to runtime
> > > > > + * suspend. It will be based on runtime conditions such as
> > > > > VRAM
> > > > > + usage for a
> > > > > + * quick and low latency resume for instance.
> > > > > + *
> > > > > + * Intel systems are capable of taking the system to S0ix
> > > > > when
> > > > > + devices are on
> > > > > + * D3hot through the runtime PM. This is also called as
> > > > > 'opportunistic-
> > S0iX'.
> > > > > + * But in this case, the `xe_pm_suspend` and `xe_pm_resume`
> > > > > won't
> > > > > + be called for
> > > > > + * S0ix.
> > > Hi Rodrigo,
> > > Sorry of late review comment, was busy with other stuff.
> >
> > no worries. Thank you so much for jumping in. Really appreciated.
> >
> > > we do need modify the doc slightly.
> >
> > indeed... I also realized that to avoid confusion we need to detach
> > the D3.
> > In our integrated devices it is power important for the package-C
> > states then
> > for 'D3' itself. One might look at our PCI config for integrated
> > and see D3hot-
> > and get confused.
> >
> > > For integrated graphics D3hot is not necessary to achieve for the
> > > host
> > > s0ix, like with PSR panel PCI device will be in D0 state as KMS
> > > CRTC will be
> > active and will held a device wakeref.
> >
> > Then let's also detach the opportunistic s0ix from the runtime_pm
> > with this
> > PSR case in mind.
> >
> > >
> > > AFAIK for discrete card perspective, host s0ix requires PCIe link
> > > to be in low
> > power state.
> >
> > yeap, but that's outside of our scope so let's minimize the doc to
> > the calls
> > around the functions that we are implementing here.
> >
> > So, what do you think of this diff between what I had here in this
> > patch and
> > what I'm seending soon on a v2:
> IMO let's keep the documentation limited to PCI PM D3 state, s0ix
> does not belongs here,
> gtidle component should document the s0ix dependency and display C
> states doc should
> document the runtime opportunistic s0ix with PSR. Xe_pm is not
> correct component.
okay then. I can simply remove this last block that explains the
opportunistic S0iX.
Although this is a confusion that we have to keep answering over and
over about these callbacks relation to S0ix.
But I agree on keeping it simple.
> Thanks,
> Anshuman Gupta.
> >
> > --- a/drivers/gpu/drm/xe/xe_pm.c
> > +++ b/drivers/gpu/drm/xe/xe_pm.c
> > @@ -33,17 +33,9 @@
> > * S4 (disk). The main functions here are `xe_pm_suspend` and
> > `xe_pm_resume`. They
> > * are the main point for the suspend to and resume from these
> > states.
> > *
> > - * Runtime Suspend (D-States) - This is the opportunistic PCIe
> > device low
> > power
> > - * state D3. Xe PM component provides `xe_pm_runtime_suspend` and
> > - * `xe_pm_runtime_resume` systems that PCI subsystem will call
> > before
> > transition
> > - * to D3. Also, Xe PM provides get and put functions that Xe
> > driver will use
> > to
> > - * indicate activity. In order to avoid locking complications with
> > the memory
> > - * management, whenever possible, these get and put functions
> > needs to be
> > called
> > - * from the higher/outer levels.
> > - *
> > - * The main cases that need to be protected from the outer levels
> > are:
> > IOCTL,
> > - * sysfs, debugfs, dma-buf sharing, GPU execution.
> > - *
> > + * PCI Device Suspend (D-States) - This is the opportunistic PCIe
> > + device low power
> > + * state D3, controlled by the PCI subsystem and ACPI with the
> > help
> > + from the
> > + * runtime_pm infrastructure.
> > * PCI D3 is special and can mean D3hot, where Vcc power is on for
> > keeping
> > memory
> > * alive and quicker low latency resume or D3Cold where Vcc power
> > is off for
> > * better power savings.
> > @@ -58,12 +50,28 @@
> > * suspend. It will be based on runtime conditions such as VRAM
> > usage for a
> > * quick and low latency resume for instance.
> > *
> > - * Intel systems are capable of taking the system to S0ix when
> > devices are on
> > - * D3hot through the runtime PM. This is also called as
> > 'opportunistic-S0iX'.
> > - * But in this case, the `xe_pm_suspend` and `xe_pm_resume` won't
> > be
> > called for
> > - * S0ix.
> > + * Runtime PM - This infrastructure provided by the Linux kernel
> > allows
> > + the
> > + * device drivers to indicate when the can be runtime suspended,
> > so the
> > + device
> > + * could be put at D3 (if supported), or allow deeper package
> > sleep
> > + states
> > + * (PC-states), and/or other low level power states. Xe PM
> > component
> > + provides
> > + * `xe_pm_runtime_suspend` and `xe_pm_runtime_resume` functions
> > that
> > + PCI
> > + * subsystem will call before transition to/from runtime suspend.
> > + *
> > + * Also, Xe PM provides get and put functions that Xe driver will
> > use
> > + to
> > + * indicate activity. In order to avoid locking complications with
> > the
> > + memory
> > + * management, whenever possible, these get and put functions
> > needs to
> > + be called
> > + * from the higher/outer levels.
> > + * The main cases that need to be protected from the outer levels
> > are:
> > + IOCTL,
> > + * sysfs, debugfs, dma-buf sharing, GPU execution.
> > + *
> > + * Intel systems are capable of taking the system to S0ix when all
> > + certain
> > + * conditions are met. This is also called as 'opportunistic-
> > S0iX'.
> > + * But in this case, the `xe_pm_suspend` and `xe_pm_resume` won't
> > be
> > + called
> > + * for S0ix. In certain cases, like when Display Panel Self-
> > Refresh
> > + (eDP PSR) is
> > + * active, not even `xe_pm_runtime_suspend` and
> > `xe_pm_runtime_resume`
> > + will be
> > + * called.
> > *
> > - * This component is no responsible for GT idleness (RC6) nor GT
> > frequency
> > + * This component is not responsible for GT idleness (RC6) nor GT
> > + frequency
> > * management (RPS).
> > */
> >
> > > Thanks,
> > > Anshuman Gupta.
> > > > > + *
> > > > > + * This component is no responsible for GT idleness (RC6)
> > > > > nor GT
> > > > > + frequency
> > > >
> > > > Isn't it s/no/not/? Or s/no/neither/ + s/nor/nor for/? In any
> > > > case:
> > > >
> > > > Reviewed-by: Francois Dugast <francois.dugast@intel.com>
> > > >
> > > > Francois
> > > >
> > > > > + * management (RPS).
> > > > > */
> > > > >
> > > > > /**
> > > > > @@ -178,6 +203,12 @@ void xe_pm_init_early(struct xe_device
> > > > > *xe)
> > > > > drmm_mutex_init(&xe->drm, &xe-
> > > > > >mem_access.vram_userfault.lock);
> > > > > }
> > > > >
> > > > > +/**
> > > > > + * xe_pm_init - Initialize Xe Power Management
> > > > > + * @xe: xe device instance
> > > > > + *
> > > > > + * This component is responsible for System and Device sleep
> > > > > states.
> > > > > + */
> > > > > void xe_pm_init(struct xe_device *xe) {
> > > > > /* For now suspend/resume is only allowed with GuC */ @@ -
> > > > > 196,6
> > > > > +227,10 @@ void xe_pm_init(struct xe_device *xe)
> > > > > xe_pm_runtime_init(xe);
> > > > > }
> > > > >
> > > > > +/**
> > > > > + * xe_pm_runtime_fini - Finalize Runtime PM
> > > > > + * @xe: xe device instance
> > > > > + */
> > > > > void xe_pm_runtime_fini(struct xe_device *xe) {
> > > > > struct device *dev = xe->drm.dev; @@ -225,6 +260,12 @@
> > > > > struct
> > > > > task_struct *xe_pm_read_callback_task(struct
> > > > xe_device *xe)
> > > > > return READ_ONCE(xe->pm_callback_task); }
> > > > >
> > > > > +/**
> > > > > + * xe_pm_runtime_suspend - Prepare our device for
> > > > > D3hot/D3Cold
> > > > > + * @xe: xe device instance
> > > > > + *
> > > > > + * Returns 0 for success, negative error code otherwise.
> > > > > + */
> > > > > int xe_pm_runtime_suspend(struct xe_device *xe) {
> > > > > struct xe_bo *bo, *on;
> > > > > @@ -290,6 +331,12 @@ int xe_pm_runtime_suspend(struct
> > > > > xe_device
> > *xe)
> > > > > return err;
> > > > > }
> > > > >
> > > > > +/**
> > > > > + * xe_pm_runtime_resume - Waking up from D3hot/D3Cold
> > > > > + * @xe: xe device instance
> > > > > + *
> > > > > + * Returns 0 for success, negative error code otherwise.
> > > > > + */
> > > > > int xe_pm_runtime_resume(struct xe_device *xe) {
> > > > > struct xe_gt *gt;
> > > > > @@ -341,22 +388,47 @@ int xe_pm_runtime_resume(struct
> > > > > xe_device
> > *xe)
> > > > > return err;
> > > > > }
> > > > >
> > > > > +/**
> > > > > + * xe_pm_runtime_get - Get a runtime_pm reference and resume
> > > > > +synchronously
> > > > > + * @xe: xe device instance
> > > > > + *
> > > > > + * Returns: Any number greater than or equal to 0 for
> > > > > success,
> > > > > +negative error
> > > > > + * code otherwise.
> > > > > + */
> > > > > int xe_pm_runtime_get(struct xe_device *xe) {
> > > > > return pm_runtime_get_sync(xe->drm.dev); }
> > > > >
> > > > > +/**
> > > > > + * xe_pm_runtime_put - Put the runtime_pm reference back and
> > > > > mark
> > > > > +as idle
> > > > > + * @xe: xe device instance
> > > > > + *
> > > > > + * Returns: Any number greater than or equal to 0 for
> > > > > success,
> > > > > +negative error
> > > > > + * code otherwise.
> > > > > + */
> > > > > int xe_pm_runtime_put(struct xe_device *xe) {
> > > > > pm_runtime_mark_last_busy(xe->drm.dev);
> > > > > return pm_runtime_put(xe->drm.dev); }
> > > > >
> > > > > +/**
> > > > > + * xe_pm_runtime_get_if_active - Get a runtime_pm reference
> > > > > if
> > > > > +device active
> > > > > + * @xe: xe device instance
> > > > > + *
> > > > > + * Returns: Any number greater than or equal to 0 for
> > > > > success,
> > > > > +negative error
> > > > > + * code otherwise.
> > > > > + */
> > > > > int xe_pm_runtime_get_if_active(struct xe_device *xe) {
> > > > > return pm_runtime_get_if_active(xe->drm.dev, true); }
> > > > >
> > > > > +/**
> > > > > + * xe_pm_assert_unbounded_bridge - Disable PM on unbounded
> > > > > pcie
> > > > > +parent bridge
> > > > > + * @xe: xe device instance
> > > > > + */
> > > > > void xe_pm_assert_unbounded_bridge(struct xe_device *xe) {
> > > > > struct pci_dev *pdev = to_pci_dev(xe->drm.dev); @@ -371,6
> > > > > +443,13
> > > > @@
> > > > > void xe_pm_assert_unbounded_bridge(struct xe_device *xe)
> > > > > }
> > > > > }
> > > > >
> > > > > +/**
> > > > > + * xe_pm_set_vram_threshold - Set a vram threshold for
> > > > > +allowing/blocking D3Cold
> > > > > + * @xe: xe device instance
> > > > > + * @threshold: VRAM size in bites for the D3cold threshold
> > > > > + *
> > > > > + * Returns 0 for success, negative error code otherwise.
> > > > > + */
> > > > > int xe_pm_set_vram_threshold(struct xe_device *xe, u32
> > > > > threshold) {
> > > > > struct ttm_resource_manager *man; @@ -395,6 +474,13 @@ int
> > > > > xe_pm_set_vram_threshold(struct xe_device *xe,
> > > > u32 threshold)
> > > > > return 0;
> > > > > }
> > > > >
> > > > > +/**
> > > > > + * xe_pm_d3cold_allowed_toggle - Check conditions to toggle
> > > > > +d3cold.allowed
> > > > > + * @xe: xe device instance
> > > > > + *
> > > > > + * To be called during runtime_pm idle callback.
> > > > > + * Check for all the D3Cold conditions ahead of runtime
> > > > > suspend.
> > > > > + */
> > > > > void xe_pm_d3cold_allowed_toggle(struct xe_device *xe) {
> > > > > struct ttm_resource_manager *man;
> > > > > --
> > > > > 2.43.0
> > > > >
^ permalink raw reply [flat|nested] 26+ messages in thread
* ✗ CI.Patch_applied: failure for series starting with [01/14] drm/xe: Document Xe PM component (rev2)
2024-02-15 19:34 [PATCH 01/14] drm/xe: Document Xe PM component Rodrigo Vivi
` (16 preceding siblings ...)
2024-02-21 12:07 ` [PATCH 01/14] " Francois Dugast
@ 2024-02-21 19:05 ` Patchwork
17 siblings, 0 replies; 26+ messages in thread
From: Patchwork @ 2024-02-21 19:05 UTC (permalink / raw)
To: Rodrigo Vivi; +Cc: intel-xe
== Series Details ==
Series: series starting with [01/14] drm/xe: Document Xe PM component (rev2)
URL : https://patchwork.freedesktop.org/series/129970/
State : failure
== Summary ==
=== Applying kernel patches on branch 'drm-tip' with base: ===
Base commit: 53c127ff2eda drm-tip: 2024y-02m-21d-16h-22m-19s UTC integration manifest
=== git am output follows ===
error: patch failed: drivers/gpu/drm/xe/xe_pm.c:33
error: drivers/gpu/drm/xe/xe_pm.c: patch does not apply
hint: Use 'git am --show-current-patch=diff' to see the failed patch
Applying: drm/xe: Document Xe PM component
Patch failed at 0001 drm/xe: Document Xe PM component
When you have resolved this problem, run "git am --continue".
If you prefer to skip this patch, run "git am --skip" instead.
To restore the original branch and stop patching, run "git am --abort".
^ permalink raw reply [flat|nested] 26+ messages in thread