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

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
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -1441,6 +1441,7 @@ u32 amdgpu_device_pcie_port_rreg(struct amdgpu_device *adev,
				u32 reg);
void amdgpu_device_pcie_port_wreg(struct amdgpu_device *adev,
				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 *gang);
bool amdgpu_device_has_display_hardware(struct amdgpu_device *adev);
+17 −4
Original line number Diff line number Diff line
@@ -6522,6 +6522,22 @@ void amdgpu_device_pcie_port_wreg(struct amdgpu_device *adev,
	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
 * @adev: amdgpu_device pointer
@@ -6538,10 +6554,7 @@ struct dma_fence *amdgpu_device_switch_gang(struct amdgpu_device *adev,

	do {
		dma_fence_put(old);
		rcu_read_lock();
		old = dma_fence_get_rcu_safe(&adev->gang_submit);
		rcu_read_unlock();

		old = amdgpu_device_get_gang(adev);
		if (old == gang)
			break;

+27 −9
Original line number Diff line number Diff line
@@ -290,7 +290,24 @@ static int amdgpu_vmid_grab_reserved(struct amdgpu_vm *vm,
	     !dma_fence_is_signaled((*id)->last_flush))) {
		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)
				ring = NULL;

@@ -302,6 +319,7 @@ static int amdgpu_vmid_grab_reserved(struct amdgpu_vm *vm,
				*fence = dma_fence_get(tmp);
				return 0;
			}
		}
		needs_flush = true;
	}