Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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: 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.intel.com

+20 -2
+2 -2
drivers/accel/ivpu/ivpu_debugfs.c
··· 331 331 return -EINVAL; 332 332 333 333 ret = ivpu_rpm_get(vdev); 334 - if (ret) 334 + if (ret < 0) 335 335 return ret; 336 336 337 337 ivpu_pm_trigger_recovery(vdev, "debugfs"); ··· 382 382 return -EINVAL; 383 383 384 384 ret = ivpu_rpm_get(vdev); 385 - if (ret) 385 + if (ret < 0) 386 386 return ret; 387 387 388 388 if (active_percent)
+18
drivers/accel/ivpu/ivpu_ms.c
··· 45 45 args->sampling_period_ns < MS_MIN_SAMPLE_PERIOD_NS) 46 46 return -EINVAL; 47 47 48 + ret = ivpu_rpm_get(vdev); 49 + if (ret < 0) 50 + return ret; 51 + 48 52 mutex_lock(&file_priv->ms_lock); 49 53 50 54 if (get_instance_by_mask(file_priv, args->metric_group_mask)) { ··· 101 97 kfree(ms); 102 98 unlock: 103 99 mutex_unlock(&file_priv->ms_lock); 100 + 101 + ivpu_rpm_put(vdev); 104 102 return ret; 105 103 } 106 104 ··· 167 161 if (!args->metric_group_mask) 168 162 return -EINVAL; 169 163 164 + ret = ivpu_rpm_get(vdev); 165 + if (ret < 0) 166 + return ret; 167 + 170 168 mutex_lock(&file_priv->ms_lock); 171 169 172 170 ms = get_instance_by_mask(file_priv, args->metric_group_mask); ··· 198 188 unlock: 199 189 mutex_unlock(&file_priv->ms_lock); 200 190 191 + ivpu_rpm_put(vdev); 201 192 return ret; 202 193 } 203 194 ··· 216 205 { 217 206 struct ivpu_file_priv *file_priv = file->driver_priv; 218 207 struct drm_ivpu_metric_streamer_stop *args = data; 208 + struct ivpu_device *vdev = file_priv->vdev; 219 209 struct ivpu_ms_instance *ms; 210 + int ret; 220 211 221 212 if (!args->metric_group_mask) 222 213 return -EINVAL; 214 + 215 + ret = ivpu_rpm_get(vdev); 216 + if (ret < 0) 217 + return ret; 223 218 224 219 mutex_lock(&file_priv->ms_lock); 225 220 ··· 235 218 236 219 mutex_unlock(&file_priv->ms_lock); 237 220 221 + ivpu_rpm_put(vdev); 238 222 return ms ? 0 : -EINVAL; 239 223 } 240 224