diff options
Diffstat (limited to 'drivers/gpu/drm/amd/amdgpu/amdgpu_xgmi.c')
-rw-r--r-- | drivers/gpu/drm/amd/amdgpu/amdgpu_xgmi.c | 54 |
1 files changed, 35 insertions, 19 deletions
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_xgmi.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_xgmi.c index 8a8bc60cb6b4..407dd16cc35c 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_xgmi.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_xgmi.c @@ -40,26 +40,40 @@ void *amdgpu_xgmi_hive_try_lock(struct amdgpu_hive_info *hive) return &hive->device_list; } -struct amdgpu_hive_info *amdgpu_get_xgmi_hive(struct amdgpu_device *adev) +struct amdgpu_hive_info *amdgpu_get_xgmi_hive(struct amdgpu_device *adev, int lock) { int i; struct amdgpu_hive_info *tmp; if (!adev->gmc.xgmi.hive_id) return NULL; + + mutex_lock(&xgmi_mutex); + for (i = 0 ; i < hive_count; ++i) { tmp = &xgmi_hives[i]; - if (tmp->hive_id == adev->gmc.xgmi.hive_id) + if (tmp->hive_id == adev->gmc.xgmi.hive_id) { + if (lock) + mutex_lock(&tmp->hive_lock); + mutex_unlock(&xgmi_mutex); return tmp; + } } - if (i >= AMDGPU_MAX_XGMI_HIVE) + if (i >= AMDGPU_MAX_XGMI_HIVE) { + mutex_unlock(&xgmi_mutex); return NULL; + } /* initialize new hive if not exist */ tmp = &xgmi_hives[hive_count++]; tmp->hive_id = adev->gmc.xgmi.hive_id; INIT_LIST_HEAD(&tmp->device_list); mutex_init(&tmp->hive_lock); + mutex_init(&tmp->reset_lock); + if (lock) + mutex_lock(&tmp->hive_lock); + + mutex_unlock(&xgmi_mutex); return tmp; } @@ -77,10 +91,6 @@ int amdgpu_xgmi_update_topology(struct amdgpu_hive_info *hive, struct amdgpu_dev "XGMI: Set topology failure on device %llx, hive %llx, ret %d", adev->gmc.xgmi.node_id, adev->gmc.xgmi.hive_id, ret); - else - dev_info(adev->dev, "XGMI: Set topology for node %d, hive 0x%llx.\n", - adev->gmc.xgmi.physical_node_id, - adev->gmc.xgmi.hive_id); return ret; } @@ -111,10 +121,14 @@ int amdgpu_xgmi_add_device(struct amdgpu_device *adev) return ret; } - mutex_lock(&xgmi_mutex); - hive = amdgpu_get_xgmi_hive(adev); - if (!hive) + hive = amdgpu_get_xgmi_hive(adev, 1); + if (!hive) { + ret = -EINVAL; + dev_err(adev->dev, + "XGMI: node 0x%llx, can not match hive 0x%llx in the hive list.\n", + adev->gmc.xgmi.node_id, adev->gmc.xgmi.hive_id); goto exit; + } hive_topology = &hive->topology_info; @@ -142,8 +156,11 @@ int amdgpu_xgmi_add_device(struct amdgpu_device *adev) break; } + dev_info(adev->dev, "XGMI: Add node %d, hive 0x%llx.\n", + adev->gmc.xgmi.physical_node_id, adev->gmc.xgmi.hive_id); + + mutex_unlock(&hive->hive_lock); exit: - mutex_unlock(&xgmi_mutex); return ret; } @@ -154,15 +171,14 @@ void amdgpu_xgmi_remove_device(struct amdgpu_device *adev) if (!adev->gmc.xgmi.supported) return; - mutex_lock(&xgmi_mutex); - - hive = amdgpu_get_xgmi_hive(adev); + hive = amdgpu_get_xgmi_hive(adev, 1); if (!hive) - goto exit; + return; - if (!(hive->number_devices--)) + if (!(hive->number_devices--)) { mutex_destroy(&hive->hive_lock); - -exit: - mutex_unlock(&xgmi_mutex); + mutex_destroy(&hive->reset_lock); + } else { + mutex_unlock(&hive->hive_lock); + } } |