Commit a6328c9c authored by Christian König's avatar Christian König Committed by Alex Deucher

drm/amdgpu: fix using the reserved VMID with gang submit

We need to ensure that even when using a reserved VMID that the gang
members can still run in parallel.
Signed-off-by: default avatarChristian König <christian.koenig@amd.com>
Reviewed-by: default avatarAlex Deucher <alexander.deucher@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent b3256385
...@@ -1441,6 +1441,7 @@ u32 amdgpu_device_pcie_port_rreg(struct amdgpu_device *adev, ...@@ -1441,6 +1441,7 @@ u32 amdgpu_device_pcie_port_rreg(struct amdgpu_device *adev,
u32 reg); u32 reg);
void amdgpu_device_pcie_port_wreg(struct amdgpu_device *adev, void amdgpu_device_pcie_port_wreg(struct amdgpu_device *adev,
u32 reg, u32 v); u32 reg, u32 v);
struct dma_fence *amdgpu_device_get_gang(struct amdgpu_device *adev);
struct dma_fence *amdgpu_device_switch_gang(struct amdgpu_device *adev, struct dma_fence *amdgpu_device_switch_gang(struct amdgpu_device *adev,
struct dma_fence *gang); struct dma_fence *gang);
bool amdgpu_device_has_display_hardware(struct amdgpu_device *adev); bool amdgpu_device_has_display_hardware(struct amdgpu_device *adev);
......
...@@ -6522,6 +6522,22 @@ void amdgpu_device_pcie_port_wreg(struct amdgpu_device *adev, ...@@ -6522,6 +6522,22 @@ void amdgpu_device_pcie_port_wreg(struct amdgpu_device *adev,
spin_unlock_irqrestore(&adev->pcie_idx_lock, flags); spin_unlock_irqrestore(&adev->pcie_idx_lock, flags);
} }
/**
* amdgpu_device_get_gang - return a reference to the current gang
* @adev: amdgpu_device pointer
*
* Returns: A new reference to the current gang leader.
*/
struct dma_fence *amdgpu_device_get_gang(struct amdgpu_device *adev)
{
struct dma_fence *fence;
rcu_read_lock();
fence = dma_fence_get_rcu_safe(&adev->gang_submit);
rcu_read_unlock();
return fence;
}
/** /**
* amdgpu_device_switch_gang - switch to a new gang * amdgpu_device_switch_gang - switch to a new gang
* @adev: amdgpu_device pointer * @adev: amdgpu_device pointer
...@@ -6538,10 +6554,7 @@ struct dma_fence *amdgpu_device_switch_gang(struct amdgpu_device *adev, ...@@ -6538,10 +6554,7 @@ struct dma_fence *amdgpu_device_switch_gang(struct amdgpu_device *adev,
do { do {
dma_fence_put(old); dma_fence_put(old);
rcu_read_lock(); old = amdgpu_device_get_gang(adev);
old = dma_fence_get_rcu_safe(&adev->gang_submit);
rcu_read_unlock();
if (old == gang) if (old == gang)
break; break;
......
...@@ -290,7 +290,24 @@ static int amdgpu_vmid_grab_reserved(struct amdgpu_vm *vm, ...@@ -290,7 +290,24 @@ static int amdgpu_vmid_grab_reserved(struct amdgpu_vm *vm,
!dma_fence_is_signaled((*id)->last_flush))) { !dma_fence_is_signaled((*id)->last_flush))) {
struct dma_fence *tmp; struct dma_fence *tmp;
/* Don't use per engine and per process VMID at the same time */ /* Wait for the gang to be assembled before using a
* reserved VMID or otherwise the gang could deadlock.
*/
tmp = amdgpu_device_get_gang(adev);
if (!dma_fence_is_signaled(tmp) && tmp != job->gang_submit) {
*id = NULL;
*fence = tmp;
return 0;
}
dma_fence_put(tmp);
/* Make sure the id is owned by the gang before proceeding */
if (!job->gang_submit ||
(*id)->owner != vm->immediate.fence_context) {
/* Don't use per engine and per process VMID at the
* same time
*/
if (adev->vm_manager.concurrent_flush) if (adev->vm_manager.concurrent_flush)
ring = NULL; ring = NULL;
...@@ -302,6 +319,7 @@ static int amdgpu_vmid_grab_reserved(struct amdgpu_vm *vm, ...@@ -302,6 +319,7 @@ static int amdgpu_vmid_grab_reserved(struct amdgpu_vm *vm,
*fence = dma_fence_get(tmp); *fence = dma_fence_get(tmp);
return 0; return 0;
} }
}
needs_flush = true; needs_flush = true;
} }
......
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