From e0c9da1fe9d8862fc89773208aa170b7c73d093b Mon Sep 17 00:00:00 2001 From: Deepak Nibade Date: Mon, 18 Apr 2016 15:46:10 +0530 Subject: gpu: nvgpu: implement sync refcounting We currently free sync when we find job list empty If aggressive_sync is set to true, we try to free sync during channel unbind() call But we rarely free sync from channel_unbind() call since freeing it when job list is empty is aggressive enough Hence remove sync free code from channel_unbind() Implement refcounting for sync: - get a refcount while submitting a job (and allocate sync if it is not allocated already) - put a refcount while freeing the job - if refcount==0 and if aggressive_sync_destroy is set, free the sync - if aggressive_sync_destroy is not set, we will free the sync during channel close time Bug 200187553 Change-Id: I74e24adb15dc26a375ebca1fdd017b3ad6d57b61 Signed-off-by: Deepak Nibade Reviewed-on: http://git-master/r/1120410 Reviewed-by: Terje Bergstrom Tested-by: Terje Bergstrom --- drivers/gpu/nvgpu/gk20a/channel_sync_gk20a.c | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'drivers/gpu/nvgpu/gk20a/channel_sync_gk20a.c') diff --git a/drivers/gpu/nvgpu/gk20a/channel_sync_gk20a.c b/drivers/gpu/nvgpu/gk20a/channel_sync_gk20a.c index 025b000e..b47c1010 100644 --- a/drivers/gpu/nvgpu/gk20a/channel_sync_gk20a.c +++ b/drivers/gpu/nvgpu/gk20a/channel_sync_gk20a.c @@ -356,6 +356,7 @@ gk20a_channel_syncpt_create(struct channel_gk20a *c) nvhost_syncpt_set_min_eq_max_ext(sp->host1x_pdev, sp->id); + atomic_set(&sp->ops.refcount, 0); sp->ops.wait_syncpt = gk20a_channel_syncpt_wait_syncpt; sp->ops.wait_fd = gk20a_channel_syncpt_wait_fd; sp->ops.incr = gk20a_channel_syncpt_incr; @@ -711,6 +712,7 @@ gk20a_channel_semaphore_create(struct channel_gk20a *c) if (!sema->timeline) goto clean_up; #endif + atomic_set(&sema->ops.refcount, 0); sema->ops.wait_syncpt = gk20a_channel_semaphore_wait_syncpt; sema->ops.wait_fd = gk20a_channel_semaphore_wait_fd; sema->ops.incr = gk20a_channel_semaphore_incr; @@ -727,6 +729,11 @@ clean_up: return NULL; } +void gk20a_channel_sync_destroy(struct gk20a_channel_sync *sync) +{ + sync->destroy(sync); +} + struct gk20a_channel_sync *gk20a_channel_sync_create(struct channel_gk20a *c) { #ifdef CONFIG_TEGRA_GK20A -- cgit v1.2.2