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

Commit 35161bbc authored by Andres Rodriguez's avatar Andres Rodriguez Committed by Alex Deucher
Browse files

drm/amdgpu: map compute rings by least recently used pipe



This patch provides a guarantee that the first n queues allocated by
an application will be on different pipes. Where n is the number of
pipes available from the hardware.

This helps avoid ring aliasing which can result in work executing in
time-sliced mode instead of truly parallel mode.

Reviewed-by: default avatarAlex Deucher <alexander.deucher@amd.com>
Signed-off-by: default avatarAndres Rodriguez <andresx7@gmail.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent 4a75aefe
Loading
Loading
Loading
Loading
+5 −3
Original line number Diff line number Diff line
@@ -121,7 +121,7 @@ static enum amdgpu_ring_type amdgpu_hw_ip_to_ring_type(int hw_ip)

static int amdgpu_lru_map(struct amdgpu_device *adev,
			  struct amdgpu_queue_mapper *mapper,
			  int user_ring,
			  int user_ring, bool lru_pipe_order,
			  struct amdgpu_ring **out_ring)
{
	int r, i, j;
@@ -139,7 +139,7 @@ static int amdgpu_lru_map(struct amdgpu_device *adev,
	}

	r = amdgpu_ring_lru_get(adev, ring_type, ring_blacklist,
				j, out_ring);
				j, lru_pipe_order, out_ring);
	if (r)
		return r;

@@ -284,8 +284,10 @@ int amdgpu_queue_mgr_map(struct amdgpu_device *adev,
		r = amdgpu_identity_map(adev, mapper, ring, out_ring);
		break;
	case AMDGPU_HW_IP_DMA:
		r = amdgpu_lru_map(adev, mapper, ring, false, out_ring);
		break;
	case AMDGPU_HW_IP_COMPUTE:
		r = amdgpu_lru_map(adev, mapper, ring, out_ring);
		r = amdgpu_lru_map(adev, mapper, ring, true, out_ring);
		break;
	default:
		*out_ring = NULL;
+20 −5
Original line number Diff line number Diff line
@@ -315,14 +315,16 @@ static bool amdgpu_ring_is_blacklisted(struct amdgpu_ring *ring,
 * @type: amdgpu_ring_type enum
 * @blacklist: blacklisted ring ids array
 * @num_blacklist: number of entries in @blacklist
 * @lru_pipe_order: find a ring from the least recently used pipe
 * @ring: output ring
 *
 * Retrieve the amdgpu_ring structure for the least recently used ring of
 * a specific IP block (all asics).
 * Returns 0 on success, error on failure.
 */
int amdgpu_ring_lru_get(struct amdgpu_device *adev, int type, int *blacklist,
			int num_blacklist, struct amdgpu_ring **ring)
int amdgpu_ring_lru_get(struct amdgpu_device *adev, int type,
			int *blacklist,	int num_blacklist,
			bool lru_pipe_order, struct amdgpu_ring **ring)
{
	struct amdgpu_ring *entry;

@@ -337,10 +339,23 @@ int amdgpu_ring_lru_get(struct amdgpu_device *adev, int type, int *blacklist,
		if (amdgpu_ring_is_blacklisted(entry, blacklist, num_blacklist))
			continue;

		if (!*ring) {
			*ring = entry;
		amdgpu_ring_lru_touch_locked(adev, *ring);

			/* We are done for ring LRU */
			if (!lru_pipe_order)
				break;
		}

		/* Move all rings on the same pipe to the end of the list */
		if (entry->pipe == (*ring)->pipe)
			amdgpu_ring_lru_touch_locked(adev, entry);
	}

	/* Move the ring we found to the end of the list */
	if (*ring)
		amdgpu_ring_lru_touch_locked(adev, *ring);

	spin_unlock(&adev->ring_lru_list_lock);

	if (!*ring) {
+3 −2
Original line number Diff line number Diff line
@@ -201,8 +201,9 @@ int amdgpu_ring_init(struct amdgpu_device *adev, struct amdgpu_ring *ring,
		     unsigned ring_size, struct amdgpu_irq_src *irq_src,
		     unsigned irq_type);
void amdgpu_ring_fini(struct amdgpu_ring *ring);
int amdgpu_ring_lru_get(struct amdgpu_device *adev, int type, int *blacklist,
			int num_blacklist, struct amdgpu_ring **ring);
int amdgpu_ring_lru_get(struct amdgpu_device *adev, int type,
			int *blacklist, int num_blacklist,
			bool lru_pipe_order, struct amdgpu_ring **ring);
void amdgpu_ring_lru_touch(struct amdgpu_device *adev, struct amdgpu_ring *ring);
static inline void amdgpu_ring_clear_ring(struct amdgpu_ring *ring)
{