Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

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

drm/radeon: use one VMID for each ring



Use multiple VMIDs for each VM, one for each ring. That allows
us to execute flushes separately on each ring, still not ideal
cause in a lot of cases rings can share IDs.

Signed-off-by: default avatarChristian König <christian.koenig@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent ad1a58a4
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -4066,6 +4066,7 @@ struct radeon_fence *cik_copy_cpdma(struct radeon_device *rdev,
void cik_ring_ib_execute(struct radeon_device *rdev, struct radeon_ib *ib)
{
	struct radeon_ring *ring = &rdev->ring[ib->ring];
	unsigned vm_id = ib->vm ? ib->vm->ids[ib->ring].id : 0;
	u32 header, control = INDIRECT_BUFFER_VALID;

	if (ib->is_const_ib) {
@@ -4094,8 +4095,7 @@ void cik_ring_ib_execute(struct radeon_device *rdev, struct radeon_ib *ib)
		header = PACKET3(PACKET3_INDIRECT_BUFFER, 2);
	}

	control |= ib->length_dw |
		(ib->vm ? (ib->vm->id << 24) : 0);
	control |= ib->length_dw | (vm_id << 24);

	radeon_ring_write(ring, header);
	radeon_ring_write(ring,
+1 −1
Original line number Diff line number Diff line
@@ -134,7 +134,7 @@ void cik_sdma_ring_ib_execute(struct radeon_device *rdev,
			      struct radeon_ib *ib)
{
	struct radeon_ring *ring = &rdev->ring[ib->ring];
	u32 extra_bits = (ib->vm ? ib->vm->id : 0) & 0xf;
	u32 extra_bits = (ib->vm ? ib->vm->ids[ib->ring].id : 0) & 0xf;

	if (rdev->wb.enabled) {
		u32 next_rptr = ring->wptr + 5;
+3 −3
Original line number Diff line number Diff line
@@ -1373,6 +1373,7 @@ void cayman_fence_ring_emit(struct radeon_device *rdev,
void cayman_ring_ib_execute(struct radeon_device *rdev, struct radeon_ib *ib)
{
	struct radeon_ring *ring = &rdev->ring[ib->ring];
	unsigned vm_id = ib->vm ? ib->vm->ids[ib->ring].id : 0;
	u32 cp_coher_cntl = PACKET3_FULL_CACHE_ENA | PACKET3_TC_ACTION_ENA |
		PACKET3_SH_ACTION_ENA;

@@ -1395,15 +1396,14 @@ void cayman_ring_ib_execute(struct radeon_device *rdev, struct radeon_ib *ib)
#endif
			  (ib->gpu_addr & 0xFFFFFFFC));
	radeon_ring_write(ring, upper_32_bits(ib->gpu_addr) & 0xFF);
	radeon_ring_write(ring, ib->length_dw | 
			  (ib->vm ? (ib->vm->id << 24) : 0));
	radeon_ring_write(ring, ib->length_dw | (vm_id << 24));

	/* flush read cache over gart for this vmid */
	radeon_ring_write(ring, PACKET3(PACKET3_SURFACE_SYNC, 3));
	radeon_ring_write(ring, PACKET3_ENGINE_ME | cp_coher_cntl);
	radeon_ring_write(ring, 0xFFFFFFFF);
	radeon_ring_write(ring, 0);
	radeon_ring_write(ring, ((ib->vm ? ib->vm->id : 0) << 24) | 10); /* poll interval */
	radeon_ring_write(ring, (vm_id << 24) | 10); /* poll interval */
}

static void cayman_cp_enable(struct radeon_device *rdev, bool enable)
+2 −1
Original line number Diff line number Diff line
@@ -123,6 +123,7 @@ void cayman_dma_ring_ib_execute(struct radeon_device *rdev,
				struct radeon_ib *ib)
{
	struct radeon_ring *ring = &rdev->ring[ib->ring];
	unsigned vm_id = ib->vm ? ib->vm->ids[ib->ring].id : 0;

	if (rdev->wb.enabled) {
		u32 next_rptr = ring->wptr + 4;
@@ -140,7 +141,7 @@ void cayman_dma_ring_ib_execute(struct radeon_device *rdev,
	 */
	while ((ring->wptr & 7) != 5)
		radeon_ring_write(ring, DMA_PACKET(DMA_PACKET_NOP, 0, 0, 0));
	radeon_ring_write(ring, DMA_IB_PACKET(DMA_PACKET_INDIRECT_BUFFER, ib->vm ? ib->vm->id : 0, 0));
	radeon_ring_write(ring, DMA_IB_PACKET(DMA_PACKET_INDIRECT_BUFFER, vm_id, 0));
	radeon_ring_write(ring, (ib->gpu_addr & 0xFFFFFFE0));
	radeon_ring_write(ring, (ib->length_dw << 12) | (upper_32_bits(ib->gpu_addr) & 0xFF));

+21 −15
Original line number Diff line number Diff line
@@ -905,9 +905,17 @@ struct radeon_vm_pt {
	uint64_t			addr;
};

struct radeon_vm_id {
	unsigned		id;
	uint64_t		pd_gpu_addr;
	/* last flushed PD/PT update */
	struct radeon_fence	*flushed_updates;
	/* last use of vmid */
	struct radeon_fence	*last_id_use;
};

struct radeon_vm {
	struct rb_root		va;
	unsigned			id;

	/* BOs moved, but not yet updated in the PT */
	struct list_head	invalidated;
@@ -917,7 +925,6 @@ struct radeon_vm {

	/* contains the page directory */
	struct radeon_bo	*page_directory;
	uint64_t			pd_gpu_addr;
	unsigned		max_pde_used;

	/* array of page tables, one for each page directory entry */
@@ -928,10 +935,9 @@ struct radeon_vm {
	struct mutex		mutex;
	/* last fence for cs using this vm */
	struct radeon_fence	*fence;
	/* last flushed PD/PT update */
	struct radeon_fence		*flushed_updates;
	/* last use of vmid */
	struct radeon_fence		*last_id_use;

	/* for id and flush management per ring */
	struct radeon_vm_id	ids[RADEON_NUM_RINGS];
};

struct radeon_vm_manager {
Loading