diff options
author | Emily Deng <Emily.Deng@amd.com> | 2018-05-23 03:53:03 -0400 |
---|---|---|
committer | Alex Deucher <alexander.deucher@amd.com> | 2018-05-24 11:07:55 -0400 |
commit | 52bf20f414bc34899203307034227ccc95d6adb3 (patch) | |
tree | f5633a7644e3ffeefbdfc07537c149a61e1876f1 | |
parent | 806f043f0253a76248c554ce9f7303bc25e43314 (diff) |
drm/sched: add rcu_barrier after entity fini
To free the fence from the amdgpu_fence_slab, need twice call_rcu, to avoid
the amdgpu_fence_slab_fini call kmem_cache_destroy(amdgpu_fence_slab) before
kmem_cache_free(amdgpu_fence_slab, fence), add rcu_barrier after drm_sched_entity_fini.
The kmem_cache_free(amdgpu_fence_slab, fence)'s call trace as below:
1.drm_sched_entity_fini ->
drm_sched_entity_cleanup ->
dma_fence_put(entity->last_scheduled) ->
drm_sched_fence_release_finished ->
drm_sched_fence_release_scheduled ->
call_rcu(&fence->finished.rcu, drm_sched_fence_free)
2.drm_sched_fence_free ->
dma_fence_put(fence->parent) ->
amdgpu_fence_release ->
call_rcu(&f->rcu, amdgpu_fence_free) ->
kmem_cache_free(amdgpu_fence_slab, fence);
v2:put the barrier before the kmem_cache_destroy
v3:put the dma_fence_put(fence->parent) before call_rcu in
drm_sched_fence_release_scheduled
Signed-off-by: Emily Deng <Emily.Deng@amd.com>
Reviewed-by: Christian König <christian.koenig@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
-rw-r--r-- | drivers/gpu/drm/scheduler/sched_fence.c | 2 |
1 files changed, 1 insertions, 1 deletions
diff --git a/drivers/gpu/drm/scheduler/sched_fence.c b/drivers/gpu/drm/scheduler/sched_fence.c index 786b47f15783..df4461648e3f 100644 --- a/drivers/gpu/drm/scheduler/sched_fence.c +++ b/drivers/gpu/drm/scheduler/sched_fence.c | |||
@@ -98,7 +98,6 @@ static void drm_sched_fence_free(struct rcu_head *rcu) | |||
98 | struct dma_fence *f = container_of(rcu, struct dma_fence, rcu); | 98 | struct dma_fence *f = container_of(rcu, struct dma_fence, rcu); |
99 | struct drm_sched_fence *fence = to_drm_sched_fence(f); | 99 | struct drm_sched_fence *fence = to_drm_sched_fence(f); |
100 | 100 | ||
101 | dma_fence_put(fence->parent); | ||
102 | kmem_cache_free(sched_fence_slab, fence); | 101 | kmem_cache_free(sched_fence_slab, fence); |
103 | } | 102 | } |
104 | 103 | ||
@@ -114,6 +113,7 @@ static void drm_sched_fence_release_scheduled(struct dma_fence *f) | |||
114 | { | 113 | { |
115 | struct drm_sched_fence *fence = to_drm_sched_fence(f); | 114 | struct drm_sched_fence *fence = to_drm_sched_fence(f); |
116 | 115 | ||
116 | dma_fence_put(fence->parent); | ||
117 | call_rcu(&fence->finished.rcu, drm_sched_fence_free); | 117 | call_rcu(&fence->finished.rcu, drm_sched_fence_free); |
118 | } | 118 | } |
119 | 119 | ||