summaryrefslogtreecommitdiff
path: root/drivers/gpu/drm/amd/amdgpu/amdgpu_xcp.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/amd/amdgpu/amdgpu_xcp.c')
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_xcp.c42
1 files changed, 31 insertions, 11 deletions
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_xcp.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_xcp.c
index 409e103ffe8c..35faea0ff17f 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_xcp.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_xcp.c
@@ -381,7 +381,8 @@ int amdgpu_xcp_get_inst_details(struct amdgpu_xcp *xcp,
enum AMDGPU_XCP_IP_BLOCK ip,
uint32_t *inst_mask)
{
- if (!xcp->valid || !inst_mask || !(xcp->ip[ip].valid))
+ if (!xcp->valid || !inst_mask || ip >= AMDGPU_XCP_MAX_BLOCKS ||
+ !(xcp->ip[ip].valid))
return -EINVAL;
*inst_mask = xcp->ip[ip].inst_mask;
@@ -468,14 +469,18 @@ void amdgpu_xcp_release_sched(struct amdgpu_device *adev,
{
struct drm_gpu_scheduler *sched =
container_of(entity->entity.rq, typeof(*sched), rq);
+ struct amdgpu_xcp_mgr *xcp_mgr = adev->xcp_mgr;
- if (!adev->xcp_mgr)
+ if (!xcp_mgr)
return;
if (drm_sched_wqueue_ready(sched)) {
struct amdgpu_ring *ring = to_amdgpu_ring(sched);
- atomic_dec(&adev->xcp_mgr->xcp[ring->xcp_id].ref_cnt);
+ mutex_lock(&xcp_mgr->xcp_lock);
+ if (ring->xcp_id < xcp_mgr->num_xcps && xcp_mgr->xcp[ring->xcp_id].valid)
+ atomic_dec(&xcp_mgr->xcp[ring->xcp_id].ref_cnt);
+ mutex_unlock(&xcp_mgr->xcp_lock);
}
}
@@ -488,7 +493,9 @@ int amdgpu_xcp_select_scheds(struct amdgpu_device *adev,
u32 sel_xcp_id;
int i;
struct amdgpu_xcp_mgr *xcp_mgr = adev->xcp_mgr;
+ int r = 0;
+ mutex_lock(&xcp_mgr->xcp_lock);
if (fpriv->xcp_id == AMDGPU_XCP_NO_PARTITION) {
u32 least_ref_cnt = ~0;
@@ -505,19 +512,27 @@ int amdgpu_xcp_select_scheds(struct amdgpu_device *adev,
}
sel_xcp_id = fpriv->xcp_id;
+ if (sel_xcp_id >= xcp_mgr->num_xcps || !xcp_mgr->xcp[sel_xcp_id].valid) {
+ dev_err(adev->dev, "Selected partition #%d is not valid.", sel_xcp_id);
+ r = -ENODEV;
+ goto out;
+ }
+
if (xcp_mgr->xcp[sel_xcp_id].gpu_sched[hw_ip][hw_prio].num_scheds) {
*num_scheds =
- xcp_mgr->xcp[fpriv->xcp_id].gpu_sched[hw_ip][hw_prio].num_scheds;
+ xcp_mgr->xcp[sel_xcp_id].gpu_sched[hw_ip][hw_prio].num_scheds;
*scheds =
- xcp_mgr->xcp[fpriv->xcp_id].gpu_sched[hw_ip][hw_prio].sched;
- atomic_inc(&adev->xcp_mgr->xcp[sel_xcp_id].ref_cnt);
+ xcp_mgr->xcp[sel_xcp_id].gpu_sched[hw_ip][hw_prio].sched;
+ atomic_inc(&xcp_mgr->xcp[sel_xcp_id].ref_cnt);
dev_dbg(adev->dev, "Selected partition #%d", sel_xcp_id);
} else {
dev_err(adev->dev, "Failed to schedule partition #%d.", sel_xcp_id);
- return -ENOENT;
+ r = -ENOENT;
}
- return 0;
+out:
+ mutex_unlock(&xcp_mgr->xcp_lock);
+ return r;
}
static void amdgpu_set_xcp_id(struct amdgpu_device *adev,
@@ -574,6 +589,9 @@ static void amdgpu_xcp_gpu_sched_update(struct amdgpu_device *adev,
{
unsigned int *num_gpu_sched;
+ if (sel_xcp_id >= MAX_XCP || sel_xcp_id == AMDGPU_XCP_NO_PARTITION)
+ return;
+
num_gpu_sched = &adev->xcp_mgr->xcp[sel_xcp_id]
.gpu_sched[ring->funcs->type][ring->hw_prio].num_scheds;
adev->xcp_mgr->xcp[sel_xcp_id].gpu_sched[ring->funcs->type][ring->hw_prio]
@@ -903,7 +921,7 @@ static void amdgpu_xcp_cfg_sysfs_init(struct amdgpu_device *adev)
{
struct amdgpu_xcp_res_details *xcp_res;
struct amdgpu_xcp_cfg *xcp_cfg;
- int i, r, j, rid, mode;
+ int i, r, rid, mode;
if (!adev->xcp_mgr)
return;
@@ -949,14 +967,16 @@ static void amdgpu_xcp_cfg_sysfs_init(struct amdgpu_device *adev)
&xcp_cfg_res_sysfs_ktype,
&xcp_cfg->kobj, "%s",
xcp_res_names[rid]);
- if (r)
+ if (r) {
+ kobject_put(&xcp_res->kobj);
goto err;
+ }
}
adev->xcp_mgr->xcp_cfg = xcp_cfg;
return;
err:
- for (j = 0; j < i; j++) {
+ while (i--) {
xcp_res = &xcp_cfg->xcp_res[i];
kobject_put(&xcp_res->kobj);
}