Files
omarchy-pkgs/pkgbuilds/linux-omarchy/8213-xe-hibernation-writeback-gated.patch
T

113 lines
4.1 KiB
Diff

diff --git a/drivers/gpu/drm/xe/xe_defaults.h b/drivers/gpu/drm/xe/xe_defaults.h
--- a/drivers/gpu/drm/xe/xe_defaults.h
+++ b/drivers/gpu/drm/xe/xe_defaults.h
@@ -24,5 +24,6 @@
#define XE_DEFAULT_SVM_NOTIFIER_SIZE 512
#define XE_DEFAULT_SHRINK_ACTIVE_MS 1000
#define XE_DEFAULT_SHRINK_DIRECT_BACKUP false
+#define XE_DEFAULT_HIBERNATE_WRITEBACK false
#endif
diff --git a/drivers/gpu/drm/xe/xe_module.c b/drivers/gpu/drm/xe/xe_module.c
--- a/drivers/gpu/drm/xe/xe_module.c
+++ b/drivers/gpu/drm/xe/xe_module.c
@@ -32,6 +32,7 @@ struct xe_modparam xe_modparam = {
.svm_notifier_size = XE_DEFAULT_SVM_NOTIFIER_SIZE,
.shrink_active_ms = XE_DEFAULT_SHRINK_ACTIVE_MS,
.shrink_direct_backup = XE_DEFAULT_SHRINK_DIRECT_BACKUP,
+ .hibernate_writeback = XE_DEFAULT_HIBERNATE_WRITEBACK,
/* the rest are 0 by default */
};
@@ -48,6 +49,10 @@ module_param_named(shrink_direct_backup, xe_modparam.shrink_direct_backup, bool,
MODULE_PARM_DESC(shrink_direct_backup, "Back up buffer objects in direct reclaim too, not only in kswapd "
"[default=" __stringify(XE_DEFAULT_SHRINK_DIRECT_BACKUP) "]");
+module_param_named(hibernate_writeback, xe_modparam.hibernate_writeback, bool, 0600);
+MODULE_PARM_DESC(hibernate_writeback, "Write buffer objects to swap before hibernation, "
+ "integrated GPUs only [default=" __stringify(XE_DEFAULT_HIBERNATE_WRITEBACK) "]");
+
module_param_named_unsafe(force_execlist, xe_modparam.force_execlist, bool, 0444);
MODULE_PARM_DESC(force_execlist, "Force Execlist submission");
diff --git a/drivers/gpu/drm/xe/xe_module.h b/drivers/gpu/drm/xe/xe_module.h
--- a/drivers/gpu/drm/xe/xe_module.h
+++ b/drivers/gpu/drm/xe/xe_module.h
@@ -27,6 +27,7 @@ struct xe_modparam {
u32 svm_notifier_size;
unsigned int shrink_active_ms;
bool shrink_direct_backup;
+ bool hibernate_writeback;
};
extern struct xe_modparam xe_modparam;
diff --git a/drivers/gpu/drm/xe/xe_pm.c b/drivers/gpu/drm/xe/xe_pm.c
--- a/drivers/gpu/drm/xe/xe_pm.c
+++ b/drivers/gpu/drm/xe/xe_pm.c
@@ -26,6 +26,7 @@
#include "xe_pcode.h"
#include "xe_printk.h"
#include "xe_pxp.h"
+#include "xe_shrinker.h"
#include "xe_sriov_vf_ccs.h"
#include "xe_sysctrl.h"
#include "xe_trace.h"
@@ -450,6 +451,9 @@ static int xe_pm_notifier_callback(struct notifier_block *nb,
if (err)
drm_dbg(&xe->drm, "Notifier evict user failed (%d)\n", err);
+ if (action == PM_HIBERNATION_PREPARE)
+ xe_shrinker_backup_for_hibernation(xe->mem.shrinker);
+
err = xe_bo_notifier_prepare_all_pinned(xe);
if (err)
drm_dbg(&xe->drm, "Notifier prepare pin failed (%d)\n", err);
diff --git a/drivers/gpu/drm/xe/xe_shrinker.c b/drivers/gpu/drm/xe/xe_shrinker.c
--- a/drivers/gpu/drm/xe/xe_shrinker.c
+++ b/drivers/gpu/drm/xe/xe_shrinker.c
@@ -172,6 +172,34 @@ static int xe_shrinker_walk(struct xe_shrinker *shrinker,
return ret;
}
+void xe_shrinker_backup_for_hibernation(struct xe_shrinker *shrinker)
+{
+ struct ttm_operation_ctx ctx = {
+ .interruptible = false,
+ .no_wait_gpu = false,
+ };
+ struct xe_bo_shrink_flags flags = {
+ .purge = false,
+ .writeback = true,
+ };
+ unsigned long to_scan, scanned = 0, freed = 0;
+ ktime_t start = ktime_get();
+ int ret;
+
+ if (!READ_ONCE(xe_modparam.hibernate_writeback) || IS_DGFX(shrinker->xe) ||
+ !ttm_backup_bytes_avail())
+ return;
+
+ read_lock(&shrinker->lock);
+ to_scan = shrinker->shrinkable_pages;
+ read_unlock(&shrinker->lock);
+
+ ret = __xe_shrinker_walk(shrinker, &ctx, flags, to_scan, &scanned, &freed);
+ drm_info(&shrinker->xe->drm,
+ "Hibernation writeback: %lu of %lu pages scanned, %lu freed in %lld ms (%d)\n",
+ scanned, to_scan, freed, ktime_ms_delta(ktime_get(), start), ret);
+}
+
static inline bool xe_shrinker_can_backup(struct xe_shrinker *shrinker,
const struct shrink_control *sc)
{
diff --git a/drivers/gpu/drm/xe/xe_shrinker.h b/drivers/gpu/drm/xe/xe_shrinker.h
--- a/drivers/gpu/drm/xe/xe_shrinker.h
+++ b/drivers/gpu/drm/xe/xe_shrinker.h
@@ -13,4 +13,6 @@ void xe_shrinker_mod_pages(struct xe_shrinker *shrinker, long shrinkable, long p
int xe_shrinker_create(struct xe_device *xe);
+void xe_shrinker_backup_for_hibernation(struct xe_shrinker *shrinker);
+
#endif