6.12-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jacek Lawrynowicz jacek.lawrynowicz@linux.intel.com
commit d893da85e06edf54737bb80648bb58ba8fd56d9f upstream.
Prevent runtime resume/suspend while MS IOCTLs are in progress. Failed suspend will call ivpu_ms_cleanup() that would try to acquire file_priv->ms_lock, which is already held by the IOCTLs.
Fixes: cdfad4db7756 ("accel/ivpu: Add NPU profiling support") Cc: stable@vger.kernel.org # v6.11+ Signed-off-by: Maciej Falkowski maciej.falkowski@linux.intel.com Reviewed-by: Lizhi Hou lizhi.hou@amd.com Signed-off-by: Jacek Lawrynowicz jacek.lawrynowicz@linux.intel.com Link: https://lore.kernel.org/r/20250325114306.3740022-3-maciej.falkowski@linux.in... Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/accel/ivpu/ivpu_debugfs.c | 4 ++-- drivers/accel/ivpu/ivpu_ms.c | 18 ++++++++++++++++++ 2 files changed, 20 insertions(+), 2 deletions(-)
--- a/drivers/accel/ivpu/ivpu_debugfs.c +++ b/drivers/accel/ivpu/ivpu_debugfs.c @@ -331,7 +331,7 @@ ivpu_force_recovery_fn(struct file *file return -EINVAL;
ret = ivpu_rpm_get(vdev); - if (ret) + if (ret < 0) return ret;
ivpu_pm_trigger_recovery(vdev, "debugfs"); @@ -408,7 +408,7 @@ static int dct_active_set(void *data, u6 return -EINVAL;
ret = ivpu_rpm_get(vdev); - if (ret) + if (ret < 0) return ret;
if (active_percent) --- a/drivers/accel/ivpu/ivpu_ms.c +++ b/drivers/accel/ivpu/ivpu_ms.c @@ -44,6 +44,10 @@ int ivpu_ms_start_ioctl(struct drm_devic args->sampling_period_ns < MS_MIN_SAMPLE_PERIOD_NS) return -EINVAL;
+ ret = ivpu_rpm_get(vdev); + if (ret < 0) + return ret; + mutex_lock(&file_priv->ms_lock);
if (get_instance_by_mask(file_priv, args->metric_group_mask)) { @@ -96,6 +100,8 @@ err_free_ms: kfree(ms); unlock: mutex_unlock(&file_priv->ms_lock); + + ivpu_rpm_put(vdev); return ret; }
@@ -160,6 +166,10 @@ int ivpu_ms_get_data_ioctl(struct drm_de if (!args->metric_group_mask) return -EINVAL;
+ ret = ivpu_rpm_get(vdev); + if (ret < 0) + return ret; + mutex_lock(&file_priv->ms_lock);
ms = get_instance_by_mask(file_priv, args->metric_group_mask); @@ -187,6 +197,7 @@ int ivpu_ms_get_data_ioctl(struct drm_de unlock: mutex_unlock(&file_priv->ms_lock);
+ ivpu_rpm_put(vdev); return ret; }
@@ -204,11 +215,17 @@ int ivpu_ms_stop_ioctl(struct drm_device { struct ivpu_file_priv *file_priv = file->driver_priv; struct drm_ivpu_metric_streamer_stop *args = data; + struct ivpu_device *vdev = file_priv->vdev; struct ivpu_ms_instance *ms; + int ret;
if (!args->metric_group_mask) return -EINVAL;
+ ret = ivpu_rpm_get(vdev); + if (ret < 0) + return ret; + mutex_lock(&file_priv->ms_lock);
ms = get_instance_by_mask(file_priv, args->metric_group_mask); @@ -217,6 +234,7 @@ int ivpu_ms_stop_ioctl(struct drm_device
mutex_unlock(&file_priv->ms_lock);
+ ivpu_rpm_put(vdev); return ms ? 0 : -EINVAL; }