From patchwork Wed May 25 21:04:22 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Alex Deucher X-Patchwork-Id: 9136203 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 89476607D7 for ; Wed, 25 May 2016 21:04:58 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 7C32625EF7 for ; Wed, 25 May 2016 21:04:58 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 71100282DA; Wed, 25 May 2016 21:04:58 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-3.3 required=2.0 tests=BAYES_00, DKIM_ADSP_CUSTOM_MED, DKIM_SIGNED, FREEMAIL_FROM, RCVD_IN_DNSWL_MED, RCVD_IN_SORBS_WEB, T_DKIM_INVALID autolearn=ham version=3.3.1 Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id D83FE25EF7 for ; Wed, 25 May 2016 21:04:57 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 950BA6E740; Wed, 25 May 2016 21:04:47 +0000 (UTC) X-Original-To: dri-devel@lists.freedesktop.org Delivered-To: dri-devel@lists.freedesktop.org Received: from mail-ig0-x243.google.com (mail-ig0-x243.google.com [IPv6:2607:f8b0:4001:c05::243]) by gabe.freedesktop.org (Postfix) with ESMTPS id D34916E2A9 for ; Wed, 25 May 2016 21:04:38 +0000 (UTC) Received: by mail-ig0-x243.google.com with SMTP id ct2so2435859igb.3 for ; Wed, 25 May 2016 14:04:38 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=9XCOLcqPw93vKMqb/4vvPskZO0fRFzOElbj/DJCM/JY=; b=UK+5ANWZtEY7GTUy0XmVk7YRNYwy0lt8zc5mqAAshvep/VfntFLRzjaLs9lsJWZUyO P8bylhIc2cG3AQz+pzrMGCkPgTqBGALoHO+WCUmpwyWA5XhDccl2Jy0z5TrrRurF+k6r 9X5HDpbTE/v/FGkCX37xpwePyhy8/Y5c5KPMEGybd0XuhB36N9yLK2PjeZxiiUKbbRmb 9vXeVqu7ukCrFW2Srdxkj4M3HjEUuy9/2RoDm3RTrPjgcCsoKt2sIJWps9pQ9UcbqkMt MODAscGQFMvdBC2YJf5mhUsgmYFcQdCzd9p4g83z6MOEM+DR/VIbSpSn8q4fOc0ZjTYV vz3A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=9XCOLcqPw93vKMqb/4vvPskZO0fRFzOElbj/DJCM/JY=; b=aUh3RZp7FCtPUhQbviosjDZZJndkjYFAa+ic803iR3ZQQzSfgE8Jy9v/i3GDhRqm0u LMGqIrDsj7Twn3qvb100mJjK3RmQnxdipCMiPfqE4GTaagAfJ403FG6GRSuK1kl+wVaD KUa1zVvKOHHFsOa0o68BniAAPX4jgodAUZIlxd/ILXeHsArfNV9yWOMOE9xkbi7gQkRY +JH+0D+DgdOWndztStrqaERM63PxucN8hpOTne8EqcLAia/EUfSgQhsUGwmFqjRpKBif 1CeaVGyris8ydwUBbTise7xmmuyk3bztFK0j/UKUl1dLOPOU6m9EZd549HqyCidFX5+g E1pQ== X-Gm-Message-State: ALyK8tLhX+DGh7imjJHGUbDe7g7xI8E7ow9ie6keVK6wYwJOhJ70Ir9A2ecKwpnEGIiO9A== X-Received: by 10.50.44.3 with SMTP id a3mr5529891igm.61.1464210277723; Wed, 25 May 2016 14:04:37 -0700 (PDT) Received: from cm.amd.com ([165.204.55.251]) by smtp.gmail.com with ESMTPSA id q128sm3364190ioe.43.2016.05.25.14.04.36 (version=TLSv1/SSLv3 cipher=OTHER); Wed, 25 May 2016 14:04:37 -0700 (PDT) From: Alex Deucher X-Google-Original-From: Alex Deucher To: dri-devel@lists.freedesktop.org Subject: [PATCH 8/8] drm/amdgpu: fix and cleanup job destruction Date: Wed, 25 May 2016 17:04:22 -0400 Message-Id: <1464210262-2912-9-git-send-email-alexander.deucher@amd.com> X-Mailer: git-send-email 2.5.5 In-Reply-To: <1464210262-2912-1-git-send-email-alexander.deucher@amd.com> References: <1464210262-2912-1-git-send-email-alexander.deucher@amd.com> MIME-Version: 1.0 Cc: Alex Deucher , =?UTF-8?q?Christian=20K=C3=B6nig?= X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" X-Virus-Scanned: ClamAV using ClamSMTP From: Christian König Remove the job reference counting and just properly destroy it from a work item which blocks on any potential running timeout handler. Signed-off-by: Christian König Reviewed-by: Monk.Liu Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/amdgpu.h | 1 - drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c | 3 +- drivers/gpu/drm/amd/amdgpu/amdgpu_job.c | 18 +++-------- drivers/gpu/drm/amd/scheduler/gpu_scheduler.c | 46 +++++++++++---------------- drivers/gpu/drm/amd/scheduler/gpu_scheduler.h | 25 +++------------ 5 files changed, 30 insertions(+), 63 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h index ec42dd5..e72104b 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h @@ -755,7 +755,6 @@ int amdgpu_job_alloc_with_ib(struct amdgpu_device *adev, unsigned size, struct amdgpu_job **job); void amdgpu_job_free(struct amdgpu_job *job); -void amdgpu_job_free_func(struct kref *refcount); int amdgpu_job_submit(struct amdgpu_job *job, struct amdgpu_ring *ring, struct amd_sched_entity *entity, void *owner, struct fence **f); diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c index d8cac31..a3d7d13 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c @@ -839,8 +839,7 @@ static int amdgpu_cs_submit(struct amdgpu_cs_parser *p, p->job = NULL; r = amd_sched_job_init(&job->base, &ring->sched, - entity, amdgpu_job_free_func, - p->filp, &fence); + entity, p->filp, &fence); if (r) { amdgpu_job_free(job); return r; diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c index 32132f2..34cd971 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c @@ -28,12 +28,6 @@ #include "amdgpu.h" #include "amdgpu_trace.h" -static void amdgpu_job_free_handler(struct work_struct *ws) -{ - struct amdgpu_job *job = container_of(ws, struct amdgpu_job, base.work_free_job); - amd_sched_job_put(&job->base); -} - static void amdgpu_job_timedout(struct amd_sched_job *s_job) { struct amdgpu_job *job = container_of(s_job, struct amdgpu_job, base); @@ -42,8 +36,6 @@ static void amdgpu_job_timedout(struct amd_sched_job *s_job) job->base.sched->name, atomic_read(&job->ring->fence_drv.last_seq), job->ring->fence_drv.sync_seq); - - amd_sched_job_put(&job->base); } int amdgpu_job_alloc(struct amdgpu_device *adev, unsigned num_ibs, @@ -64,7 +56,6 @@ int amdgpu_job_alloc(struct amdgpu_device *adev, unsigned num_ibs, (*job)->vm = vm; (*job)->ibs = (void *)&(*job)[1]; (*job)->num_ibs = num_ibs; - INIT_WORK(&(*job)->base.work_free_job, amdgpu_job_free_handler); amdgpu_sync_create(&(*job)->sync); @@ -103,9 +94,10 @@ static void amdgpu_job_free_resources(struct amdgpu_job *job) amdgpu_sync_free(&job->sync); } -void amdgpu_job_free_func(struct kref *refcount) +void amdgpu_job_free_cb(struct amd_sched_job *s_job) { - struct amdgpu_job *job = container_of(refcount, struct amdgpu_job, base.refcount); + struct amdgpu_job *job = container_of(s_job, struct amdgpu_job, base); + kfree(job); } @@ -126,8 +118,7 @@ int amdgpu_job_submit(struct amdgpu_job *job, struct amdgpu_ring *ring, if (!f) return -EINVAL; - r = amd_sched_job_init(&job->base, &ring->sched, - entity, amdgpu_job_free_func, owner, &fence); + r = amd_sched_job_init(&job->base, &ring->sched, entity, owner, &fence); if (r) return r; @@ -198,4 +189,5 @@ const struct amd_sched_backend_ops amdgpu_sched_ops = { .dependency = amdgpu_job_dependency, .run_job = amdgpu_job_run, .timedout_job = amdgpu_job_timedout, + .free_job = amdgpu_job_free_cb }; diff --git a/drivers/gpu/drm/amd/scheduler/gpu_scheduler.c b/drivers/gpu/drm/amd/scheduler/gpu_scheduler.c index cb56d90..2425172 100644 --- a/drivers/gpu/drm/amd/scheduler/gpu_scheduler.c +++ b/drivers/gpu/drm/amd/scheduler/gpu_scheduler.c @@ -319,19 +319,13 @@ static bool amd_sched_entity_in(struct amd_sched_job *sched_job) return added; } -static void amd_sched_free_job(struct fence *f, struct fence_cb *cb) { - struct amd_sched_job *job = container_of(cb, struct amd_sched_job, - cb_free_job); - - schedule_work(&job->work_free_job); -} - /* job_finish is called after hw fence signaled, and * the job had already been deleted from ring_mirror_list */ -static void amd_sched_job_finish(struct amd_sched_job *s_job) +static void amd_sched_job_finish(struct work_struct *work) { - struct amd_sched_job *next; + struct amd_sched_job *s_job = container_of(work, struct amd_sched_job, + finish_work); struct amd_gpu_scheduler *sched = s_job->sched; unsigned long flags; @@ -339,19 +333,26 @@ static void amd_sched_job_finish(struct amd_sched_job *s_job) spin_lock_irqsave(&sched->job_list_lock, flags); list_del_init(&s_job->node); if (sched->timeout != MAX_SCHEDULE_TIMEOUT) { - if (cancel_delayed_work(&s_job->work_tdr)) - amd_sched_job_put(s_job); + struct amd_sched_job *next; + + cancel_delayed_work_sync(&s_job->work_tdr); /* queue TDR for next job */ next = list_first_entry_or_null(&sched->ring_mirror_list, struct amd_sched_job, node); - if (next) { - amd_sched_job_get(next); + if (next) schedule_delayed_work(&next->work_tdr, sched->timeout); - } } spin_unlock_irqrestore(&sched->job_list_lock, flags); + sched->ops->free_job(s_job); +} + +static void amd_sched_job_finish_cb(struct fence *f, struct fence_cb *cb) +{ + struct amd_sched_job *job = container_of(cb, struct amd_sched_job, + finish_cb); + schedule_work(&job->finish_work); } static void amd_sched_job_begin(struct amd_sched_job *s_job) @@ -364,10 +365,7 @@ static void amd_sched_job_begin(struct amd_sched_job *s_job) if (sched->timeout != MAX_SCHEDULE_TIMEOUT && list_first_entry_or_null(&sched->ring_mirror_list, struct amd_sched_job, node) == s_job) - { - amd_sched_job_get(s_job); schedule_delayed_work(&s_job->work_tdr, sched->timeout); - } spin_unlock_irqrestore(&sched->job_list_lock, flags); } @@ -390,9 +388,9 @@ void amd_sched_entity_push_job(struct amd_sched_job *sched_job) { struct amd_sched_entity *entity = sched_job->s_entity; - fence_add_callback(&sched_job->s_fence->base, - &sched_job->cb_free_job, amd_sched_free_job); trace_amd_sched_job(sched_job); + fence_add_callback(&sched_job->s_fence->base, &sched_job->finish_cb, + amd_sched_job_finish_cb); wait_event(entity->sched->job_scheduled, amd_sched_entity_in(sched_job)); } @@ -401,20 +399,17 @@ void amd_sched_entity_push_job(struct amd_sched_job *sched_job) int amd_sched_job_init(struct amd_sched_job *job, struct amd_gpu_scheduler *sched, struct amd_sched_entity *entity, - void (*free_cb)(struct kref *refcount), void *owner, struct fence **fence) { - INIT_LIST_HEAD(&job->node); - kref_init(&job->refcount); job->sched = sched; job->s_entity = entity; job->s_fence = amd_sched_fence_create(entity, owner); if (!job->s_fence) return -ENOMEM; - job->s_fence->s_job = job; + INIT_WORK(&job->finish_work, amd_sched_job_finish); + INIT_LIST_HEAD(&job->node); INIT_DELAYED_WORK(&job->work_tdr, amd_sched_job_timedout); - job->free_callback = free_cb; if (fence) *fence = &job->s_fence->base; @@ -468,9 +463,6 @@ static void amd_sched_process_job(struct fence *f, struct fence_cb *cb) struct amd_gpu_scheduler *sched = s_fence->sched; atomic_dec(&sched->hw_rq_count); - - amd_sched_job_finish(s_fence->s_job); - amd_sched_fence_signal(s_fence); trace_amd_sched_process_job(s_fence); diff --git a/drivers/gpu/drm/amd/scheduler/gpu_scheduler.h b/drivers/gpu/drm/amd/scheduler/gpu_scheduler.h index f0de46c..e63034e 100644 --- a/drivers/gpu/drm/amd/scheduler/gpu_scheduler.h +++ b/drivers/gpu/drm/amd/scheduler/gpu_scheduler.h @@ -74,19 +74,16 @@ struct amd_sched_fence { struct amd_gpu_scheduler *sched; spinlock_t lock; void *owner; - struct amd_sched_job *s_job; }; struct amd_sched_job { - struct kref refcount; struct amd_gpu_scheduler *sched; struct amd_sched_entity *s_entity; struct amd_sched_fence *s_fence; - struct fence_cb cb_free_job; - struct work_struct work_free_job; - struct list_head node; - struct delayed_work work_tdr; - void (*free_callback)(struct kref *refcount); + struct fence_cb finish_cb; + struct work_struct finish_work; + struct list_head node; + struct delayed_work work_tdr; }; extern const struct fence_ops amd_sched_fence_ops; @@ -109,6 +106,7 @@ struct amd_sched_backend_ops { struct fence *(*dependency)(struct amd_sched_job *sched_job); struct fence *(*run_job)(struct amd_sched_job *sched_job); void (*timedout_job)(struct amd_sched_job *sched_job); + void (*free_job)(struct amd_sched_job *sched_job); }; enum amd_sched_priority { @@ -154,18 +152,5 @@ void amd_sched_fence_signal(struct amd_sched_fence *fence); int amd_sched_job_init(struct amd_sched_job *job, struct amd_gpu_scheduler *sched, struct amd_sched_entity *entity, - void (*free_cb)(struct kref* refcount), void *owner, struct fence **fence); -static inline void amd_sched_job_get(struct amd_sched_job *job) -{ - if (job) - kref_get(&job->refcount); -} - -static inline void amd_sched_job_put(struct amd_sched_job *job) -{ - if (job) - kref_put(&job->refcount, job->free_callback); -} - #endif