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

Commit 7851820e authored by Jordan Crouse's avatar Jordan Crouse
Browse files

drm/msm: Use per-ring submit lists



To make it easier to determine what submit(s) are currently active
on any given ring, store the active submits in per-ring lists instead
of a master list.

Change-Id: Ic0dedbadb331cd8e4e85dfcfa51cb1ceabe6efa9
Signed-off-by: default avatarJordan Crouse <jcrouse@codeaurora.org>
parent 5fb06424
Loading
Loading
Loading
Loading
+1 −1
Original line number Original line Diff line number Diff line
@@ -140,7 +140,7 @@ static inline uint32_t msm_gem_fence(struct msm_gem_object *msm_obj,
struct msm_gem_submit {
struct msm_gem_submit {
	struct drm_device *dev;
	struct drm_device *dev;
	struct msm_gem_address_space *aspace;
	struct msm_gem_address_space *aspace;
	struct list_head node;   /* node in gpu submit_list */
	struct list_head node;   /* node in ring submit list */
	struct list_head bo_list;
	struct list_head bo_list;
	struct ww_acquire_ctx ticket;
	struct ww_acquire_ctx ticket;
	uint32_t fence;
	uint32_t fence;
+23 −32
Original line number Original line Diff line number Diff line
@@ -278,7 +278,8 @@ static void inactive_start(struct msm_gpu *gpu)
 * Hangcheck detection for locked gpu:
 * Hangcheck detection for locked gpu:
 */
 */


static void retire_submits(struct msm_gpu *gpu, uint32_t fence);
static void retire_submits(struct msm_gpu *gpu, struct msm_ringbuffer *ring,
		uint32_t fence);


static void recover_worker(struct work_struct *work)
static void recover_worker(struct work_struct *work)
{
{
@@ -296,28 +297,21 @@ static void recover_worker(struct work_struct *work)
		inactive_cancel(gpu);
		inactive_cancel(gpu);


		FOR_EACH_RING(gpu, ring, i) {
		FOR_EACH_RING(gpu, ring, i) {
			uint32_t fence;
			uint32_t fence = gpu->funcs->last_fence(gpu, ring);

			if (!ring)
				continue;

			fence = gpu->funcs->last_fence(gpu, ring);


			/*
			retire_submits(gpu, ring,
			 * Retire the faulting command on the active ring and
				gpu->funcs->active_ring(gpu) == ring ?
			 * make sure the other rings are cleaned up
					fence + 1 : fence);
			 */
			if (ring == gpu->funcs->active_ring(gpu))
				retire_submits(gpu, fence + 1);
			else
				retire_submits(gpu, fence);
		}
		}


		/* Recover the GPU */
		/* Recover the GPU */
		gpu->funcs->recover(gpu);
		gpu->funcs->recover(gpu);


		/* replay the remaining submits for all rings: */
		/* Replay the remaining on all rings, highest priority first */
		list_for_each_entry(submit, &gpu->submit_list, node) {
		for (i = gpu->nr_rings - 1; i >= 0; i--) {
			struct msm_ringbuffer *ring = gpu->rb[i];

			list_for_each_entry(submit, &ring->submits, node)
				gpu->funcs->submit(gpu, submit);
				gpu->funcs->submit(gpu, submit);
		}
		}
	}
	}
@@ -465,24 +459,21 @@ out:
 * Cmdstream submission/retirement:
 * Cmdstream submission/retirement:
 */
 */


static void retire_submits(struct msm_gpu *gpu, uint32_t fence)
static void retire_submits(struct msm_gpu *gpu, struct msm_ringbuffer *ring,
		uint32_t fence)
{
{
	struct drm_device *dev = gpu->dev;
	struct drm_device *dev = gpu->dev;
	struct msm_gem_submit *submit, *tmp;
	struct msm_gem_submit *submit, *tmp;


	WARN_ON(!mutex_is_locked(&dev->struct_mutex));
	WARN_ON(!mutex_is_locked(&dev->struct_mutex));


	/*
	list_for_each_entry_safe(submit, tmp, &ring->submits, node) {
	 * Find and retire all the submits in the same ring that are older than
		if (submit->fence > fence)
	 * or equal to 'fence'
			break;
	 */


	list_for_each_entry_safe(submit, tmp, &gpu->submit_list, node) {
		if (COMPARE_FENCE_LTE(submit->fence, fence)) {
		msm_gem_submit_free(submit);
		msm_gem_submit_free(submit);
	}
	}
}
}
}


static bool _fence_signaled(struct msm_gem_object *obj, uint32_t fence)
static bool _fence_signaled(struct msm_gem_object *obj, uint32_t fence)
{
{
@@ -492,11 +483,12 @@ static bool _fence_signaled(struct msm_gem_object *obj, uint32_t fence)
	return COMPARE_FENCE_LTE(obj->read_fence, fence);
	return COMPARE_FENCE_LTE(obj->read_fence, fence);
}
}


static void _retire_ring(struct msm_gpu *gpu, uint32_t fence)
static void _retire_ring(struct msm_gpu *gpu, struct msm_ringbuffer *ring,
		uint32_t fence)
{
{
	struct msm_gem_object *obj, *tmp;
	struct msm_gem_object *obj, *tmp;


	retire_submits(gpu, fence);
	retire_submits(gpu, ring, fence);


	list_for_each_entry_safe(obj, tmp, &gpu->active_list, mm_list) {
	list_for_each_entry_safe(obj, tmp, &gpu->active_list, mm_list) {
		if (_fence_signaled(obj, fence)) {
		if (_fence_signaled(obj, fence)) {
@@ -524,7 +516,7 @@ static void retire_worker(struct work_struct *work)
		msm_update_fence(gpu->dev, fence);
		msm_update_fence(gpu->dev, fence);


		mutex_lock(&dev->struct_mutex);
		mutex_lock(&dev->struct_mutex);
		_retire_ring(gpu, fence);
		_retire_ring(gpu, ring, fence);
		mutex_unlock(&dev->struct_mutex);
		mutex_unlock(&dev->struct_mutex);
	}
	}


@@ -554,7 +546,7 @@ int msm_gpu_submit(struct msm_gpu *gpu, struct msm_gem_submit *submit)


	inactive_cancel(gpu);
	inactive_cancel(gpu);


	list_add_tail(&submit->node, &gpu->submit_list);
	list_add_tail(&submit->node, &ring->submits);


	msm_rd_dump_submit(submit);
	msm_rd_dump_submit(submit);


@@ -817,7 +809,6 @@ int msm_gpu_init(struct drm_device *drm, struct platform_device *pdev,
	INIT_WORK(&gpu->inactive_work, inactive_worker);
	INIT_WORK(&gpu->inactive_work, inactive_worker);
	INIT_WORK(&gpu->recover_work, recover_worker);
	INIT_WORK(&gpu->recover_work, recover_worker);


	INIT_LIST_HEAD(&gpu->submit_list);


	setup_timer(&gpu->inactive_timer, inactive_handler,
	setup_timer(&gpu->inactive_timer, inactive_handler,
			(unsigned long)gpu);
			(unsigned long)gpu);
+0 −3
Original line number Original line Diff line number Diff line
@@ -147,9 +147,6 @@ struct msm_gpu {
	struct timer_list hangcheck_timer;
	struct timer_list hangcheck_timer;
	uint32_t hangcheck_fence[MSM_GPU_MAX_RINGS];
	uint32_t hangcheck_fence[MSM_GPU_MAX_RINGS];
	struct work_struct recover_work;
	struct work_struct recover_work;

	struct list_head submit_list;

	struct msm_snapshot *snapshot;
	struct msm_snapshot *snapshot;
};
};


+1 −0
Original line number Original line Diff line number Diff line
@@ -47,6 +47,7 @@ struct msm_ringbuffer *msm_ringbuffer_new(struct msm_gpu *gpu, int id)
	ring->next  = ring->start;
	ring->next  = ring->start;
	ring->cur   = ring->start;
	ring->cur   = ring->start;


	INIT_LIST_HEAD(&ring->submits);
	spin_lock_init(&ring->lock);
	spin_lock_init(&ring->lock);


	return ring;
	return ring;
+1 −0
Original line number Original line Diff line number Diff line
@@ -28,6 +28,7 @@ struct msm_ringbuffer {
	uint64_t iova;
	uint64_t iova;
	uint32_t submitted_fence;
	uint32_t submitted_fence;
	spinlock_t lock;
	spinlock_t lock;
	struct list_head submits;
};
};


struct msm_ringbuffer *msm_ringbuffer_new(struct msm_gpu *gpu, int id);
struct msm_ringbuffer *msm_ringbuffer_new(struct msm_gpu *gpu, int id);