Skip to content

Commit

Permalink
accel/ivpu: Fix PM related deadlocks in MS IOCTLs
Browse files Browse the repository at this point in the history
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: cdfad4d ("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.intel.com
  • Loading branch information
Jacek Lawrynowicz committed Mar 31, 2025
1 parent 9a6f567 commit d893da8
Show file tree
Hide file tree
Showing 2 changed files with 20 additions and 2 deletions.
4 changes: 2 additions & 2 deletions drivers/accel/ivpu/ivpu_debugfs.c
Original file line number Diff line number Diff line change
Expand Up @@ -331,7 +331,7 @@ ivpu_force_recovery_fn(struct file *file, const char __user *user_buf, size_t si
return -EINVAL;

ret = ivpu_rpm_get(vdev);
if (ret)
if (ret < 0)
return ret;

ivpu_pm_trigger_recovery(vdev, "debugfs");
Expand Down Expand Up @@ -382,7 +382,7 @@ static int dct_active_set(void *data, u64 active_percent)
return -EINVAL;

ret = ivpu_rpm_get(vdev);
if (ret)
if (ret < 0)
return ret;

if (active_percent)
Expand Down
18 changes: 18 additions & 0 deletions drivers/accel/ivpu/ivpu_ms.c
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,10 @@ int ivpu_ms_start_ioctl(struct drm_device *dev, void *data, struct drm_file *fil
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)) {
Expand Down Expand Up @@ -97,6 +101,8 @@ int ivpu_ms_start_ioctl(struct drm_device *dev, void *data, struct drm_file *fil
kfree(ms);
unlock:
mutex_unlock(&file_priv->ms_lock);

ivpu_rpm_put(vdev);
return ret;
}

Expand Down Expand Up @@ -161,6 +167,10 @@ int ivpu_ms_get_data_ioctl(struct drm_device *dev, void *data, struct drm_file *
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);
Expand Down Expand Up @@ -188,6 +198,7 @@ int ivpu_ms_get_data_ioctl(struct drm_device *dev, void *data, struct drm_file *
unlock:
mutex_unlock(&file_priv->ms_lock);

ivpu_rpm_put(vdev);
return ret;
}

Expand All @@ -205,11 +216,17 @@ int ivpu_ms_stop_ioctl(struct drm_device *dev, void *data, struct drm_file *file
{
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);
Expand All @@ -218,6 +235,7 @@ int ivpu_ms_stop_ioctl(struct drm_device *dev, void *data, struct drm_file *file

mutex_unlock(&file_priv->ms_lock);

ivpu_rpm_put(vdev);
return ms ? 0 : -EINVAL;
}

Expand Down

0 comments on commit d893da8

Please sign in to comment.