Commit fe8f5b2f authored by Dave Airlie's avatar Dave Airlie

Merge tag 'amd-drm-fixes-6.2-2022-12-21' of...

Merge tag 'amd-drm-fixes-6.2-2022-12-21' of https://gitlab.freedesktop.org/agd5f/linux into drm-next

amd-drm-fixes-6.2-2022-12-21:

amdgpu:
- Avoid large variable on the stack
- S0ix fixes
- SMU 13.x fixes
- VCN fix
- Add missing fence reference

amdkfd:
- Fix init vm error handling
- Fix double release of compute pasid
Signed-off-by: default avatarDave Airlie <airlied@redhat.com>
From: Alex Deucher <alexander.deucher@amd.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20221221205828.6093-1-alexander.deucher@amd.com
parents 38624d2c c1c4a8b2
...@@ -270,8 +270,10 @@ int amdgpu_amdkfd_get_pcie_bandwidth_mbytes(struct amdgpu_device *adev, bool is_ ...@@ -270,8 +270,10 @@ int amdgpu_amdkfd_get_pcie_bandwidth_mbytes(struct amdgpu_device *adev, bool is_
(&((struct amdgpu_fpriv *) \ (&((struct amdgpu_fpriv *) \
((struct drm_file *)(drm_priv))->driver_priv)->vm) ((struct drm_file *)(drm_priv))->driver_priv)->vm)
int amdgpu_amdkfd_gpuvm_set_vm_pasid(struct amdgpu_device *adev,
struct file *filp, u32 pasid);
int amdgpu_amdkfd_gpuvm_acquire_process_vm(struct amdgpu_device *adev, int amdgpu_amdkfd_gpuvm_acquire_process_vm(struct amdgpu_device *adev,
struct file *filp, u32 pasid, struct file *filp,
void **process_info, void **process_info,
struct dma_fence **ef); struct dma_fence **ef);
void amdgpu_amdkfd_gpuvm_release_process_vm(struct amdgpu_device *adev, void amdgpu_amdkfd_gpuvm_release_process_vm(struct amdgpu_device *adev,
......
...@@ -1429,10 +1429,9 @@ static void amdgpu_amdkfd_gpuvm_unpin_bo(struct amdgpu_bo *bo) ...@@ -1429,10 +1429,9 @@ static void amdgpu_amdkfd_gpuvm_unpin_bo(struct amdgpu_bo *bo)
amdgpu_bo_unreserve(bo); amdgpu_bo_unreserve(bo);
} }
int amdgpu_amdkfd_gpuvm_acquire_process_vm(struct amdgpu_device *adev, int amdgpu_amdkfd_gpuvm_set_vm_pasid(struct amdgpu_device *adev,
struct file *filp, u32 pasid, struct file *filp, u32 pasid)
void **process_info,
struct dma_fence **ef)
{ {
struct amdgpu_fpriv *drv_priv; struct amdgpu_fpriv *drv_priv;
struct amdgpu_vm *avm; struct amdgpu_vm *avm;
...@@ -1443,10 +1442,6 @@ int amdgpu_amdkfd_gpuvm_acquire_process_vm(struct amdgpu_device *adev, ...@@ -1443,10 +1442,6 @@ int amdgpu_amdkfd_gpuvm_acquire_process_vm(struct amdgpu_device *adev,
return ret; return ret;
avm = &drv_priv->vm; avm = &drv_priv->vm;
/* Already a compute VM? */
if (avm->process_info)
return -EINVAL;
/* Free the original amdgpu allocated pasid, /* Free the original amdgpu allocated pasid,
* will be replaced with kfd allocated pasid. * will be replaced with kfd allocated pasid.
*/ */
...@@ -1455,14 +1450,36 @@ int amdgpu_amdkfd_gpuvm_acquire_process_vm(struct amdgpu_device *adev, ...@@ -1455,14 +1450,36 @@ int amdgpu_amdkfd_gpuvm_acquire_process_vm(struct amdgpu_device *adev,
amdgpu_vm_set_pasid(adev, avm, 0); amdgpu_vm_set_pasid(adev, avm, 0);
} }
/* Convert VM into a compute VM */ ret = amdgpu_vm_set_pasid(adev, avm, pasid);
ret = amdgpu_vm_make_compute(adev, avm);
if (ret) if (ret)
return ret; return ret;
ret = amdgpu_vm_set_pasid(adev, avm, pasid); return 0;
}
int amdgpu_amdkfd_gpuvm_acquire_process_vm(struct amdgpu_device *adev,
struct file *filp,
void **process_info,
struct dma_fence **ef)
{
struct amdgpu_fpriv *drv_priv;
struct amdgpu_vm *avm;
int ret;
ret = amdgpu_file_to_fpriv(filp, &drv_priv);
if (ret) if (ret)
return ret; return ret;
avm = &drv_priv->vm;
/* Already a compute VM? */
if (avm->process_info)
return -EINVAL;
/* Convert VM into a compute VM */
ret = amdgpu_vm_make_compute(adev, avm);
if (ret)
return ret;
/* Initialize KFD part of the VM and process info */ /* Initialize KFD part of the VM and process info */
ret = init_kfd_vm(avm, process_info, ef); ret = init_kfd_vm(avm, process_info, ef);
if (ret) if (ret)
......
...@@ -3016,14 +3016,15 @@ static int amdgpu_device_ip_suspend_phase2(struct amdgpu_device *adev) ...@@ -3016,14 +3016,15 @@ static int amdgpu_device_ip_suspend_phase2(struct amdgpu_device *adev)
continue; continue;
} }
/* skip suspend of gfx and psp for S0ix /* skip suspend of gfx/mes and psp for S0ix
* gfx is in gfxoff state, so on resume it will exit gfxoff just * gfx is in gfxoff state, so on resume it will exit gfxoff just
* like at runtime. PSP is also part of the always on hardware * like at runtime. PSP is also part of the always on hardware
* so no need to suspend it. * so no need to suspend it.
*/ */
if (adev->in_s0ix && if (adev->in_s0ix &&
(adev->ip_blocks[i].version->type == AMD_IP_BLOCK_TYPE_PSP || (adev->ip_blocks[i].version->type == AMD_IP_BLOCK_TYPE_PSP ||
adev->ip_blocks[i].version->type == AMD_IP_BLOCK_TYPE_GFX)) adev->ip_blocks[i].version->type == AMD_IP_BLOCK_TYPE_GFX ||
adev->ip_blocks[i].version->type == AMD_IP_BLOCK_TYPE_MES))
continue; continue;
/* XXX handle errors */ /* XXX handle errors */
......
...@@ -238,8 +238,10 @@ static int amdgpu_vm_sdma_update(struct amdgpu_vm_update_params *p, ...@@ -238,8 +238,10 @@ static int amdgpu_vm_sdma_update(struct amdgpu_vm_update_params *p,
/* Wait for PD/PT moves to be completed */ /* Wait for PD/PT moves to be completed */
dma_resv_iter_begin(&cursor, bo->tbo.base.resv, DMA_RESV_USAGE_KERNEL); dma_resv_iter_begin(&cursor, bo->tbo.base.resv, DMA_RESV_USAGE_KERNEL);
dma_resv_for_each_fence_unlocked(&cursor, fence) { dma_resv_for_each_fence_unlocked(&cursor, fence) {
dma_fence_get(fence);
r = drm_sched_job_add_dependency(&p->job->base, fence); r = drm_sched_job_add_dependency(&p->job->base, fence);
if (r) { if (r) {
dma_fence_put(fence);
dma_resv_iter_end(&cursor); dma_resv_iter_end(&cursor);
return r; return r;
} }
......
...@@ -1342,7 +1342,8 @@ static int mes_v11_0_late_init(void *handle) ...@@ -1342,7 +1342,8 @@ static int mes_v11_0_late_init(void *handle)
{ {
struct amdgpu_device *adev = (struct amdgpu_device *)handle; struct amdgpu_device *adev = (struct amdgpu_device *)handle;
if (!amdgpu_in_reset(adev) && /* it's only intended for use in mes_self_test case, not for s0ix and reset */
if (!amdgpu_in_reset(adev) && !adev->in_s0ix &&
(adev->ip_versions[GC_HWIP][0] != IP_VERSION(11, 0, 3))) (adev->ip_versions[GC_HWIP][0] != IP_VERSION(11, 0, 3)))
amdgpu_mes_self_test(adev); amdgpu_mes_self_test(adev);
......
...@@ -666,6 +666,7 @@ static int soc21_common_early_init(void *handle) ...@@ -666,6 +666,7 @@ static int soc21_common_early_init(void *handle)
AMD_CG_SUPPORT_VCN_MGCG | AMD_CG_SUPPORT_VCN_MGCG |
AMD_CG_SUPPORT_JPEG_MGCG; AMD_CG_SUPPORT_JPEG_MGCG;
adev->pg_flags = AMD_PG_SUPPORT_VCN | adev->pg_flags = AMD_PG_SUPPORT_VCN |
AMD_PG_SUPPORT_VCN_DPG |
AMD_PG_SUPPORT_GFX_PG | AMD_PG_SUPPORT_GFX_PG |
AMD_PG_SUPPORT_JPEG; AMD_PG_SUPPORT_JPEG;
adev->external_rev_id = adev->rev_id + 0x1; adev->external_rev_id = adev->rev_id + 0x1;
......
...@@ -689,13 +689,13 @@ void kfd_process_destroy_wq(void) ...@@ -689,13 +689,13 @@ void kfd_process_destroy_wq(void)
} }
static void kfd_process_free_gpuvm(struct kgd_mem *mem, static void kfd_process_free_gpuvm(struct kgd_mem *mem,
struct kfd_process_device *pdd, void *kptr) struct kfd_process_device *pdd, void **kptr)
{ {
struct kfd_dev *dev = pdd->dev; struct kfd_dev *dev = pdd->dev;
if (kptr) { if (kptr && *kptr) {
amdgpu_amdkfd_gpuvm_unmap_gtt_bo_from_kernel(mem); amdgpu_amdkfd_gpuvm_unmap_gtt_bo_from_kernel(mem);
kptr = NULL; *kptr = NULL;
} }
amdgpu_amdkfd_gpuvm_unmap_memory_from_gpu(dev->adev, mem, pdd->drm_priv); amdgpu_amdkfd_gpuvm_unmap_memory_from_gpu(dev->adev, mem, pdd->drm_priv);
...@@ -795,7 +795,7 @@ static void kfd_process_device_destroy_ib_mem(struct kfd_process_device *pdd) ...@@ -795,7 +795,7 @@ static void kfd_process_device_destroy_ib_mem(struct kfd_process_device *pdd)
if (!qpd->ib_kaddr || !qpd->ib_base) if (!qpd->ib_kaddr || !qpd->ib_base)
return; return;
kfd_process_free_gpuvm(qpd->ib_mem, pdd, qpd->ib_kaddr); kfd_process_free_gpuvm(qpd->ib_mem, pdd, &qpd->ib_kaddr);
} }
struct kfd_process *kfd_create_process(struct file *filep) struct kfd_process *kfd_create_process(struct file *filep)
...@@ -1277,7 +1277,7 @@ static void kfd_process_device_destroy_cwsr_dgpu(struct kfd_process_device *pdd) ...@@ -1277,7 +1277,7 @@ static void kfd_process_device_destroy_cwsr_dgpu(struct kfd_process_device *pdd)
if (!dev->cwsr_enabled || !qpd->cwsr_kaddr || !qpd->cwsr_base) if (!dev->cwsr_enabled || !qpd->cwsr_kaddr || !qpd->cwsr_base)
return; return;
kfd_process_free_gpuvm(qpd->cwsr_mem, pdd, qpd->cwsr_kaddr); kfd_process_free_gpuvm(qpd->cwsr_mem, pdd, &qpd->cwsr_kaddr);
} }
void kfd_process_set_trap_handler(struct qcm_process_device *qpd, void kfd_process_set_trap_handler(struct qcm_process_device *qpd,
...@@ -1576,9 +1576,9 @@ int kfd_process_device_init_vm(struct kfd_process_device *pdd, ...@@ -1576,9 +1576,9 @@ int kfd_process_device_init_vm(struct kfd_process_device *pdd,
p = pdd->process; p = pdd->process;
dev = pdd->dev; dev = pdd->dev;
ret = amdgpu_amdkfd_gpuvm_acquire_process_vm( ret = amdgpu_amdkfd_gpuvm_acquire_process_vm(dev->adev, drm_file,
dev->adev, drm_file, p->pasid, &p->kgd_process_info,
&p->kgd_process_info, &p->ef); &p->ef);
if (ret) { if (ret) {
pr_err("Failed to create process VM object\n"); pr_err("Failed to create process VM object\n");
return ret; return ret;
...@@ -1593,13 +1593,19 @@ int kfd_process_device_init_vm(struct kfd_process_device *pdd, ...@@ -1593,13 +1593,19 @@ int kfd_process_device_init_vm(struct kfd_process_device *pdd,
if (ret) if (ret)
goto err_init_cwsr; goto err_init_cwsr;
ret = amdgpu_amdkfd_gpuvm_set_vm_pasid(dev->adev, drm_file, p->pasid);
if (ret)
goto err_set_pasid;
pdd->drm_file = drm_file; pdd->drm_file = drm_file;
return 0; return 0;
err_set_pasid:
kfd_process_device_destroy_cwsr_dgpu(pdd);
err_init_cwsr: err_init_cwsr:
kfd_process_device_destroy_ib_mem(pdd);
err_reserve_ib_mem: err_reserve_ib_mem:
kfd_process_device_free_bos(pdd);
pdd->drm_priv = NULL; pdd->drm_priv = NULL;
return ret; return ret;
......
...@@ -522,9 +522,9 @@ typedef enum { ...@@ -522,9 +522,9 @@ typedef enum {
TEMP_HOTSPOT_M, TEMP_HOTSPOT_M,
TEMP_MEM, TEMP_MEM,
TEMP_VR_GFX, TEMP_VR_GFX,
TEMP_VR_SOC,
TEMP_VR_MEM0, TEMP_VR_MEM0,
TEMP_VR_MEM1, TEMP_VR_MEM1,
TEMP_VR_SOC,
TEMP_VR_U, TEMP_VR_U,
TEMP_LIQUID0, TEMP_LIQUID0,
TEMP_LIQUID1, TEMP_LIQUID1,
......
...@@ -28,6 +28,7 @@ ...@@ -28,6 +28,7 @@
#define SMU13_DRIVER_IF_VERSION_INV 0xFFFFFFFF #define SMU13_DRIVER_IF_VERSION_INV 0xFFFFFFFF
#define SMU13_DRIVER_IF_VERSION_YELLOW_CARP 0x04 #define SMU13_DRIVER_IF_VERSION_YELLOW_CARP 0x04
#define SMU13_DRIVER_IF_VERSION_ALDE 0x08 #define SMU13_DRIVER_IF_VERSION_ALDE 0x08
#define SMU13_DRIVER_IF_VERSION_SMU_V13_0_0_0 0x34
#define SMU13_DRIVER_IF_VERSION_SMU_V13_0_4 0x07 #define SMU13_DRIVER_IF_VERSION_SMU_V13_0_4 0x07
#define SMU13_DRIVER_IF_VERSION_SMU_V13_0_5 0x04 #define SMU13_DRIVER_IF_VERSION_SMU_V13_0_5 0x04
#define SMU13_DRIVER_IF_VERSION_SMU_V13_0_0_10 0x32 #define SMU13_DRIVER_IF_VERSION_SMU_V13_0_0_10 0x32
......
...@@ -290,6 +290,8 @@ int smu_v13_0_check_fw_version(struct smu_context *smu) ...@@ -290,6 +290,8 @@ int smu_v13_0_check_fw_version(struct smu_context *smu)
smu->smc_driver_if_version = SMU13_DRIVER_IF_VERSION_ALDE; smu->smc_driver_if_version = SMU13_DRIVER_IF_VERSION_ALDE;
break; break;
case IP_VERSION(13, 0, 0): case IP_VERSION(13, 0, 0):
smu->smc_driver_if_version = SMU13_DRIVER_IF_VERSION_SMU_V13_0_0_0;
break;
case IP_VERSION(13, 0, 10): case IP_VERSION(13, 0, 10):
smu->smc_driver_if_version = SMU13_DRIVER_IF_VERSION_SMU_V13_0_0_10; smu->smc_driver_if_version = SMU13_DRIVER_IF_VERSION_SMU_V13_0_0_10;
break; break;
......
...@@ -1441,12 +1441,23 @@ static void smu_v13_0_0_get_unique_id(struct smu_context *smu) ...@@ -1441,12 +1441,23 @@ static void smu_v13_0_0_get_unique_id(struct smu_context *smu)
static int smu_v13_0_0_get_fan_speed_pwm(struct smu_context *smu, static int smu_v13_0_0_get_fan_speed_pwm(struct smu_context *smu,
uint32_t *speed) uint32_t *speed)
{ {
int ret;
if (!speed) if (!speed)
return -EINVAL; return -EINVAL;
return smu_v13_0_0_get_smu_metrics_data(smu, ret = smu_v13_0_0_get_smu_metrics_data(smu,
METRICS_CURR_FANPWM, METRICS_CURR_FANPWM,
speed); speed);
if (ret) {
dev_err(smu->adev->dev, "Failed to get fan speed(PWM)!");
return ret;
}
/* Convert the PMFW output which is in percent to pwm(255) based */
*speed = MIN(*speed * 255 / 100, 255);
return 0;
} }
static int smu_v13_0_0_get_fan_speed_rpm(struct smu_context *smu, static int smu_v13_0_0_get_fan_speed_rpm(struct smu_context *smu,
......
...@@ -1363,12 +1363,23 @@ static int smu_v13_0_7_populate_umd_state_clk(struct smu_context *smu) ...@@ -1363,12 +1363,23 @@ static int smu_v13_0_7_populate_umd_state_clk(struct smu_context *smu)
static int smu_v13_0_7_get_fan_speed_pwm(struct smu_context *smu, static int smu_v13_0_7_get_fan_speed_pwm(struct smu_context *smu,
uint32_t *speed) uint32_t *speed)
{ {
int ret;
if (!speed) if (!speed)
return -EINVAL; return -EINVAL;
return smu_v13_0_7_get_smu_metrics_data(smu, ret = smu_v13_0_7_get_smu_metrics_data(smu,
METRICS_CURR_FANPWM, METRICS_CURR_FANPWM,
speed); speed);
if (ret) {
dev_err(smu->adev->dev, "Failed to get fan speed(PWM)!");
return ret;
}
/* Convert the PMFW output which is in percent to pwm(255) based */
*speed = MIN(*speed * 255 / 100, 255);
return 0;
} }
static int smu_v13_0_7_get_fan_speed_rpm(struct smu_context *smu, static int smu_v13_0_7_get_fan_speed_rpm(struct smu_context *smu,
...@@ -1440,7 +1451,7 @@ static int smu_v13_0_7_get_power_limit(struct smu_context *smu, ...@@ -1440,7 +1451,7 @@ static int smu_v13_0_7_get_power_limit(struct smu_context *smu,
static int smu_v13_0_7_get_power_profile_mode(struct smu_context *smu, char *buf) static int smu_v13_0_7_get_power_profile_mode(struct smu_context *smu, char *buf)
{ {
DpmActivityMonitorCoeffIntExternal_t activity_monitor_external[PP_SMC_POWER_PROFILE_COUNT]; DpmActivityMonitorCoeffIntExternal_t *activity_monitor_external;
uint32_t i, j, size = 0; uint32_t i, j, size = 0;
int16_t workload_type = 0; int16_t workload_type = 0;
int result = 0; int result = 0;
...@@ -1448,6 +1459,12 @@ static int smu_v13_0_7_get_power_profile_mode(struct smu_context *smu, char *buf ...@@ -1448,6 +1459,12 @@ static int smu_v13_0_7_get_power_profile_mode(struct smu_context *smu, char *buf
if (!buf) if (!buf)
return -EINVAL; return -EINVAL;
activity_monitor_external = kcalloc(PP_SMC_POWER_PROFILE_COUNT,
sizeof(*activity_monitor_external),
GFP_KERNEL);
if (!activity_monitor_external)
return -ENOMEM;
size += sysfs_emit_at(buf, size, " "); size += sysfs_emit_at(buf, size, " ");
for (i = 0; i <= PP_SMC_POWER_PROFILE_WINDOW3D; i++) for (i = 0; i <= PP_SMC_POWER_PROFILE_WINDOW3D; i++)
size += sysfs_emit_at(buf, size, "%-14s%s", amdgpu_pp_profile_name[i], size += sysfs_emit_at(buf, size, "%-14s%s", amdgpu_pp_profile_name[i],
...@@ -1460,15 +1477,17 @@ static int smu_v13_0_7_get_power_profile_mode(struct smu_context *smu, char *buf ...@@ -1460,15 +1477,17 @@ static int smu_v13_0_7_get_power_profile_mode(struct smu_context *smu, char *buf
workload_type = smu_cmn_to_asic_specific_index(smu, workload_type = smu_cmn_to_asic_specific_index(smu,
CMN2ASIC_MAPPING_WORKLOAD, CMN2ASIC_MAPPING_WORKLOAD,
i); i);
if (workload_type < 0) if (workload_type < 0) {
return -EINVAL; result = -EINVAL;
goto out;
}
result = smu_cmn_update_table(smu, result = smu_cmn_update_table(smu,
SMU_TABLE_ACTIVITY_MONITOR_COEFF, workload_type, SMU_TABLE_ACTIVITY_MONITOR_COEFF, workload_type,
(void *)(&activity_monitor_external[i]), false); (void *)(&activity_monitor_external[i]), false);
if (result) { if (result) {
dev_err(smu->adev->dev, "[%s] Failed to get activity monitor!", __func__); dev_err(smu->adev->dev, "[%s] Failed to get activity monitor!", __func__);
return result; goto out;
} }
} }
...@@ -1496,7 +1515,10 @@ do { \ ...@@ -1496,7 +1515,10 @@ do { \
PRINT_DPM_MONITOR(Fclk_BoosterFreq); PRINT_DPM_MONITOR(Fclk_BoosterFreq);
#undef PRINT_DPM_MONITOR #undef PRINT_DPM_MONITOR
return size; result = size;
out:
kfree(activity_monitor_external);
return result;
} }
static int smu_v13_0_7_set_power_profile_mode(struct smu_context *smu, long *input, uint32_t size) static int smu_v13_0_7_set_power_profile_mode(struct smu_context *smu, long *input, uint32_t size)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment