lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <20250731-b4-dont-wake-next-v1-2-e51bdc347fa3@gmail.com>
Date: Thu, 31 Jul 2025 07:36:35 +0200
From: Philipp Zabel <philipp.zabel@...il.com>
To: Alex Deucher <alexander.deucher@....com>, 
 Christian König <christian.koenig@....com>, 
 David Airlie <airlied@...il.com>, Simona Vetter <simona@...ll.ch>
Cc: amd-gfx@...ts.freedesktop.org, dri-devel@...ts.freedesktop.org, 
 linux-kernel@...r.kernel.org, Philipp Zabel <p.zabel@...gutronix.de>, 
 Philipp Zabel <philipp.zabel@...il.com>
Subject: [PATCH RFC 2/6] drm/amdgpu: don't wake up the GPU when opening the
 device

Don't wake the GPU when opening the device. Delay amdgpu_fpriv (and
with it VM) initialization until the first IOCTL that wakes the GPU
anyway, unless it is already active.

Link: https://gitlab.freedesktop.org/drm/amd/-/issues/2295
Signed-off-by: Philipp Zabel <philipp.zabel@...il.com>
---
 drivers/gpu/drm/amd/amdgpu/amdgpu.h         |  4 ++
 drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c |  3 ++
 drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c     | 11 +++++
 drivers/gpu/drm/amd/amdgpu/amdgpu_fdinfo.c  |  3 ++
 drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c     | 66 ++++++++++++++++++++---------
 5 files changed, 68 insertions(+), 19 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
index a1737556a77eb..e33c90c44697e 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
@@ -508,6 +508,8 @@ struct amdgpu_fpriv {
 
 	/** GPU partition selection */
 	uint32_t		xcp_id;
+	struct mutex		init_lock;
+	bool			initialized;
 };
 
 int amdgpu_file_to_fpriv(struct file *filp, struct amdgpu_fpriv **fpriv);
@@ -1617,6 +1619,8 @@ extern const int amdgpu_max_kms_ioctl;
 int amdgpu_driver_load_kms(struct amdgpu_device *adev, unsigned long flags);
 void amdgpu_driver_unload_kms(struct drm_device *dev);
 int amdgpu_driver_open_kms(struct drm_device *dev, struct drm_file *file_priv);
+int amdgpu_driver_init_fpriv(struct drm_device *dev, struct drm_file *file_priv,
+			     struct amdgpu_fpriv *fpriv);
 void amdgpu_driver_postclose_kms(struct drm_device *dev,
 				 struct drm_file *file_priv);
 void amdgpu_driver_release_kms(struct drm_device *dev);
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c
index 0e6e2e2acf5b5..2b6cb3b1ca276 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c
@@ -1784,6 +1784,9 @@ static int amdgpu_debugfs_vm_info_show(struct seq_file *m, void *unused)
 		struct amdgpu_vm *vm = &fpriv->vm;
 		struct amdgpu_task_info *ti;
 
+		if (!fpriv->initialized)
+			continue;
+
 		ti = amdgpu_vm_get_task_info_vm(vm);
 		if (ti) {
 			seq_printf(m, "pid:%d\tProcess:%s ----------\n", ti->task.pid, ti->process_name);
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
index 34b9d63a86227..732f398922da5 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
@@ -2967,6 +2967,7 @@ long amdgpu_drm_ioctl(struct file *filp,
 		      unsigned int cmd, unsigned long arg)
 {
 	struct drm_file *file_priv = filp->private_data;
+	struct amdgpu_fpriv *fpriv = file_priv->driver_priv;
 	struct drm_device *dev;
 	long ret;
 	bool wake = true;
@@ -2984,10 +2985,17 @@ long amdgpu_drm_ioctl(struct file *filp,
 		ret = pm_runtime_get_sync(dev->dev);
 		if (ret < 0)
 			goto out;
+
+		if (unlikely(!fpriv->initialized)) {
+			ret = amdgpu_driver_init_fpriv(dev, file_priv, fpriv);
+			if (ret < 0)
+				goto out_suspend;
+		}
 	}
 
 	ret = drm_ioctl(filp, cmd, arg);
 
+out_suspend:
 	if (wake)
 		pm_runtime_mark_last_busy(dev->dev);
 out:
@@ -3017,6 +3025,9 @@ static int amdgpu_flush(struct file *f, fl_owner_t id)
 	struct amdgpu_fpriv *fpriv = file_priv->driver_priv;
 	long timeout = MAX_WAIT_SCHED_ENTITY_Q_EMPTY;
 
+	if (!fpriv->initialized)
+		return 0;
+
 	timeout = amdgpu_ctx_mgr_entity_flush(&fpriv->ctx_mgr, timeout);
 	timeout = amdgpu_vm_wait_idle(&fpriv->vm, timeout);
 
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_fdinfo.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_fdinfo.c
index 91d638098889d..e13024bcd8bd1 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_fdinfo.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_fdinfo.c
@@ -73,6 +73,9 @@ void amdgpu_show_fdinfo(struct drm_printer *p, struct drm_file *file)
 	};
 	unsigned int hw_ip, i;
 
+	if (!fpriv->initialized)
+		return;
+
 	amdgpu_vm_get_memory(vm, stats);
 	amdgpu_ctx_mgr_usage(&fpriv->ctx_mgr, usage);
 
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c
index 8a76960803c65..60f36e03def2a 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c
@@ -1382,7 +1382,7 @@ int amdgpu_driver_open_kms(struct drm_device *dev, struct drm_file *file_priv)
 {
 	struct amdgpu_device *adev = drm_to_adev(dev);
 	struct amdgpu_fpriv *fpriv;
-	int r, pasid;
+	int r;
 
 	/* Ensure IB tests are run on ring */
 	flush_delayed_work(&adev->delayed_init_work);
@@ -1395,16 +1395,45 @@ int amdgpu_driver_open_kms(struct drm_device *dev, struct drm_file *file_priv)
 
 	file_priv->driver_priv = NULL;
 
-	r = pm_runtime_get_sync(dev->dev);
+	fpriv = kzalloc(sizeof(*fpriv), GFP_KERNEL);
+	if (unlikely(!fpriv))
+		return -ENOMEM;
+
+	mutex_init(&fpriv->init_lock);
+
+	r = pm_runtime_get_if_active(dev->dev);
 	if (r < 0)
-		goto pm_put;
+		goto error_free;
 
-	fpriv = kzalloc(sizeof(*fpriv), GFP_KERNEL);
-	if (unlikely(!fpriv)) {
-		r = -ENOMEM;
-		goto out_suspend;
+	if (r == 1) {
+		r = amdgpu_driver_init_fpriv(dev, file_priv, fpriv);
+
+		pm_runtime_mark_last_busy(dev->dev);
+		pm_runtime_put_autosuspend(dev->dev);
+
+		if (r < 0)
+			goto error_free;
 	}
 
+	file_priv->driver_priv = fpriv;
+	return 0;
+
+error_free:
+	kfree(fpriv);
+
+	return r;
+}
+
+int amdgpu_driver_init_fpriv(struct drm_device *dev, struct drm_file *file_priv,
+			     struct amdgpu_fpriv *fpriv)
+{
+	struct amdgpu_device *adev = drm_to_adev(dev);
+	int r, pasid;
+
+	mutex_lock(&fpriv->init_lock);
+	if (fpriv->initialized)
+		goto out_unlock;
+
 	pasid = amdgpu_pasid_alloc(16);
 	if (pasid < 0) {
 		dev_warn(adev->dev, "No more PASIDs available!");
@@ -1457,8 +1486,8 @@ int amdgpu_driver_open_kms(struct drm_device *dev, struct drm_file *file_priv)
 
 	amdgpu_ctx_mgr_init(&fpriv->ctx_mgr, adev);
 
-	file_priv->driver_priv = fpriv;
-	goto out_suspend;
+	fpriv->initialized = true;
+	goto out_unlock;
 
 error_vm:
 	amdgpu_vm_fini(adev, &fpriv->vm);
@@ -1469,13 +1498,8 @@ int amdgpu_driver_open_kms(struct drm_device *dev, struct drm_file *file_priv)
 		amdgpu_vm_set_pasid(adev, &fpriv->vm, 0);
 	}
 
-	kfree(fpriv);
-
-out_suspend:
-	pm_runtime_mark_last_busy(dev->dev);
-pm_put:
-	pm_runtime_put_autosuspend(dev->dev);
-
+out_unlock:
+	mutex_unlock(&fpriv->init_lock);
 	return r;
 }
 
@@ -1500,6 +1524,9 @@ void amdgpu_driver_postclose_kms(struct drm_device *dev,
 	if (!fpriv)
 		return;
 
+	if (!fpriv->initialized)
+		goto out_free;
+
 	pm_runtime_get_sync(dev->dev);
 
 	if (amdgpu_device_ip_get_ip_block(adev, AMD_IP_BLOCK_TYPE_UVD) != NULL)
@@ -1537,11 +1564,12 @@ void amdgpu_driver_postclose_kms(struct drm_device *dev,
 	idr_destroy(&fpriv->bo_list_handles);
 	mutex_destroy(&fpriv->bo_list_lock);
 
-	kfree(fpriv);
-	file_priv->driver_priv = NULL;
-
 	pm_runtime_mark_last_busy(dev->dev);
 	pm_runtime_put_autosuspend(dev->dev);
+
+out_free:
+	kfree(fpriv);
+	file_priv->driver_priv = NULL;
 }
 
 

-- 
2.50.1


Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ