diff options
author | Christian König <christian.koenig@amd.com> | 2015-10-20 18:38:07 +0300 |
---|---|---|
committer | Alex Deucher <alexander.deucher@amd.com> | 2015-10-30 08:51:11 +0300 |
commit | ee327caf1a2cdba9313167c36db2d7ff02d534bc (patch) | |
tree | c09c7b851e4a819944375b0c420cc2e689550c4e /drivers/gpu | |
parent | 318cd340c5573a1f021f5b7711893133fe5e8480 (diff) | |
download | linux-ee327caf1a2cdba9313167c36db2d7ff02d534bc.tar.xz |
drm/amdgpu: switch to common fence_wait_any_timeout v2
No need to duplicate the functionality any more.
v2: fix handling if no fence is available.
Signed-off-by: Christian König <christian.koenig@amd.com>
Reviewed-by: Alex Deucher <alexander.deucher@amd.com> (v1)
Diffstat (limited to 'drivers/gpu')
-rw-r--r-- | drivers/gpu/drm/amd/amdgpu/amdgpu.h | 4 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c | 98 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/amdgpu/amdgpu_sa.c | 20 |
3 files changed, 13 insertions, 109 deletions
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h index a9c0def6ce31..dd7d2ce2355c 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h @@ -447,10 +447,6 @@ int amdgpu_fence_wait_next(struct amdgpu_ring *ring); int amdgpu_fence_wait_empty(struct amdgpu_ring *ring); unsigned amdgpu_fence_count_emitted(struct amdgpu_ring *ring); -signed long amdgpu_fence_wait_any(struct fence **array, - uint32_t count, - bool intr, - signed long t); struct amdgpu_fence *amdgpu_fence_ref(struct amdgpu_fence *fence); void amdgpu_fence_unref(struct amdgpu_fence **fence); diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c index 663caa9d1175..c4bb28292b9f 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c @@ -822,104 +822,6 @@ static const char *amdgpu_fence_get_timeline_name(struct fence *f) return (const char *)fence->ring->name; } -static bool amdgpu_test_signaled_any(struct fence **fences, uint32_t count) -{ - int idx; - struct fence *fence; - - for (idx = 0; idx < count; ++idx) { - fence = fences[idx]; - if (fence) { - if (test_bit(FENCE_FLAG_SIGNALED_BIT, &fence->flags)) - return true; - } - } - return false; -} - -struct amdgpu_wait_cb { - struct fence_cb base; - struct task_struct *task; -}; - -static void amdgpu_fence_wait_cb(struct fence *fence, struct fence_cb *cb) -{ - struct amdgpu_wait_cb *wait = - container_of(cb, struct amdgpu_wait_cb, base); - wake_up_process(wait->task); -} - -/** - * Wait the fence array with timeout - * - * @array: the fence array with amdgpu fence pointer - * @count: the number of the fence array - * @intr: when sleep, set the current task interruptable or not - * @t: timeout to wait - * - * It will return when any fence is signaled or timeout. - */ -signed long amdgpu_fence_wait_any(struct fence **array, uint32_t count, - bool intr, signed long t) -{ - struct amdgpu_wait_cb *cb; - struct fence *fence; - unsigned idx; - - BUG_ON(!array); - - cb = kcalloc(count, sizeof(struct amdgpu_wait_cb), GFP_KERNEL); - if (cb == NULL) { - t = -ENOMEM; - goto err_free_cb; - } - - for (idx = 0; idx < count; ++idx) { - fence = array[idx]; - if (fence) { - cb[idx].task = current; - if (fence_add_callback(fence, - &cb[idx].base, amdgpu_fence_wait_cb)) { - /* The fence is already signaled */ - goto fence_rm_cb; - } - } - } - - while (t > 0) { - if (intr) - set_current_state(TASK_INTERRUPTIBLE); - else - set_current_state(TASK_UNINTERRUPTIBLE); - - /* - * amdgpu_test_signaled_any must be called after - * set_current_state to prevent a race with wake_up_process - */ - if (amdgpu_test_signaled_any(array, count)) - break; - - t = schedule_timeout(t); - - if (t > 0 && intr && signal_pending(current)) - t = -ERESTARTSYS; - } - - __set_current_state(TASK_RUNNING); - -fence_rm_cb: - for (idx = 0; idx < count; ++idx) { - fence = array[idx]; - if (fence && cb[idx].base.func) - fence_remove_callback(fence, &cb[idx].base); - } - -err_free_cb: - kfree(cb); - - return t; -} - const struct fence_ops amdgpu_fence_ops = { .get_driver_name = amdgpu_fence_get_driver_name, .get_timeline_name = amdgpu_fence_get_timeline_name, diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_sa.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_sa.c index 5cb27d525e43..3f48759793de 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_sa.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_sa.c @@ -337,6 +337,7 @@ int amdgpu_sa_bo_new(struct amdgpu_device *adev, { struct fence *fences[AMDGPU_MAX_RINGS]; unsigned tries[AMDGPU_MAX_RINGS]; + unsigned count; int i, r; signed long t; @@ -371,13 +372,18 @@ int amdgpu_sa_bo_new(struct amdgpu_device *adev, /* see if we can skip over some allocations */ } while (amdgpu_sa_bo_next_hole(sa_manager, fences, tries)); - spin_unlock(&sa_manager->wq.lock); - t = amdgpu_fence_wait_any(fences, AMDGPU_MAX_RINGS, - false, MAX_SCHEDULE_TIMEOUT); - r = (t > 0) ? 0 : t; - spin_lock(&sa_manager->wq.lock); - /* if we have nothing to wait for block */ - if (r == -ENOENT) { + for (i = 0, count = 0; i < AMDGPU_MAX_RINGS; ++i) + if (fences[i]) + fences[count++] = fences[i]; + + if (count) { + spin_unlock(&sa_manager->wq.lock); + t = fence_wait_any_timeout(fences, count, false, + MAX_SCHEDULE_TIMEOUT); + r = (t > 0) ? 0 : t; + spin_lock(&sa_manager->wq.lock); + } else { + /* if we have nothing to wait for block */ r = wait_event_interruptible_locked( sa_manager->wq, amdgpu_sa_event(sa_manager, size, align) |