[PATCH 3/6] drm/amdgpu: refactor amdgpu_info_ioctl to allow finer pm

Pierre-Eric Pelloux-Prayer pierre-eric.pelloux-prayer at amd.com
Tue Jun 18 15:23:24 UTC 2024


AMDGPU_INFO_xxx has lots of different queries, and only a small
number of them actually reaches out to the GPU.

This commit extract the amdgpu_info_ioctl implementation to a
helper function, and then wrap it with the runtime pm logic
each query type needs.

Signed-off-by: Pierre-Eric Pelloux-Prayer <pierre-eric.pelloux-prayer at amd.com>
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c |  2 +
 drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c | 94 ++++++++++++++++++++-----
 2 files changed, 80 insertions(+), 16 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
index d21d5af7f187..f51f121d804e 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
@@ -2871,6 +2871,8 @@ long amdgpu_drm_ioctl(struct file *filp,
 
 	if (is_driver_ioctl) {
 		switch (nr - DRM_COMMAND_BASE) {
+		/* amdgpu_info_ioctl will resume the device if it needs to. */
+		case DRM_AMDGPU_INFO:
 		/* These 4 only operate on kernel data structure. */
 		case DRM_AMDGPU_VM:
 		case DRM_AMDGPU_SCHED:
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c
index 260cd0ad286d..b32ff6e1baaf 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c
@@ -543,22 +543,7 @@ static int amdgpu_hw_ip_info(struct amdgpu_device *adev,
 	return 0;
 }
 
-/*
- * Userspace get information ioctl
- */
-/**
- * amdgpu_info_ioctl - answer a device specific request.
- *
- * @dev: drm device pointer
- * @data: request object
- * @filp: drm filp
- *
- * This function is used to pass device specific parameters to the userspace
- * drivers.  Examples include: pci device id, pipeline parms, tiling params,
- * etc. (all asics).
- * Returns 0 on success, -EINVAL on failure.
- */
-int amdgpu_info_ioctl(struct drm_device *dev, void *data, struct drm_file *filp)
+static int amdgpu_info(struct drm_device *dev, void *data, struct drm_file *filp)
 {
 	struct amdgpu_device *adev = drm_to_adev(dev);
 	struct drm_amdgpu_info *info = data;
@@ -1278,6 +1263,83 @@ int amdgpu_info_ioctl(struct drm_device *dev, void *data, struct drm_file *filp)
 	return 0;
 }
 
+/*
+ * Userspace get information ioctl
+ */
+/**
+ * amdgpu_info_ioctl - answer a device specific request.
+ *
+ * @dev: drm device pointer
+ * @data: request object
+ * @filp: drm filp
+ *
+ * This function is used to pass device specific parameters to the userspace
+ * drivers.  Examples include: pci device id, pipeline parms, tiling params,
+ * etc. (all asics).
+ * Returns 0 on success, -EINVAL on failure.
+ */
+int amdgpu_info_ioctl(struct drm_device *dev, void *data, struct drm_file *filp)
+{
+	struct drm_amdgpu_info *info = data;
+	bool need_runtime_pm;
+	int ret;
+
+	if (!info->return_size || !info->return_pointer)
+		return -EINVAL;
+
+	switch (info->query) {
+	case AMDGPU_INFO_ACCEL_WORKING:
+	case AMDGPU_INFO_CRTC_FROM_ID:
+	case AMDGPU_INFO_HW_IP_INFO:
+	case AMDGPU_INFO_HW_IP_COUNT:
+	case AMDGPU_INFO_FW_VERSION:
+	case AMDGPU_INFO_NUM_BYTES_MOVED:
+	case AMDGPU_INFO_NUM_EVICTIONS:
+	case AMDGPU_INFO_NUM_VRAM_CPU_PAGE_FAULTS:
+	case AMDGPU_INFO_VRAM_USAGE:
+	case AMDGPU_INFO_VIS_VRAM_USAGE:
+	case AMDGPU_INFO_GTT_USAGE:
+	case AMDGPU_INFO_GDS_CONFIG:
+	case AMDGPU_INFO_VRAM_GTT:
+	case AMDGPU_INFO_MEMORY:
+	case AMDGPU_INFO_VCE_CLOCK_TABLE:
+	case AMDGPU_INFO_VBIOS:
+	case AMDGPU_INFO_NUM_HANDLES:
+	case AMDGPU_INFO_VRAM_LOST_COUNTER:
+	case AMDGPU_INFO_RAS_ENABLED_FEATURES:
+	case AMDGPU_INFO_VIDEO_CAPS:
+	case AMDGPU_INFO_MAX_IBS:
+	case AMDGPU_INFO_GPUVM_FAULT:
+		need_runtime_pm = false;
+		break;
+
+	case AMDGPU_INFO_TIMESTAMP:
+	case AMDGPU_INFO_READ_MMR_REG:
+	case AMDGPU_INFO_DEV_INFO:
+	case AMDGPU_INFO_SENSOR:
+		need_runtime_pm = true;
+		break;
+	default:
+		DRM_DEBUG_KMS("Invalid request %d\n", info->query);
+		return -EINVAL;
+	}
+
+	if (need_runtime_pm) {
+		ret = pm_runtime_get_sync(dev->dev);
+		if (ret < 0)
+			goto put_pm;
+	}
+
+	ret = amdgpu_info(dev, data, filp);
+
+put_pm:
+	if (need_runtime_pm) {
+		pm_runtime_mark_last_busy(dev->dev);
+		pm_runtime_put_autosuspend(dev->dev);
+	}
+
+	return ret;
+}
 
 /*
  * Outdated mess for old drm with Xorg being in charge (void function now).
-- 
2.40.1



More information about the amd-gfx mailing list