Skip to content

Commit d893da8

Browse files
committed
accel/ivpu: Fix PM related deadlocks in MS IOCTLs
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: [email protected] # v6.11+ Signed-off-by: Maciej Falkowski <[email protected]> Reviewed-by: Lizhi Hou <[email protected]> Signed-off-by: Jacek Lawrynowicz <[email protected]> Link: https://lore.kernel.org/r/[email protected]
1 parent 9a6f567 commit d893da8

File tree

2 files changed

+20
-2
lines changed

2 files changed

+20
-2
lines changed

drivers/accel/ivpu/ivpu_debugfs.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -331,7 +331,7 @@ ivpu_force_recovery_fn(struct file *file, const char __user *user_buf, size_t si
331331
return -EINVAL;
332332

333333
ret = ivpu_rpm_get(vdev);
334-
if (ret)
334+
if (ret < 0)
335335
return ret;
336336

337337
ivpu_pm_trigger_recovery(vdev, "debugfs");
@@ -382,7 +382,7 @@ static int dct_active_set(void *data, u64 active_percent)
382382
return -EINVAL;
383383

384384
ret = ivpu_rpm_get(vdev);
385-
if (ret)
385+
if (ret < 0)
386386
return ret;
387387

388388
if (active_percent)

drivers/accel/ivpu/ivpu_ms.c

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,10 @@ int ivpu_ms_start_ioctl(struct drm_device *dev, void *data, struct drm_file *fil
4545
args->sampling_period_ns < MS_MIN_SAMPLE_PERIOD_NS)
4646
return -EINVAL;
4747

48+
ret = ivpu_rpm_get(vdev);
49+
if (ret < 0)
50+
return ret;
51+
4852
mutex_lock(&file_priv->ms_lock);
4953

5054
if (get_instance_by_mask(file_priv, args->metric_group_mask)) {
@@ -97,6 +101,8 @@ int ivpu_ms_start_ioctl(struct drm_device *dev, void *data, struct drm_file *fil
97101
kfree(ms);
98102
unlock:
99103
mutex_unlock(&file_priv->ms_lock);
104+
105+
ivpu_rpm_put(vdev);
100106
return ret;
101107
}
102108

@@ -161,6 +167,10 @@ int ivpu_ms_get_data_ioctl(struct drm_device *dev, void *data, struct drm_file *
161167
if (!args->metric_group_mask)
162168
return -EINVAL;
163169

170+
ret = ivpu_rpm_get(vdev);
171+
if (ret < 0)
172+
return ret;
173+
164174
mutex_lock(&file_priv->ms_lock);
165175

166176
ms = get_instance_by_mask(file_priv, args->metric_group_mask);
@@ -188,6 +198,7 @@ int ivpu_ms_get_data_ioctl(struct drm_device *dev, void *data, struct drm_file *
188198
unlock:
189199
mutex_unlock(&file_priv->ms_lock);
190200

201+
ivpu_rpm_put(vdev);
191202
return ret;
192203
}
193204

@@ -205,11 +216,17 @@ int ivpu_ms_stop_ioctl(struct drm_device *dev, void *data, struct drm_file *file
205216
{
206217
struct ivpu_file_priv *file_priv = file->driver_priv;
207218
struct drm_ivpu_metric_streamer_stop *args = data;
219+
struct ivpu_device *vdev = file_priv->vdev;
208220
struct ivpu_ms_instance *ms;
221+
int ret;
209222

210223
if (!args->metric_group_mask)
211224
return -EINVAL;
212225

226+
ret = ivpu_rpm_get(vdev);
227+
if (ret < 0)
228+
return ret;
229+
213230
mutex_lock(&file_priv->ms_lock);
214231

215232
ms = get_instance_by_mask(file_priv, args->metric_group_mask);
@@ -218,6 +235,7 @@ int ivpu_ms_stop_ioctl(struct drm_device *dev, void *data, struct drm_file *file
218235

219236
mutex_unlock(&file_priv->ms_lock);
220237

238+
ivpu_rpm_put(vdev);
221239
return ms ? 0 : -EINVAL;
222240
}
223241

0 commit comments

Comments
 (0)