mirror of
https://github.com/torvalds/linux.git
synced 2026-09-22 04:34:03 +02:00
drm/amdgpu: add generic interfaces for PTL requests in virtualization
Add Performance Throttle Limiter (PTL) support for SR-IOV guest. Since VF cannot communicate with PSP directly at runtime in SR-IOV environment, use mailbox data fields to pass PTL parameters to PF, and parse response status from host mailbox registers. v2: - remove redundent checks - remove unused marco Signed-off-by: Victor Zhao <Victor.Zhao@amd.com> Reviewed-by: Lijo Lazar <lijo.lazar@amd.com> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
This commit is contained in:
parent
0827279ac1
commit
cabbba1716
|
|
@ -1292,8 +1292,19 @@ static int psp_ptl_invoke(struct psp_context *psp, u32 req_code,
|
|||
{
|
||||
struct psp_gfx_cmd_resp *cmd;
|
||||
struct amdgpu_ptl *ptl = &psp->ptl;
|
||||
struct amdgpu_device *adev = psp->adev;
|
||||
int ret;
|
||||
|
||||
if (amdgpu_sriov_vf(adev)) {
|
||||
ret = amdgpu_virt_ptl_request(adev, req_code, ptl_state, fmt1, fmt2);
|
||||
if (!ret) {
|
||||
ptl->enabled = *ptl_state;
|
||||
ptl->fmt1 = *fmt1;
|
||||
ptl->fmt2 = *fmt2;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
cmd = acquire_psp_cmd_buf(psp);
|
||||
|
||||
cmd->cmd_id = GFX_CMD_ID_PERF_HW;
|
||||
|
|
@ -1356,15 +1367,18 @@ int amdgpu_ptl_perf_monitor_ctrl(struct amdgpu_device *adev, u32 req_code,
|
|||
if (!adev || !ptl_state || !fmt1 || !fmt2)
|
||||
return -EINVAL;
|
||||
|
||||
if (amdgpu_sriov_vf(adev))
|
||||
return 0;
|
||||
|
||||
psp = &adev->psp;
|
||||
ptl = &psp->ptl;
|
||||
|
||||
if (ptl->permanently_disabled && *ptl_state == 1)
|
||||
return 0;
|
||||
|
||||
if (amdgpu_sriov_vf(adev)) {
|
||||
ptl_fmt1 = *fmt1;
|
||||
ptl_fmt2 = *fmt2;
|
||||
return psp_ptl_invoke(psp, req_code, ptl_state, &ptl_fmt1, &ptl_fmt2);
|
||||
}
|
||||
|
||||
if (amdgpu_ip_version(adev, GC_HWIP, 0) != IP_VERSION(9, 4, 4) ||
|
||||
psp->sos.fw_version < 0x0036081a)
|
||||
return -EOPNOTSUPP;
|
||||
|
|
|
|||
|
|
@ -2090,3 +2090,39 @@ int amdgpu_virt_send_remote_ras_cmd(struct amdgpu_device *adev,
|
|||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int amdgpu_virt_ptl_request(struct amdgpu_device *adev, u32 req_code,
|
||||
uint32_t *ptl_state, uint32_t *fmt1, uint32_t *fmt2)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (!ptl_state || !fmt1 || !fmt2)
|
||||
return -EINVAL;
|
||||
|
||||
if (!amdgpu_sriov_ptl_support(adev) ||
|
||||
!adev->virt.ops || !adev->virt.ops->req_ptl_update)
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
if (req_code == PSP_PTL_PERF_MON_SET && *ptl_state) {
|
||||
if (*fmt1 == *fmt2) {
|
||||
dev_warn(adev->dev,
|
||||
"PTL formats must be different (fmt1=%u, fmt2=%u)\n",
|
||||
*fmt1, *fmt2);
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
ret = adev->virt.ops->req_ptl_update(adev, req_code, *ptl_state, *fmt1, *fmt2);
|
||||
if (ret) {
|
||||
dev_warn(adev->dev, "VF PTL update request failed: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (req_code == PSP_PTL_PERF_MON_QUERY) {
|
||||
*ptl_state = adev->virt.ptl_state;
|
||||
*fmt1 = adev->virt.ptl_pref_format1;
|
||||
*fmt2 = adev->virt.ptl_pref_format2;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -116,6 +116,8 @@ struct amdgpu_virt_ops {
|
|||
int (*req_ras_chk_criti)(struct amdgpu_device *adev, u64 addr);
|
||||
int (*req_remote_ras_cmd)(struct amdgpu_device *adev,
|
||||
u32 param1, u32 param2, u32 param3);
|
||||
int (*req_ptl_update)(struct amdgpu_device *adev,
|
||||
u32 req_code, u32 ptl_state, u32 fmt1, u32 fmt2);
|
||||
};
|
||||
|
||||
/*
|
||||
|
|
@ -341,6 +343,11 @@ struct amdgpu_virt {
|
|||
/* Spinlock to protect access to the RLCG register interface */
|
||||
spinlock_t rlcg_reg_lock;
|
||||
|
||||
/* PTL (Performance Throttle Limiter) response from host */
|
||||
uint32_t ptl_state;
|
||||
uint32_t ptl_pref_format1;
|
||||
uint32_t ptl_pref_format2;
|
||||
|
||||
struct mutex access_req_mutex;
|
||||
|
||||
union amd_sriov_ras_caps ras_en_caps;
|
||||
|
|
@ -447,6 +454,8 @@ static inline bool is_virtual_machine(void)
|
|||
((adev)->virt.gim_feature & AMDGIM_FEATURE_MES_INFO_ENABLE)
|
||||
#define amdgpu_sriov_is_unitid_support(adev) \
|
||||
((adev)->virt.gim_feature & AMDGIM_FEATURE_UNITID_SUPPORT)
|
||||
#define amdgpu_sriov_ptl_support(adev) \
|
||||
((adev)->virt.gim_feature & AMDGIM_FEATURE_PTL_SUPPORT)
|
||||
|
||||
#define amdgpu_virt_xgmi_migrate_enabled(adev) \
|
||||
((adev)->virt.is_xgmi_node_migrate_enabled && (adev)->gmc.xgmi.node_segment_size != 0)
|
||||
|
|
@ -457,6 +466,8 @@ int amdgpu_virt_request_full_gpu(struct amdgpu_device *adev, bool init);
|
|||
int amdgpu_virt_release_full_gpu(struct amdgpu_device *adev, bool init);
|
||||
int amdgpu_virt_reset_gpu(struct amdgpu_device *adev);
|
||||
void amdgpu_virt_request_init_data(struct amdgpu_device *adev);
|
||||
int amdgpu_virt_ptl_request(struct amdgpu_device *adev, u32 req_code,
|
||||
uint32_t *ptl_state, uint32_t *fmt1, uint32_t *fmt2);
|
||||
void amdgpu_virt_ready_to_reset(struct amdgpu_device *adev);
|
||||
int amdgpu_virt_wait_reset(struct amdgpu_device *adev);
|
||||
int amdgpu_virt_alloc_mm_table(struct amdgpu_device *adev);
|
||||
|
|
|
|||
|
|
@ -404,6 +404,9 @@ enum amd_sriov_mailbox_request_message {
|
|||
MB_REQ_RAS_ERROR_COUNT = 203,
|
||||
MB_REQ_RAS_CPER_DUMP = 204,
|
||||
MB_REQ_RAS_BAD_PAGES = 205,
|
||||
MB_REQ_RAS_CHK_CRITI = 206,
|
||||
MB_REQ_RAS_REMOTE_CMD = 207,
|
||||
MB_REQ_MSG_PTL_UPDATE = 208,
|
||||
};
|
||||
|
||||
/* mailbox message send from host to guest */
|
||||
|
|
@ -424,9 +427,33 @@ enum amd_sriov_mailbox_response_message {
|
|||
MB_RES_MSG_RAS_BAD_PAGES_READY = 15,
|
||||
MB_RES_MSG_RAS_BAD_PAGES_NOTIFICATION = 16,
|
||||
MB_RES_MSG_UNRECOV_ERR_NOTIFICATION = 17,
|
||||
MB_RES_RAS_CHK_CRITI_READY = 18,
|
||||
MB_RES_RAS_REMOTE_CMD_READY = 19,
|
||||
MB_RES_MSG_PTL_UPDATE_READY = 20,
|
||||
MB_RES_MSG_TEXT_MESSAGE = 255
|
||||
};
|
||||
|
||||
/*
|
||||
* Generic response status codes for mailbox data fields.
|
||||
* Used in msg_data[1..N] to indicate operation result.
|
||||
*/
|
||||
enum amd_sriov_response_status {
|
||||
AMD_SRIOV_RESP_SUCCESS = 0,
|
||||
AMD_SRIOV_RESP_FAIL = 1,
|
||||
AMD_SRIOV_RESP_UNSUPPORTED = 2,
|
||||
};
|
||||
|
||||
/*
|
||||
* PTL mailbox data format:
|
||||
* Request: msg_data[1]=req_code, msg_data[2]=ptl_state, msg_data[3]=(fmt1<<16)|fmt2
|
||||
* Response: msg_data[1]=(status<<16)|ptl_state, msg_data[2]=(fmt1<<16)|fmt2
|
||||
*/
|
||||
#define AMD_SRIOV_PTL_PACK_FORMATS(fmt1, fmt2) ((((fmt1) & 0xFFFF) << 16) | ((fmt2) & 0xFFFF))
|
||||
#define AMD_SRIOV_PTL_UNPACK_STATUS(dw) (((dw) >> 16) & 0xFFFF)
|
||||
#define AMD_SRIOV_PTL_UNPACK_STATE(dw) ((dw) & 0xFFFF)
|
||||
#define AMD_SRIOV_PTL_UNPACK_FMT1(dw) (((dw) >> 16) & 0xFFFF)
|
||||
#define AMD_SRIOV_PTL_UNPACK_FMT2(dw) ((dw) & 0xFFFF)
|
||||
|
||||
enum amd_sriov_ras_telemetry_gpu_block {
|
||||
RAS_TELEMETRY_GPU_BLOCK_UMC = 0,
|
||||
RAS_TELEMETRY_GPU_BLOCK_SDMA = 1,
|
||||
|
|
|
|||
|
|
@ -214,6 +214,9 @@ static int xgpu_nv_send_access_requests_with_param(struct amdgpu_device *adev,
|
|||
case IDH_REQ_RAS_REMOTE_CMD:
|
||||
event = IDH_REQ_RAS_REMOTE_CMD_READY;
|
||||
break;
|
||||
case IDH_REQ_PTL_UPDATE:
|
||||
event = IDH_PTL_UPDATE_READY;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
|
@ -253,6 +256,23 @@ static int xgpu_nv_send_access_requests_with_param(struct amdgpu_device *adev,
|
|||
adev->virt.fw_reserve.checksum_key =
|
||||
RREG32_NO_KIQ(mmMAILBOX_MSGBUF_RCV_DW2);
|
||||
}
|
||||
|
||||
/* Retrieve PTL response from mailbox */
|
||||
if (req == IDH_REQ_PTL_UPDATE) {
|
||||
u32 dw1 = RREG32_NO_KIQ(mmMAILBOX_MSGBUF_RCV_DW1);
|
||||
u32 dw2 = RREG32_NO_KIQ(mmMAILBOX_MSGBUF_RCV_DW2);
|
||||
u32 status = AMD_SRIOV_PTL_UNPACK_STATUS(dw1);
|
||||
|
||||
if (status == AMD_SRIOV_RESP_UNSUPPORTED) {
|
||||
r = -EOPNOTSUPP;
|
||||
} else if (status == AMD_SRIOV_RESP_FAIL) {
|
||||
r = -EIO;
|
||||
} else {
|
||||
adev->virt.ptl_state = AMD_SRIOV_PTL_UNPACK_STATE(dw1);
|
||||
adev->virt.ptl_pref_format1 = AMD_SRIOV_PTL_UNPACK_FMT1(dw2);
|
||||
adev->virt.ptl_pref_format2 = AMD_SRIOV_PTL_UNPACK_FMT2(dw2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
out:
|
||||
|
|
@ -597,6 +617,13 @@ static int xgpu_nv_req_remote_ras_cmd(struct amdgpu_device *adev,
|
|||
adev, IDH_REQ_RAS_REMOTE_CMD, param1, param2, param3);
|
||||
}
|
||||
|
||||
static int xgpu_nv_req_ptl_update(struct amdgpu_device *adev,
|
||||
u32 req_code, u32 ptl_state, u32 fmt1, u32 fmt2)
|
||||
{
|
||||
return xgpu_nv_send_access_requests_with_param(adev, IDH_REQ_PTL_UPDATE,
|
||||
req_code, ptl_state, AMD_SRIOV_PTL_PACK_FORMATS(fmt1, fmt2));
|
||||
}
|
||||
|
||||
const struct amdgpu_virt_ops xgpu_nv_virt_ops = {
|
||||
.req_full_gpu = xgpu_nv_request_full_gpu_access,
|
||||
.rel_full_gpu = xgpu_nv_release_full_gpu_access,
|
||||
|
|
@ -612,4 +639,5 @@ const struct amdgpu_virt_ops xgpu_nv_virt_ops = {
|
|||
.req_bad_pages = xgpu_nv_req_ras_bad_pages,
|
||||
.req_ras_chk_criti = xgpu_nv_check_vf_critical_region,
|
||||
.req_remote_ras_cmd = xgpu_nv_req_remote_ras_cmd,
|
||||
.req_ptl_update = xgpu_nv_req_ptl_update,
|
||||
};
|
||||
|
|
|
|||
|
|
@ -45,6 +45,7 @@ enum idh_request {
|
|||
IDH_REQ_RAS_BAD_PAGES = 205,
|
||||
IDH_REQ_RAS_CHK_CRITI = 206,
|
||||
IDH_REQ_RAS_REMOTE_CMD = 207,
|
||||
IDH_REQ_PTL_UPDATE = 208
|
||||
};
|
||||
|
||||
enum idh_event {
|
||||
|
|
@ -66,6 +67,7 @@ enum idh_event {
|
|||
IDH_UNRECOV_ERR_NOTIFICATION = 17,
|
||||
IDH_REQ_RAS_CHK_CRITI_READY = 18,
|
||||
IDH_REQ_RAS_REMOTE_CMD_READY = 19,
|
||||
IDH_PTL_UPDATE_READY = 20,
|
||||
|
||||
IDH_TEXT_MESSAGE = 255,
|
||||
};
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user