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); +	}  } | 
